This makes "sequential" more or less mean an octave vertical interval,
but only for in-key mode. For chromatic mode, "sequential" is still just a
naive wrap-around layout for every note.
This juggles the implementation slightly in a way that's more resilient to
mistakes: the representation of pads in the surfaces is always fully reset
before setting up the grid, and a state message is sent for every single pad
once after the scale algorithm sets things up.
This means that scale algorithms don't need to deal with hairy edge cases like
running off the end of the scale or the valid range of MIDI notes.
"Mostly" because there are still some issues with horizontal overlap between
entries, but I think that's something that needs to be addressed separately.
Like earlier issues, this was caused by using a screen-derived or default
cairo/pango context. I also tinkered with some constants to make things look
sensible to me, and hopefully everywhere since it should always look the same
with the context fix.
We no longer have a distinct "position" property, because the "length" property
defines both extent and position. But we must not call ::recompute_at_start()
when the position has not changed, so here we use Region::last_length() to
simulate the position property.
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.
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.
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.