C++ 实时音频处理
我想使用Qt进行实时音频处理并使用FFTW3显示基频 我分步骤完成的工作: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; //将声音样
double
数组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);