使用Apple的Accelerate框架,FFT,Hann窗口和重叠

时间:2013-09-21 11:14:43

标签: ios xcode fft accelerate-framework

我正在尝试为项目设置FFT,但实际上并没有清楚地了解事情...... 基本上,我使用Audio Units从设备的麦克风获取数据。然后,我想对该数据进行FFT。这是我到目前为止所理解的:我需要为我的数据设置一个循环缓冲区。在每个填充的缓冲区上,我应用Hann window然后执行FFT。但是,我仍然需要一些重叠的帮助。为了获得更精确的结果,我知道我需要特别使用它,因为我正在使用窗口。但是,我找不到任何关于此... 这是我到目前为止(用于音调检测):

// Setup -------------  
UInt32 log2N          = 10; // 1024 samples  
UInt32 N              = (1 << log2N);  
FFTSetup FFTSettings  = vDSP_create_fftsetup(log2N, kFFTRadix2);  
COMPLEX_SPLIT FFTData;  
FFTData.realp         = (float *) malloc(sizeof(float) * N/2);  
FFTData.imagp         = (float *) malloc(sizeof(float) * N/2);  
float * hannWindow = (float *) malloc(sizeof(float) * N);  

// create an array of floats to represent a hann window  
vDSP_hann_window(hannWindow, N, 0);

// FFT Time ----------  
// Moving data from A to B via hann window  
vDSP_vmul(A, 1, hannWindow, 1, B, 1, N);                                 

// Converting data in B into split complex form  
vDSP_ctoz((COMPLEX *) B, 2, &FFTData, 1, N/2);  

// Doing the FFT  
vDSP_fft_zrip(FFTSettings, &FFTData, 1, log2N, kFFTDirection_Forward);   

// calculating square of magnitude for each value  
vDSP_zvmags(&FFTData, 1, FFTData.realp, 1, N/2);  

// Inverse FFT  
vDSP_fft_zrip(FFTSettings, &FFTData, 1, log2N, kFFTDirection_Inverse);  

// Storing the autocorrelation results in B  
vDSP_ztoc(&FFTData, 1, (COMPLEX *)B, 2, N/2);  

vDSP_Length lastZeroCrosssing;  
vDSP_Length zeroCrossingCount;  
vDSP_nzcros(B, 1, N, &lastZeroCrossing, &zeroCrossingCount, N);  

// Cleanup -----------  
vDSP_destroy_fftsetup(FFTSettings);  
free(FFTOutput.realp);  
free(FFTOutput.imagp);  
free(hannWindow);

那么我将在何处以及如何包含重叠?此外,任何代码片段都会受到欢迎。感谢

更新:

这个项目的最终目标是尽可能接近实时地对音频进行指纹识别,因此我需要尽可能准确的结果 - 因此重叠。为此,我认为我实际上可以将所有部分从反向清除到清理。

1 个答案:

答案 0 :(得分:1)

您实际上需要重叠 - 通常情况下,帧会重叠以在时间轴上提供更高的分辨率,例如:用于绘制光谱图或用于估计音符开始时间。你现在可以让你的代码在没有重叠的情况下工作,因为它不那么复杂,然后决定你以后是否需要更高的时间轴分辨率。

如果您确定要添加重叠,则需要保存前一个缓冲区的一大块(例如50%),然后对于每个新缓冲区,您将处理两个完整的缓冲区,如下所示:

  • 处理旧缓冲区的50%+新缓冲区的前50%
  • 处理100%的新缓冲区
  • 为下一次迭代保存新缓冲区的最后50%

对于不同的重叠百分比,类似的逻辑适用。

请注意,增加重叠超过某一点可能会适得其反,因为所需的处理带宽会大大增加而分辨率几乎没有增加。