MIDI 持续时间的实际音符持续时间
我目前正在实现一个应用程序来对 MIDI 文件执行一些任务,我当前的问题是将我读到的音符输出到 LilyPond 文件中。
我已将 note_on 和 note_off 事件合并到具有绝对开始和绝对持续时间的单个音符对象,但我真的不知道如何将该持续时间转换为实际的音乐符号。我猜测持续时间 376 是我正在阅读的文件中的四分音符,因为我知道这首歌,显然 188 是八分音符,但这当然不能推广到所有 MIDI 文件。
有什么想法吗?
I'm currently implementing an application to perform some tasks on MIDI files, and my current problem is to output the notes I've read to a LilyPond file.
I've merged note_on and note_off events to single notes object with absolute start and absolute duration, but I don't really see how to convert that duration to actual music notation. I've guessed that a duration of 376 is a quarter note in the file I'm reading because I know the song, and obviously 188 is an eighth note, but this certainly does not generalise to all MIDI files.
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
默认情况下,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
。三胞胎和其他群体会让事情变得更复杂一些。最常见的分度值是 96 (3*2^5)、192 (3*2^6) 和 384 (3*2^7),这并非偶然;这样,三元组就可以用整数个刻度来表示。
在某些情况下您可能必须猜测或简化,这就是为什么没有“midi 到标准符号”程序可以 100% 准确的原因。
By default a MIDI file is set to a tempo of 120 bpm and the MThd chunk in the file will tell you the resolution in terms of "pulses per quarter note" (ppqn).
If the ppqn is, say, 96 than a delta of 96 ticks is a quarter note.
Should you be interested in the real duration (in seconds) of each sound you should also consider the "tempo" that can be changed by an event "FF 51 03 tt tt tt"; the three bytes are the microseconds for a quarter note.
With these two values you should find what you need. Beware that the duration in the midi file can be approximate, especially if that MIDI file it's the recording of a human player.
I've put together a C library to read/write midifiles a long time ago: https://github.com/rdentato/middl in case it may be helpful (it's quite some time I don't look at the code, feel free to ask if there's anything unclear).
I would suggest to follow this approach:
In your case, take 1/32 as minimal note and 384 as division (that would be 48 ticks). For your note of 376 tick you'll have 376/48=7.8 which you round to 8 (the closest integer) and 8/32 = 1/4.
If you find a note whose duration is 193 ticks you can see it's a 1/8 note as 193/48 is 4.02 (which you can round to 4) and 4/32 = 1/8.
Continuing this reasoning you can see that a note of duration 671 ticks should be a double dotted quarter note.
In fact, 671 should be approximated to 672 (the closest multiple of 48) which is 14*48. So your note is a 14/32 -> 7/16 -> (1/16 + 2/16 + 4/16) -> 1/16 + 1/8 + 1/4.
If you are comfortable using binary numbers, you could notice that 14 is
1110
and from there, directly derive the presence of 1/16, 1/4 and 1/8.As a further example, a note of 480 ticks of duration is a quarter note tied with a 1/16 note since 480=48*10 and 10 is
1010
in binary.Triplets and other groups would make things a little bit more complex. It's not by chance that the most common division values are 96 (3*2^5), 192 (3*2^6) and 384 (3*2^7); this way triplets can be represented with an integer number of ticks.
You might have to guess or simplify in some situations, that's why no "midi to standard notation" program can be 100% accurate.