loop_test.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // Copyright 2018 The Ebiten Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package audio_test
  15. import (
  16. "bytes"
  17. "io"
  18. "math"
  19. "testing"
  20. "github.com/hajimehoshi/ebiten/v2/audio"
  21. )
  22. func TestInfiniteLoop(t *testing.T) {
  23. indexToByte := func(index int) byte {
  24. return byte(math.Sin(float64(index)) * 256)
  25. }
  26. src := make([]byte, 256)
  27. for i := range src {
  28. src[i] = indexToByte(i)
  29. }
  30. l := audio.NewInfiniteLoop(bytes.NewReader(src), int64(len(src)))
  31. buf := make([]byte, len(src)*4)
  32. if _, err := io.ReadFull(l, buf); err != nil {
  33. t.Error(err)
  34. }
  35. for i, b := range buf {
  36. got := b
  37. want := indexToByte(i % len(src))
  38. if got != want {
  39. t.Errorf("index: %d, got: %v, want: %v", i, got, want)
  40. }
  41. }
  42. n, err := l.Seek(int64(len(src))*5+128, io.SeekStart)
  43. if err != nil {
  44. t.Error(err)
  45. }
  46. if want := int64(128); n != want {
  47. t.Errorf("got: %v, want: %v", n, want)
  48. }
  49. n2, err := l.Seek(int64(len(src))*6+64, io.SeekCurrent)
  50. if err != nil {
  51. t.Error(err)
  52. }
  53. if want := int64(192); n2 != want {
  54. t.Errorf("got: %v, want: %v", n, want)
  55. }
  56. buf2 := make([]byte, len(src)*7)
  57. if _, err := io.ReadFull(l, buf2); err != nil {
  58. t.Error(err)
  59. }
  60. for i, b := range buf2 {
  61. got := b
  62. want := indexToByte((i + 192) % len(src))
  63. if got != want {
  64. t.Errorf("index: %d, got: %v, want: %v", i, got, want)
  65. }
  66. }
  67. // Seek to negative position is an error.
  68. if _, err := l.Seek(-1, io.SeekStart); err == nil {
  69. t.Errorf("got: %v, want: %v", err, nil)
  70. }
  71. }
  72. func TestInfiniteLoopWithIntro(t *testing.T) {
  73. const (
  74. srcLength = 17 * 4
  75. introLength = 19 * 4
  76. loopLength = 23 * 4
  77. )
  78. indexToByte := func(index int) byte {
  79. return byte(math.Sin(float64(index)) * 256)
  80. }
  81. src := make([]byte, srcLength)
  82. for i := range src {
  83. src[i] = indexToByte(i)
  84. }
  85. srcInf := audio.NewInfiniteLoop(bytes.NewReader(src), srcLength)
  86. srcInf.SetNoBlendForTesting(true)
  87. l := audio.NewInfiniteLoopWithIntro(srcInf, introLength, loopLength)
  88. l.SetNoBlendForTesting(true)
  89. buf := make([]byte, srcLength*4)
  90. if _, err := io.ReadFull(l, buf); err != nil {
  91. t.Error(err)
  92. }
  93. for i, b := range buf {
  94. got := b
  95. want := byte(0)
  96. if i < introLength {
  97. want = indexToByte(i % srcLength)
  98. } else {
  99. want = indexToByte(((i-introLength)%loopLength + introLength) % srcLength)
  100. }
  101. if got != want {
  102. t.Errorf("index: %d, got: %v, want: %v", i, got, want)
  103. }
  104. }
  105. n, err := l.Seek(srcLength*5+128, io.SeekStart)
  106. if err != nil {
  107. t.Error(err)
  108. }
  109. if want := int64((srcLength*5+128-introLength)%loopLength + introLength); n != want {
  110. t.Errorf("got: %v, want: %v", n, want)
  111. }
  112. n2, err := l.Seek(srcLength*6+64, io.SeekCurrent)
  113. if err != nil {
  114. t.Error(err)
  115. }
  116. if want := int64(((srcLength*11+192)-introLength)%loopLength + introLength); n2 != want {
  117. t.Errorf("got: %v, want: %v", n, want)
  118. }
  119. buf2 := make([]byte, srcLength*7)
  120. if _, err := io.ReadFull(l, buf2); err != nil {
  121. t.Error(err)
  122. }
  123. for i, b := range buf2 {
  124. got := b
  125. idx := ((int(n2+int64(i))-introLength)%loopLength + introLength) % srcLength
  126. want := indexToByte(idx)
  127. if got != want {
  128. t.Errorf("index: %d, got: %v, want: %v", i, got, want)
  129. }
  130. }
  131. // Seek to negative position is an error.
  132. if _, err := l.Seek(-1, io.SeekStart); err == nil {
  133. t.Errorf("got: %v, want: %v", err, nil)
  134. }
  135. }
  136. func TestInfiniteLoopWithIncompleteSize(t *testing.T) {
  137. // s1 should work as if 4092 is given.
  138. s1 := audio.NewInfiniteLoop(bytes.NewReader(make([]byte, 4096)), 4095)
  139. n1, err := s1.Seek(4093, io.SeekStart)
  140. if err != nil {
  141. t.Error(err)
  142. }
  143. if got, want := n1, int64(4093-4092); got != want {
  144. t.Errorf("got: %d, want: %d", got, want)
  145. }
  146. // s2 should work as if 2044 and 2044 are given.
  147. s2 := audio.NewInfiniteLoopWithIntro(bytes.NewReader(make([]byte, 4096)), 2047, 2046)
  148. n2, err := s2.Seek(4093, io.SeekStart)
  149. if err != nil {
  150. t.Error(err)
  151. }
  152. if got, want := n2, int64(2044+(4093-(2044+2044))); got != want {
  153. t.Errorf("got: %d, want: %d", got, want)
  154. }
  155. }
  156. type slowReader struct {
  157. src io.ReadSeeker
  158. eof bool
  159. }
  160. func (s *slowReader) Read(buf []byte) (int, error) {
  161. if len(buf) == 0 {
  162. if s.eof {
  163. return 0, io.EOF
  164. }
  165. return 0, nil
  166. }
  167. n, err := s.src.Read(buf[:1])
  168. if err == io.EOF {
  169. s.eof = true
  170. }
  171. return n, err
  172. }
  173. func (s *slowReader) Seek(offset int64, whence int) (int64, error) {
  174. s.eof = false
  175. return s.src.Seek(offset, whence)
  176. }
  177. func TestInfiniteLoopWithSlowSource(t *testing.T) {
  178. src := make([]byte, 4096)
  179. for i := range src {
  180. src[i] = byte(i)
  181. }
  182. r := &slowReader{
  183. src: bytes.NewReader(src),
  184. }
  185. loop := audio.NewInfiniteLoop(r, 4096)
  186. buf := make([]byte, 4096)
  187. // With a slow source, whose Read always reads at most one byte,
  188. // an infinite loop should adjust the reading size along with bitDepthInBytes (= 2).
  189. n0, err := loop.Read(buf)
  190. if err != nil {
  191. t.Error(err)
  192. }
  193. if got, want := n0, 0; got != want {
  194. t.Errorf("got: %d, want: %d", got, want)
  195. }
  196. n1, err := loop.Read(buf)
  197. if err != nil {
  198. t.Error(err)
  199. }
  200. if got, want := n1, 2; got != want {
  201. t.Errorf("got: %d, want: %d", got, want)
  202. }
  203. if got, want := buf[0], byte(0); got != want {
  204. t.Errorf("got: %d, want: %d", got, want)
  205. }
  206. if got, want := buf[1], byte(1); got != want {
  207. t.Errorf("got: %d, want: %d", got, want)
  208. }
  209. n2, err := loop.Read(buf)
  210. if err != nil {
  211. t.Error(err)
  212. }
  213. if got, want := n2, 0; got != want {
  214. t.Errorf("got: %d, want: %d", got, want)
  215. }
  216. n3, err := loop.Read(buf)
  217. if err != nil {
  218. t.Error(err)
  219. }
  220. if got, want := n3, 2; got != want {
  221. t.Errorf("got: %d, want: %d", got, want)
  222. }
  223. if got, want := buf[0], byte(2); got != want {
  224. t.Errorf("got: %d, want: %d", got, want)
  225. }
  226. if got, want := buf[1], byte(3); got != want {
  227. t.Errorf("got: %d, want: %d", got, want)
  228. }
  229. }