2015-06-08 38 views
0

我在我的PC上(-1和+1之间)使用32位浮点音频(44.1Khz),使用Port Audio并使用fftw采用fft。fftw 16bit Audio :: peak出现错误2f

现在我需要采取16位int音频并采取其fft。我已将音频样本转换为在-1和+1之间浮动。 fft可以工作,但峰值出​​现的频率应为2倍,因此最大频率分辨率也会降低。所以在44KHz的情况下,我能看到的最大分量是10KHz左右,而32K的整数/浮点频率是20KHz左右。

例如,如果我将来自符号发生器的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); 
} 
+0

你是否对16位和32位使用相同的int-> float转换? – jaket

回答

1

您需要实施两种不同的转换方法。一个用于int32浮动,另一个用于int16浮动。按照目前的实现,它在int16的情况下使用int32转换。与此相关的一个问题是用于转换为浮点的缩放因子是错误的。另一个问题是,它跨越输入信号两倍的速度,因为它会导致频率全部被关闭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是可疑的。我不明白你为什么需要这个。

+0

谢谢,我知道转换内容有问题。实际上从int16到float的转换在我的代码中也很好,当我声明指针时,编译器可能会首先将样本转换为32位int。 但是,可能是我得到错误频率的原因是,因为我的指针增加了4个字节,所以我总是失去一个采样,输入信号处理速度加快了2倍。 所以现在当我使用你的代码我的样本不会丢失,频率显示正确, – jav321

+0

而[代码] framesperBuffer [/代码]这是我没有得到以及当我使用framesperBuffer为int32,它运行良好。对于int16,程序开始给内存错误。对于int16 framesperBuffer/2工作正常。同样,对于int 8 framesperBuffer/4的作品好吗? – jav321

+0

通常使用术语框架来表示单个采样乘以通道数量,以便如果您有两个通道数据,则一个帧将是两个采样。我会假设除以2是需要的,因为你正在以2倍的速度跨越数据。 – jaket