PCM音频数据,是模拟音频信号经过数模转换后直接形成的二进制序列,是一种罕见的音频文件格式,因此在对pcm文件进行读写的时候,要选用以二进制的形式打开。
此次读写的PCM文件,单声道,采样率是16KHz,分辨率是16位,也就是2个字节的长度。
在程序编写之前,要考虑一个问题,pcm文件内的数据为short型,我们调整音量倍数可能是float型,因此两者相乘后值为float型,若强行进行取整运算,则会对数据产生较大影响,即引入了较大噪声,因此我们通过以下流程进行实现:short_in→float_in→float_in*float_vol=float_out→short_out。
在short<—>float的转换中,我们利用了归一化的思想,通过几组数据,验证得出他们之间的替换关系,如下:
*short型数据,在人为查看时,并不能直观判定该数据大小,即并不知晓其占满量程的百分比,因此通常归一化为float数据,
那如何进行short和float之间的转换那,可以用以下代码来验证,最后得出两个常量值,当short为负数时,除以32768,且要乘以-1,
当short为正数时,除以32767,就可将short转换为float,当需要存储到文件的时候,再乘以相应的数值,转换为short后进行存储。*/
const short MAX_VOL_S16_N = 32768; //16Bit满量程转换
const short MAX_VOL_S16_P = 32767;
// 以下代码进行了short-float之间的转换
/*
short test_a = 32767;
float test_b = 0.5;
short test_c = -32768;
float test_d = -0.5;
short tmp_s;
short tmp_s2;
float tmp_f;
float tmp_f2;
tmp_s=(short)(test_b*MAX_VOL_S16_P);
tmp_s2=(short)(test_d*MAX_VOL_S16_N);
tmp_f=(float)test_a/MAX_VOL_S16_P;
tmp_f2=(float)test_c/MAX_VOL_S16_N;
printf("%d\n",tmp_s); //运行结果为16383,符合预期
printf("%f\n",tmp_f);//运行结果为1,符合预期
printf("%d\n",tmp_s2);//运行结果为16384,不符合预期
printf("%d\n",(short)(-1*test_d*MAX_VOL_S16_N)); //运行结果为-16383,符合预期
printf("%f\n",tmp_f2);//运行结果为1,不符合预期
printf("%f\n",(float)-1*test_c/MAX_VOL_S16_N); //运行结果为-1,符合预期
*/
/*综上,4个