c++将实时接收的pcm二进制裸数据保存为wav格式
时间: 2023-11-18 11:02:09 浏览: 34
要将实时接收的PCM二进制裸数据保存为WAV格式,您可以按照以下步骤进行操作:
1. 打开一个输出文件流,将WAV文件头信息写入文件。WAV文件头包含文件格式、采样率、声道数、位深度等信息。
```c++
#include <fstream>
// 定义WAV文件头结构体
struct WavHeader {
char chunkId[4]; // 文件标识符(RIFF)
int chunkSize; // 文件大小(不包括文件标识符和文件大小字段)
char format[4]; // 格式(WAVE)
char subchunk1Id[4]; // 子块1标识符(fmt )
int subchunk1Size; // 子块1大小(16)
short audioFormat; // 音频格式(1表示PCM)
short numChannels; // 声道数
int sampleRate; // 采样率
int byteRate; // 每秒数据传输率
short blockAlign; // 数据块对齐单位(每个采样点字节数)
short bitsPerSample; // 位深度
char subchunk2Id[4]; // 子块2标识符(data)
int subchunk2Size; // 子块2大小(采样数据大小)
};
WavHeader wavHeader;
// 初始化WAV文件头
void initWavHeader(int sampleRate, short numChannels, short bitsPerSample) {
// 初始化WAV文件头结构体
strcpy(wavHeader.chunkId, "RIFF");
wavHeader.chunkSize = 0;
strcpy(wavHeader.format, "WAVE");
strcpy(wavHeader.subchunk1Id, "fmt ");
wavHeader.subchunk1Size = 16;
wavHeader.audioFormat = 1;
wavHeader.numChannels = numChannels;
wavHeader.sampleRate = sampleRate;
wavHeader.bitsPerSample = bitsPerSample;
wavHeader.byteRate = sampleRate * numChannels * bitsPerSample / 8;
wavHeader.blockAlign = numChannels * bitsPerSample / 8;
strcpy(wavHeader.subchunk2Id, "data");
wavHeader.subchunk2Size = 0;
// 打开输出文件流
std::ofstream outFile("output.wav", std::ios::binary | std::ios::out);
if (!outFile) {
std::cerr << "Failed to open output file!" << std::endl;
exit(1);
}
// 写入WAV文件头
outFile.write((char*)&wavHeader, sizeof(WavHeader));
}
// 关闭输出文件流
void closeWavFile() {
// 打开输出文件流
std::ofstream outFile("output.wav", std::ios::binary | std::ios::out | std::ios::in);
if (!outFile) {
std::cerr << "Failed to open output file!" << std::endl;
exit(1);
}
// 计算文件大小并写入文件
int fileSize = outFile.tellp();
wavHeader.chunkSize = fileSize - 8;
wavHeader.subchunk2Size = fileSize - sizeof(WavHeader);
outFile.seekp(0);
outFile.write((char*)&wavHeader, sizeof(WavHeader));
// 关闭输出文件流
outFile.close();
}
```
2. 在实时接收到PCM数据时,将数据写入输出文件流中。
```c++
void writePcmDataToFile(char* data, int size) {
// 打开输出文件流
std::ofstream outFile("output.wav", std::ios::binary | std::ios::out | std::ios::app);
if (!outFile) {
std::cerr << "Failed to open output file!" << std::endl;
exit(1);
}
// 写入PCM数据
outFile.write(data, size);
// 关闭输出文件流
outFile.close();
}
```
3. 在数据接收结束时,更新WAV文件头信息并关闭输出文件流。
```c++
closeWavFile();
```
这样就完成了将实时接收的PCM二进制裸数据保存为WAV格式的过程。需要注意的是,如果接收的PCM数据是16位的,每个采样点占用2个字节,因此在写入数据时需要将数据转换为char类型的指针。如果接收的数据是其他位深度的,需要相应地修改WAV文件头的位深度字段。