decode.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright 2017 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 mp3 provides MP3 decoder.
  15. //
  16. // On desktops and mobiles, a pure Go decoder is used.
  17. // On browsers, a native decoder on the browser is used.
  18. package mp3
  19. import (
  20. "io"
  21. "github.com/hajimehoshi/go-mp3"
  22. "github.com/hajimehoshi/ebiten/v2/audio"
  23. "github.com/hajimehoshi/ebiten/v2/audio/internal/convert"
  24. )
  25. const (
  26. bitDepthInBytesInt16 = 2
  27. bitDepthInBytesFloat32 = 4
  28. )
  29. // Stream is a decoded stream.
  30. type Stream struct {
  31. readSeeker io.ReadSeeker
  32. length int64
  33. sampleRate int
  34. }
  35. // Read is implementation of io.Reader's Read.
  36. func (s *Stream) Read(buf []byte) (int, error) {
  37. return s.readSeeker.Read(buf)
  38. }
  39. // Seek is implementation of io.Seeker's Seek.
  40. func (s *Stream) Seek(offset int64, whence int) (int64, error) {
  41. return s.readSeeker.Seek(offset, whence)
  42. }
  43. // Length returns the size of decoded stream in bytes.
  44. func (s *Stream) Length() int64 {
  45. return s.length
  46. }
  47. // SampleRate returns the sample rate of the decoded stream.
  48. func (s *Stream) SampleRate() int {
  49. return s.sampleRate
  50. }
  51. // DecodeF32 decodes an MP3 source and returns a decoded stream in 32bit float, little endian, 2 channels (stereo) format.
  52. //
  53. // DecodeF32 returns error when decoding fails or IO error happens.
  54. //
  55. // The returned Stream's Seek is available only when src is an io.Seeker.
  56. //
  57. // A Stream doesn't close src even if src implements io.Closer.
  58. // Closing the source is src owner's responsibility.
  59. func DecodeF32(src io.Reader) (*Stream, error) {
  60. d, err := mp3.NewDecoder(src)
  61. if err != nil {
  62. return nil, err
  63. }
  64. r := convert.NewFloat32BytesReadSeekerFromInt16BytesReadSeeker(d)
  65. s := &Stream{
  66. readSeeker: r,
  67. length: d.Length() / bitDepthInBytesInt16 * bitDepthInBytesFloat32,
  68. sampleRate: d.SampleRate(),
  69. }
  70. return s, nil
  71. }
  72. // DecodeWithoutResampling decodes an MP3 source and returns a decoded stream in signed 16bit integer, little endian, 2 channels (stereo) format.
  73. //
  74. // DecodeWithoutResampling returns error when decoding fails or IO error happens.
  75. //
  76. // The returned Stream's Seek is available only when src is an io.Seeker.
  77. //
  78. // A Stream doesn't close src even if src implements io.Closer.
  79. // Closing the source is src owner's responsibility.
  80. func DecodeWithoutResampling(src io.Reader) (*Stream, error) {
  81. d, err := mp3.NewDecoder(src)
  82. if err != nil {
  83. return nil, err
  84. }
  85. s := &Stream{
  86. readSeeker: d,
  87. length: d.Length(),
  88. sampleRate: d.SampleRate(),
  89. }
  90. return s, nil
  91. }
  92. // DecodeWithSampleRate decodes an MP3 source and returns a decoded stream in signed 16bit integer, little endian, 2 channels (stereo) format.
  93. //
  94. // DecodeWithSampleRate returns error when decoding fails or IO error happens.
  95. //
  96. // DecodeWithSampleRate automatically resamples the stream to fit with sampleRate if necessary.
  97. //
  98. // The returned Stream's Seek is available only when src is an io.Seeker.
  99. //
  100. // A Stream doesn't close src even if src implements io.Closer.
  101. // Closing the source is src owner's responsibility.
  102. //
  103. // Resampling can be a very heavy task. Stream has a cache for resampling, but the size is limited.
  104. // Do not expect that Stream has a resampling cache even after whole data is played.
  105. func DecodeWithSampleRate(sampleRate int, src io.Reader) (*Stream, error) {
  106. d, err := mp3.NewDecoder(src)
  107. if err != nil {
  108. return nil, err
  109. }
  110. var r io.ReadSeeker = d
  111. length := d.Length()
  112. if d.SampleRate() != sampleRate {
  113. r2 := convert.NewResampling(d, d.Length(), d.SampleRate(), sampleRate, bitDepthInBytesInt16)
  114. r = r2
  115. length = r2.Length()
  116. }
  117. s := &Stream{
  118. readSeeker: r,
  119. length: length,
  120. sampleRate: sampleRate,
  121. }
  122. return s, nil
  123. }
  124. // Decode decodes MP3 source and returns a decoded stream in signed 16bit integer, little endian, 2 channels (stereo) format.
  125. //
  126. // Decode returns error when decoding fails or IO error happens.
  127. //
  128. // Decode automatically resamples the stream to fit with the audio context 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. //
  135. // Deprecated: as of v2.1. Use DecodeWithSampleRate instead.
  136. func Decode(context *audio.Context, src io.Reader) (*Stream, error) {
  137. return DecodeWithSampleRate(context.SampleRate(), src)
  138. }