package pkg import ( "bytes" "encoding/binary" "fmt" "io" "l_szr_go/entity" "os" ) func SaveAsWav(buffer *bytes.Buffer, filename string, config entity.Config) error { if buffer.Len() == 0 { return fmt.Errorf("缓冲区为空,无法保存") } file, err := os.Create(filename) if err != nil { return fmt.Errorf("创建文件失败: %v", err) } defer file.Close() // 写入 WAV 头部 if err := writeWavHeader(file, config.SampleRate, config.BitDepth, config.Channels, buffer.Len()); err != nil { return fmt.Errorf("写入 WAV 头部失败: %v", err) } // 写入 PCM 数据 if _, err := buffer.WriteTo(file); err != nil { return fmt.Errorf("写入 PCM 数据失败: %v", err) } return nil } func writeWavHeader(w io.Writer, sampleRate, bitDepth, channels, dataSize int) error { header := struct { ChunkID [4]byte ChunkSize uint32 Format [4]byte Subchunk1ID [4]byte Subchunk1Size uint32 AudioFormat uint16 NumChannels uint16 SampleRate uint32 ByteRate uint32 BlockAlign uint16 BitsPerSample uint16 Subchunk2ID [4]byte Subchunk2Size uint32 }{ ChunkID: [4]byte{'R', 'I', 'F', 'F'}, ChunkSize: 36 + uint32(dataSize), Format: [4]byte{'W', 'A', 'V', 'E'}, Subchunk1ID: [4]byte{'f', 'm', 't', ' '}, Subchunk1Size: 16, AudioFormat: 1, // PCM NumChannels: uint16(channels), SampleRate: uint32(sampleRate), ByteRate: uint32(sampleRate * channels * bitDepth / 8), BlockAlign: uint16(channels * bitDepth / 8), BitsPerSample: uint16(bitDepth), Subchunk2ID: [4]byte{'d', 'a', 't', 'a'}, Subchunk2Size: uint32(dataSize), } return binary.Write(w, binary.LittleEndian, header) }