package asteriskws import ( "encoding/binary" "math" "time" "ai-operator/internal/audio" "ai-operator/internal/media" ) func GenerateSilence(codec media.Codec, duration time.Duration, sampleRate int) []byte { if duration <= 0 || sampleRate <= 0 { return nil } switch codec { case media.CodecSLIN16: case media.CodecULaw: samples := int(duration.Seconds() * float64(sampleRate)) out := make([]byte, samples) for i := range out { out[i] = 0xff } return out default: return nil } samples := int(duration.Seconds() * float64(sampleRate)) return make([]byte, samples*2) } func GenerateSineToneSLIN16(frequencyHz float64, duration time.Duration, sampleRate int, amplitude float64) []byte { if frequencyHz <= 0 || duration <= 0 || sampleRate <= 0 { return nil } if amplitude < 0 { amplitude = 0 } if amplitude > 1 { amplitude = 1 } samples := int(duration.Seconds() * float64(sampleRate)) out := make([]byte, samples*2) for i := 0; i < samples; i++ { v := int16(math.Sin(2*math.Pi*frequencyHz*float64(i)/float64(sampleRate)) * amplitude * math.MaxInt16) binary.LittleEndian.PutUint16(out[i*2:], uint16(v)) } return out } func GenerateSineTone(codec media.Codec, frequencyHz float64, duration time.Duration, sampleRate int, amplitude float64) []byte { pcm := GenerateSineToneSLIN16(frequencyHz, duration, sampleRate, amplitude) if codec == media.CodecULaw { return audio.EncodeULaw(pcm) } if codec == media.CodecSLIN16 { return pcm } return nil }