MIDIUtil
MIDIUtil copied to clipboard
deInterleaveNotes() crashes when there are two many to handle
Here is an example that will usually crash:
from midiutil import MIDIFile import random R = random.random degrees = [60, 62, 64, 65, 67, 69, 71, 72] # MIDI note number track = 0 channel = 0 time = 0 # In beats duration = 1 # In beats tempo = 60 # In BPM volume = 100 # 0-127, as per the MIDI standard MyMIDI = MIDIFile(1) # One track MyMIDI.addTempo(track, time, tempo) for i in range(100000): pitch = 20 + int(R() * 80) time = .1 + R() * 100 volume = random.randint(10, 100) dur = .1 + R() * 4 MyMIDI.addNote(track, channel, pitch, time, dur, volume) with open("new_song.mid", "wb") as output_file: MyMIDI.writeFile(output_file)
Same here, here's the output:
Traceback (most recent call last):
File "/usr/local/Cellar/[email protected]/3.9.1_8/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/local/Cellar/[email protected]/3.9.1_8/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/Users/angus/delphos/mds-vinyls/mds-vinyls/prototypes/spiral_1.py", line 11, in <module>
write_tracklist_to_midi_file('delete_spiral1.midi', midi_tracks)
File "/Users/angus/.local/share/virtualenvs/mds-vinyls-O2eeAYrs/lib/python3.9/site-packages/midi_python/midi_file_writer.py", line 13, in write_tracklist_to_midi_file
exporter.writeFile(output_file)
File "/Users/angus/.local/share/virtualenvs/mds-vinyls-O2eeAYrs/lib/python3.9/site-packages/midiutil/MidiFile.py", line 1637, in writeFile
self.close()
File "/Users/angus/.local/share/virtualenvs/mds-vinyls-O2eeAYrs/lib/python3.9/site-packages/midiutil/MidiFile.py", line 1688, in close
self.tracks[i].closeTrack()
File "/Users/angus/.local/share/virtualenvs/mds-vinyls-O2eeAYrs/lib/python3.9/site-packages/midiutil/MidiFile.py", line 826, in closeTrack
self.processEventList()
File "/Users/angus/.local/share/virtualenvs/mds-vinyls-O2eeAYrs/lib/python3.9/site-packages/midiutil/MidiFile.py", line 789, in processEventList
self.deInterleaveNotes()
File "/Users/angus/.local/share/virtualenvs/mds-vinyls-O2eeAYrs/lib/python3.9/site-packages/midiutil/MidiFile.py", line 889, in deInterleaveNotes
stack[noteeventkey].pop()
IndexError: pop from empty list
A quick look at the code:
for event in self.MIDIEventList:
if event.evtname in ['NoteOn', 'NoteOff']:
# !!! Pitch 101 channel 5 produces the same key as pitch 10 channel 15.
# !!! This is not the only pair of pitch,channel tuples which
# !!! collide to the same key, just one example. Should fix by
# !!! putting a separator char between pitch and channel.
noteeventkey = str(event.pitch) + str(event.channel)
...So there's something easily fixed there, not sure if it'll resolve this issue...?
I have the same problem. What is exactly the purpose of the stack in this method? Passing the tick between NoteOn and NoteOff events?
Pull request #36 seems to address this problem, but does not seem to take tick passing into account