Tests would fail as:
Test name: AutomationListPropertyTest::basicTest
equality assertion failed
- Expected: 4
- Actual : 5
It is slightly more informative when the size assertion is the last
check and it fails as:
- Expected: state
- Actual : time-domain
The performance benefits from checking size first is not relevant.
With this, all tests are passing for me.
While Ardour doesn't use TDD and has low test coverage, it is nice to
maintain that all active tests are passing.
At present, TempoTwist is Primary-drag on the tempo ruler, and TempoCurve is Primary-drag on the meter
ruler. Not sure that this is quite what we want here, but it makes more sense than the prior
design, in which TempoTwist was available from non-tempo-related rulers
This avoids breaking bindings, and since the action name is generally not a part of the GUI,
really doesn't hurt anything in terms of understandability
An attempt to satisfy #8848.
Add a new action, "fork-regions-from-unselected", which unlinks all
selected MIDI regions from any unselected regions, but maintains links
within the selection, and add the new action to the region MIDI context
menu as "Unlink from unselected". Rename the existing "fork-region" action
to "fork-selected-regions", and amend the existing "Unlink from other
copies" menu item to "Unlink all selected regions" to (try to) clarify the
difference.
Attach the <Tertiary>U default key-binding to the new action: I personally
think it's generally slightly more useful (otherwise I wouldn't have
implemented it), though I'm not that fussed.
In the case that there's only one MIDI region selected, or that none of
the selected regions are mutually linked, both actions will have exactly
the same result. Ideally, we'd only show a single menu item in this case,
but that would require (a) implementing a function to check whether the
selection contains any linked regions, and (b) making the region MIDI
context sub-menu dynamically generated, so that it can change based on the
result of that function, neither of which I've tried to do yet.
Original code is of questionable historical provenance, and
was needlessly (it seems) complexity. New code is relatively
simple arithmetic linear interpolation.
Session dirs must exist when loading Sources of a project.
SourceFactory::init() starts the PeakFileBuilder background thread
early on when libardour is initialized.
This thread [re-]creates missing peak files when Sources are
created or loaded. However AudioSource::prepare_for_peakfile_writes
assumes the peak/ folder exists. This may not be true, which lead to
"AudioSource: cannot open _peakpath [..] (No such file or directory)"
errors.
Also drop creation from Source::get_transients_path() as this
may be called concurrently from Analyser background threads.
The fix here is really just dropping the use of _offset when computing the session position
of a control point. This was just an arithmetical error.
However, session_sample_position() was redundant and just caused more work, so this
method was removed, and only ::session_position() is now used.
In addition, several closely related places now use C++11 (or later) "auto"
syntax for iterating over containers, for cleaner looking code
This reverts commit 96ebac646d.
There are some valid cases where refill is called from the GUI
thread. e.g adding tracks, or adding channels to an existing track.
This happened initially during session load.
The GUI thread performed a direct refill (blocking wait)
`Session::post_engine_init() -> Track::seek() -> DiskReader::seek() -> DiskReader::do_refill_with_alloc()`
while concurrently the butler thread does the same:
```
Session::butler_transport_work() -> Track::non_realtime_locate() -> Route::non_realtime_locate()
-> DiskIOProcessor::non_realtime_locate() -> DiskReader::seek() -> DiskReader::do_refill_with_alloc()
-> DiskReader::refill_audio()
```
We do not want the GUI to wait, so now we just request a locate
and let refill happen in the background.