package recorder import ( "encoding/binary" "os" ) func writeWAV(path string, samples []float32, sampleRate int) error { f, err := os.Create(path) if err != nil { return err } defer f.Close() // 16-bit PCM dataSize := uint32(len(samples) * 2) // RIFF header if _, err := f.Write([]byte("RIFF")); err != nil { return err } if err := binary.Write(f, binary.LittleEndian, uint32(36)+dataSize); err != nil { return err } if _, err := f.Write([]byte("WAVE")); err != nil { return err } // fmt chunk if _, err := f.Write([]byte("fmt ")); err != nil { return err } if err := binary.Write(f, binary.LittleEndian, uint32(16)); err != nil { return err } if err := binary.Write(f, binary.LittleEndian, uint16(1)); err != nil { // PCM return err } if err := binary.Write(f, binary.LittleEndian, uint16(1)); err != nil { // mono return err } if err := binary.Write(f, binary.LittleEndian, uint32(sampleRate)); err != nil { return err } byteRate := uint32(sampleRate * 2) if err := binary.Write(f, binary.LittleEndian, byteRate); err != nil { return err } if err := binary.Write(f, binary.LittleEndian, uint16(2)); err != nil { // block align return err } if err := binary.Write(f, binary.LittleEndian, uint16(16)); err != nil { // bits return err } // data chunk if _, err := f.Write([]byte("data")); err != nil { return err } if err := binary.Write(f, binary.LittleEndian, dataSize); err != nil { return err } // samples for _, s := range samples { v := int16(clip(s * 32767)) if err := binary.Write(f, binary.LittleEndian, v); err != nil { return err } } return nil } func clip(v float32) float32 { if v > 32767 { return 32767 } if v < -32768 { return -32768 } return v }