Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 实时音频处理_C++_Qt_Audio_Real Time_Fftw - Fatal编程技术网

C++ 实时音频处理

C++ 实时音频处理,c++,qt,audio,real-time,fftw,C++,Qt,Audio,Real Time,Fftw,我想使用Qt进行实时音频处理并使用FFTW3显示基频 我分步骤完成的工作: 我从计算机设备中捕获任何声音并将其填入缓冲区 我将声音样本分配给double数组 我计算基频 问题 我的代码总是返回0作为基本频率 QByteArray*缓冲区; QAudioInput*音频输入; audioInput=新的QAudioInput(格式,this); //检查输入缓冲区中的样本数 qint64 len=音频输入->字节就绪(); //限制样本量 如果(len>4096) len=4096; //将声音样

我想使用Qt进行实时音频处理并使用FFTW3显示基频

我分步骤完成的工作:
  • 我从计算机设备中捕获任何声音并将其填入缓冲区
  • 我将声音样本分配给
    double
    数组
  • 我计算基频
  • 问题 我的代码总是返回0作为基本频率

    QByteArray*缓冲区;
    QAudioInput*音频输入;
    audioInput=新的QAudioInput(格式,this);
    //检查输入缓冲区中的样本数
    qint64 len=音频输入->字节就绪();
    //限制样本量
    如果(len>4096)
    len=4096;
    //将声音样本从输入设备读取到缓冲器
    qint64 l=输入->读取(buffer.data(),len);
    如果(l>0)
    {
    int input_size=缓冲区大小;
    //计算相应数量的复杂输出样本
    int输出大小=(输入大小/2+1);
    double*input\u buffer=static\u cast(fftw\u malloc(input\u size*sizeof(double));
    fftw_complex*out=静态_cast(fftw_malloc(输出大小*sizeof(fftw_complex));
    //将声音样本分配给双数组
    input_buffer=(双*)buffer.data();
    fftw_计划p3;
    //创建计划
    p3=fftw_计划_dft_r2c_1d(输入_大小、输入_缓冲区、输出、fftw_估计);
    fftw_执行(p3);
    双reout[缓冲区大小];
    双imgout[BufferSize];
    双幅[BufferSize/2];
    long ffond=0.0;//频率的位置
    double max=0;//最大振幅
    对于(int i=0;i我能看出你有两个紧迫的问题:

  • 您没有应用a,因此会出现相当大的频谱“涂抹”(可能是一个大的DC(0 Hz)分量和相关的“裙子”)

  • 你假设频谱中最大的幅度是基频,这很可能是不正确的,原因有两个:(a)你很可能有一个大于基频或谐波的0 Hz分量;(b)根据您试图分析的声音的性质,基波的幅值可能小于谐波(甚至可能完全缺失)

  • 我建议你做以下几点:

    • 在FFT之前应用一个合适的方法-这将使您的峰值得到更好的定义,并将减少0 Hz及以上的伪影

    • 从适当的bin而不是0开始搜索,例如,如果您感兴趣的最小基频是50 Hz,则从相应的bin开始搜索50 Hz而不是0

    • 添加一个调试选项以图形方式显示频谱-当您想知道为什么您的结果没有意义时,此可视化调试辅助工具将非常有帮助

    • 如果您真正想要测量的是基音而不是基音频率,那么请仔细阅读,例如谐波积谱-这比试图识别基音(其频率与一般情况下的基音不同)的天真方法要有效得多


    非常感谢@paul,我想在执行您的建议之前显示震级,但是qdebug()返回“nan”,我非常惊讶
    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);