我正在研究一个钢琴调音程序,其中一部分需要实时音高检测。这是我到目前为止的方案,它在某种程度上有效,但可能需要一些改进。
我正在以 2^14 个样本块的形式捕获单声道、44.1kHz、16 位 PCM 音频。我将最后 4 个样本合并到一个 2^16 长度的缓冲区中,将 Hann 窗口应用于缓冲区并在其上运行 FFT。然后,我将 FFT 的结果分成两个分辨率。首先,我将桶分成 200 个桶,然后以这个粒度运行 HPS 音高检测算法。我不需要在这里获得确切的频率,我只想靠近。然后,我将其分成 12000 个桶,从 10Hz 到 10kHz 的分辨率为 1 美分。一旦我从 200 bin HPS 算法中知道了一个近似频率,我就会在 12000 bin 案例的范围内搜索一个峰值以获得更准确的频率。
这似乎适用于键盘中间的音符。低音符会发生大约 1.5 秒的错误识别,通常是真实音符的第二或第三部分,然后正确识别该音符。
在我创建的所有光谱图中,我希望看到发生了什么,峰的宽度更大。从 200 箱到 12000 箱的情况,这个宽度在视觉上有些一致。我本来预计在 200 箱的情况下峰值会更窄。
所以,信号处理对我来说是新的,所以可能会有一些我不想问的问题,但就具体问题而言,样本量是否足以完成这项任务?Hann 是正确的窗口选择吗?我应该在 FFT 之前也平滑数据吗?HPS 对 bin 数量有多敏感?我在想,如果我使用了很多箱,那么不和谐可能不会使部分与 HPS 算法的简单方法(除以 2、3、4 等)重叠它们的基本原理。