From d2c58dac8c7a636f51603e8029b679b8604cfb0d Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 18 May 2024 20:09:28 +0900 Subject: [PATCH] audio/vorbis: add (*Stream).SampleRate Updates #2996 --- audio/vorbis/vorbis.go | 23 +++++++++++++++++------ audio/vorbis/vorbis_test.go | 26 +++++++++++++++----------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/audio/vorbis/vorbis.go b/audio/vorbis/vorbis.go index 71381ab9d..919bda10e 100644 --- a/audio/vorbis/vorbis.go +++ b/audio/vorbis/vorbis.go @@ -27,8 +27,9 @@ import ( // Stream is a decoded audio stream. type Stream struct { - decoded io.ReadSeeker - size int64 + decoded io.ReadSeeker + size int64 + sampleRate int } // Read is implementation of io.Reader's Read. @@ -50,6 +51,11 @@ func (s *Stream) Length() int64 { return s.size } +// SampleRate returns the sample rate of the decoded stream. +func (s *Stream) SampleRate() int { + return s.sampleRate +} + type decoder interface { Read([]float32) (int, error) SetPosition(int64) error @@ -152,7 +158,7 @@ func decode(in io.Reader) (*decoded, 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) { - decoded, channelCount, _, err := decode(src) + decoded, channelCount, sampleRate, err := decode(src) if err != nil { return nil, err } @@ -166,8 +172,9 @@ func DecodeWithoutResampling(src io.Reader) (*Stream, error) { size *= 2 } stream := &Stream{ - decoded: s, - size: size, + decoded: s, + size: size, + sampleRate: sampleRate, } return stream, nil } @@ -204,7 +211,11 @@ func DecodeWithSampleRate(sampleRate int, src io.Reader) (*Stream, error) { s = r size = r.Length() } - stream := &Stream{decoded: s, size: size} + stream := &Stream{ + decoded: s, + size: size, + sampleRate: sampleRate, + } return stream, nil } diff --git a/audio/vorbis/vorbis_test.go b/audio/vorbis/vorbis_test.go index 97f2da280..ef028e333 100644 --- a/audio/vorbis/vorbis_test.go +++ b/audio/vorbis/vorbis_test.go @@ -50,16 +50,16 @@ func TestMono(t *testing.T) { } // Stream decoded by audio/vorbis.DecodeWithSampleRate() is always 16bit stereo. - got := s.Length() - // On the other hand, the original vorbis package is monoral. // As Length() represents the number of samples, // this needs to be doubled by 2 (= bytes in 16bits). - want := r.Length() * 2 * 2 - - if got != want { + if got, want := s.Length(), r.Length()*2*2; got != want { t.Errorf("s.Length(): got: %d, want: %d", got, want) } + + if got, want := s.SampleRate(), audioContext.SampleRate(); got != want { + t.Errorf("s.SampleRate(): got: %d, want: %d", got, want) + } } func TestTooShort(t *testing.T) { @@ -70,11 +70,13 @@ func TestTooShort(t *testing.T) { t.Fatal(err) } - got := s.Length() - want := int64(79424) - if got != want { + if got, want := s.Length(), int64(79424); got != want { t.Errorf("s.Length(): got: %d, want: %d", got, want) } + + if got, want := s.SampleRate(), audioContext.SampleRate(); got != want { + t.Errorf("s.SampleRate(): got: %d, want: %d", got, want) + } } type reader struct { @@ -93,9 +95,11 @@ func TestNonSeeker(t *testing.T) { t.Fatal(err) } - got := s.Length() - want := int64(0) - if got != want { + if got, want := s.Length(), int64(0); got != want { t.Errorf("s.Length(): got: %d, want: %d", got, want) } + + if got, want := s.SampleRate(), audioContext.SampleRate(); got != want { + t.Errorf("s.SampleRate(): got: %d, want: %d", got, want) + } }