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
Apparently a user managed to remove a SC input and then
use the input's context-menu before the UI had caught up.
(PluginPinWidget::plugin_reconfigured happens during idle)
---
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 [..] PluginPinWidget::sc_input_press(_GdkEventButton*, boost::weak_ptr<ARDOUR::Port>) + 1140
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.
AudioRegionView() c'tor calls create_waves() early on
before the _height is set [1].
Now one following can happen:
1. All peak-files are present. create_waves() directly calls
create_one_wave() for each channel. They are initialized
with zero height.
But all channels are present so waves[] is populated and
a later call to set_height() corrects this
2. All peak-files are still missing. create_waves() schedules
callbacks via PeaksReady -> peaks_ready_handler()
Those callbacks arrive after set_height() was called and
the waveforms are displayed correctly.
3. Only some peak-files are present. This can happen at
rec-stop when the region is created.
create_waves() directly calls create_one_wave() for available
peaks, and schedules peaks_ready_handler() for the remainder.
The directly created waves have zero-height.
Since not all waves are ready, they are stored in tmp_waves.
waves[] remains unpopulated.
The set_height() call only ever changed the height of wave[], which
resulted in hidden waveforms, until a user manually changed the
height of the track.
[1] the height is set from
```
#1 AudioStreamView::create_region_view(boost::shared_ptr<ARDOUR::Region>, bool, bool)
#2 AudioStreamView::add_region_view_internal(boost::shared_ptr<ARDOUR::Region>, bool, bool)
#3 StreamView::add_region_view(boost::weak_ptr<ARDOUR::Region>)
...
## PBD::Signal1 Playlist::RegionAdded()
```
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.
We have to call close_view(), which calls IPlugView::removed()
before destroying the parent widget.
Previously ~VST3PluginUI() was called after the derived class
destroyed the owned private `_gui_widget`, `_ns_view` or x11 parent.
On windows that may lead to the hwnd of the window becoming invalid
before the call to ::removed().
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