upper_bound() returns the first element that is **greater** than
the given value. So during reverse playback we need the value
before that.
Likewise for forward playback, lower_bound() returns an iterator
pointing to the element before the one that need to be played.
'lower_bound()' iterates between param #1 and param #2, comparing the result
with param #3 - either by making the comparison internally or by deferring to
an external comparator function. Prior to C99 however, BOTH cases required
param #3 to match the type being iterated.
In the case of a deferred comparison, there was apparently a proposal to
relax this restriction in C99, though I'm not sure if it in fact got
implemented (can't find any examples of it anywhere...)
When looping, we do not want to resolve notes at the end of the loop via ::realtime_locate() -
::get_midi_playback() has already taken care of this. But when not looping, we need this. So,
add an argument to tell all interested parties whether the locate is for a loop end or not
Split cycles are run as if they are an entire self-contained cycle, starting at zero and running for "nframes".
We adjust the timing and position of data only when retrieving and writing it to Port buffers.
Reduces load time of Glass MIDI piece with 48k note events by about 35%. Improves data
locality. Omits size for all 3 byte or less MIDI events, uses implicit size. No limit
on size of sysex.
Relies on the fact that the data structure is always filled linearly in time, and
never modified.