audio/vorbis: add (*Stream).SampleRate

Updates #2996
This commit is contained in:
Hajime Hoshi 2024-05-18 20:09:28 +09:00
parent fbd067c96e
commit d2c58dac8c
2 changed files with 32 additions and 17 deletions

View File

@ -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
}

View File

@ -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)
}
}