Files
go-sip/internal/ai/asr_sample_rate_test.go
T

113 lines
3.0 KiB
Go

package ai
import (
"bytes"
"strconv"
"testing"
)
func TestBindStoresConfiguredASRSampleRate(t *testing.T) {
for _, rate := range []int{8000, 16000, 24000, 48000} {
t.Run(strconv.Itoa(rate), func(t *testing.T) {
task, providers := currentFixture(t, "asr_only")
task = changeCurrentAgent(t, task, func(agent map[string]any) {
asr := agent["asr"].(map[string]any)
params := asr["params"].(map[string]any)
params["sample_rate"] = rate
})
bound, err := Bind(task, providers)
if err != nil {
t.Fatal(err)
}
if bound.ASR.SampleRate != rate {
t.Fatalf("sample rate = %d, want %d", bound.ASR.SampleRate, rate)
}
})
}
}
func TestBindRejectsMissingASRSampleRate(t *testing.T) {
task, providers := currentFixture(t, "asr_only")
task = changeCurrentAgent(t, task, func(agent map[string]any) {
asr := agent["asr"].(map[string]any)
params := asr["params"].(map[string]any)
delete(params, "sample_rate")
})
if _, err := Bind(task, providers); err == nil {
t.Fatal("Bind accepted ASR parameters without sample_rate")
}
}
func TestBindRejectsInvalidASRSampleRates(t *testing.T) {
for name, rate := range map[string]any{
"null": nil,
"string": "8000",
"fractional": 8000.5,
"boolean": true,
"zero": 0,
"below-min": 7999,
"above-max": 48001,
} {
t.Run(name, func(t *testing.T) {
task, providers := currentFixture(t, "asr_only")
task = changeCurrentAgent(t, task, func(agent map[string]any) {
asr := agent["asr"].(map[string]any)
params := asr["params"].(map[string]any)
params["sample_rate"] = rate
})
if _, err := Bind(task, providers); err == nil {
t.Fatalf("Bind accepted invalid sample_rate %v", rate)
}
})
}
}
func TestPrepareASRPCM16ResamplesToConfiguredRate(t *testing.T) {
input := []byte{1, 0, 2, 0, 3, 0, 4, 0}
got, err := prepareASRPCM16(input, 8000)
if err != nil {
t.Fatal(err)
}
if want := []byte{1, 0, 3, 0}; !bytes.Equal(got, want) {
t.Fatalf("resampled PCM16 = %v, want %v", got, want)
}
if want := []byte{1, 0, 2, 0, 3, 0, 4, 0}; !bytes.Equal(input, want) {
t.Fatalf("input PCM16 was modified: %v", input)
}
}
func TestPrepareASRPCM16CopiesAtInternalRate(t *testing.T) {
input := []byte{1, 0, 2, 0}
got, err := prepareASRPCM16(input, internalPCM16SampleRate)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(got, input) {
t.Fatalf("PCM16 = %v, want %v", got, input)
}
got[0] = 9
if input[0] != 1 {
t.Fatal("prepared ASR audio aliases the caller's PCM buffer")
}
}
func TestPrepareASRPCM16RejectsInvalidAudioOrRate(t *testing.T) {
for name, test := range map[string]struct {
pcm []byte
rate int
}{
"empty": {nil, 8000},
"odd-length": {[]byte{1}, 8000},
"too-short-after-downsample": {[]byte{1, 0}, 8000},
"below-min-rate": {[]byte{1, 0, 2, 0}, 7999},
"above-max-rate": {[]byte{1, 0, 2, 0}, 48001},
} {
t.Run(name, func(t *testing.T) {
if _, err := prepareASRPCM16(test.pcm, test.rate); err == nil {
t.Fatal("expected conversion to fail")
}
})
}
}