Steven T
Steven T

Reputation: 93

MIDI messages confusion [Python]

I'm trying to get the start and stop times of all the notes from a MIDI file for a piano. From my understanding, there are note_on and note_off events with delta time in ticks, which I can use to get the start and stop times. However, what I'm confused with is with the time variable. When I just have a simple program such as

for msg in mid:
    print(msg.dict())

I get outputs such as:

{'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}

From my understanding, this means that the notes have delta times that are all less than 1 tick, which seems completely wrong to me. However, what I like is that doing it this way has the note_on, note_off, and set_tempo events in the order that they occur. When I instead do

mid.print_tracks()

I get an output such as:

<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>

The time element in the messages make more sense to me, as they all have 100+ ticks, but the ordering is by track, and so all the tempo changes are printed at once, then all the note events for the right hand, and then all the note events for the left hand (etc). Is it possible to get the best of both worlds, where I can get a list of the MIDI events based on time with the time attribute being the 100+ numbers that I get from print_tracks()?

Upvotes: 1

Views: 1168

Answers (1)

CL.
CL.

Reputation: 180010

The documentation says:

The time attribute is used in several different ways:

  • inside a track, it is delta time in ticks. This must be an integer.
  • in messages yielded from play(), it is delta time in seconds (time elapsed since the last yielded message)

Delta times are relative to the previous message in the same track, so you have to add them up separately for each track.

Upvotes: 1

Related Questions