123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- // Copyright 2018 The Ebiten Authors
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package audio_test
- import (
- "bytes"
- "io"
- "math"
- "testing"
- "github.com/hajimehoshi/ebiten/v2/audio"
- )
- func TestInfiniteLoop(t *testing.T) {
- indexToByte := func(index int) byte {
- return byte(math.Sin(float64(index)) * 256)
- }
- src := make([]byte, 256)
- for i := range src {
- src[i] = indexToByte(i)
- }
- l := audio.NewInfiniteLoop(bytes.NewReader(src), int64(len(src)))
- buf := make([]byte, len(src)*4)
- if _, err := io.ReadFull(l, buf); err != nil {
- t.Error(err)
- }
- for i, b := range buf {
- got := b
- want := indexToByte(i % len(src))
- if got != want {
- t.Errorf("index: %d, got: %v, want: %v", i, got, want)
- }
- }
- n, err := l.Seek(int64(len(src))*5+128, io.SeekStart)
- if err != nil {
- t.Error(err)
- }
- if want := int64(128); n != want {
- t.Errorf("got: %v, want: %v", n, want)
- }
- n2, err := l.Seek(int64(len(src))*6+64, io.SeekCurrent)
- if err != nil {
- t.Error(err)
- }
- if want := int64(192); n2 != want {
- t.Errorf("got: %v, want: %v", n, want)
- }
- buf2 := make([]byte, len(src)*7)
- if _, err := io.ReadFull(l, buf2); err != nil {
- t.Error(err)
- }
- for i, b := range buf2 {
- got := b
- want := indexToByte((i + 192) % len(src))
- if got != want {
- t.Errorf("index: %d, got: %v, want: %v", i, got, want)
- }
- }
- // Seek to negative position is an error.
- if _, err := l.Seek(-1, io.SeekStart); err == nil {
- t.Errorf("got: %v, want: %v", err, nil)
- }
- }
- func TestInfiniteLoopWithIntro(t *testing.T) {
- const (
- srcLength = 17 * 4
- introLength = 19 * 4
- loopLength = 23 * 4
- )
- indexToByte := func(index int) byte {
- return byte(math.Sin(float64(index)) * 256)
- }
- src := make([]byte, srcLength)
- for i := range src {
- src[i] = indexToByte(i)
- }
- srcInf := audio.NewInfiniteLoop(bytes.NewReader(src), srcLength)
- srcInf.SetNoBlendForTesting(true)
- l := audio.NewInfiniteLoopWithIntro(srcInf, introLength, loopLength)
- l.SetNoBlendForTesting(true)
- buf := make([]byte, srcLength*4)
- if _, err := io.ReadFull(l, buf); err != nil {
- t.Error(err)
- }
- for i, b := range buf {
- got := b
- want := byte(0)
- if i < introLength {
- want = indexToByte(i % srcLength)
- } else {
- want = indexToByte(((i-introLength)%loopLength + introLength) % srcLength)
- }
- if got != want {
- t.Errorf("index: %d, got: %v, want: %v", i, got, want)
- }
- }
- n, err := l.Seek(srcLength*5+128, io.SeekStart)
- if err != nil {
- t.Error(err)
- }
- if want := int64((srcLength*5+128-introLength)%loopLength + introLength); n != want {
- t.Errorf("got: %v, want: %v", n, want)
- }
- n2, err := l.Seek(srcLength*6+64, io.SeekCurrent)
- if err != nil {
- t.Error(err)
- }
- if want := int64(((srcLength*11+192)-introLength)%loopLength + introLength); n2 != want {
- t.Errorf("got: %v, want: %v", n, want)
- }
- buf2 := make([]byte, srcLength*7)
- if _, err := io.ReadFull(l, buf2); err != nil {
- t.Error(err)
- }
- for i, b := range buf2 {
- got := b
- idx := ((int(n2+int64(i))-introLength)%loopLength + introLength) % srcLength
- want := indexToByte(idx)
- if got != want {
- t.Errorf("index: %d, got: %v, want: %v", i, got, want)
- }
- }
- // Seek to negative position is an error.
- if _, err := l.Seek(-1, io.SeekStart); err == nil {
- t.Errorf("got: %v, want: %v", err, nil)
- }
- }
- func TestInfiniteLoopWithIncompleteSize(t *testing.T) {
- // s1 should work as if 4092 is given.
- s1 := audio.NewInfiniteLoop(bytes.NewReader(make([]byte, 4096)), 4095)
- n1, err := s1.Seek(4093, io.SeekStart)
- if err != nil {
- t.Error(err)
- }
- if got, want := n1, int64(4093-4092); got != want {
- t.Errorf("got: %d, want: %d", got, want)
- }
- // s2 should work as if 2044 and 2044 are given.
- s2 := audio.NewInfiniteLoopWithIntro(bytes.NewReader(make([]byte, 4096)), 2047, 2046)
- n2, err := s2.Seek(4093, io.SeekStart)
- if err != nil {
- t.Error(err)
- }
- if got, want := n2, int64(2044+(4093-(2044+2044))); got != want {
- t.Errorf("got: %d, want: %d", got, want)
- }
- }
- type slowReader struct {
- src io.ReadSeeker
- eof bool
- }
- func (s *slowReader) Read(buf []byte) (int, error) {
- if len(buf) == 0 {
- if s.eof {
- return 0, io.EOF
- }
- return 0, nil
- }
- n, err := s.src.Read(buf[:1])
- if err == io.EOF {
- s.eof = true
- }
- return n, err
- }
- func (s *slowReader) Seek(offset int64, whence int) (int64, error) {
- s.eof = false
- return s.src.Seek(offset, whence)
- }
- func TestInfiniteLoopWithSlowSource(t *testing.T) {
- src := make([]byte, 4096)
- for i := range src {
- src[i] = byte(i)
- }
- r := &slowReader{
- src: bytes.NewReader(src),
- }
- loop := audio.NewInfiniteLoop(r, 4096)
- buf := make([]byte, 4096)
- // With a slow source, whose Read always reads at most one byte,
- // an infinite loop should adjust the reading size along with bitDepthInBytes (= 2).
- n0, err := loop.Read(buf)
- if err != nil {
- t.Error(err)
- }
- if got, want := n0, 0; got != want {
- t.Errorf("got: %d, want: %d", got, want)
- }
- n1, err := loop.Read(buf)
- if err != nil {
- t.Error(err)
- }
- if got, want := n1, 2; got != want {
- t.Errorf("got: %d, want: %d", got, want)
- }
- if got, want := buf[0], byte(0); got != want {
- t.Errorf("got: %d, want: %d", got, want)
- }
- if got, want := buf[1], byte(1); got != want {
- t.Errorf("got: %d, want: %d", got, want)
- }
- n2, err := loop.Read(buf)
- if err != nil {
- t.Error(err)
- }
- if got, want := n2, 0; got != want {
- t.Errorf("got: %d, want: %d", got, want)
- }
- n3, err := loop.Read(buf)
- if err != nil {
- t.Error(err)
- }
- if got, want := n3, 2; got != want {
- t.Errorf("got: %d, want: %d", got, want)
- }
- if got, want := buf[0], byte(2); got != want {
- t.Errorf("got: %d, want: %d", got, want)
- }
- if got, want := buf[1], byte(3); got != want {
- t.Errorf("got: %d, want: %d", got, want)
- }
- }
|