利用傅里葉變換求得音頻數據的頻率,根據音高頻率對照表,可測試出吉他每根弦與標準音的差值,實現調音器效果。
目錄
- 程序效果
- 實現過程
- 樣例代碼
- 測試用例
- 參考資料
程序效果
截圖1:程序效果
輸入需要調整的弦,即開始錄音,彈對應的弦即可,錄音時間大約10秒,10秒後短暫計算處理後會顯示結果。
實現過程
截圖2:流程圖
主要步驟如上,需要注意的細節有:
1.如何獲取有效的4096個採樣數據點
截圖3:有效數據前的雜音及靜音數據
本程序強行跳過前8000個採樣數據點,並且用600進行邊界判定,從第一個大於600的點開始採集。這要求使用的環境很安靜才行,如果有其他聲音干擾,對結果有較大影響。
2.6弦的特殊情況 :1-5弦使用正常時,6弦的頻率值一直爲正常值的2倍,無法定位問題情況下,強行將結果除以2,保證功能可以正常使用。
樣例代碼
1.下載鏈接:https://download.csdn.net/download/u013025955/11190369
部分主要代碼
//傅里葉變換
void getFFTEnergy(double *data)
{
double pr[DATASIZE], pi[DATASIZE], fr[DATASIZE], fi[DATASIZE];
int i=0;
//原始數據作爲實部,虛部填0.0
for (i=0; i<DATASIZE; i++)
{
pr[i] = *(data+i);
pi[i] = 0.0;
}
/*
入參解釋:
pr:採樣數據的實部,對應PCM數據,返回傅里葉變換的模(能量)
pi:採樣數據的虛部,填0.0,返回傅里葉變換的幅角,本程序不使用
DATASIZE:採樣點數,這裏對應4096
12:採樣點數4096對應是2的12次方
fr:傅里葉變換後的實部
fi:傅里葉變換後的虛部
0:使用傅里葉變換功能,1爲逆變換
1:計算模和幅角,0的話不會計算,這裏要注意
*/
//調用FFT快速離散傅里葉變換函數
kfft(pr, pi, DATASIZE, 12, fr, fi, 0, 1);
//模(能量)返回
for (i=0; i<DATASIZE; i++)
{
*(data+i) = pr[i];
}
}
//換算頻率
double getFrequence(double *data, int chooseStr)
{
int locate; //能量值對應的橫座標
int i;
double frequence; //頻率
double max; //能量最大值
max = *data;
//求能量最大值對應的橫座標
for (i=0; i<(DATASIZE/2); i++)
{
if (*(data+i) > max)
{
max = *(data+i);
locate = i;
}
}
//計算頻率,頻率=橫座標*(採樣率/採樣點數)
frequence = locate*(8000.0/DATASIZE);
//6弦的特殊處理,除以2
if (chooseStr == 6)
{
frequence = frequence/2.0;
}
return frequence;
}
測試用例
截圖4:測試用例
參考資料
1.《常用算法程序集(C語言描述)》FFT快速離散傅里葉變換例程
2.深入淺出解釋FFT(一)——用fft求頻譜
https://blog.csdn.net/wordwarwordwar/article/details/68951388
3.fseek()用法 設定文件的當前讀寫位置
https://blog.csdn.net/Tian_fourpieces/article/details/79970098