This allows to distinguish Processor::configure_io from the
Plugin API with the same name. Despite the identical name,
both functions serve different purposes.
Likewise the ::can_support_io_configuration() API is renamed.
The signature of that function call has already diverged.
The Plugin-API has to handle optional busses (e.g. side-chain)
and replication. The PluginInsert processor provides context.
This change is in preparation for AudioUnit and VST3 busses.
Currently a stereo-input (1 bus) cannot be distinguished from
mono + sidechain (2 busses).
Since the file-modification timestamp of the module-path is used
if the cache is up-to-date, the file must exist.
For macOS/X bundles the mandatory file as per VST3 spec is Info.plist
A call to VST3Plugin::has_editor() can create the view of
a plugin. If the GUI is never displayed, the view would
not have been released, which can lead to crashes when
unloading the plugin.
Both TimeType (8byte) and EventType (4byte) are written
in an un-aligned buffer (usually 3 byte MIDI messages).
This caused an Illegal Instruction for 32bit ARM builds
The cross-over point of an exponential fade occurs further towards
start of the fade. This increases consistency of cross-fades moving
the cross-over point to the center of the fade.
Also looped material is likely correlated in which a linear fade
is more appropriate.
This is only relevant when automating a plugin-bypass, due to
ActiveChanged the following could happen from the realtime thread:
#2 ARDOUR::Session::update_latency_compensation (false, false)
#3 PBD::Signal0<void, PBD::OptionalLastValue<void> >
#4 ARDOUR::AutomationControl::actually_set_value
#5 ARDOUR::PluginInsert::PluginControl::actually_set_value
#6 ARDOUR::PluginInsert::connect_and_run
#7 ARDOUR::PluginInsert::automate_and_run
In this specific case the update_latency_compensation()
is called with process-lock held but the caller lied:
called_from_backend=false
When a delayline update is needed, this can lead to a deadlock,
since the process-lock is acquired again.
Simply postponing the update is preferable since this also
postpones the change when actively recording.
PS. This may need special casing for freewheel export.
IO::latency iterates over the port-set retrieving the
private_latency_range of each port. The value can cached
since it can only change when connections or latency changes.
see also 40eefeddd6
This is to allow passing the EventType to the Buffer, using a
consistent {[Time], Type, size, data} API, that is equivalent
for all classes.
This is particularly useful for Lua scripts and plugin UIs
than can call `write_immediate_event()` while being ignorant
where the data is routed to (MIDI tracks, plugins, processors).
The motivation for this is to determine if a given event
originates from a user-controlled live input controller or
from playback from disk or a MIDI file.
This distinction is required for VST3 MIDI learn.
This is required. From the "RestartFlags" documentation:
> kLatencyChanged:
> Latency has changed The plug informs the host that its latency
> has changed, getLatencySamples should return the new latency after
> setActive (true) was called The host has to deactivate and reactivate
> the plug-in, then afterwards the host could ask for the current
> latency (getLatencySamples) see IAudioProcessor::getLatencySamples
This can happen during pre-roll when buffers are filled
to start audible playback at zero.
While the position argument is signed for all plugin-standards,
it seems that some do not support negative timestamps before
00:00:00:00. (e.g. https://github.com/falkTX/Carla/issues/1236)
Furthermore TempoMap::bbt_at_sample() returns 0 for all negative
timestamps, but it was possible tthat tempo-map transmission,
as well as beat-position returned negative values.
When the engine is restarted, ports are re-established,
and previously queued port-connections need to be cleared.
This caused a bug:
* when the engine is stopped all ports are disconnected.
_port_connection_queue contains all disconnections
* engine is stopped so _port_connection_queue is not processed
* engine-restart re-etablishes ports and appends those connections
to _port_connection_queue
* process-callback processes the list in **reverse** order
```
while (!_port_connection_queue.empty ()) {
_port_connection_queue.pop_back ();
}
```
* ARDOUR::PortManager::connect_callback() is first called
with connected() and the disconnected()
* All ports are assumed to not be connected
Port::_externally_connected == 0 for all ports
Result:
* vari-speed playback resampling does not work (only external
I/O is reampled), split cycles processing (looping) fails
since AudioPort::get_audio_buffer() does not apply the
_global_port_buffer_offset
Previously when locating process_can_proceed() was set to true,
and routes were not processed while transport states are cleared.
As a result live input was also not processed.
This is no longer needed because the DiskReader handles seeking
directly.
This fixes segfaults as well as corrupt listes when copy/pasting
due to invalid iterators.
::mark_dirty() must be called with WriterLock, and
::rt_safe_earliest_event_linear_unlocked() must not be called
while _events is being modified. The Sequence iterator
(only user of that function) does not ensure this. Only the
sequence read-lock is taken.
When recording audio, simply not writing to the ringbuffer
offsets the recording accordingly.
When recording MIDI, absolute timestamps are used, so the recording
has to be offset by the accumulated difference.
Previously this went unnoticed because tests using the Dummy
backend the accumulated offset never exceeded 1 cycle.
* amend previous commit, fix runtime_error implementation
* Do not copy-construct classes that have a PBD::scoped connection list.
Replace std::map::emplace[C+11], an store shared pointers the std::map.
* Update ArdourMixerStrip is-a ScopedConnectionList (not has-a)
Rename all {object}_n variables and arguments to {object}_id
Parts of code were using the former convention, now use the latter everywhere
Another step towards supporting visual position agnostic identifiers in the future
Use maps instead of vectors for holding strips and plugins
This allows to deal with "holes" after objects are removed
Also paves the way for a future improved way of identifying
individual strips and plugins
Apparently gcc-6.2 with -O3 and -mfpu=neon can use ARM instructions
that requires 64bit alignment (here vst1.64) with data that
is not 64bit aligned (g->strcache) https://i.imgur.com/vYktsUn.png
So we need to be able to build "arm_neon_functions.cc" with
-mfpu=neon, while not automatically using NEON for the rest
of the codebase, unless explicitly asked for.
the proper check using compiler flags would be
defined(__ARM_NEON) || defined(__aarch64__)
however explicit wscript defined "ARM_NEON_SUPPORT" is prefereable.
This commit adds ARM NEON optimized routines for the following procedures
below:
*_compute_peak
*_find_peaks
*_apply_gain_to_buffer
*_mix_buffers_with_gain
*_mix_buffers_no_gain
*_copy_vector
NEON optimized routines have a prefix of: arm_neon_
Previously when the master-bus had more outputs than inputs,
Ardour crashed when the monitor-section was set up.
Removing a master-bus output port calls
Route::output_change_handler (master-bus)
-> Session::reset_monitor_section
which first removes the corresponding monitor-section input,
then output port. The latter triggers
ARDOUR::Route::output_change_handler (monitor-bus).
All with the process-lock held, so at this point in time Ardour
has removed the port-reference but the port still exists in the
backend.
Now the monitor-bus processors are re-configured and
the channel-count is updated. The port that was just removed
and triggered the ::output_change_handler() callback is
re-created.
unable to create port 'Monitor/audio_out 2': failed constructor
This fix changes the monitor-section to use strict-i/o (for plugins)
and also use master-bus output (not input) when configuring
processors.
Ardour's "pbd/i18n.h" needs to be included last,
after any include that may indirectly pull in getext or libintl.
For that reason "pbd/i18n.h" must not be used in header files either.
These are longer be used since Seuqnce has a "force_discrete"
boolen that needs to be taken into account in addition to
user-configurable ControlList _interpolation mode.
`_mm256_cvtss_f32` is only available in avxintrin.h of gcc-8 or
later. There it is defined as
```
extern __inline float
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_cvtss_f32 (__m256 __A)
{
return __A[0];
}
```
While explicit `vcurrent[0]` works with gcc-5 and gcc-6,
older gcc-4 fails with the following
error: invalid types 'float __vector__[int]' for array subscript
This fixes symbol mangle for window builds, and offers backwards
compatibility with older systems where the inline _mm256_cvtss_f32
is not defined in avxintrin.h
This commit adds AVX optimized routines for the following
procedures below:
*_compute_peak
*_find_peaks
*_apply_gain_to_buffer
*_mix_buffers_with_gain
*_mix_buffers_no_gain
AVX optimized routine has the prefix of: x86_sse_avx_
Note: mix_buffer_with_gain and mix_buffers_no_gain may prefer
SSE implementaion over AVX if source and destination pointers
are aligned to 16 byte boundaries. Therefore, it will be optimal if
_all_ audio buffers are allocated to 32 byte boundaries to take
full advantage of AVX ISA extension.
Previously when loading old session Route::init() of the master-bus
was called without the "MasterOut" or "MonitorOut" flag being set.
Various conditions that relied on is_master() or is_monitor()
during initialization failed when loading those sessions, leading
to subtle breakage.
i18n must be included last, after all template specialization.
Otherwise the following happens:
In file included from ../libs/pbd/pbd/i18n.h:22:
../libs/pbd/pbd/compose.h:122:6: error: call to function 'operator<<' that is neither visible in the template definition nor found by argument-dependent lookup
This fixes an issue with Renoise Redux. The plugin reports the following:
Reported Channel Capabilities (explicit):
[2, 2] [1, 2] [0, 2]
When it is added to an Arodur MIDI track, the 0 in, 2 output variant is
chosen, since Ardour MIDI tracks don't have audio by default.
However the render callback was set uncondionally for all busses. This
lead to issues with this specific plugin.
This fixes issues on MacOS (and Windows) unit-tests. The
unit-test run readless without proper UI thread. Discovering new
AU or VST can stall the app indefinitely or cause crashes.
NB. LADSPA, LV2 (and Lua) plugins are scanned regardless. Also
VST and AU cache files are read. The unit-test however only lists
LADSPA plugins.
This fixes a circular shared_ptr<> reference that prevents
plugin destruction.
LuaProc may hold references to Route that contains the plugin
or the PluginInsert of the LuaPlugin. These are only dropped
when the interpreter collects garbage.
Previously this happened in the d'tor or LuaProc, but while the
Plugin has a reference to the Insert, the Insert is not deleted
and the d'tor is never called.
This is useful in cases where an object owns child objects
which in turn hold a reference to the parent.
In this case PluginInsert has-a Plugin, which may have a reference
to the insert or the Route.
This follows 5a41ca8fdf and df1e6fda2d.
Even though this kind of precision is rarely needed, rounding
to a single digit is inconsistent with various places that display
more than one digit, or allow more accurate control.
On GLIBC systems pbd_stack_size() adds __pthread_get_minstack,
this is no available on mac systems, causing issues with some
libraries used by plugins.
In some rare cases the butler may be busy for a long time
(e.g. seek in a large session may still be active when
export is started).
8 second timeout seems reasonable to prevent the app from hanging
without desktops showing a "unresponsive" popup in case the
timeout is reached for some reason (e.g the engine dies, and
no TFSM transition can happen).
At present only audio data from disk readers is declicked. MIDI tracks with audio output should
likely also be declicked, at which time Session::need_declick_before_locate() will require
amending
previously this subscription was handle done in
Route::add_routes() -> add_routes_inner() for MIDI tracks only.
Since f6c0b02d9f this was only done when adding
tracks, after any instruments were loaded (and fanned out).
This consolidates instrument creation for midi tracks & routes.
If an instrument is added, output auto-connect is postponed until
after the instrument plugin is added. Also when a multi-channel
instrument is fanned-out, the track outputs are not auto-connected.
This also subscribes MIDI-Busses to auto-connect when an instrument
is loaded or replaced at a later time.
Since fan-out happens (interactively) in the GUI thread,
we need to keep track of this, in order to prevent later
auto-connection of the track to the master-bus.
..forth and back..
1882c1ba7edabd5715e9fac8d84786
This needs a [much] better solution:
e.g. Wait until instrument is instantiated (ports are created),
then auto-connect, and finally fan-out
(or alternatively skip auto-connect for fanned-out tracks).
Currently both auto-connect as well as fan-out and port-creation
take place asynchronously.
Also MIDI track subscribe to &Session::midi_output_change_handler,
(MIDI busses don't).
This may (or may not) fix#8317. Usually changing I/O triggers
an auto-connect. The actual issue seems that auto-connect
thread runs before the ports are created.
This significantly speeds up parsing MIDI files with complex
tempo-maps. e.g. "Black MIDI Trilogy_2.mid" has 24134 Tempo
changes. Prior to this commit parsing that file took over 5 minutes.
now it loads in under one seconds (libsmf only; libardour still
add overhead, and now needs about 30-40 seconds, previously
it took about 10 mins).
The problem was that every call to `smf_track_add_event_pulses()`
calls `seconds_from_pulses()` which calls `smf_get_tempo_by_seconds()`
which iterates over the tempo-map:
for every midi-event { for ever tempo until that midi-event {..} }
This does not scale to 3.5M events and 24k tempo-changes.
see also https://github.com/stump/libsmf/pull/7
* Fix validity checks of escaped data
* Handle non-EOT-terminated tracks.
* Fix buffer overflow on tempo change event
* Fix memory leaks in case loading fails
* Fix a logic errors in extract_escaped_event()
* Fix the assertion problem `is_sysex_byte(status)`
* Make libsmf more tolerant to malformed MIDI files.
(fixes import of files generated by NoteEdit)
https://lv2plug.in/doc/html/group__options.html specifies
a NULL terminated array of options (not a single option).
Since the call is the "instantiation" LV2 threading class, and
a single fixed value is passed with a direct call into the
plugin, using a stack-allocated LV2_Options_Option is sufficient.
This is only relevant with JACK, where different implementations
use threads for the latency callback.
With jack 2, jack_port_register() blocks and the jack_latency_callback
arrives in a different thread: https://pastebin.com/mitGBwpq
with jack 1 the callback arrives in sync
In either case this usually happens while
_adding_routes_in_progress == true and Ardour holds the process-lock,
because jack2 can process in parallel with reconfiguring latency
See also 1983f56592
When removing a plugin-insert that has a sidechain on a bus
that is implicitly soloed the following happens:
* Route::remove_processor() takes a WriterLock(_processor_lock)
* The sidechain input is disconnected
* Route::sidechain_change_handler() is called which calls
* Route::input_change_handler()
* Since the route is implicitly soloed, propagation is attempted
which calls
* Route::direct_feeds_according_to_reality()
which takes ReaderLock(_processor_lock)
Recursive locks, reader-lock after writer-lock don't cause
a deadlock, releasing the reader-lock effectively also
releases the writer-lock...