package ffmpeg import ( "bytes" "encoding/binary" ) // encodeWAV writes float32 PCM samples (range [-1, 1]) as a 16-bit PCM mono // WAV file, matching how uma-tts-api's soundfile.write step feeds pydub // (samples get truncated/clamped rather than wrapped on overflow). func encodeWAV(pcm []float32, sampleRate int) []byte { const ( numChannels = 1 bitsPerSample = 16 ) byteRate := sampleRate * numChannels * bitsPerSample / 8 blockAlign := numChannels * bitsPerSample / 8 dataSize := len(pcm) * 2 var buf bytes.Buffer buf.WriteString("RIFF") _ = binary.Write(&buf, binary.LittleEndian, uint32(36+dataSize)) buf.WriteString("WAVE") buf.WriteString("fmt ") _ = binary.Write(&buf, binary.LittleEndian, uint32(16)) // PCM fmt chunk size _ = binary.Write(&buf, binary.LittleEndian, uint16(1)) // PCM format tag _ = binary.Write(&buf, binary.LittleEndian, uint16(numChannels)) _ = binary.Write(&buf, binary.LittleEndian, uint32(sampleRate)) _ = binary.Write(&buf, binary.LittleEndian, uint32(byteRate)) _ = binary.Write(&buf, binary.LittleEndian, uint16(blockAlign)) _ = binary.Write(&buf, binary.LittleEndian, uint16(bitsPerSample)) buf.WriteString("data") _ = binary.Write(&buf, binary.LittleEndian, uint32(dataSize)) for _, sample := range pcm { _ = binary.Write(&buf, binary.LittleEndian, int16(clampSample(sample)*32767)) } return buf.Bytes() } func clampSample(s float32) float32 { switch { case s > 1: return 1 case s < -1: return -1 default: return s } }