::length() was non-virtual, and so calling SrcFileSource::length() would access
the base class (AudioFileSource)'s version. Since SrcFileSource is essentially
a pimpl-like pattern, this was incorrect; we need to make sure we call the
pimpl-style method instead.
Audio ports are sorted using PBD::naturally_less.
PBD::naturally_less is also used as compare function
for port-lists, port-sets, and port-maps.
So in sets and maps, the function is used to test
for uniqueness. This lead to issues since naturally_less
treats whitespace and underscores as identical.
While it was possible to have routes named "Audio_1",
and "Audio 1", this resulted in missing ports for one
of the routes.
see also 60ff3ef764
This is mainly motivated by DPF's new VST3 implementation, but
also takes a leaf out of JUCE's book, unconditionally initializing
the VST::IEditController even if it is-a VST::IComponent.
and likewise calling terminate().
If time domains differ, it is necessary to first convert the argument duration into a duration
at the position of "this", in the correct time domain. Then we recursively call the operator
again, but this time we will use the fast path that just adds two timepos_t values.
This fixes async callback from CoreAudio via
AudioDeviceAddPropertyListener. Apparently in rare cases it can
happen that the property listener calls back concurrently with
processing on M1 machines using Rosetta.
https://pastebin.com/upvc9LTc Thread 44 vs. Thread 32
May also be caused by plugin(s) taking a long time to
change buffersize. Processing continues even though the
buffersize callback has not yet completed.
PS. I have not been able to reproduce this on an Intel
machine, even with excessive buffersize changes. However
since buffersize changes cannot (usually) happen concurrently
with processing, taking the lock is reasonable.
Some plugins have a min/max range of 1, for stepwise enumerated
values of a control. e.g. waves maps note-names this way.
https://discourse.ardour.org/t/106429/