fftw轻微的峰值不准确/漂移

时间:2015-06-12 14:29:01

标签: c++ signal-processing fft fftw portaudio

我正在使用fftw来获取音频信号的频谱。我在float32中获得了Audio Samples,并且还使用 PortAudio 尝试了其他格式。然后我用fftw取fft。在所有格式中,我从实际频率略微漂移了频率峰值。我的设置是。

  • 信号发生器提供正弦信号。
  • 采样率为44.1KHz。

我得到的正确/相对准确的读数直到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应用程序中显示正确。

谢谢,

1 个答案:

答案 0 :(得分:0)

您实际上并未显示计算峰值频率的代码,但我的猜测是问题在于:

int n=fftSize/2+1;

这很可能是:

int n=fftSize/2;

有关如何从FFT输出确定频率的说明,请参阅this answer和/或this answer。 (TL; DR:f = Fs * i / n