Skip to content

Commit 6d0c474

Browse files
committed
Handle repeated notes when the second note on is listed before the first note off
1 parent e241e3f commit 6d0c474

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

TrackData.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)