You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
music21.midi.MidiEvent.getBytes() confuses SEQUENCER_SPECIFIC_META_EVENT (0x7F) with POLY_MODE_ON (also 0x7F) #1772
Operating System(s) checked
OS agnostic
(I am on Ubuntu 24.04, though, but that should be irrelevant.)
Problem summary music21.midi.MidiEvent.getBytes() confuses SEQUENCER_SPECIFIC_META_EVENT (0x7F) with POLY_MODE_ON (also 0x7F) and will therefore cause a TypeError if the former does not care about channels (i.e self.channel == None).
FYI: Actually I encountered this issue not by instantiating a MidiEvent manually but by writing a MidiFile which comes with some SEQUENCER_SPECIFIC_META_EVENT's.
mf = midi.MidiFile()
mf.open(inputfile)
mf.read()
mf.close()
# write the contents back immediately without touching anything
mf.open(outputfile, 'wb')
mf.write()
mf.close()
Expected vs. actual behavior
EXPECTED BEHAVIOUR: music21.midi.MidiEvent.getBytes() should process all MIDI events correctly without triggering any exception.
ACTUAL BEHAVIOUR:
File "/foo/bar/lib/python3.12/site-packages/music21/midi/__init__.py", line 982, in getBytes
channelMode = bytes([0xB0 + self.channel - 1])
~~~~~^~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
More information
The current code of music21.midi.MidiEvent.getBytes() checks the event type essentially by looking at its value only:
Thanks for the bug report. I'd like to fix, but the proposed fix, I'm afraid, is unlikely to be the way forward.
We're not going to do isinstance checking on each byte/message because we're using int-enums so that should be irrelevant. There should be another feature that tells us if we should be implementing the Event as a MetaEvent or a ChannelVoiceMessage -- I think we record that somewhere, but just not properly for these (and a few other conflicts) -- so that needs to move up.
To be clear if self.type is 0x7F it's could be either a ChannelVoiceMessage or a MetaEvent -- there has to be some other way of telling not just the class of the enum.
Activity
mscuthbert commentedon May 26, 2025
Thanks for the bug report. I'd like to fix, but the proposed fix, I'm afraid, is unlikely to be the way forward.
We're not going to do isinstance checking on each byte/message because we're using int-enums so that should be irrelevant. There should be another feature that tells us if we should be implementing the Event as a MetaEvent or a ChannelVoiceMessage -- I think we record that somewhere, but just not properly for these (and a few other conflicts) -- so that needs to move up.
To be clear if self.type is 0x7F it's could be either a ChannelVoiceMessage or a MetaEvent -- there has to be some other way of telling not just the class of the enum.
Thanks!