簡體   English   中英

實時音頻處理

[英]Real time audio processing

我想使用Qt進行實時音頻處理使用FFTW3 顯示基本頻率

我已經完成的步驟:

  1. 我捕獲了來自計算機設備的任何聲音,並將其填充到緩沖區中。
  2. 我將聲音樣本分配給double數組
  3. 我計算基本頻率。

問題

我的代碼始終返回0作為基本頻率

QByteArray *buffer;
QAudioInput *audioInput;
audioInput = new QAudioInput(format, this);

//Check the number of samples in input buffer
qint64 len = audioInput->bytesReady();

//Limit sample size
if(len > 4096)
    len = 4096;

//Read sound samples from input device to buffer
qint64 l = input->read(buffer.data(), len);

if(l > 0)
{
    int input_size = BufferSize;

    // Compute corresponding number of complex output samples
    int output_size = (input_size/2 + 1);
    double *input_buffer = static_cast<double*>(fftw_malloc(input_size * sizeof(double)));
    fftw_complex *out = static_cast<fftw_complex*>(fftw_malloc(output_size * sizeof(fftw_complex)));

    //Assign sound samples to double array
    input_buffer = (double*)buffer.data();
    fftw_plan p3;

    //Create plan
    p3 = fftw_plan_dft_r2c_1d(input_size, input_buffer, out, FFTW_ESTIMATE);

    fftw_execute(p3);
    double reout[BufferSize];
    double imgout[BufferSize];
    double magnitude[BufferSize/2];

    long ffond = 0.0; // Position of the frequency
    double max = 0; // Maximal amplitude

    for (int i = 0; i < BufferSize/2; i++)
    {
        reout[i] = out[i][0];
        imgout[i] = out[i][1];
        cout << imgout[i] << endl;
        magnitude[i] = sqrt(reout[i]*reout[i] + imgout[i]*imgout[i]); //Calculate magnitude of first
        double t = sqrt(reout[i]*reout[i] + imgout[i]*imgout[i]);

        if(t > max)
        {
            max = t;
            ffond = i;
        }
    }

    qDebug() << "fundamental frequency is :" << QString::number(ffond*static_cast<double>);
    fftw_destroy_plan(p3);

您可以立即看到兩個問題:

  1. 您沒有應用窗函數 ,因此會發生相當大的頻譜泄漏以及相關的頻譜“拖尾”現象(可能還有較大的DC(0 Hz)分量與相關的“裙邊”)

  2. 您假設頻譜中最大的幅度是基頻,這很可能是不正確的,原因有兩個:(a)您可能有一個較大的0 Hz分量,它大於您的基頻或諧波,並且(b)根據您要分析的聲音的性質,基頻的幅度可能小於諧波(甚至可能完全消失)

我建議您執行以下操作:

  • 在FFT之前應用合適的窗口函數 -這樣可以使您的峰更好地定義,並應減少0 Hz及以上的偽像

  • 從一個合適的檔位而不是0開始搜索,例如,如果您感興趣的最小基本頻率是50 Hz,則從相應的檔位開始以50 Hz而不是從0開始

  • 添加調試選項以圖形方式顯示頻譜-當您想知道為什么結果沒有意義時,此可視化調試輔助工具將極大地幫助您

  • 如果您真正要測量的是基音而不是基頻,那么請閱讀基音檢測算法 ,例如“諧波乘積頻譜”,這比嘗試識別基頻的天真的方法要好得多(后者的頻率不會與一般情況下的音高相同)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM