我有一系列 MIDI 音符以 MIDI 音符编号的形式存储在数组中。有没有一种算法可以让我得到这些音符所代表的歌曲的音调和音阶?
4 回答
如果您使用的是 Python,则可以使用 music21 工具包来执行此操作:
import music21
score = music21.converter.parse('filename.mid')
key = score.analyze('key')
print(key.tonic.name, key.mode)
如果您关心密钥查找的特定算法,则可以使用它们而不是通用的“密钥”:
key1 = score.analyze('Krumhansl')
key2 = score.analyze('AardenEssen')
等等。这些方法中的任何一种也适用于和弦。
(免责声明:music21 是我的项目,所以我当然对推广它有既得利益;但您可以查看 music21.analysis.discrete 模块,从那里为其他项目/语言获取想法。如果您有 MIDI 解析器, Krumhansl 算法并不难实现)。
Carol Krumhansl 的算法是最著名的。基本思想非常简单。参考音高样本是从已知调的音乐中提取的,并移调到其他 11 个调。大调和小调必须分开处理。然后从未知调的音乐中抽取一个音高样本。这会为 24 个参考样本和一个未知样本中的每一个生成一个 12 分量的音调向量,例如:
[ I, I#, II, II# III, IV, IV#, V, V#, VI, VI#, VII ]
[ 0.30, 0.02, 0.10, 0.05, 0.25, 0.20, 0.03, 0.30, 0.05, 0.13, 0.10 0.15]
计算未知基音向量和每个参考基音向量之间的相关系数,并选择最佳匹配。
Craig Sapp 编写了(受版权保护的)代码,可在http://sig.sapp.org/doc/examples/humextra/keycor/获得
David Temperley 和 Daniel Sleator 开发了一种不同的、更困难的算法,作为他们(受版权保护的)Melisma 软件包的一部分,可在 http://www.link.cs.cmu.edu/music-analysis/ftp-contents.html获得
T. Eerola 和 P. Toiviainen 在他们的 Midi 工具箱中提供了 Krumhansl 算法的(免费)Matlab 版本: https ://www.jyu.fi/hum/laitokset/musiikki/en/research/coe/materials/miditoolbox
周围有许多关键的查找算法,特别是 Carol Krumhansl 的算法(我见过的大多数论文总是引用 Krumhansl 的方法)
假设没有键更改,一个简单的算法可以基于音级直方图(一个数组,每个音级有 12 个条目(每个音符在一个八度音阶中)),当你得到一个音符时,你在正确的条目中添加一个,然后在最后你很可能有两个最常见的音符,它们分别是 7 个半音(或条目),分别代表主音和主音,主音是你要找的音符,主音是上面的 7 个半音或下面的 5 个半音.
这种方法的好处是它与音阶无关,它依赖于主音和主音,这是两个最重要的音符,并且出现得更频繁。通过对乐曲的大细分的第一个和最后一个音符给予额外的权重,该算法可能会变得更加健壮。
至于检测音阶,一旦你有了键,你就可以在直方图中生成一个高于某个阈值的音符列表作为从那个根音符的偏移量,所以假设你检测到 A 的键(从具有 A 和 E更频繁地发生)并且您拥有的音符是 ACDEG 然后您将获得 offsets ,在这样的数据库0 3 5 7 10
中搜索会为您提供“Minor Pentatonic”作为音阶名称。