Not doing so can make source or object files appear multiple times in
the list of files to be compiled or linked, e.g. when doing './waf build
install', subsequently leading to linker errors.
bug:
1) freeze a track
2) Session Cleanup > Cleanup unused sources
2a) confirm playlist deletion
3) quit, reload -> track is no longer frozen
because _freeze_record.playlist is missing.
session is in an odd state.
This has been tested on four devices:
- A RME HDSP Multiface
- A Yamaha AG06
- A Focusrite 2i2
- A built-in soundcard running ASIO4ALL
The HDSP and the AG06 only return one buffer size when queried so the preferred
size is used as before.
The Focusrite returns a min corresponding to the position of the slider in the
control dialog and the max is 1024. The granularity is 1 so this means that the
number of values needs to be reduced for the current UI design with a combo
box so the granularity is increased until there are around 8-9 buffer sizes to
choose from evenly spaced between min and max(but we could easily change this
if the UI changes etc).
The ASIO4ALL driver returns a min of 64 and a max of 2048 and a granularity of
8. So where the minimum buffer size and granularity is a power of 2 use only
buffer sizes that are power of 2.
If the driver returns different values for min and max it is not currently
possible to indicate which is the driver preferred value. A checkbox or other
UI element could be added to the AudioSetup dialog to only use the preferred
value but that is more work and perhaps not necessary.
Specifically, 'PhaseControllable::channel()' and 'PhaseControllable::set_channel()' get called from 'mackie/strip.cc'
At some point we might also need to do this for the related classes (SoloControllable and MuteControllable) although it doesn't seem to be needed right at this moment.
Backport from Mixbus. In Ardour this does not currently matter
since there is no top-level canvas destroyed top-down.
...
Editor::session_going_away
MixerStrip::~MixerStrip
MixbusStripCanvas::~MixbusStripCanvas
ArdourCanvas::GtkCanvas::~GtkCanvas
ArdourCanvas::Canvas::~Canvas
ArdourCanvas::Root::~Root
ArdourCanvas::Container::~Container
ArdourCanvas::Item::~Item
ArdourCanvas::Item::clear_items
GtkCanvas::item_going_away()
queue_draw_item_area()
..expose can take place async to garbage collection: crash in one of the
items.
This avoids "[ERROR]: JACK: jack_port_set_name: deprecated".
if libjack does not have jack_port_rename(), weak_libjack.def provides
a fallback using jack_port_set_name().
When loading a Session add the Session patchfiles directory to the
MidiPatchManager search path and only process/parse the files for that
directory rather than refreshing/reparsing all the files. Similarly for unload,
just unload the devices that are from the Session specific midnam files instead
of removing the path and refreshing/reparsing all the files.
This will not remove the "system" midnam files as they are always added first
and duplicates from the session patchfiles directory are ignored.
The MidiPatchManager only requires a reference to the session to get the path
to the Session midnam directory so change it so that the path is passed to
MidiPatchManager::add_search_path on Session construction and removed on
Session Destruction. This will also make it easier to test and reduce compile
times etc.
For the common case where the Session doesn't have a Session specific midnam
patch files directory(for instance a new session) it won't cause a refresh and
reparsing of all the midnam files. This saves about 2 seconds to load a Session
on my machine(fast machine with SSD), or about half the time spent in the
Session constructor for a new session.
There is still going to be that initial cost of parsing the midnam files when
the first session is created after starting Ardour. Options to remove that
would be to parse the files asynchronously and or use a faster xml
parser(eventually), neither of which seem worth doing at this stage.
This change will cause a performance regression for the uncommon case where a
Session with Session specific midnam files is unloaded and then another Session
with Session specific midnam files is loaded as it will cause the common midnam
files in midi_patch_path to be parsed twice(unload and load).
Currently when loading a session for the first time MidiPatchManager::instance
creates the MidiPatchManager singleton which calls MPM::refresh and all the
midnam files are parsed etc. MPM::set_session is then immediately called and
all the MPM state that has just been set when parsing all the midnam files is
cleared and the parsing of all the files is performed again but this time with
any session specific midnam patch files.
MPM::instance and MPM::set_session consume about 55% of the time spent in the
Session ctor according to kcachegrind and removing the double call to refresh
brings Session construction time for a particular test session down from 7.5s
to 5.5s
There is a highly unlikely case where the render thread can have zero
requests in the queue, but it is not supposed to be terminated.
1) WaveView::queue_get_image();
wake up thread, *but* the thread does not start yet
2) WaveView::cancel_my_render_request();
and now the thread starts.
1,2 are initiated by user actions from the GUI thread and are normally
orders of magnitude slower than scheduler-thread wakeup.
Classes derived from AutomationControl now check ::writable() in their ::set_value() methods to ensure that they
do not attempt to overwrite data sent to them while automation playback is underway.
The signal exists to notify listeners that something outside of the host's control (e.g. a plugin's own GUI for AU or VST)
has modified a plugin parameter. Previous code had strange feedback loops and ambiguous semantics.
The signal exists to notify listeners that something outside of the host's control (e.g. a plugin's own GUI for AU or VST)
has modified a plugin parameter. Previous code had strange feedback loops and ambiguous semantics.
Significant modification of LV2 GUI updating was required.
Still to be tested for feedback loop issues: AudioUnits
- don't attempt to insert two points on toggle.
- remove forced touch->write mode change on toggle
- initial state still wrong, but works much better overall.
- disallow simultaneous events via ControlList::editor_add ()
- clicking on an automation line selects the points that define it.
- don't 'flash' a region selection when using mousedraw mode.
- cp click selection resembles region selection.
- region gain points respect snap modifier (a la automation points).
the actual issues is in the connection management:
bundle.cc:323: void ARDOUR::Bundle::connect(): Assertion `N == other->nchannels().n_total()' failed.
That could be resolved. However, combining tracks without panners will
almost never do what the user really wants, so this case has been
disabled for now.
Fixes all kinds of miscellaneous issues with MCP. Also removes several theoretical pan modes, replace "Tracks"
pan mode with "Trim", and takes a tiny step towards view modes
Taking a readlock after a writelock in the same thread should result
in a deadlock, yet pthread on Linux returns EDEADLK and continues.
glib-2.42.0 ignores EDEADLK and assumes the lock was taken. Releasing
the lock later causes issues: "Calling g_rw_lock_writer_unlock() on a
lock that is not held by the current thread leads to undefined behaviour."
The issue at hand:
AudioStreamView::redisplay_track()
-> foreach_region() #<< WriteLock
-> add_region_view()
...
-> AudioRegionView::create_one_wave()
-> RegionView::update_coverage_frames
-> Playlist::top_unmuted_region_at() #<< ReadLock
All current users of Playlist::foreach_region() are in the GUI
and AFAICT read-only (display regions, update visuals)
in any way that causes problems, just loss of pre-existing connectivity.
1. retain state of current device (and serialize to disk) when switching
devices, and restore that state when switching back to it.
2. fix port and surfacenaming.
3. fix bundle assembly so that all ports (for multi-surface combos) work.
4. rationalize master position numbering
5. add small sleep before starting device handshake after reconnection. This
is ugly but seems to be necessary, unfortunately.
Increased the size of the FIFO that acts as the intermediate between writers and the MidiBuffer. Changed
implementation of ::write() to notice if MidiBuffer::push_back() fails, and then just leave data queued
for subsequent calls to ::flush_output_fifo().
Note: the logic here will be broken by invalid events/data, which ALSO cause MidiBuffer::push_back() to
return false. That needs fixing
1. there's no reason to make the same logic checks in both the Event and 3-arg variants when the Event
version simply calls the 3-arg variant
2. the Event version returned true under all conditions, even if the 3-arg part had failed to push
the Event data into the buffer. It now returns true or false, as intended.
3. remove debug output if a MidiBuffer is full during ::push_back(). The cases where this matters
emit output of their own, or simply remain silent and queue data later
PluginInsert::automation_run() subdivides plugin-run on every
control-port automation event (without splitting the process cycle).
libevoral has no automation-control context, hence this function
must be implemented by Automatable.
midiInReset triggers the sysex callback to tell the application that it has
finished with the buffer. Calling midiInAddBuffer results in an infinite loop
so just return during shutdown.
Currently the last backend error string is only set when calling
AudioBackend::start. Errors that occur when calling other AudioBackend methods
like AudioBackend::set_buffer_size do not set the last backend error string.
So until all the required AudioBackend methods return an ErrorCode and
last_backend_error() can be removed just set it to a default string.
Until all errors that occur are correctly indicated by returning an error code
there will still be situations where last_backend_error() is not indicative of
the true error. For instance AudioEngine::start is called and it fails but
returns a valid error code so last_backend_error() is set, then some other
engine/backend method is called that fails and as last_backend_error is not
set the GUI will display the incorrect error message.
* solo groups
* cancel-solo
* SIP <> AFL/PFL changes
The optimized plural-form route_solo_changed() relied on the false
premise that solo-groups and port-connections are disjoint sets.
-=-
e.g. "cancel all solo" calls set_solo(get_routes(), false);
Since All routes are affected, the "non_solo_change" set is empty, and
no changes were propagated up/downstream.
Routes that indirectly change state as group-members, wrongly end up in
the "non_solo_change" list instead of the "solo_change" list.
If a route feeds another in the same group, no changes were propagated.
Applied gain to both emph click and default click using sox.
This results in louder click sound by default and user is
able to boost click to 0dBFS using the fader on the pref pane.
Signed-off-by: Damien Zammit <damien@zamaudio.com>