bixb922 / umidiparser

MIDI file parser for Micropython, CircuitPython and Python
MIT License
27 stars 4 forks source link

How to determine which track a note_on or note_off belongs to? #2

Closed TimHanewich closed 1 year ago

TimHanewich commented 1 year ago

Hi @bixb922 , thank you for creating and providing this useful module. I have a quick question for you: how are we to determine which track a particular note_on or note_off event belongs to? For example, consider the following events that were listed using the .play() method of the MidiFile class:

control_change delta[miditicks]=0 data=b'd\x00' delta[usec]=0 channel=1 control=100 status=176 value=0
control_change delta[miditicks]=0 data=b'\x06\x0c' delta[usec]=0 channel=1 control=6 status=176 value=12
control_change delta[miditicks]=0 data=b'\n@' delta[usec]=0 channel=1 control=10 status=176 value=64
control_change delta[miditicks]=0 data=b'\x07d' delta[usec]=0 channel=1 control=7 status=176 value=100
pitchwheel delta[miditicks]=0 data=b'\x00@' delta[usec]=0 channel=1 pitch=0 status=224
program_change delta[miditicks]=0 data=b'\x00' delta[usec]=0 channel=1 program=0 status=192
note_off delta[miditicks]=24 data=b'H@' delta[usec]=117188 channel=0 note=72 status=128 velocity=64
note_on delta[miditicks]=72 data=b'Hd' delta[usec]=351563 channel=1 note=72 status=144 velocity=100
note_off delta[miditicks]=24 data=b'H@' delta[usec]=117188 channel=1 note=72 status=128 velocity=64
note_on delta[miditicks]=72 data=b'Hd' delta[usec]=351563 channel=0 note=72 status=144 velocity=100
note_off delta[miditicks]=24 data=b'H@' delta[usec]=117188 channel=0 note=72 status=128 velocity=64
note_on delta[miditicks]=72 data=b'Hd' delta[usec]=351563 channel=1 note=72 status=144 velocity=100
note_off delta[miditicks]=24 data=b'H@' delta[usec]=117188 channel=1 note=72 status=128 velocity=64
control_change delta[miditicks]=72 data=b'e\x00' delta[usec]=351563 channel=0 control=101 status=176 value=0
control_change delta[miditicks]=0 data=b'd\x00' delta[usec]=0 channel=0 control=100 status=176 value=0
control_change delta[miditicks]=0 data=b'\x06\x0c' delta[usec]=0 channel=0 control=6 status=176 value=12
control_change delta[miditicks]=0 data=b'\n@' delta[usec]=0 channel=0 control=10 status=176 value=64

How would one be able to determine which track each note_on and note_off event belongs to? Thank you for the help!

bixb922 commented 1 year ago

Hi Tim, no, there is currently no track attribute. Many MIDI files have one track per instrument, but in many, many files there are several instruments per track or one instrument is present in several tracks. In order to identify which instrument has to be played, I use the event.channel attribute, since the track attribute would not be reliable to identify the instrument. All channel events, such as note on, note off, control change, program change already have the channel atribute. When MIDI is sent over USB or BLE, no track number is present, the channel number identifies what where notes belong. In other MIDI file parsers, such as MIDO (for CPython), the track information is also not returned, for the same reasons. You also can get the events in each track with umididparser. This is intended for midi type 2 files, which are not very common, but also works for type 0 and 1 files.

Is this useful for you use case?

TimHanewich commented 1 year ago

Thank you for the quick response! Yes this is very helpful. Thanks again and great work on this.