【问题标题】:Using Apple's Accelerate framework, FFT, Hann windowing and Overlapping使用 Apple 的 Accelerate 框架、FFT、Hann 窗口和重叠
【发布时间】:2013-09-26 17:38:43
【问题描述】:

我正在尝试为一个项目设置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);

那么我将在何处以及如何包含重叠?此外,任何代码 sn-ps 都会更受欢迎。谢谢

更新:

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

【问题讨论】:

    标签: ios xcode fft accelerate-framework


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 好的 - 请参阅我回答的最后一部分,了解如何进行重叠。
    • 我正在考虑将采样率降低到大约 16kHz,而不是典型的 44.1KHz。这应该允许我在不增加处理带宽的情况下添加更大的重叠。无论如何都会尝试这个,让你知道它是怎么回事
    • 是的,如果您对高频分量不感兴趣,请尽可能降低采样率以减少计算带宽。我建议从 50% 的重叠开始,这会使计算要求加倍。我当然不会超过 75% 的重叠(4 倍计算带宽)。
    • 我实际上对语音频率比其他任何东西都更感兴趣......考虑到这一点,我认为我实际上可以低至 10kHz。你碰巧也知道任何示例代码或者我在哪里可以找到一些?这里面有很多 c,而不是我习惯的目标 c……
    • 嗯,缓冲区管理的东西很简单。而且我认为您可以使用现有的 iOS API 以较低的采样率获取音频。你还需要什么代码吗?
    猜你喜欢
    • 2011-03-24
    • 1970-01-01
    • 2011-09-15
    • 2011-05-29
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 2015-09-11
    • 2011-06-15
    相关资源
    最近更新 更多