113 lines
3.0 KiB
Go
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")
|
|
}
|
|
})
|
|
}
|
|
}
|