1. 为什么写这篇博文
- 看了很多文章,很多资料都是直接使用FFmpeg工具进行重采样,而且大多数资料错误,比如我看到的csdn站内的48K转16K音频重采样。
- 做个记录本并分享给有用的人
2. 需要做什么准备
- 了解wav文件结构:数据头+原始音频
- 了解音频知识:通道、采样率、采样深度
- 了解原始音频音频数据交织的结构
3.重采样采样深度
常用的采样深度:8bit,16bit,32bit
采样深度越大代表声音越真实,但是数量量会成倍数的增加,负载也越大。
以16bit为例,采样值的范围在–32768~ +32767(int16),
32bit采样值的范围在–1~ +1(float)。
32bit转16bit代码:
int16_t PCMFloat32ToInt16FmtConvert(float sample)
{
if (sample < -0.999999f)
return INT16_MIN;
else if (sample > 0.999999f)
return INT16_MAX;
else if(sample)
return static_cast<int16_t>(sample * 32767.0f);
return 0;
}
void pcm_32bit_to_16bit(char* inbuf, char* outbuf){
int *pbuf = (int*)inbuf;
short* outpbuf = (short*)outbuf;
float magnification =0;
//frame_num:帧数
//sample_chanel:通道数
for (int i = 0; i < frame_num * sample_chanel; i++) {
//int32数据归一化
magnification = *pbuf / (8.0 * 0x10000000);
//转16bit
*outpbuf = PCMFloat32ToInt16FmtConvert(magnification);
pbuf++;
outpbuf++;
}
}
4.重采样采样通道
在很多情况化,比如需要裁剪通道,比如说有一个64通道的数据,但是我们只需要发送起始一个或者2和通道的数据,我们就需要对通道进行裁剪
5.重采样采样率
采样率为单位时间内采样的次数,比如48K,即1秒钟进行48K次采样。常用的采样率8K,16K,44.1K,48K。一般重采样都是对原始数据的采样率降低,倍数之间的转变更加简单,比如48K转18K,相当于每3个采样点去其中一个采样点即可,但是得明白原始数据是怎样交织的。
#define DATE_TYPE int16 //(int8,int16,float)
void pcm_48K_to_16k(FILE* infile, FILE* outfile){
DATE_TYPE read_buf;
while (!feof(fp)) {
size = fread(&read_buf, sizeof(DATE_TYPE), 1, infile);
if (size > 0) {
cnt++;
if (cnt == chanal * 3)
cnt = 0; // 重置计数
if (cnt <= chanal)
fwrite(&read_buf, sizeof(DATE_TYPE), 1, outfile); //写入数据
}
}
}