13
0

fix handling of SMF files with consecutive noteOn events

We no longer store nascent notes when noteOn is received, but wait till noteOff arrives. We also
ignore all other noteOn events between the earliest received and the noteOff.

Potentially we may want to use the _overlap_pitch_resolution member at some point
to offer control of this behavior.
This commit is contained in:
Paul Davis 2021-06-28 08:30:22 -06:00
parent f715edf7bc
commit 5c3e5f9afb

View File

@ -1004,10 +1004,7 @@ Sequence<Time>::append_note_on_unlocked (const Event<Time>& ev, event_id_t evid)
assert (note->end_time() == std::numeric_limits<Temporal::Beats>::max());
note->set_id (evid);
add_note_unlocked (note);
DEBUG_TRACE (DEBUG::Sequence, string_compose ("Appending active note on %1 channel %2\n",
(unsigned)(uint8_t)note->note(), note->channel()));
DEBUG_TRACE (DEBUG::Sequence, string_compose ("New nascent/active note on %1 channel [%2]\n\n", (int) note->note(), note->channel()));
_write_notes[note->channel()].insert (note);
}
@ -1047,21 +1044,32 @@ Sequence<Time>::append_note_off_unlocked (const Event<Time>& ev)
++tmp;
NotePtr nn = *n;
if (ev.note() == nn->note() && nn->channel() == ev.channel()) {
assert(ev.time() >= nn->time());
if (!resolved) {
assert(ev.time() >= nn->time());
nn->set_length (ev.time() - nn->time());
nn->set_off_velocity (ev.velocity());
nn->set_length (ev.time() - nn->time());
nn->set_off_velocity (ev.velocity());
_write_notes[ev.channel()].erase(n);
DEBUG_TRACE (DEBUG::Sequence, string_compose ("resolved note @ %2 length: %1\n", nn->length(), nn->time()));
resolved = true;
break;
add_note_unlocked (nn);
_write_notes[ev.channel()].erase(n);
DEBUG_TRACE (DEBUG::Sequence, string_compose ("resolved note @ %1\n", *nn));
resolved = true;
} else {
/* additional matching nascent notes ... just
delete them.
*/
DEBUG_TRACE (DEBUG::Sequence, string_compose ("dropping additional nascent note @ %1\n", *nn));
_write_notes[ev.channel()].erase(n);
}
}
n = tmp;
}
if (!resolved) {
cerr << this << " spurious note off chan " << (int)ev.channel()
<< ", note " << (int)ev.note() << " @ " << ev.time() << endl;