c语言pcm转wav
时间: 2023-07-28 07:06:46 浏览: 231
将PCM音频数据转换为WAV格式的方法如下:
1. 创建一个WAV文件头。
WAV文件头是固定大小的结构体,包含WAV文件的格式和参数信息。需要根据实际情况填充以下字段:
- ChunkID:文件头标识符,固定为“RIFF”。
- ChunkSize:文件大小,不包括文件头的8个字节。
- Format:文件格式标识符,固定为“WAVE”。
- Subchunk1ID:子块1标识符,固定为“fmt ”。
- Subchunk1Size:子块1大小,固定为16。
- AudioFormat:音频格式,PCM为1。
- NumChannels:声道数,1为单声道,2为双声道。
- SampleRate:采样率,如44100。
- ByteRate:码率,等于采样率×声道数×采样位数/8。
- BlockAlign:数据块对齐单位,等于声道数×采样位数/8。
- BitsPerSample:采样位数,如16。
- Subchunk2ID:子块2标识符,固定为“data”。
- Subchunk2Size:子块2大小,等于音频数据的字节数。
2. 打开PCM文件,读取音频数据。
使用fopen()函数打开PCM文件,使用fread()函数读取PCM数据。
3. 将PCM数据写入WAV文件。
使用fwrite()函数将PCM数据写入WAV文件。
4. 关闭文件。
使用fclose()函数关闭文件。
下面是一个简单的C语言程序,实现了将单声道16位PCM音频数据转换为WAV格式的功能:
```
#include <stdio.h>
typedef struct {
char ChunkID[4]; // RIFF标识符
unsigned int ChunkSize; // 文件大小
char Format[4]; // WAVE格式标识符
char Subchunk1ID[4]; // fmt标识符
unsigned int Subchunk1Size; // fmt块大小
unsigned short AudioFormat; // 音频格式
unsigned short NumChannels; // 声道数
unsigned int SampleRate; // 采样率
unsigned int ByteRate; // 码率
unsigned short BlockAlign; // 数据块对齐单位
unsigned short BitsPerSample; // 采样位数
char Subchunk2ID[4]; // data标识符
unsigned int Subchunk2Size; // 音频数据大小
} WAVE_HEADER;
int main(int argc, char *argv[]) {
char *pcm_file = "test.pcm";
char *wav_file = "test.wav";
unsigned int pcm_size;
unsigned char *pcm_data;
WAVE_HEADER wav_header;
FILE *pcm_fp, *wav_fp;
// 打开PCM文件
pcm_fp = fopen(pcm_file, "rb");
if (!pcm_fp) {
printf("Open PCM file failed!\n");
return -1;
}
// 获取PCM数据大小
fseek(pcm_fp, 0, SEEK_END);
pcm_size = ftell(pcm_fp);
rewind(pcm_fp);
// 分配PCM数据缓冲区
pcm_data = (unsigned char *)malloc(pcm_size);
if (!pcm_data) {
printf("Allocate memory failed!\n");
fclose(pcm_fp);
return -1;
}
// 读取PCM数据
if (fread(pcm_data, 1, pcm_size, pcm_fp) != pcm_size) {
printf("Read PCM data failed!\n");
free(pcm_data);
fclose(pcm_fp);
return -1;
}
// 关闭PCM文件
fclose(pcm_fp);
// 填充WAV文件头
wav_header.ChunkID[0] = 'R';
wav_header.ChunkID[1] = 'I';
wav_header.ChunkID[2] = 'F';
wav_header.ChunkID[3] = 'F';
wav_header.ChunkSize = pcm_size + sizeof(WAVE_HEADER) - 8;
wav_header.Format[0] = 'W';
wav_header.Format[1] = 'A';
wav_header.Format[2] = 'V';
wav_header.Format[3] = 'E';
wav_header.Subchunk1ID[0] = 'f';
wav_header.Subchunk1ID[1] = 'm';
wav_header.Subchunk1ID[2] = 't';
wav_header.Subchunk1ID[3] = ' ';
wav_header.Subchunk1Size = 16;
wav_header.AudioFormat = 1;
wav_header.NumChannels = 1;
wav_header.SampleRate = 44100;
wav_header.ByteRate = 44100 * 2;
wav_header.BlockAlign = 2;
wav_header.BitsPerSample = 16;
wav_header.Subchunk2ID[0] = 'd';
wav_header.Subchunk2ID[1] = 'a';
wav_header.Subchunk2ID[2] = 't';
wav_header.Subchunk2ID[3] = 'a';
wav_header.Subchunk2Size = pcm_size;
// 打开WAV文件
wav_fp = fopen(wav_file, "wb");
if (!wav_fp) {
printf("Open WAV file failed!\n");
free(pcm_data);
return -1;
}
// 写入WAV文件头
if (fwrite(&wav_header, sizeof(WAVE_HEADER), 1, wav_fp) != 1) {
printf("Write WAV header failed!\n");
free(pcm_data);
fclose(wav_fp);
return -1;
}
// 写入PCM数据
if (fwrite(pcm_data, 1, pcm_size, wav_fp) != pcm_size) {
printf("Write WAV data failed!\n");
free(pcm_data);
fclose(wav_fp);
return -1;
}
// 关闭WAV文件
fclose(wav_fp);
// 释放PCM数据缓冲区
free(pcm_data);
printf("Convert PCM to WAV success!\n");
return 0;
}
```
阅读全文