PCM(脉冲 +编码+调制)为原始音频数据采集的一种格式,可以只包含负载(payload),也可以包含头信息(header)+负载(payload)。通过arecord得到的PCM文件是包含头信息(header)+负载(payload)的格式。
头信息为44个字节的格式如下:
内容 | 长度 |
“RIFF” | 4 |
后续字节长度(即文件大小-8) | 4 |
“WAVE” | 4 |
“fmt ” | 4 |
下一结构体变成16位长(10 00 00 00) | 4 |
PCM标示(01 00) | 2 |
通道数 | 2 |
采样率(44 AC 00 00 表示 44100Hz) | 4 |
每秒字节数(采样率x通道数x每个采样点字节数) | 4 |
每个采样点字节数(04 00 表示双声道16位采样) | 2 |
量化比特数(10 00表示16比特采样) | 2 |
“data” | 4 |
实际负载长度 | 4 |
负载格式如下:
1. 8 Bit 单声道:
采样点1 | 采样点2 |
数据1 | 数据2 |
2. 8 Bit 双声道
采样点1 | 采样点2 | ||
声道1数据1 | 声道2数据1 | 声道1数据2 | 声道2数据2 |
3. 16 Bit 单声道:
采样点1 | 采样点2 | ||
数据1低字节 | 数据1高字节 | 数据1低字节 | 数据1高字节 |
4. 16 Bit 双声道
采样点1 | |||
声道1数据1低字节 | 声道1数据1高字节 | 声道2数据1低字节 | 声道2数据1高字节 |
采样点2 | |||
声道1数据2低字节 | 声道1数据2高字节 | 声道2数据2低字节 | 声道2数据2高字节 |
测试代码如下:
#include <iostream>
int main()
{
FILE* fp=fopen("brocast.pcm","rb");
FILE* fpw=fopen("brocastwb.pcm","wb");
for(int i=0;i<11;i++)//读过44个字节的头信息
{
unsigned char* buffer=(unsigned char*)malloc(4*8);
fread(buffer,4,1,fp);
fwrite(buffer,4,1,fpw);
// printf("%x %x %x %x\n",buffer[0],buffer[1],buffer[2],buffer[3] );
free(buffer);
}
for(int i=0;i<600000;i++)//将左声道的数据写到右声道
{
unsigned char* buffer=(unsigned char*)malloc(4*8);
fread(buffer,4,1,fp);
// buffer[0]=0;
// buffer[1]=0;
// buffer[2] = buffer[2]-abs(buffer[2]-buffer[0]);
buffer[0]=buffer[2];
buffer[1]=buffer[3];
fwrite(buffer,4,1,fpw);
// printf("%x %x %x %x\n",buffer[0],buffer[1],buffer[2],buffer[3] );
free(buffer);
}
fflush(fpw);
fclose(fp);
fclose(fpw);
return 0;
}
功能为:读入brocast.pcm文件,假设是16位采样双声道的音频,将左声道的数据写入右声道,然后保存为brocastwb.pcm文件。