因为PCM文件直接保存采样的量化值,所以按照规定格式,先编写头,再写音频数据就可以了。
这里是录制一个6s长度的WAV音频文件,PCM格式,单声道,44.1kHz采样频率,88200的音频码率,16bit的数据,算下来的数据大小是88200*6=529.200KB。
//(数据字段包含数据的大小。如无扩展块,则值为16;有扩展块,则值为= 16 + 2字节扩展块长度 + 扩展块长度或者值为18(只有扩展块的长度为2字节,值为0)
char header[]= {82,73,70,70, //"RIFF"
0x54,0x13,8,0,//FileSize-8
87,65,86,69,//"WAVE"
102,109,116,32,//"fmt "
16,0,0,0,//数据段16bit
1,0,//PCM格式
1,0,//单声道 2,0,//双声道
68,172,0,0,//采样率44.1kHz
136,88,1,0,//音频码率=采样率*通道数*bit数/8 16,177,2,0,//音频码率=采样率*通道数*bit数/8
2,0,//采样一次占1个字节 4,0,//采样一次占4个字节
16,0,//每个通道8bit数据 16,0,//每个通道16bit数据
100,97,116,97,//"data"
0x30,0x13,8,0//数据长度 6s
};
void writeWave()
{
FIL *f_test;
u8 buffer[100];
u8 data[4];
unsigned long int t;
long int adcValue;
UINT bw;
unsigned int FATFSNumSize;
f_test=(FIL*)mymalloc(SRAMIN,sizeof(FIL));
if(f_test==NULL)
{
printf("申请内存失败\r\n");
return;
}
for(t=0; t<100; t++) buffer[t]=0;
printf("begin write:\r\n");
f_unlink( "0:3.wav");
f_open(f_test, "0:3.wav", FA_OPEN_ALWAYS | FA_WRITE);
f_write(f_test,header,44, &bw);
for(t=0; t<264600; t++) //6s
{
TIM_SetCounter(TIM3,0);//重设TIM3定时器的计数器值
adcValue=Get_Adc(ADC_Channel_10); //12bit
data[0]=((adcValue<<4)&0xFF);
data[1]=(adcValue>>4);
f_write(f_test,data,2, &bw);
time=TIM_GetCounter(TIM3);
while(time<23) //50us 20kHz
{
time=TIM_GetCounter(TIM3); //计算所用时间
}
}
f_close(f_test);
printf("write ok\r\n");
myfree(SRAMIN,f_test); //释放内存
}
因为stm32的adc是12位精度的,所以强行左移4位,低位补零,然后存写入文件中。
每次采样16bit,采集264600次就是529.200KB了。
可能是咪头本身的频率响应不是很好,录制邓紫棋的喜欢你,播放出来感觉高频都没有了,听着像是一个男人的声音,而且还有一些沙沙的低噪。
u16 Get_Adc(u8 ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
//ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles ); //ADC1,ADC通道,480个周期,提高采样时间可以提高精确度
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_56Cycles ); //ADC1,ADC通道,480个周期,提高采样时间可以提高精确度
ADC_SoftwareStartConv(ADC1); //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}
因为使用的是F4的板子,在ADC采样时,采样周期为ADC_SampleTime_480Cycles
时,采样时间会超过1000000/44100=22.67us,所以这里降低了采样周期,也可能是造成后面效果的原因之一。
附邓紫棋-喜欢你.wav文件的信息头:
/* love you
file size:21552932
RIFF chunck:RIFF
RIFF size:21552958
RIFF data:WAVE
Format sub-chunck:fmt
Format size:16
Format data:
Format tag:1
Format channel:1
Format fmt_samplehz:44100
Format fmt_bytepsec:88200
Format fmt_bytesample:2
Format fmt_bitpsample:16
Data sub_chunk:data
Data size:21552888
Data data:
82,73,70,70,62,223,72,1,87,65,86,69,102,109,116,32,16,0,0,0,1,0,1,0,68,172,0,0,136,88,1,0,2,0,16,0,100,97,116,97,248,222,72,1,
*/