This fixes an issues with missing monitor-sends when creating
a session from a template with monitor-section, or when creating
tracks from a route-template.
When exporting long sessions with freewheeling, pulseaudio
may meanwhile suspend the corked audio device. The "FAIL_ON_SUSPEND"
option then prevents ardour to uncork it after export, and the
audio-backend is halted.
*PluginInfo::load() eventually calls `plugin->set_info()`
which depends on a valid PluginPtr. The method needs to return
early if `plugin` is unset or null.
Route::realtime_handle_transport_stopped() does have insufficient
information (PostTransportLocate), so "flush" is called from
Route::non_realtime_transport_stop in the butler thread.
However plugin de/activate() must not be called concurrently with
processing. e.g. https://lv2plug.in/ns/lv2core explicitly states:
"Hosts MUST guarantee that: An Instantiation function for an instance
is never called concurrently with any other function for that instance."
This would later trigger an assert() in MidiRingBuffer<T>::read
when reading the status-byte, and cause undefined behavior down
in optimized builds.
It is unsure if this can happen, but it may explain
https://marcan.st/paste/LHDXNQ9x.txt
The file linked from the bug report has a meter-change
in the middle of a bar. Ardour maps this back to the previous
bar, which already has a meter-change. Session load fails with
"Multiple meter definitions found at 473"
The tempo-map of the file ends like this:
```
Meter 11/32 @227040 (beat 473)
Meter 4 / 4 @227680 (beat 483.666667)
```
This potentially breaks various assumptions (e.g. no resampling,
fixed buffersize) when the stream is moved to a different device.
Then again it's pulseaudio, which is unsuitable for pro-audio to
begin with.
This uses an atomic counter and spins only on the writer side, which
preserves realtime behavior on the reader side. The spinning yields (by
using the same Boost function from Boost spinlocks) to be
scheduler-friendly.
Fixing this bug also lets us be able to confidently drop garbage early
in the writer if appropriate, so do that and avoid keeping dead wood if
possible.
This reverts commit f95439a502:
"add spinlock to RCU manager to protect concurrent reader() and update() calls"
This can happen if the buffers have different sizes.
This fixes crashes that bisected to 7c37a18b7, but it is not the root
cause; it just happened to make things worse.
This fixes an issue with some soundcards e.g. "AxeFx III".
Device configuration fails unless set_hwpar() is performed
for the capture device before configuring the playack
device (half duplex is fine, too).
When a route's output is connected to multiple busses, re-establishing
port-connections on session-load calls Route::output_change_handler
multiple times.
Implicit solo counts are saved and restored by the route's SoloControl,
however the output_change_handler invalidated it on session load.
Since connections are restored iteratively, counting soloed downstream
routes will yield an incorrect result until all connections are
established.
This fixes the issue that implicit solo is lost on session-reload
in case a route has multiple connections with different up/downstream
solo states.
* Include main-out channel-count when bouncing the output
* Do not de-activate disk-reader and mains-out when freezing a track
* Ignore meter when counting channels
TMM ports cannot exist without a backend.
This fixes crashes where the PortEngine is re-initialized
(backend change):
Previously, TMM ports were only dropped (and recreated)
in TMM::restart() called from ARDOUR::init_post_engine().
When starting a new backend the old one is already destroyed,
but TM still held reference to Ports owned by that backend.
Calling the port's d'tor caused a memory corruption trying to
acquire the backend's port_callback_mutex:
e.g. When creating new session with a different backend
from a running instance, or unit-test after call to
AudioEngine::destroy(): https://pastebin.com/4D6pLA5s
While Ardour uses separate indices when naming tracks and busses
("track 1", "track 2", "bus 1", "bus 2"), the indices are contiguous
(0: "track 1", 1: "track 2", 2: "bus 1", 3: "bus 2").
* replace signal-emission with direct calls to CoreSelecton
using BaseUI's session pointer
* remove unused leftmost strip API
* use CoreSelection for first-selected strip
* Accessing CoreSelection does not modify the session
(allow access from const callbacks)
* replace static calls in P2 surface
This removes indirection and dependency on the GUI for
managing strip selection.