75 lines
2.1 KiB
Go
75 lines
2.1 KiB
Go
package audio
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func TestDecodeMP3ToPCM16Mono(t *testing.T) {
|
|
encoded, err := os.ReadFile("testdata/sine_16k_mono.mp3")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
pcm16k, sourceRate, err := DecodeMP3ToPCM16Mono(encoded, 16000, 1<<20)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if sourceRate != 16000 {
|
|
t.Fatalf("source sample rate = %d, want 16000", sourceRate)
|
|
}
|
|
if len(pcm16k) == 0 || len(pcm16k)%2 != 0 {
|
|
t.Fatalf("decoded PCM16 length = %d, want nonempty complete samples", len(pcm16k))
|
|
}
|
|
|
|
pcm8k, decodedRate, err := DecodeMP3ToPCM16Mono(encoded, 8000, 1<<20)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if decodedRate != sourceRate {
|
|
t.Fatalf("source sample rate changed between conversions: %d != %d", decodedRate, sourceRate)
|
|
}
|
|
if len(pcm16k) != 2*len(pcm8k) {
|
|
t.Fatalf("16 kHz output has %d bytes, 8 kHz output has %d; want 2:1", len(pcm16k), len(pcm8k))
|
|
}
|
|
}
|
|
|
|
func TestDecodeMP3ToPCM16MonoSupportsMPEG25At8k(t *testing.T) {
|
|
// Fixture is a 1-second 440-Hz mono MP3 generated with FFmpeg/libmp3lame at 8 kHz, including ID3v2 metadata.
|
|
encoded, err := os.ReadFile("testdata/sine_8k_mono_mpeg25.mp3")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !bytes.HasPrefix(encoded, []byte("ID3")) {
|
|
t.Fatal("fixture must include the provider-style ID3v2 header")
|
|
}
|
|
|
|
pcm16, sourceRate, err := DecodeMP3ToPCM16Mono(encoded, 16000, 1<<20)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if sourceRate != 8000 {
|
|
t.Fatalf("source sample rate = %d, want 8000", sourceRate)
|
|
}
|
|
if len(pcm16) == 0 || len(pcm16)%2 != 0 {
|
|
t.Fatalf("decoded PCM16 length = %d, want nonempty complete samples", len(pcm16))
|
|
}
|
|
}
|
|
|
|
func TestDecodeMP3ToPCM16MonoRejectsInvalidAndOversizedAudio(t *testing.T) {
|
|
if _, _, err := DecodeMP3ToPCM16Mono([]byte("not an MP3"), 16000, 1<<20); err == nil {
|
|
t.Fatal("invalid MP3 was accepted")
|
|
} else if errors.Unwrap(err) == nil {
|
|
t.Fatalf("decoder failure cause was hidden: %v", err)
|
|
}
|
|
encoded, err := os.ReadFile("testdata/sine_16k_mono.mp3")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, _, err := DecodeMP3ToPCM16Mono(encoded, 16000, 2048); err == nil {
|
|
t.Fatal("decoded output beyond the limit was accepted")
|
|
}
|
|
}
|