l_szy_go/pkg/func.go

69 lines
1.7 KiB
Go

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)
}