This is a revision of the initial API 8ba7df9105, to
address issues with dynamica ports (fa791ae9cc).
* Group meter + scope/monitor per port (atomic access)
* Use shared pointer to allow access while ports change
* Use RCU to update port map
* Add/remove ports without clearing the map
* Add signal to notify GUI about Input Port changes
This allow to restore original engine port-names as set
by the backend. ALSA MIDI, CoreAudio, CoreMIDI and PortAudio
drivers can provide human readable physical port names for
some devices.
Various playlist operations can change region-properties
which results in Region::send_change being emitted while
the Playlist::RegionWriteLock is held.
This can result in recursive lock and/or deadlocks or crashes. e.g.
Insert time -> Playlist::shift -> Region::RegionPropertyChanged
-> EditorSummary::set_background_dirty -> Editor::session_gui_extents
-> Playlist::get_extent -> read-lock is taken after write-lock.
FoldbackStrip::update_send_box() GUI relies on ->fed_by() to
determine if a FB bus has a send from a route.
Under the hood this uses direct_feeds_according_to_reality()
and InternalSend::feeds(). When `allow_feedback` is set a send is
assumed to not directly feed a target (to allow loopbacks).
This mode must not be used for foldback sends.
Older compilers do not yet have fmaintrin.h. This fixes compile errors:
```
x86_functions_fma.cc:51:39: error: '_mm_fmadd_ss' was not declared in this scope
x86_functions_fma.cc:85:35: error: '_mm256_fmadd_ps' was not declared in this scope
x86_functions_fma.cc:106:35: error: '_mm256_fmadd_ps' was not declared in this scope
x86_functions_fma.cc:129:39: error: '_mm_fmadd_ss' was not declared in this scope
```
By supporting FMA extension, the number of instruction needed
for multiply accumulate to mix channels are reduced. Since,
this extension has been around since middle of 2012, more
computers have this instruction set available.
This also reverts 768d8362cd since it causes crashes
with various plugins (eg. surge.vst3).
Ardour now provides AudioBusBuffers for all audio I/O busses,
regardless of Ardour using those busses.
This fixes crashes of plugins that ignore ProcessData::numInputs
or ProcessData::numOutputs. Those plugins are expected to check
numChannels and channelBuffers for those excess channels, which are
0, NULL for unused busses.
ProcessData numInputs, numOutputs does correctly reflect actual
busses that are in-use (at most one main and one aux for each direction).
This should fix an issue with yabridge and MCompressor.
The plugin has two kMain inputs and expects ProcessData:inputs
to always have two entries, even if the second bus is explicitly
disabled.
see https://hastebin.com/ekewojiqep.txt
```
IComponent::activateBus(type = 0, dir = 0, index = 1, state = false)
data.numInputs = 1;
```
TODO: optimize (pre-allocate) if it works as expected
This significantly speeds up loading export formats that use ffmpeg.
A single call to ::transcoder_exe() took 300-400ms on Windows.
With multiple formats using an external transcoder, showing the
export dialog could take to 2-3 sec.
Those are blank to begin with, nothing is drawn, yet they'd still be
cached.
This may happen during an initial exposure (see 1a49d7d42b),
or when deleting regions.
The file has to be flushed to disk before it can be used.
This fixes an edge case only.
Since PeaksReady() is a cross-thread signal that calls
AudioRegionView::peaks_ready_handler in the GUI thread, the
function [almost] always completed, before the GUI was woken up
to schedule a WaveView render request (which uses the peak-file).
This is needed for threaded peak-file creation. The same
nested source may be accessed multiple times concurrently
(in addition to the butler thread reading it).
This fixes Bitrunner's "filum2020" session randomly showing garbage
waveforms.
This was not a typo after all, but a way to show the gain in the
name-display, as per manual:
> In the case where Gainmode is set to position, the track name
> will show the dB value while values are changing.
This reverts commit 3290d66a43.
This amends 5950df2b74. The VST3 SDK does not recursively search
directories that are bundles IFF the file inside the bundle's
architecture folder matches the bundle's name.
In case there's a file with a different name resides inside the
bundle it is treated as standalone, unbundled plugin.
Since Ardour, PBD::Searchpath always does a recursive search, the
bundled plugins need to be weeded after the fact.
This now follows the VST3 SDK by not just checking the arch name,
but also Contents and bundle.vst3 parent dirnames.
When using the export-tool, the very first callback may already be
freewheeling. In this case the first call to the butler also happens
directly from the freewheel process-callback and initial session events
are handled there. Setting PostTransportAdjustPlaybackBuffering
took the process-lock, which caused a deadlock:
Glib::Threads::Mutex::Lock::Lock(Glib::Threads::Mutex&) at /usr/include/glibmm-2.4/glibmm/threads.h:687
ARDOUR::Session::butler_transport_work() at ../libs/ardour/session_transport.cc:1157
ARDOUR::Session::process_export_fw(unsigned int) at ../libs/ardour/session_export.cc:303
ARDOUR::AudioEngine::process_callback(unsigned int) at ../libs/ardour/audioengine.cc:486
ARDOUR::DummyAudioBackend::main_process_thread() at ../libs/backends/dummy/dummy_audiobackend.cc:951
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.