@@ -9,6 +9,10 @@ def __init__(self, name="", middle_c="C4"):
99 self .notes = []
1010 # maps pitches to notes without end times
1111 self .incomplete_notes = {}
12+ # for handling a note on followed by a note off at the same time
13+ # note on - - - note on, note off - - - note off treated as two notes:
14+ # first note on to first note off, second note on to second note off
15+ self .skipped_note_on_events = {}
1216 self .events = []
1317 self .name = name
1418 self .delta_time_total = 0
@@ -18,6 +22,14 @@ def __init__(self, name="", middle_c="C4"):
1822 self .middle_c = middle_c
1923 return
2024
25+ def note_from_note_on_event (self , note_on_event ):
26+ return Note (note_on_event .start_time ,
27+ note_on_event .start_time_ticks ,
28+ note_on_event .note_number ,
29+ note_on_event .velocity ,
30+ note_on_event .channel ,
31+ self .middle_c )
32+
2133 # Events need to be added in order, last event must be end of track
2234 def add_event (self , event ):
2335 self .events .append (event )
@@ -26,22 +38,30 @@ def add_event(self, event):
2638 elif (isinstance (event , NoteOnEvent ) and
2739 not (event .is_note_off ())):
2840 if event .note_number in self .incomplete_notes and self .debug :
41+ self .skipped_note_on_events [event .note_number ] = self .note_from_note_on_event (event )
42+ # note will be skipped unless there is a note off event at the same time
2943 print ("Note on event for note " + str (event .note_number )
30- + " already playing, skipping..." )
44+ + " already playing, potentially skipping..." )
3145 else :
32- self .incomplete_notes [event .note_number ] = Note (event .start_time ,
33- event .start_time_ticks ,
34- event .note_number ,
35- event .velocity ,
36- event .channel ,
37- self .middle_c )
46+ self .incomplete_notes [event .note_number ] = self .note_from_note_on_event (event )
3847 elif (isinstance (event , NoteOffEvent ) or
3948 (isinstance (event , NoteOnEvent ) and event .is_note_off ())):
4049 if event .note_number in self .incomplete_notes :
4150 self .incomplete_notes [event .note_number ].set_end_time (event .start_time )
4251 self .incomplete_notes [event .note_number ].set_end_time_ticks (event .start_time_ticks )
4352 self .notes .append (self .incomplete_notes [event .note_number ])
4453 del self .incomplete_notes [event .note_number ]
54+
55+ # check if there was a note on event for the next note at the same time in case it was listed before
56+ # this note off event
57+ if event .note_number in self .skipped_note_on_events :
58+ skipped_note = self .skipped_note_on_events [event .note_number ]
59+ if skipped_note .start_time == event .start_time :
60+ # add the note back so it can be completed by the next note off
61+ if self .debug :
62+ print ("Note off at same time as note on for " + str (event .note_number ) +
63+ ". Un-skipping note-on event" )
64+ self .incomplete_notes [event .note_number ] = skipped_note
4565 elif self .debug :
4666 print ("Note off event for note " + str (event .note_number )
4767 + " not playing, skipping..." )
@@ -94,4 +114,4 @@ def __init__(self, delta_time_total, tempo):
94114 self .tempo = tempo
95115
96116 def __lt__ (self , other ):
97- return self .deltaTimeTotal < other .deltaTimeTotal
117+ return self .delta_time_total < other .delta_time_total
0 commit comments