您最初打算如何使用 FFT?
如果要天真地寻找幅度谱中的峰值并从中推断出频率,这是一个坏主意。如您所见,这在最低频率下的分辨率有限。撇开分辨率限制不谈,在 FFT 中寻找峰值是一种不好的估计周期性的方法,因为真正的基频可能不是具有最显着幅度的频率。
但是,您可以使用 FFT 作为中间步骤来有效地计算自相关函数(FFT 对输入进行零填充以避免回绕 -> 系数幅度的平方 -> IFFT)。在自相关函数中寻找峰值是比 FFT 峰值更可靠的周期估计器。
因此,根据您的要求,您可以使用具有 61% 重叠的 256 个样本的滑动窗口,通过 FFT 计算自相关,在 [50, 125] 样本范围内寻找自相关峰值并将其用作对时期。由于 61% 的重叠,这将为您提供每秒一个周期值。请注意,可以使用较大的分析窗口(256 个样本或更多)并使它们重叠,这样我们仍然可以对每 100 个样本进行检测。不利的一面是,如果信号的周期快速变化,您的检测将被“弄脏”。
对于您的问题,我看到了一些其他方法,它们不会在时间轴上受到任何分辨率妥协:
- 如果您的输入信号的波形是已知的(方波、锯齿波、正弦波...),您可以尝试通过 PLL 锁定一个与其相似波形的振荡器,并使用 PLL 频率作为您的估计器。
- 如果您的信号是纯正弦的,您可以对其拟合一个复指数(通过自相关矩阵的特征分析)。
- 一种可以提供非常高分辨率(每个样本一个决定)的方法是将您的信号并行通过一组 75 个梳状滤波器,延迟为 0.5、0.51、0.52 .. 1.25 秒。计算这 75 个信号中每一个的输出能量;能量最高的那个给你周期。
请注意,您的问题与速度检测的要求非常相似(起始检测产生 100 Hz 或类似的包络信号,我们的目标是获得 60 BPM - 180 BPM 的速度图,即 0.33 - 1Hz 范围,具有1s的时间分辨率)。历史上,使用梳状滤波器组方法;而最近的解决方案是基于自相关或类似的基于自相关的音高估计器(yin);分析窗口在 5 - 10 秒范围内。