首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实时音频处理

实时音频处理
EN

Stack Overflow用户
提问于 2014-06-03 15:05:33
回答 1查看 2.3K关注 0票数 2

我想让实时音频处理,,Qt,用FFTW3显示基频

我所做的每一步

  1. 我从计算机设备中捕捉到任何声音,并将其填充到缓冲器中。
  2. 我将声音样本分配给double数组
  3. 我计算基频。

问题

我的代码总是将作为基频返回。

代码语言:javascript
复制
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);
EN

回答 1

Stack Overflow用户

发布于 2014-06-03 16:27:18

你有两个眼前的问题,我看得出来:

  1. 您没有应用窗口函数,因此会有相当大的光谱泄漏和相关的光谱“模糊”(可能是一个大的DC (0 Hz)分量与相关的“裙边”)。
  2. 你假设频谱中最大的震级是基频,这很可能是不正确的,原因有两个:(a)你很可能有一个很大的0赫兹分量,比你的基波或谐波大;(b)根据你想分析的声音的性质,基波可能比谐波小(它甚至可能完全丢失)。

我建议你做以下几点:

  • 在快速傅立叶变换之前应用一个合适的窗口函数 -这将使你的峰值更好的定义,并应减少在0赫兹以上的人工制品。
  • 从适当的bin而不是0开始搜索,例如,如果您感兴趣的最小基频是50 Hz,那么从对应的bin开始搜索50 Hz,而不是0。
  • 添加一个调试选项,以图形方式显示频谱--当您想知道为什么您的结果没有意义时,这种可视化调试辅助工具将非常有用。
  • 如果你真正要测量的是基频而不是基频,那就在基音检测算法上读一读,例如谐波乘积谱--这将比试图识别基频的天真方法(其频率在一般情况下与基音不相同)要好得多。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24018607

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档