我可以使用 FFT 识别钢琴上的音符吗?

电器工程 信号处理 傅立叶
2022-01-13 20:31:45

我想创建一个识别一些音符的工具(我知道这是在重新发明轮子)。所以我会在钢琴上弹奏中音 C、D 和 E,它应该能够对这些音符进行分类。以下是我认为我应该如何处理它:

  1. 录制我弹奏音符的样本
  2. 使用快速傅立叶变换将信号转换到频域
  3. 找到最存在的频率(基本上是频域数据的argmax)
  4. 假设频率来自播放的音符,并使用它来分类音符

我还没有尝试过任何这些,因为我不想走错路。那么,理论上,这会奏效吗?

4个回答

这个概念很好,但你会发现在实践中并不是那么简单。

音高不仅仅是主要的音调,因此存在第 1 个问题。

FFT 频率箱不能同时击中音阶的所有(甚至多个)音调。

我建议在尝试使用 FFT 执行特定任务之前,先玩一个包含 FFT 分析器和音调发生器的音频程序(例如 Audacity),以了解它可以(和不能)做什么。

如果您只需要检测几个特定的​​音调,您可能会发现Goertzel 算法更简单、更快捷。

音高检测很复杂,该领域仍在进行研究。音调检测非常简单,但可能无法满足您的需求。

我会说使用信号的多模式观察窗口会更好。类似于音频信号的小波分解的东西,这将使您能够识别音符内的多个泛音。是的,实际上小波,我想说的是要走的路。

这是对什么是小波的非常概括的细分,但可以将它们视为像 STFT 一样通过您的信号的多分辨率窗口。因此,您可以识别出现在信号中不同时间位置的不同正弦曲线。这也很重要,因为您弹奏的音符不是静止的信号,它会随着时间的推移播放然后衰减。我不是音乐家,但我相信音调优势会随着音符的衰减而变化。

当然,在小波分解之后,您将需要实现识别音符和外围音调的算法。

我认为小波确实解决了人们一直在谈论的关于音高识别的问题。

如果您想了解小波的工作原理,这是 HP 发布的关于它的精彩白皮书 :) http://www.hpl.hp.com/hpjournal/94dec/dec94a6.pdf小波简介

对于实现,MATLAB 有一个小波工具,我相信还有大量其他包可用于 R 等平台。

我猜你正在考虑在钢琴范围的中间(比如 200 到 500 Hz 之间)演奏的音符,但即使在那个范围内,单个音符也会有很多泛音,这些泛音不是基频的精确倍数,而且也是在每个音符的开头,也许在结尾处也有大量的宽带噪声。

对于音符范围低端的响亮音符,您会发现只有很少的声音能量(小于 1%)实际上位于音符的基本音高中。

另一个问题是对 FFT 的简单解释假设您尝试检测的信号具有恒定幅度。这不适用于振幅实际上遵循几个叠加指数衰减的钢琴音符 - 衰减的初始部分具有相对较短的时间常数,但后期部分具有较长的时间常数。

您可能会更好地研究短时间尺度的傅立叶变换方法,例如 Gabor 变换或基于小波的方法。

请注意,由于每个音符的连续音符的基本音高增加约 6%,因此您不一定需要非常高的准确度来识别音频中谐波的频率。正确识别音符与确定音符是否与音阶准确一致并不是完全相同的问题,其中频率可能需要测量到优于 0.1% 的准确度。

是的,这就是 FFT 的全部意义所在!为您提供您提供的数据的频谱。正如您所提到的,困难的部分是实现细节。

根据您想要做什么,确切地说,会改变答案。

如果您只想分析自己的音乐,已经有软件可以做到这一点。您可以查看显示响应的 EQ(基本上是 FFT),或者获得一个也显示音高的“音乐 EQ”。您可以将音频转换为 midi VST,将您播放的内容转换为正确的 midi 音符。如果你的键盘是midi,跳过VST,直接录制midi。

如果您想自学 FFT 以及它与音乐的关系,那么最好使用 Matlab 之类的工具,您可以在其中计算任何数据的 FFT。它具有录制和播放以及读取 wav 文件等的能力。然后这些就真的很容易使用了。如果您知道语法,您可以很快地绘制音频并进行各种分析。

如果你想构建一个设备来做这样的事情,那么它是相当复杂的。你需要一个 uC/dsp/fpga/etc 来进行计算。大多数流行的设备已经带有 FFT 代码,因此您不必自己编写代码(也很复杂)。

您需要构建电路和所有这些。这并不难,但根据您的经验/知识,这可能需要相当长的时间并且学习曲线陡峭。它还取决于最终产品的质量。

在数学上,理想的音符由“基本”的几何系列组成。

假设 F0 是基频,那么大多数音符将近似为 F(t) + F0*sum(a_k e^(2^k F0*pi i t)) = F0 + a_1*F1 + a_2*F2 + 。 ...

a_k 只是那些较高频率 F_k 的强度,而 F_k 只是 F0 的某个倍数。如果所有 k 的 a_k = 0,那么我们有一个纯正弦曲线。这个音高很容易检测。只需找到 FFT 的最大值,该频率就是音调的基础 = 音符。

当您进行 FFT 时,您最终会得到数据,然后进行数学运算。它基本上是微积分。

这一切都相对容易。

有些问题你必须处理。请注意,并非所有这些都已“解决”。

  1. 延迟——如果你要做任何类型的实时工作,这可能会成为一个问题。

  2. 多个音符 - 由于所有额外的谐波,很难确定音符组。如果播放 A = 440hz 和 A' = 880hz,大部分谐波会重叠。你可以很容易地得到 A = 440hz,但得到 A' = 880hz 就比较困难了。当您想到和弦、快速运行等时,很难准确地获取所有信息(音符)。虽然一切通常在数学上都是可能的,但数据本身存在错误和偏差,并且在某些情况下方程定义不足。

  3. 噪声 - 信号中的噪声会给您带来虚假的结果。如果出现音乐噪音,它可能会破坏您的结果。然后需要更好的算法=时间+金钱+知识。