2012-09-28 31 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