SJRO6NUN6TTFKDAF7TWQQCNLHSCFD3637UVFUKNMW4UI2OY26AHAC UE4TOOVXPEWPYVE5UEC6OTKYDUDVBTRV22HNOZ4XES2PWCBT24YAC IK7B2IKI726M74IEPSJZXFMTCV2CTJFFIDDF2QBLONGBSBUNJFNQC P6OU2H3DSB5V53JKM2GZ3IXSNSUF23YRXQRWSEJ2U3ARCR5TP4IQC IFVRAERTCCDICNTYTG3TX2WASB6RXQQEJWWXQMQZJSQDQ3HLE5OQC GQ2FYLG2VGDDKQ7TJTCFM2XPLJOAX2N737OZWPRCNKSFIH7YJ6EQC 3QTZPFWEDJVI4FKNCJFOAEHTI5C7P2NQANRIW7D54RHXKETNEYLQC 2C4FPBSQTF4FM4J45HZGWB6L3E56U7M26TLYIRUMXC6SULR6XSQAC 3JA7HYRMHV57SIMGMGPDOMKQ3NBQS2SKOX3EKDHRBQRP7ZPZGFTQC XLL6JFARO2VSNEOJQPXPKZLYYYF7XQGBCR2QJSIFF2RKYZKI25LAC DBOROCRFD6A5SJBMFYFEJI5S5M77X4EFEK6KDQWA5QDMQJKIHRWQC J62FGJ3BGFTUWEOUON4ATYNDFBEUIR6FCIOZSHOVHAA7KGFYHW6AC ILFBB4ISBFKXETYLV7QEO4SKOMPHSWRLKN3MVHEGFOPQ5RQJWDDQC EBCNGTNVY2YFFHKC4PHDEHNBOWJ4JDCEXTTJ3WKD5VWQZLLDZ65AC RFSUR7ZEXTQNHH3IFJAL2NNOTGRPWOWB3PFIVH7VLI2JPTIBMW5AC OCRETPZZPDCUSOPYRH5MVRATJ37TRFGVSIMOI4IV755HFXXOVHEAC RMWLXG5HGB44LH3CEA7FWTAFPSZQZQGH52OHVQJUDP6ASPVDVQJAC EPODZ6CKMHUMTDYIQV3DN662KN2RC3U26LTX6GRHO25WTHBOEZ5AC // WAV parameterschannels := 1bitsPerSample := 16bytesPerSample := bitsPerSample / 8byteRate := sampleRate * channels * bytesPerSampleblockAlign := channels * bytesPerSampledataSize := len(samples) * bytesPerSampletotalSize := 36 + dataSize // 36 = header size before data chunk
// Write WAV and flush; check close to ensure data is persisted.err = func() error {
// Write 44-byte WAV header in one goheader := make([]byte, 44)copy(header[0:4], "RIFF")binary.LittleEndian.PutUint32(header[4:8], uint32(totalSize))copy(header[8:12], "WAVE")copy(header[12:16], "fmt ")binary.LittleEndian.PutUint32(header[16:20], 16) // chunk sizebinary.LittleEndian.PutUint16(header[20:22], 1) // PCM formatbinary.LittleEndian.PutUint16(header[22:24], uint16(channels))binary.LittleEndian.PutUint32(header[24:28], uint32(sampleRate))binary.LittleEndian.PutUint32(header[28:32], uint32(byteRate))binary.LittleEndian.PutUint16(header[32:34], uint16(blockAlign))binary.LittleEndian.PutUint16(header[34:36], uint16(bitsPerSample))copy(header[36:40], "data")binary.LittleEndian.PutUint32(header[40:44], uint32(dataSize))
// WAV parameterschannels := 1bitsPerSample := 16bytesPerSample := bitsPerSample / 8byteRate := sampleRate * channels * bytesPerSampleblockAlign := channels * bytesPerSampledataSize := len(samples) * bytesPerSampletotalSize := 36 + dataSize // 36 = header size before data chunk
if _, err := w.Write(header); err != nil {return err}
// Write 44-byte WAV header in one goheader := make([]byte, 44)copy(header[0:4], "RIFF")binary.LittleEndian.PutUint32(header[4:8], uint32(totalSize))copy(header[8:12], "WAVE")copy(header[12:16], "fmt ")binary.LittleEndian.PutUint32(header[16:20], 16) // chunk sizebinary.LittleEndian.PutUint16(header[20:22], 1) // PCM formatbinary.LittleEndian.PutUint16(header[22:24], uint16(channels))binary.LittleEndian.PutUint32(header[24:28], uint32(sampleRate))binary.LittleEndian.PutUint32(header[28:32], uint32(byteRate))binary.LittleEndian.PutUint16(header[32:34], uint16(blockAlign))binary.LittleEndian.PutUint16(header[34:36], uint16(bitsPerSample))copy(header[36:40], "data")binary.LittleEndian.PutUint32(header[40:44], uint32(dataSize))
// Convert all float64 samples to 16-bit PCM in a single bufferbuf := make([]byte, dataSize)for i, sample := range samples {// Clamp to [-1, 1]if sample > 1.0 {sample = 1.0} else if sample < -1.0 {sample = -1.0
if _, err := w.Write(header); err != nil {return err
if _, err := w.Write(buf); err != nil {return err}
// Convert all float64 samples to 16-bit PCM in a single bufferbuf := make([]byte, dataSize)for i, sample := range samples {// Clamp to [-1, 1]if sample > 1.0 {sample = 1.0} else if sample < -1.0 {sample = -1.0}binary.LittleEndian.PutUint16(buf[i*2:], uint16(int16(sample*32767)))}