【小程序】C語言吉他調音器-利用FFT傅里葉變換求頻率實現

利用傅里葉變換求得音頻數據的頻率,根據音高頻率對照表,可測試出吉他每根弦與標準音的差值,實現調音器效果。

目錄

  • 程序效果
  • 實現過程
  • 樣例代碼
  • 測試用例
  • 參考資料

程序效果

截圖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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章