audio/vorbis: Add DecodeWithSampleRate

Updates #1460
This commit is contained in:
Hajime Hoshi 2021-01-06 22:57:21 +09:00
parent 5b7ed246c0
commit 96ca0a7ff9
2 changed files with 24 additions and 10 deletions

View File

@ -137,16 +137,16 @@ func decode(in io.ReadSeeker) (*decoded, int, int, error) {
return d, r.Channels(), r.SampleRate(), nil
}
// Decode decodes Ogg/Vorbis data to playable stream.
// DecodeWithSampleRate decodes Ogg/Vorbis data to playable stream.
//
// Decode returns error when decoding fails or IO error happens.
// DecodeWithSampleRate returns error when decoding fails or IO error happens.
//
// Decode automatically resamples the stream to fit with the audio context if necessary.
// DecodeWithSampleRate automatically resamples the stream to fit with the audio context if necessary.
//
// A Stream doesn't close src even if src implements io.Closer.
// Closing the source is src owner's responsibility.
func Decode(context *audio.Context, src io.ReadSeeker) (*Stream, error) {
decoded, channelNum, sampleRate, err := decode(src)
func DecodeWithSampleRate(sampleRate int, src io.ReadSeeker) (*Stream, error) {
decoded, channelNum, origSampleRate, err := decode(src)
if err != nil {
return nil, err
}
@ -159,11 +159,25 @@ func Decode(context *audio.Context, src io.ReadSeeker) (*Stream, error) {
s = convert.NewStereo16(s, true, false)
size *= 2
}
if sampleRate != context.SampleRate() {
r := convert.NewResampling(s, size, sampleRate, context.SampleRate())
if origSampleRate != sampleRate {
r := convert.NewResampling(s, size, sampleRate, sampleRate)
s = r
size = r.Length()
}
stream := &Stream{decoded: s, size: size}
return stream, nil
}
// Decode decodes Ogg/Vorbis data to playable stream.
//
// Decode returns error when decoding fails or IO error happens.
//
// Decode automatically resamples the stream to fit with the audio context if necessary.
//
// A Stream doesn't close src even if src implements io.Closer.
// Closing the source is src owner's responsibility.
//
// Deprecated: as of v2.1. Use DecodeWithSampleRate instead.
func Decode(context *audio.Context, src io.ReadSeeker) (*Stream, error) {
return DecodeWithSampleRate(context.SampleRate(), src)
}

View File

@ -29,7 +29,7 @@ var audioContext = audio.NewContext(44100)
func TestMono(t *testing.T) {
bs := test_mono_ogg
s, err := Decode(audioContext, bytes.NewReader(bs))
s, err := DecodeWithSampleRate(audioContext.SampleRate(), bytes.NewReader(bs))
if err != nil {
t.Fatal(err)
}
@ -39,7 +39,7 @@ func TestMono(t *testing.T) {
t.Fatal(err)
}
// Stream decoded by audio/vorbis.Decode() is always 16bit stereo.
// Stream decoded by audio/vorbis.DecodeWithSampleRate() is always 16bit stereo.
got := s.Length()
// On the other hand, the original vorbis package is monoral.
@ -55,7 +55,7 @@ func TestMono(t *testing.T) {
func TestTooShort(t *testing.T) {
bs := test_tooshort_ogg
s, err := Decode(audioContext, bytes.NewReader(bs))
s, err := DecodeWithSampleRate(audioContext.SampleRate(), bytes.NewReader(bs))
if err != nil {
t.Fatal(err)
}