我目前正在实现一个应用程序来对MIDI文件执行某些任务,而我目前的问题是将我读过的笔记输出到LilyPond文件。
我已将note_on和note_off事件合并为具有绝对开始和绝对持续时间的单个音符对象,但我真的没有看到如何将该持续时间转换为实际的音乐符号。我已经猜到376的持续时间是我正在阅读的文件中的四分音符,因为我知道这首歌,显然188是八分音符,但这肯定不会推广到所有MIDI文件。
有什么想法吗?
答案 0 :(得分:7)
默认情况下,MIDI文件设置为120 bpm的速度,文件中的MThd块将以“每四分音符脉冲数”(ppqn)的形式告诉您分辨率。
如果ppqn是96,那么96的四分之一是四分音符。
如果您对每种声音的实际持续时间(以秒为单位)感兴趣,您还应该考虑可以通过事件“FF 51 03 tt tt tt”更改的“速度”;三个字节是四分音符的微秒。
有了这两个值,你应该找到你需要的东西。请注意midi文件中的持续时间可能是近似的,特别是如果该MIDI文件是人类播放器的录制。
很久以前我已经把一个C库放在一起读/写midifiles:https://github.com/rdentato/middl以防它可能有帮助(很长一段时间我不看代码,随便问一下如果有什么不清楚的话。)
我建议采用这种方法:
在你的情况下,将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
二进制。
Triplets和其他团体会让事情变得更复杂一些。最常见的除法值是96(3 * 2 ^ 5),192(3 * 2 ^ 6)和384(3 * 2 ^ 7)并非偶然;这样三元组就可以用整数个刻度表示。
在某些情况下您可能需要猜测或简化,这就是为什么没有“midi到标准符号”程序可以100%准确。