The read_index is adjusted in the loop, which means that the calculation of how much
data can be delivered to the stretcher must also be inside the loop
When we add a region to a slot, we create a new Trigger, set its region,
then arrange for an "atomic" swap with the existing Trigger. This
means that the property change signal is emitted on a Trigger that
does not yet exist inside a TriggerBox, and so cannot be found using
row/col or x,y coordinates. Pass a raw pointer instead (lifetime
management is not an issue ... or is it.
The GUI was able to free memory (MidiTracer::disconnect),
while the tracer is concurrently still in use in rt-context.
This lead to memory corruption in MIDI::Parser::scanner.
This is mostly a simple lexical search+replace but the absence of operator< for
std::weak_ptr<T> leads to some complications, particularly with Evoral::Sequence
and ExportPortChannel.
If the stop takes effect on a process cycle boundary, do not just blindly pick
the next trigger; instead using the same logic as if the stop was not on the
boundary.
This is never for inline references to parameters, only for starting parameter
documentation blocks. The "@p" command is for this, although unfortunately
Doxygen doesn't actually do anything with it and it's just an alias for code
text.
'unbang' is better described as a mouse-up or button-release event
* if launch-style is Gate or Repeat, then UnBang will stop the playing clip
* in other launch-styles, UnBang is ignored
some prior code using UnBang will change to
stop_quantized() or request_stop()
normally we operate on TriggerPtr's which are a safe way to track
trigger lifetime, safely modify their properties, and launch them.
bang_trigger_at() is a convenience function to look up a trigger by index,
and launch it, in one step. Potentially useful for control surfaces.
We now try to get to the right location within the MIDI data and continue
playing, rather than pretending that we reached the end.
This also fixes a thinko that caused only the first few notes of a
MIDI trigger to play.
This may also solve cases where due to length, sample rate and tempo
settings, a trigger finished precisely on a ::run() call boundary.
The iterator into the model can become incorrect in the sense that it is no longer the correct
next event to play. This can happen at least with a tempo map change, and possible under other
conditions. Catch this when it happens, and act as if we reached the end of the trigger
This change still runs the triggerbox during latency-preroll, but as with the disk reader,
the transport speed argument is set to zero. The triggerbox notices this and behaves
appropriately (I think !)
Rather than start at zero, we now search backwards for the first relevant cue
before the locate position, making our task in ffwd'ing from there much simpler
since there are no other cues to consider
* there are rare cases where a midi clip would not advance the ffwd position, looping endlessly
* this problem did not occur when the user chose an explicit Follow Length (different code path)
This workaround bypasses RegionMap and SessionPlaylist APIs
(region_use_count, destroy_region) which are not directly
applicable to Triggerboxes. There are likely various edge
cases until TriggerBoxes integrate with Session Playlist.
e.g. whole file regions generated for regions/source used by
triggerboxes are cleaned up.