用ADC編碼PCM資料錄製WAV格式音訊檔案
阿新 • • 發佈:2018-12-05
因為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,
*/