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

53 lines
1.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package ai
import (
"encoding/json"
"errors"
"fmt"
"math"
"git.ipao.vip/rogee/go-sip/internal/audio"
)
const (
internalPCM16SampleRate = 16000
minASRSampleRate = 8000
maxASRSampleRate = 48000
)
func parseASRSampleRate(params map[string]json.RawMessage) (int, error) {
raw, ok := params["sample_rate"]
if !ok {
return 0, errors.New("ASR params.sample_rate is required")
}
return parseSampleRateValue(raw, "ASR params.sample_rate")
}
func parseSampleRateValue(raw json.RawMessage, field string) (int, error) {
var rate float64
if err := json.Unmarshal(raw, &rate); err != nil {
return 0, fmt.Errorf("%s must be numeric", field)
}
if math.IsNaN(rate) || math.IsInf(rate, 0) || math.Trunc(rate) != rate || rate < minASRSampleRate || rate > maxASRSampleRate {
return 0, fmt.Errorf("%s must be an integer from 8000 to 48000 Hz", field)
}
return int(rate), nil
}
func prepareASRPCM16(pcm16 []byte, targetRate int) ([]byte, error) {
if len(pcm16) == 0 || len(pcm16)%2 != 0 {
return nil, errors.New("ASR input must contain nonempty signed PCM16 samples")
}
if targetRate < minASRSampleRate || targetRate > maxASRSampleRate {
return nil, errors.New("ASR target sample rate is outside the supported 8000–48000 Hz range")
}
// The media layer uses the same resampler when converting the supported
// 8-kHz PCMA wire audio to the agent's 16-kHz PCM16 format.
resampled := audio.ResamplePCM16(pcm16, internalPCM16SampleRate, targetRate)
if len(resampled) == 0 || len(resampled)%2 != 0 {
return nil, errors.New("ASR resampling produced no complete PCM16 samples")
}
return resampled, nil
}