【发布时间】:2017-11-14 05:41:54
【问题描述】:
我正在尝试从钢琴的 MIDI 文件中获取所有音符的开始和停止时间。据我了解,有 note_on 和 note_off 事件,时间间隔为刻度,我可以使用它们来获取开始和停止时间。但是,我感到困惑的是时间变量。当我只有一个简单的程序时,例如
for msg in mid:
print(msg.dict())
我得到如下输出:
{'note': 60, 'velocity': 61, 'type': 'note_on', 'channel': 0, 'time': 0.0016891895833333333}
{'note': 64, 'velocity': 57, 'type': 'note_on', 'channel': 0, 'time': 0.20270275}
{'note': 67, 'velocity': 56, 'type': 'note_on', 'channel': 0, 'time': 0.20270275}
{'note': 67, 'velocity': 0, 'type': 'note_on', 'channel': 0, 'time': 0.20270275}
{'note': 72, 'velocity': 60, 'type': 'note_on', 'channel': 0, 'time': 0}
{'type': 'set_tempo', 'tempo': 794702, 'time': 0.20101356041666665}
据我了解,这意味着音符的增量时间都小于 1 个刻度,这对我来说似乎完全错误。然而,我喜欢这样做的方式是让 note_on、note_off 和 set_tempo 事件按照它们发生的顺序排列。当我改为这样做时
mid.print_tracks()
我得到如下输出:
<meta message set_tempo tempo=794702 time=480>
<meta message set_tempo tempo=810811 time=120>
<meta message set_tempo tempo=800000 time=960>
<meta message set_tempo tempo=810811 time=360>
...
=== Track 1
<meta message midi_port port=0 time=0>
<meta message track_name name=u'Piano right' time=0>
<message program_change channel=0 program=0 time=0>
<message control_change channel=0 control=7 value=100 time=0>
<message control_change channel=0 control=10 value=64 time=0>
<message control_change channel=0 control=91 value=127 time=0>
<meta message text text=u'bdca426d104a26ac9dcb070447587523' time=0>
<message note_on channel=0 note=67 velocity=56 time=241>
<message note_on channel=0 note=67 velocity=0 time=120>
消息中的时间元素对我来说更有意义,因为它们都有 100 多个刻度,但排序是按音轨的,因此所有速度变化都会立即打印,然后是右手的所有音符事件,然后是左手的所有音符事件(等)。是否有可能两全其美,我可以在其中获得基于时间的 MIDI 事件列表,时间属性是我从 print_tracks() 获得的 100 多个数字?
【问题讨论】:
-
哪个库生成了这些对象?
-
很抱歉没有具体说明。我正在使用的库是 Mido mido.readthedocs.io/en/latest