This does the internal shutdown of a Trigger that is shared between
a normal shutdown and when stopping for a locate/stop. There's no
output to buffers possible.
This method/design may need to change if/when we add declicking for
various conditions
Now using a globally-scoped static variable which is updated by the
AudioEngine whenever an SR change occurs. Defaults to 48kHz and can
be used even before there is a backend.
Due to recent changes, when the master bus is disconnected its
private port latency was never unset. This lead to misalignment
when using stem-export if master (or monitor) output was not
connected.
This will eventually have to be fixed, currently split-channel
files are not correctly tagged and post process commands
are only emitted for the last file.
But fixing this is complicated, so meanwhile a workaround is used.
Eventually this commit should be [mostly] reverted!
When a track's output is not connected, we assume
its output playback latency matches that of the master-bus.
This is to prevent the track's output latency to float
freely (see also a556e96ed0).
This failed if a track is connected to another track which is
not connected.
On Intel systems ArdourCanvas::COORD_MAX (1.7e+307) was rounded
to (gint) -2147483648. gtk+ treats negative window size-requests
as 1px.
However on ARM, COORD_MAX was truncated to +2147483648, gtk+ limits
this to 65535. Most WM/Xwin systems cannot handle windows this large.
It also exceeds the max size of cairo [image] surfaces.
This issue was introduced in a1c67b4ad7
when "natural_size" was removed. Before that change infinitely large
canvas had a natural_size of 2x2 px.
This fixes an issue when loading sessions in "safe mode".
Internal side-chain sends are removed if the target port
does not exist. Also other port connections are lost if the
target port does not exist.
Since cc6c0f1263 there is no Properties::position event
when a region is moved. So notify_region_moved() or
notify_region_start_trimmed() was never emitted and
Session::maybe_update_session_range() was not called.
When a track's output is not connected, but the track feeds
other tracks via sends (common case in Mixbus) the stem
export of the track was not correctly aligned.
The track is correctly latency compensated (due to sends), but
the unconnected port's latency is not set.
However stem-export uses the private latency of the port as alignment.
* audio files can be named "0bpm" to make them un-stretchable
* however they still need a sensible beatcnt, and therefore tempo
* assume tempo 120bpm and assign a beatcnt based on the file's length
* the user might later enable stretch, and we need to be sensible about it
VCAManager::create_vca sets PI::order while holding the
VCAManager:lock mutex. PI order changes emit a "changed" signal
which in turn can result in querying a list of all strips
(reassign_track_numbers) which requires the VCA mutex:
See also 729ff35faf
```
#2 Glib::Threads::Mutex::Lock::Lock(Glib::Threads::Mutex&) (this=0x7fffffffb070, mutex=...) at /usr/include/glibmm-2.4/glibmm/threads.h:687
#3 ARDOUR::VCAManager::vcas[abi:cxx11]() const (this=0x5555599b6d10) at ../libs/ardour/vca_manager.cc:77
#4 ARDOUR::Session::get_stripables(std::__cxx11::list<boost::shared_ptr<ARDOUR::Stripable>, std::allocator<boost::shared_ptr<ARDOUR::Stripable> > >&, ARDOUR::PresentationInfo::Flag) const (this=0x55555bf03910, sl=std::__cxx11::list = {...}, fl=127) at ../libs/ardour/session.cc:3949
#5 ARDOUR::Session::ensure_stripable_sort_order() (this=0x55555bf03910) at ../libs/ardour/session.cc:2634
#6 ARDOUR::Session::notify_presentation_info_change(PBD::PropertyChange const&) (this=0x55555bf03910, what_changed=...) at ../libs/ardour/session.cc:7016
[ .. connect same thread ..]
#13 ARDOUR::PresentationInfo::send_static_change(PBD::PropertyChange const&) (what_changed=...) at ../libs/ardour/presentation_info.cc:113
#14 ARDOUR::PresentationInfo::set_order(unsigned int) (this=0x5555619ceca0, order=5) at ../libs/ardour/presentation_info.cc:288
#15 ARDOUR::Stripable::set_presentation_order(unsigned int) (this=0x5555619ce8a0, order=5) at ../libs/ardour/stripable.cc:55
#16 ARDOUR::VCAManager::create_vca(unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
(this=0x5555599b6d10, howmany=1, name_template="VCA %n") at ../libs/ardour/vca_manager.cc:105
```
Control surfaces c'tor usually subscribe to signals e.g.
PortConnectedOrDisconnected. This happens after the parent BaseUI
is created, but before set_active() -> BaseUI::run() is called.
At this point in time there is no run_loop thread.
There are two options to handle AbstractUI::call_slot():
A. Queue the event in the event-loop, using the thread-local
request buffer of the caller. Then hope the BaseUI
thread is started, and calls ::handle_ui_requests() before
the memory pool runs out of space.
B. Handle the event in the calling thread. -- This may not be
rt-safe and may call functions with locks held by the caller.
It will however not accumulate events.
This takes approach (B). If _run_loop_thread is NULL, directly
handle the signal.
In the past, prior to 50abcc74b5, approach (A) was taken.
NULL never matched Glib::Threads::Thread::self().
This also reverts a prior attempt (e417495505) to address this issue.
The Model must be destroyed after the iterator, otherwise
the iterator's d'tor will cause memory corruption trying to lock
the model:
```
Invalid read of size 4
at pthread_rwlock_unlock (pthread_rwlock_unlock.c:39)
by Glib::Threads::RWLock::ReaderLock::~ReaderLock() (threads.h:828)
by void boost::checked_delete<Glib::Threads::RWLock::ReaderLock>(Glib::Threads::RWLock::ReaderLock*) (checked_delete.hpp:36)
by boost::detail::sp_counted_impl_p<Glib::Threads::RWLock::ReaderLock>::dispose() (sp_counted_impl.hpp:89)
by boost::detail::sp_counted_base::release() (sp_counted_base_gcc_atomic.hpp:120)
by boost::detail::shared_count::~shared_count() (shared_count.hpp:432)
by boost::shared_ptr<Glib::Threads::RWLock::ReaderLock>::~shared_ptr() (shared_ptr.hpp:335)
by Evoral::Sequence<Temporal::Beats>::const_iterator::~const_iterator() (Sequence.h:224)
by ARDOUR::MIDITrigger::~MIDITrigger() (triggerbox.cc:2037)
by ARDOUR::MIDITrigger::~MIDITrigger() (triggerbox.cc:2039)
by ARDOUR::TriggerBoxThread::delete_trigger(ARDOUR::Trigger*) (triggerbox.cc:4386)
by ARDOUR::TriggerBoxThread::thread_work() (triggerbox.cc:4314)
by ARDOUR::TriggerBoxThread::_thread_work(void*) (triggerbox.cc:4285)
by fake_thread_start(void*) (pthread_utils.cc:101)
by start_thread (pthread_create.c:477)
by clone (clone.S:95)
Address 0x28229798 is 24 bytes inside a block of size 56 free'd
at free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
by Glib::Threads::RWLock::~RWLock() (in /usr/lib/x86_64-linux-gnu/libglibmm-2.4.so.1.3.0)
by Evoral::Sequence<Temporal::Beats>::~Sequence() (Sequence.h:68)
by ARDOUR::AutomatableSequence<Temporal::Beats>::~AutomatableSequence() (automatable_sequence.h:31)
by ARDOUR::MidiModel::~MidiModel() (midi_model.h:58)
by ARDOUR::MidiModel::~MidiModel() (midi_model.h:58)
by void boost::checked_delete<ARDOUR::MidiModel>(ARDOUR::MidiModel*) (checked_delete.hpp:36)
by boost::detail::sp_counted_impl_p<ARDOUR::MidiModel>::dispose() (sp_counted_impl.hpp:89)
by boost::detail::sp_counted_base::release() (sp_counted_base_gcc_atomic.hpp:120)
by boost::detail::shared_count::~shared_count() (shared_count.hpp:432)
by boost::shared_ptr<ARDOUR::MidiModel>::~shared_ptr() (shared_ptr.hpp:335)
by ARDOUR::MIDITrigger::~MIDITrigger() (triggerbox.cc:2037)
by ARDOUR::MIDITrigger::~MIDITrigger() (triggerbox.cc:2039)
by ARDOUR::TriggerBoxThread::delete_trigger(ARDOUR::Trigger*) (triggerbox.cc:4386)
by ARDOUR::TriggerBoxThread::thread_work() (triggerbox.cc:4314)
by ARDOUR::TriggerBoxThread::_thread_work(void*) (triggerbox.cc:4285)
by fake_thread_start(void*) (pthread_utils.cc:101)
by start_thread (pthread_create.c:477)
by clone (clone.S:95)
```