5

我目前正在实现一个应用程序来对 MIDI 文件执行一些任务,而我目前的问题是将我读过的音符输出到 LilyPond 文件中。

我已经将 note_on 和 note_off 事件合并到具有绝对开始和绝对持续时间的单音符对象中,但我真的不知道如何将该持续时间转换为实际的音乐符号。我猜想 376 的持续时间是我正在阅读的文件中的四分音符,因为我知道这首歌,显然 188 是八分音符,但这当然不能推广到所有 MIDI 文件。

有任何想法吗?

4

1 回答 1

9

默认情况下,MIDI 文件设置为 120 bpm 的速度,文件中的 MThd 块将以“每四分音符的脉冲数”(ppqn) 的形式告诉您分辨率。

如果 ppqn 是 96,那么 96 个刻度的增量就是一个四分音符。

如果您对每个声音的实际持续时间(以秒为单位)感兴趣,您还应该考虑可以通过事件“FF 51 03 tt tt tt”改变的“节奏”;这三个字节是四分音符的微秒。

使用这两个值,您应该找到所需的内容。请注意,midi 文件中的持续时间可能是近似的,特别是如果该 MIDI 文件是人类演奏者的录音。

很久以前我已经整理了一个C库来读/写midifile:https ://github.com/rdentato/middl 以防万一它可能会有所帮助(有一段时间我不看代码,感觉有什么不清楚的地方可以追问)。

我建议遵循这种方法:

  1. 选择一个与您的划分兼容的“最小音符”(例如 1/128)并将其用作一种网格。
  2. 将每个音符与最近的网格线对齐(即与最小节点的最接近的整数倍)
  3. 将其转换为标准符号(例如四分音符、八分音符等)。

在您的情况下,将 1/32 作为最小音符,将 384 作为除法(即 48 个刻度)。对于 376 刻度的注释,您将得到 376/48=7.8,将其四舍五入为 8(最接近的整数)和 8/32 = 1/4。

如果您找到一个持续时间为 193 个刻度的音符,您可以看到它是 1/8 音符,因为 193/48 是 4.02(您可以四舍五入为 4)并且 4/32 = 1/8。

继续这个推理,您可以看到持续时间为 671 节拍的音符应该是双点四分音符。

实际上,671 应该近似为 672(48 的最接近的倍数),即 14*48。所以你的笔记是 14/32 -> 7/16 -> (1/16 + 2/16 + 4/16) -> 1/16 + 1/8 + 1/4。

如果您习惯使用二进制数,您可能会注意到 14 是1110并且从那里直接推导出 1/16、1/4 和 1/8 的存在。

再举一个例子,一个持续时间为 480 节拍的音符是一个与 1/16 音符相关的四分音符,因为 480=48*10 并且 10 是1010二进制的。

三胞胎和其他组会使事情变得更复杂一些。最常见的除法值是 96 (3*2^5)、192 (3*2^6) 和 384 (3*2^7) 并非偶然;这样,三元组可以用整数个刻度表示。

在某些情况下,您可能不得不猜测或简化,这就是为什么没有“midi 到标准符号”程序可以 100% 准确的原因。

于 2010-03-18T15:29:05.620 回答