我正在使用fftw来获取音频信号的频谱。我在float32中获得了Audio Samples,并且还使用 PortAudio 尝试了其他格式。然后我用fftw取fft。在所有格式中,我从实际频率略微漂移了频率峰值。我的设置是。
我得到的正确/相对准确的读数直到10KHz。然而,当我逐渐增加发电机的频率时,我开始得到偏移。例如,高于10KHz,就会发生这种情况。
Actual frequency Peak on Spectrum
10KHz 10.5KHz
12KHz 12.9KHz
14KHz 15.5KHz
16KHz 18.2KHz
fft代码是这样的。
//Take Samples and do Windowing
for( i=0; i<framesPerBuffer; i++ )
{
samples[i] = in[i];
fft->fftIn[i] = (0.54-(0.46*cos(scale_fact*i))) * samples[i];
}
//Zero Padding
for(i=framesPerBuffer; i<fftSize; i++)
{
fft->fftIn[i] = 0.0;
}
//FFTW Code
{ fftSize = fftSize;
this->fftSize = fftSize;
cout << "Plan start " << endl;
outArraySize = fftSize/2+1;
cout << "fft Processor start \n";
fftIn = ((double*) fftw_malloc(sizeof(double) * fftSize));
fftOut = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * outArraySize );
fftOutAbs = (double*) fftw_malloc(sizeof(double) * outArraySize );
fftwPlan = fftw_plan_dft_r2c_1d(fftSize, fftIn, fftOut, FFTW_ESTIMATE);
// fftwPlan = fftw_plan_dft_r2c_1d(fftSize, fftIn, fftOut, FFTW_MEASURE);
}
//Absolute response
int n=fftSize/2+1;
for(int i=0; i < n; i++)
{
fftOutAbs[i] = sqrt(fftOut[i][0]*fftOut[i][0] + fftOut[i][1]*fftOut[i][1]);
}
for(unsigned int i=0; i < n; i++)
{
mainCureYData[i] = 20.0 * log10(one_over_n * fft->fftOutAbs[i]);
}
我需要一些提示,说明这个问题可能在哪里/为什么?
硬件设置看起来很好,因为峰值在sndpeek应用程序中显示正确。
谢谢,
答案 0 :(得分:0)
您实际上并未显示计算峰值频率的代码,但我的猜测是问题在于:
int n=fftSize/2+1;
这很可能是:
int n=fftSize/2;
有关如何从FFT输出确定频率的说明,请参阅this answer和/或this answer。 (TL; DR:f = Fs * i / n
)