diff --git a/audio/internal/convert/stereo16.go b/audio/internal/convert/stereoi16.go similarity index 88% rename from audio/internal/convert/stereo16.go rename to audio/internal/convert/stereoi16.go index 87557b73c..12637f898 100644 --- a/audio/internal/convert/stereo16.go +++ b/audio/internal/convert/stereoi16.go @@ -18,22 +18,22 @@ import ( "io" ) -type Stereo16 struct { +type StereoI16 struct { source io.ReadSeeker mono bool eight bool buf []byte } -func NewStereo16(source io.ReadSeeker, mono, eight bool) *Stereo16 { - return &Stereo16{ +func NewStereoI16(source io.ReadSeeker, mono, eight bool) *StereoI16 { + return &StereoI16{ source: source, mono: mono, eight: eight, } } -func (s *Stereo16) Read(b []byte) (int, error) { +func (s *StereoI16) Read(b []byte) (int, error) { l := len(b) if s.mono { l /= 2 @@ -85,7 +85,7 @@ func (s *Stereo16) Read(b []byte) (int, error) { return n, err } -func (s *Stereo16) Seek(offset int64, whence int) (int64, error) { +func (s *StereoI16) Seek(offset int64, whence int) (int64, error) { if s.mono { offset /= 2 } diff --git a/audio/vorbis/vorbis.go b/audio/vorbis/vorbis.go index 76bb9a973..194164505 100644 --- a/audio/vorbis/vorbis.go +++ b/audio/vorbis/vorbis.go @@ -121,14 +121,14 @@ func (s *i16Stream) Length() int64 { return int64(s.totalBytes) } -// decode accepts an ogg stream and returns a decorded stream. -func decode(in io.Reader) (*i16Stream, int, int, error) { +// decodeI16 accepts an ogg stream and returns a decorded stream. +func decodeI16(in io.Reader) (*i16Stream, error) { r, err := oggvorbis.NewReader(in) if err != nil { - return nil, 0, 0, err + return nil, err } if r.Channels() != 1 && r.Channels() != 2 { - return nil, 0, 0, fmt.Errorf("vorbis: number of channels must be 1 or 2 but was %d", r.Channels()) + return nil, fmt.Errorf("vorbis: number of channels must be 1 or 2 but was %d", r.Channels()) } s := &i16Stream{ @@ -138,15 +138,16 @@ func decode(in io.Reader) (*i16Stream, int, int, error) { posInBytes: 0, vorbisReader: r, } + // Read some data for performance (#297). if _, ok := in.(io.Seeker); ok { if _, err := s.Read(make([]byte, 65536)); err != nil && err != io.EOF { - return nil, 0, 0, err + return nil, err } if _, err := s.Seek(0, io.SeekStart); err != nil { - return nil, 0, 0, err + return nil, err } } - return s, r.Channels(), r.SampleRate(), nil + return s, nil } // DecodeWithoutResampling decodes Ogg/Vorbis data to playable stream. @@ -158,22 +159,22 @@ func decode(in io.Reader) (*i16Stream, int, int, error) { // A Stream doesn't close src even if src implements io.Closer. // Closing the source is src owner's responsibility. func DecodeWithoutResampling(src io.Reader) (*Stream, error) { - i16Stream, channelCount, sampleRate, err := decode(src) + i16Stream, err := decodeI16(src) if err != nil { return nil, err } var s io.ReadSeeker = i16Stream length := i16Stream.Length() - if channelCount == 1 { - s = convert.NewStereo16(s, true, false) + if i16Stream.vorbisReader.Channels() == 1 { + s = convert.NewStereoI16(s, true, false) length *= 2 } stream := &Stream{ readSeeker: s, length: length, - sampleRate: sampleRate, + sampleRate: i16Stream.vorbisReader.SampleRate(), } return stream, nil } @@ -192,19 +193,19 @@ func DecodeWithoutResampling(src io.Reader) (*Stream, error) { // Resampling can be a very heavy task. Stream has a cache for resampling, but the size is limited. // Do not expect that Stream has a resampling cache even after whole data is played. func DecodeWithSampleRate(sampleRate int, src io.Reader) (*Stream, error) { - i16Stream, channelCount, origSampleRate, err := decode(src) + i16Stream, err := decodeI16(src) if err != nil { return nil, err } var s io.ReadSeeker = i16Stream length := i16Stream.Length() - if channelCount == 1 { - s = convert.NewStereo16(s, true, false) + if i16Stream.vorbisReader.Channels() == 1 { + s = convert.NewStereoI16(s, true, false) length *= 2 } - if origSampleRate != sampleRate { - r := convert.NewResampling(s, length, origSampleRate, sampleRate, bitDepthInBytesInt16) + if i16Stream.vorbisReader.SampleRate() != sampleRate { + r := convert.NewResampling(s, length, i16Stream.vorbisReader.SampleRate(), sampleRate, bitDepthInBytesInt16) s = r length = r.Length() } diff --git a/audio/wav/decode.go b/audio/wav/decode.go index 428b365f5..ad33da913 100644 --- a/audio/wav/decode.go +++ b/audio/wav/decode.go @@ -198,7 +198,7 @@ chunks: var s io.ReadSeeker = newSectionReader(src, headerSize, dataSize) if mono || bitsPerSample != 16 { - s = convert.NewStereo16(s, mono, bitsPerSample != 16) + s = convert.NewStereoI16(s, mono, bitsPerSample != 16) if mono { dataSize *= 2 }