MIDI消息混乱[Python]

时间:2017-11-14 05:41:54

标签: python midi

我试图从钢琴的MIDI文件中获取所有音符的开始和停止时间。根据我的理解,有note_on和note_off事件,其中delta时间以刻度表示,我可以使用它来获取开始和停止时间。但是,我与之混淆的是时间变量。当我只有一个简单的程序,如

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}

根据我的理解,这意味着音符的delta时间都小于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多个数字?

1 个答案:

答案 0 :(得分:1)

documentation说:

  

time属性以多种不同的方式使用:

     
      
  • 在轨道内,它是以刻度表示的增量时间。这必须是整数。
  •   
  • 在来自play()的消息中,是以秒为单位的增量时间(自上次产生消息后经过的时间)
  •   

Delta时间相对于同一曲目中的上一条消息,因此您必须为每个曲目单独添加它们。