Editor::insert_time(), Editor::remove_time() handle automation
directly because time may be inserted to Routes without playlists
and combined undo-operation with marker, and tempo-changes.
However when the preference "automation_follows_regions" is enabled,
the playlist already moves the automation of region under any region
(possibly overriding future automation).
This resulted in possibly lossy, duplicate automation moves.
* Remove leading and trailing whitespace.
* use tabs to indent, space to align
/* prefer C-style comments like this,
* always use an asterisk on every line, this
* way small ASCII-graphics are always aligned
* using spaces after the asterisk.
*
* ^
* / \
* / \
* / \
* / \
* / \
* / /\ \
* /__/ \_/\_^__\
* A R D O U R
*
<< NO asterisk, there may be tabs :(
*
*/
eg. LV2 externalUI windows are not managed by ardour; Ardour cannot
intercept mapped() or delete_event() signals and hence also not
create a visibility-tracker.
First call to WindowProxy::toggle() creates the window, and the 2nd call
crashed since 6ca8ec5141, due to missing vistracker.
e.g. externalUI plugin windows, the processor-box uses WindowProxy
for all plugin-UIs incl. externalUIs.
lv2 state mandates that
> The plugin MUST use this function [ absolute_path] in order to
> actually open or otherwise use any paths loaded from plugin state.
Previously the plugin uses the value directly. Also
> The caller is responsible for freeing the returned value with free().
is now implemented on systems other than windows (where this is not
possible, since the memory must be free()ed in the same module where it
was allocated.
Use RCU of automated parameter when looking for next automation event
to use for split processing. This speeds up PluginInsert processing
when rolling for plugins with many not-automated parameters.
Keep a dedicated list of automated parameters to evaluate in realtime.
This fixes a performance issue with plugins that have many controls
with only few of them being automated.
This fixes inconsistent WM::Proxy state when a window is destroyed
Specifically "session-options-editor" when the session is unloaded;
previously "toggle-session-options-editor" was never unset.
This fixes issues with analysis and archiving that rely on a readable
to return 0.
Note however that createSilent() uses max_samplecnt (INT64_MAX) by
default. This relies on a region setting the length of its missing
source.
These processors don't have a UI, so their load stats are not easily
visible. The stats can still be queried via Lua API or DSP-load
overview window, so we retain this for debug builds.
Use AU's preset->presetNumber as identifier since std::map are sorted
this also indirectly sorts presets by preset-number. (user presets
start with a '/' and are listed first, sorted by name).
Since Presets are now identified by URI on session load (53a0199a0)
and AU user-presets can added/be removed (since ae4604a24b), simple
sequential numbering is no longer an option.
This is a step in the right direction: first load the preset and
only if preset-loading was successful mark it as loaded.
This still does not properly unset "parameter_changed_since_last_preset".
AU signals "kAudioUnitEvent_ParameterValueChange" later in the event-loop.
* PortEngine::available() implementation
* AudioEngine::connected() wrapper
Eventually we may re-introduce PortEngine::available along
with a libardour internal port-engine.
Adding/removing the Monitor section changes port-connections,
a port-engine is needed to establish connections.
Ideally we'd allow this and queue for connection changes. This
will however require deep changes.
Also toggling the monitor-section on/off/on w/o engine can later
result in failure to register ports. Due to lack of engine-signals
not all shared_ptr<> port references are dropped.
Previously Port::PortDrop was never handled.
The signal was disconnected directly when the connection
is re-used by Port::PortSignalDrop.
Ports::drop() was not called when the engine was stopped
or disconnected, and port-handles were not invalidated.
This lead to crashes whenever a port-related operation was performed
while the engine was stopped. e.g. adding/removing tracks or plugins
(latency recompute, notify port-engine) and various other operations.
This fixes an error while loading shared libraries: libardour.so
R_PPC64_ADDR32 reloc at 0x... for symbol `' out of range
Treating a local as an immediate value in asm code makes the library
non-relocatable.
This saves some memory (gmsynth loads a 30MB soundfont), and also
re-initializes the synth every time to gm defaults in case some
.mid changes patches or parameters.
This adds an experimental pipe to ffmpeg to encode mp3. Currently
quality is hardcoded and various aspects remain to be implemented.
However, it is sufficient for initial testing.
This will incorrectly list some vocders or reaktor and the likes of
plugins with audio + midi input as Instruments IFF they also announce
effFlagsIsSynth flag.
NB. this is a first step only. we still need to override PluginInfo
While gnu-gcc had `std::map:at const` as non-standard extension
it is n/a for older gcc on OSX.
Surprisingly this const& p() const; performs a tad better as well, likely
due to different exception handling.
Perhaps it is also worth investigating boost::flat_map<> as replacement
for std::map<>, here. Our common case is just a single entry, so using
a std::vector emulated mapping might help.
Another micro-optmization shaving off some ten microseconds for every
plugin. Also copying maps isn't RT-safe.
This may however cause issue if const map references can change
while a plugin is running.
For plugins with 10000 Control Inputs, dynamic_pointer_cast<> overhead
is significant, here ~2msec (~0.2usec per cast, optimized build, i7-5600U,
2.60GHz)
When a route with a sidechain is created from a template or by route
duplication the number of ports of the sidechain are set according to the
XMLNode defining the sidechain. Then the names are set according to the name of
the newly created route.
Thus all the pin connections defined in the template are replicated in the
newly created route.
When a PluginInsert is created it does not have an owner right away. That's why
a we need to set the sidechains name once the owner is known, in order to
include owner's name into the name.
Furthermore we need to follow renames of the owner.
Some plugins return 0 from effGetVstVersion and are hence not detected
as instruments. e.g. VeeSeeVSTRack (VCV). This may also explain why MIDI
port of some other VSTs are not exposed.
Most VST2.4 return 2400, so checking [effGetVstVersion] >=2 (and not 2000)
was incorrect to begin with.
VCVRack VST currently exposes 9999 automatable-control parmaters.
This slows down various GUI dropdown lists and dialogs.
(even worse: those parameters are not mapped to anything by default).
This change allows to limit automatable parameters to a reasonable number,
without loosing state of already automated parameters in existing sessions.
This is required by 7d8b93ad for showing error when actively recording.
It also prevents other UIs (OSC, Lua,..) to change re-configuring
sidechain ports/plugins while recording.
A "fall through" comment is most portable way to indicate
"no break, fallthru" cases.
* __attribute__ ((fallthrough)) // is not portable
* [[fallthrough]]; // is C++17
lili93's session (#ardour) triggered this w/jackd 512fpp:
Drag/Drop copy a latent plugin from one track to another while rolling.
The GUI-thread as well as the auto-connect thread concurrently call
jack_recompute_total_latencies(). The auto-connect thread holds
a process lock while doing so. The GUI does not use any mutexes.
This randomly deadlocks in libjack.
backtrace: https://pastebin.com/6m3KGhWS
This is more of a workaround than a fix. Simply by forcing the
URI to be sortable (VST-user presets are sorted at the end).
This eventually needs a deeper cleanup and API consolidation
PluginInfo::get_presets(bool) returns an ordered std::vector.
However this API is only used in a few cases where the plugin is
not instantiated. PluginInfo::get_presets(bool).
The problem is Plugin::get_presets(). The method returns
information that was previously cached by Plugin::find_presets() in
std::map<URI, ...>
Ardour's VST MIDI buffer API does not yet implement offsets and limits.
When a cycle is split, the same midi-buffer is used for all sub-divisions
leading to duplicate, offset, events.