craffel / pretty-midi

Utility functions for handling MIDI data in a nice/intuitive way.
MIT License
873 stars 151 forks source link

pretty_midi cannot find midi track only with control change #168

Closed luciaicull closed 5 years ago

luciaicull commented 5 years ago

When a midi file has a track which has only control_change and no notes, pretty_midi cannot get that track as one instrument and just blow off it while mido can get that as one track.

Example:

midi_file = mido.MidiFile('./testfile/test')
for track in midi_file.tracks:
    print(track)

## output
# <midi track '' 2 messages>
# <midi track '' 1469 messages>
# <midi track '' 6398 messages>
# <midi track '' 698 messages>

above example, <midi track '' 2 messages> is a meta message, <midi track '' 1469 messages> has only notes information, and <midi track '' 6398 messages> and <midi track '' 698 messages> have only control changes. However,

pretty_midi_file = pretty_midi.PrettyMIDI('./testfile/test/')
for instrument in pretty_midi_file.instrumets:
    print(instrument)

## output
# Instrument(program=0, is_drum=False, name="")

pretty_midi gets only the second track of the four tracks of mido output.

craffel commented 5 years ago

In pretty_midi an Instrument will only be created once a note appears. It does not make much sense to have a track with only control changes - that would be as if I sat down at a piano and pressed the sustain pedal a few times but never hit any notes. Control changes affect playback and there is no playback without any notes. If you want the control changes to affect the playback of the second track (1469 messages, with notes) then you should put the control changes on that track. If you really want to override this behavior, you can change this 0 (False) to 1 (True): https://github.com/craffel/pretty-midi/blob/master/pretty_midi/pretty_midi.py#L382 Note that setting create_new=0 as is done on that line is necessary to fix https://github.com/craffel/pretty-midi/issues/75.