vorbis.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright 2015 Hajime Hoshi
  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 vorbis provides Ogg/Vorbis decoder.
  15. package vorbis
  16. import (
  17. "fmt"
  18. "io"
  19. "github.com/jfreymuth/oggvorbis"
  20. "github.com/hajimehoshi/ebiten/v2/audio"
  21. "github.com/hajimehoshi/ebiten/v2/audio/internal/convert"
  22. )
  23. // Stream is a decoded audio stream.
  24. type Stream struct {
  25. decoded io.ReadSeeker
  26. size int64
  27. }
  28. // Read is implementation of io.Reader's Read.
  29. func (s *Stream) Read(p []byte) (int, error) {
  30. return s.decoded.Read(p)
  31. }
  32. // Seek is implementation of io.Seeker's Seek.
  33. //
  34. // Note that Seek can take long since decoding is a relatively heavy task.
  35. func (s *Stream) Seek(offset int64, whence int) (int64, error) {
  36. return s.decoded.Seek(offset, whence)
  37. }
  38. // Length returns the size of decoded stream in bytes.
  39. func (s *Stream) Length() int64 {
  40. return s.size
  41. }
  42. type decoder interface {
  43. Read([]float32) (int, error)
  44. SetPosition(int64) error
  45. Length() int64
  46. Channels() int
  47. SampleRate() int
  48. }
  49. type decoded struct {
  50. totalBytes int
  51. posInBytes int
  52. decoder decoder
  53. decoderr io.Reader
  54. }
  55. func (d *decoded) Read(b []byte) (int, error) {
  56. if d.decoderr == nil {
  57. d.decoderr = convert.NewReaderFromFloat32Reader(d.decoder)
  58. }
  59. l := d.totalBytes - d.posInBytes
  60. if l > len(b) {
  61. l = len(b)
  62. }
  63. if l < 0 {
  64. return 0, io.EOF
  65. }
  66. retry:
  67. n, err := d.decoderr.Read(b[:l])
  68. if err != nil && err != io.EOF {
  69. return 0, err
  70. }
  71. if n == 0 && l > 0 && err != io.EOF {
  72. // When l is too small, decoder's Read might return 0 for a while. Let's retry.
  73. goto retry
  74. }
  75. d.posInBytes += n
  76. if d.posInBytes == d.totalBytes || err == io.EOF {
  77. return n, io.EOF
  78. }
  79. return n, nil
  80. }
  81. func (d *decoded) Seek(offset int64, whence int) (int64, error) {
  82. next := int64(0)
  83. switch whence {
  84. case io.SeekStart:
  85. next = offset
  86. case io.SeekCurrent:
  87. next = int64(d.posInBytes) + offset
  88. case io.SeekEnd:
  89. next = int64(d.totalBytes) + offset
  90. }
  91. // pos should be always even
  92. next = next / 2 * 2
  93. d.posInBytes = int(next)
  94. if err := d.decoder.SetPosition(next / int64(d.decoder.Channels()) / 2); err != nil {
  95. return 0, err
  96. }
  97. d.decoderr = nil
  98. return next, nil
  99. }
  100. func (d *decoded) Length() int64 {
  101. return int64(d.totalBytes)
  102. }
  103. // decode accepts an ogg stream and returns a decorded stream.
  104. func decode(in io.Reader) (*decoded, int, int, error) {
  105. r, err := oggvorbis.NewReader(in)
  106. if err != nil {
  107. return nil, 0, 0, err
  108. }
  109. d := &decoded{
  110. // TODO: r.Length() returns 0 when the format is unknown.
  111. // Should we check that?
  112. totalBytes: int(r.Length()) * r.Channels() * 2, // 2 means 16bit per sample.
  113. posInBytes: 0,
  114. decoder: r,
  115. }
  116. if _, err := d.Read(make([]byte, 65536)); err != nil && err != io.EOF {
  117. return nil, 0, 0, err
  118. }
  119. if _, err := d.Seek(0, io.SeekStart); err != nil {
  120. return nil, 0, 0, err
  121. }
  122. return d, r.Channels(), r.SampleRate(), nil
  123. }
  124. // DecodeWithSampleRate decodes Ogg/Vorbis data to playable stream.
  125. //
  126. // DecodeWithSampleRate returns error when decoding fails or IO error happens.
  127. //
  128. // DecodeWithSampleRate automatically resamples the stream to fit with sampleRate if necessary.
  129. //
  130. // The returned Stream's Seek is available only when src is an io.Seeker.
  131. //
  132. // A Stream doesn't close src even if src implements io.Closer.
  133. // Closing the source is src owner's responsibility.
  134. func DecodeWithSampleRate(sampleRate int, src io.Reader) (*Stream, error) {
  135. decoded, channelNum, origSampleRate, err := decode(src)
  136. if err != nil {
  137. return nil, err
  138. }
  139. if channelNum != 1 && channelNum != 2 {
  140. return nil, fmt.Errorf("vorbis: number of channels must be 1 or 2 but was %d", channelNum)
  141. }
  142. var s io.ReadSeeker = decoded
  143. size := decoded.Length()
  144. if channelNum == 1 {
  145. s = convert.NewStereo16(s, true, false)
  146. size *= 2
  147. }
  148. if origSampleRate != sampleRate {
  149. r := convert.NewResampling(s, size, origSampleRate, sampleRate)
  150. s = r
  151. size = r.Length()
  152. }
  153. stream := &Stream{decoded: s, size: size}
  154. return stream, nil
  155. }
  156. // Decode decodes Ogg/Vorbis data to playable stream.
  157. //
  158. // Decode returns error when decoding fails or IO error happens.
  159. //
  160. // Decode automatically resamples the stream to fit with the audio context if necessary.
  161. //
  162. // The returned Stream's Seek is available only when src is an io.Seeker.
  163. //
  164. // A Stream doesn't close src even if src implements io.Closer.
  165. // Closing the source is src owner's responsibility.
  166. //
  167. // Deprecated: as of v2.1. Use DecodeWithSampleRate instead.
  168. func Decode(context *audio.Context, src io.Reader) (*Stream, error) {
  169. return DecodeWithSampleRate(context.SampleRate(), src)
  170. }