TempoMap::use() assumes the thread_local pointer has been set up. This
is not the case for the control protocol event loop, so call ::fetch()
instead which does not require this assumption (and sets the thread_local
pointer too, though nothing else in the Mackie code uses it)
This also required a mechanism to prevent the fact of a non-null "currently_playing" value in
the TriggerBox from starting the transport, which is handled with Triggerbox::_locate_armed. This
is set when _currently_playing is set from TriggerBox::fast_forward()
In order to detect if route delaylines need to be updated,
aux-send delaylines need to be updated first. This was previously
done directly in the latency-callback, which may be concurrent
with processing.
Now only the information (pending_delay) is set, and the actual
change happens later at the end of process().
Due to _init_countdown when the engine starts, it is
extremely unlikely that Session::initialize_latencies(),
which is invoked by AudioEngine::Running runs concurrently
with Session::process, but at least in theory it would be possible.
This reverts commit 220b1386ab.
because it causes crashes when saving sessions.
_channel_map[] must not be empty, otherwise
Program terminated with signal SIGSEGV, Segmentation fault.
snprintf (buf, sizeof (buf), "%d", _channel_map[chn]);
#0 ARDOUR::MIDITrigger::get_state() (this=0x55d676b4c600) at ../libs/ardour/triggerbox.cc:1962
#1 0x00007f58ccb40b12 in ARDOUR::TriggerBox::get_state() (this=0x55d676b4d720) at ../libs/ardour/triggerbox.cc:33
Calls DR::set_pending_overwrite() sets DR::run_must_resolve
before the first run.
Previously this variable was set after the first ::run,
which resulted in notes at the beginning of audition to be
cut short.
Previously events with different reasons where treated as two
separate events. Processing an Overwrite request causes
post-transport-work to set.
Since ::non_realtime_work_pending() is true, process_event()
is not called, and no further immediate events are evaluated in
the same cycle.
So Overwrite requests were repeated over multiple cycles.
Files that have many tracks, each with tempo information
were near impossible to load (30+ mins on modern 4.2Ghz CPU!),
because tempo is parsed incrementally:
```
For each new track:
for each new tempo-event:
rewind()
for each loaded track so far:
for each event on this track so far
```
This reduces the complexity from O(tracks^2 * tempos^2)
to O(tracks * tempos).
"Come Thou Fount Tempo Map.mid" has 238 Tracks and 56168 total
Tempo Changes (236 per track). This now requires only 56168 iterations
in smf_create_tempo_map_and_compute_seconds, rather than 1.64e+9
iterations
block_processing() may hold the process-lock, waiting
for the latency-lock. at the same time audio-engine
may hold the latter, trying to acquire the former.
This does not maintain note timing, but once the buffer contents arrive at a receiver, it should
be playing all the notes that were marked on in the tracker
When bouncing Region or Range, Session::write_one_track()
blocks processing, but takes no process-lock.
It is possible that a latency-callback arrives at the same
time while Route::bounce_process is active and calls ::run.
This can trigger a delayline.cc Assertion `lm.locked ()' failed
in either thread.
Now latency-callbacks are postponed until the session can
process normally again
process_index should not be compared/combined with expected_end_sample, since
the former is a process-cycle count and the latter is a timeline position.
* first the region is scanned for bpm and one-shot status
* then we handle properties that should be applied from a drag&drop
* then we handle the existing arrangement-style slot properties that should persist
This addresses the issue described in 83719fba1a.
First process all queued self_delete() requests before scheduling
Editor::redisplay_track_views() which uses PRIORITY_DEFAULT.
THe length of a Source(File) is always measured from its start. In this sense,
the length is like a position on the timeline, which is a duration with an
implicit origin, or a Region start, also a duration with an implicit origin (in
that case the start of the Source). There is no good reason for using
a timecnt_t for this value, because the position component of a timecnt_t
(the origin for the duration) is implicit and always zero. So we make
this property into a timepos_t, and include a number of asserts() to check
for common possible coding errors related to the time domain