2012-09-28 35 views
4

我有一個vDSP_zrip & AudioUnit的使用和配置問題。事實上,我配置了AudioUnit以將打包數據保存爲浮點數。 我創建了一個循環緩衝區,當這個緩衝區滿時,我計算一個fft。 我有一個結果,但我不明白爲什麼FFT輸出中是壞的(參見圖)帶浮動緩衝區的FFT輸出AudioUnit

AudioUnit配置:

// describe format 
AudioStreamBasicDescription audioFormat; 
audioFormat.mSampleRate  = 44100; 
audioFormat.mFormatID   = kAudioFormatLinearPCM; 
audioFormat.mFormatFlags  = kAudioFormatFlagsNativeEndian|kAudioFormatFlagIsPacked|kAudioFormatFlagIsFloat|kAudioFormatFlagIsNonInterleaved; 
audioFormat.mFramesPerPacket = 1; 
audioFormat.mChannelsPerFrame = 1; // mono 
audioFormat.mBitsPerChannel = sizeof(float) * 8; 
audioFormat.mBytesPerFrame = audioFormat.mChannelsPerFrame * sizeof(float); 
audioFormat.mBytesPerPacket = audioFormat.mFramesPerPacket * audioFormat.mBytesPerFrame; 

循環緩衝區:

_audioSample = new AudioSample(8192, 44100); 
// in recording callback : 
for(int i = 0; i < bufferList.mNumberBuffers; ++i) 
{ 
    if(!status) 
    { 
     if(_sample->needData()) 
      _sample->put((float*)bufferList.mBuffers[i].mData, 
        bufferList.mBuffers[i].mDataByteSize); 
     [...] 
    } 
} 

VDSP電話:

// get a split complex vector (real signal divided into an even-odd config 
    vDSP_ctoz((COMPLEX *)sample.get(), 2, &_complex, 1, _fftsize); 
    vDSP_fft_zrip(_fftsetup, &_complex, 1, _log2n, kFFTDirection_Forward); 
    // scale (from vDSP reference) 
    float scale = 1.0/(2.0 * _samples); 
    vDSP_vsmul(_complex.realp, 1, &scale, _complex.realp, 1, _fftsize); 
    vDSP_vsmul(_complex.imagp, 1, &scale, _complex.imagp, 1, _fftsize); 
    _complex.imagp[0] = 0.0; 

其中_fftsize = _audioSample.capacity()/2

figure

+0

澄清,你的輸出有什麼不好?它看起來非常合理的FFT輸出。什麼是輸入?預期產出是多少? – admsyn

回答

9

你的輸出看起來很合理,所以我要解釋你的問題更多的是「我如何清理這些結果?」

1)你可能使用矩形窗口

這意味着你沒有做任何windowing,這將引入一些噪聲結果。 VDSP附帶了一些功能進行窗口,您可以使用這樣的:

// N = number of samples in your buffer 
int N = _audioSample.capacity(); 

// allocate space for a hamming window 
float * hammingWindow = (float *) malloc(sizeof(float) * N); 

// generate the window values and store them in the hamming window buffer 
vDSP_hamm_window(hammingWindow, N, 0); 

然後,當你即將做你的FFT,窗口中的第一個樣本(如,你vDSP_ctoz調用之前做到這一點) :

vDSP_vmul(sample.get(), 1, hammingWindow, 1, sample.get(), 1, N); 

2)您可能要對結果

運行幅度功能這會給你的結果與那些你在一個標準的FFT柱狀圖音樂可視化的東西看。爲此後FFT:

vDSP_zvmags(&_complex, 1, &_complex.realp, 1, _fftsize); 

在此之後,_complex.realp將表示每個FFT區間的大小的浮點值的陣列。

+0

感謝您的回覆,我已經使用'vDSP_zvmags'函數,但我不使用windwing函數,所以我應用了一個漢明窗口,我得到了更好的結果。 – xunien