fft的16bit Audio :: peak在2f出现错误

时间:2015-06-08 15:00:05

标签: c++ audio fft fftw portaudio

我正在使用Port Audio在我的电脑上(在-1和+1之间)使用32位浮动音频(44.1Khz)并使用fftw获取fft。

现在我需要采用16bit int Audio并取其fft。我已将音频样本转换为-1到+1之间的浮点数。 fft工作但峰值出现在它应该的频率的2倍处,因此最大频率分辨率也降低了。因此,对于44KHz,我能看到的最大分量大约是10KHz,而它是大约20KHz,32位int / float。

例如,如果我从Sign generator向声卡发出10KHz信号,则峰值现在显示为20KHz。而我唯一改变的是从paInt32到paInt16的格式。它在paInt32格式上正常工作。

  outputStreamParam.channelCount = 1;
  outputStreamParam.device = Pa_GetDefaultOutputDevice();
  outputStreamParam.sampleFormat = paInt16;
  outputStreamParam.suggestedLatency = suggestedLatency;
  outputStreamParam.hostApiSpecificStreamInfo = NULL;

  inputStreamParam.channelCount = 1;
  inputStreamParam.device = Pa_GetDefaultInputDevice();
  inputStreamParam.sampleFormat = paInt16;
  inputStreamParam.suggestedLatency = suggestedLatency;
  inputStreamParam.hostApiSpecificStreamInfo = NULL; 

将int(16或32)转换为-1到+1之间的浮点数。

int audioProcessor::processingCallback(const void *inputBuffer,
                                        void *outputBuffer,
                                        unsigned long framesPerBuffer,
                                        const PaStreamCallbackTimeInfo* timeInfo,
                                       PaStreamCallbackFlags statusFlags)
{   unsigned int i;
     framesPerBuffer = framesPerBuffer/2;

      int *inint = (int*) inputBuffer;

    float *out = (float*) outputBuffer;
    float *in = (float*) inputBuffer;


     for( i=0; i<framesPerBuffer; i++ )
     {


        in[i] = inint[i]/2147483647.0f;


     }

FFTW处理器代码。

 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);
  cout << "Plan succeed " <<  endl;

    fftwPlan = fftw_plan_dft_r2c_1d(fftSize, fftIn, fftOut, FFTW_MEASURE);
}

1 个答案:

答案 0 :(得分:1)

您需要实现两种不同的转换方法。一个用于int32浮动,另一个用于int16到float。正如目前实现的那样,它在int16情况下使用int32转换。这样做的一个问题是转换为float的缩放因子是错误的。另一个问题是它通过输入信号的速度是预期的两倍,这使得频率全部关闭了2倍。

对于从int16的转换,您需要执行以下操作:

{   
   unsigned int i;
   framesPerBuffer = framesPerBuffer/2;

   short *in = (short*) inputBuffer;
   float *out = (float*) outputBuffer;

   for (i=0; i<framesPerBuffer; i++)
   {
      out[i] = in[i]/32767.0f;
   }

发布代码的另一个问题是它正在将浮点样本写回错误的缓冲区。从sizeof(int)==sizeof(float)开始,您可能没有注意到int32。

此外,framesPerFrameBuffer = framesPerFrameBuffer/2是可疑的。我不明白为什么你需要那个。