Collect and postpone send delayline updates
In order to detect if route delaylines need to be updated, aux-send delaylines need to be updated first. This was previously done directly in the latency-callback, which may be concurrent with processing. Now only the information (pending_delay) is set, and the actual change happens later at the end of process().
This commit is contained in:
parent
31b7e18d7d
commit
2328df23e5
@ -199,6 +199,8 @@ public:
|
||||
void emit_pending_signals ();
|
||||
MeterPoint meter_point() const { return _pending_meter_point; }
|
||||
|
||||
void update_send_delaylines ();
|
||||
|
||||
void set_meter_type (MeterType t);
|
||||
MeterType meter_type () const;
|
||||
|
||||
|
@ -54,8 +54,10 @@ public:
|
||||
* (via Route::update_signal_latency)
|
||||
*/
|
||||
virtual void set_delay_out (samplecnt_t, size_t bus = 0) = 0;
|
||||
virtual void update_delaylines (bool rt_ok) = 0;
|
||||
|
||||
static PBD::Signal0<void> ChangedLatency;
|
||||
static PBD::Signal0<void> QueueUpdate;
|
||||
|
||||
protected:
|
||||
samplecnt_t _delay_in;
|
||||
@ -105,6 +107,8 @@ public:
|
||||
void activate ();
|
||||
void deactivate ();
|
||||
|
||||
void update_delaylines (bool rt_ok);
|
||||
|
||||
bool set_name (const std::string& str);
|
||||
|
||||
static std::string name_and_id_new_send (Session&, Delivery::Role r, uint32_t&, bool);
|
||||
@ -127,8 +131,6 @@ private:
|
||||
void pannable_changed ();
|
||||
void snd_output_changed (IOChange, void*);
|
||||
|
||||
void update_delaylines ();
|
||||
|
||||
int set_state_2X (XMLNode const &, int);
|
||||
|
||||
bool _remove_on_disconnect;
|
||||
|
@ -1428,6 +1428,7 @@ private:
|
||||
samplecnt_t _worst_route_latency;
|
||||
samplecnt_t _io_latency;
|
||||
uint32_t _send_latency_changes;
|
||||
bool _update_send_delaylines;
|
||||
bool _have_captured;
|
||||
samplecnt_t _capture_duration;
|
||||
unsigned int _capture_xruns;
|
||||
@ -1457,6 +1458,7 @@ private:
|
||||
void set_worst_input_latency ();
|
||||
|
||||
void send_latency_compensation_change ();
|
||||
void update_send_delaylines ();
|
||||
|
||||
void ensure_buffers (ChanCount howmany = ChanCount::ZERO);
|
||||
|
||||
|
@ -4034,6 +4034,17 @@ Route::silent_roll (pframes_t nframes, samplepos_t /*start_sample*/, samplepos_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Route::update_send_delaylines ()
|
||||
{
|
||||
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
|
||||
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
|
||||
if (boost::shared_ptr<LatentSend> snd = boost::dynamic_pointer_cast<LatentSend> (*i)) {
|
||||
snd->update_delaylines (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
__attribute__((annotate("realtime")))
|
||||
#endif
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "pbd/xml++.h"
|
||||
|
||||
#include "ardour/amp.h"
|
||||
#include "ardour/audioengine.h"
|
||||
#include "ardour/boost_debug.h"
|
||||
#include "ardour/buffer_set.h"
|
||||
#include "ardour/debug.h"
|
||||
@ -51,6 +52,7 @@ using namespace PBD;
|
||||
using namespace std;
|
||||
|
||||
PBD::Signal0<void> LatentSend::ChangedLatency;
|
||||
PBD::Signal0<void> LatentSend::QueueUpdate;
|
||||
|
||||
LatentSend::LatentSend ()
|
||||
: _delay_in (0)
|
||||
@ -152,7 +154,7 @@ Send::signal_latency () const
|
||||
}
|
||||
|
||||
void
|
||||
Send::update_delaylines ()
|
||||
Send::update_delaylines (bool rt_ok)
|
||||
{
|
||||
if (_role == Listen) {
|
||||
/* Don't align monitor-listen (just yet).
|
||||
@ -166,6 +168,19 @@ Send::update_delaylines ()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rt_ok && AudioEngine::instance()->running() && AudioEngine::instance()->in_process_thread ()) {
|
||||
if (_delay_out > _delay_in) {
|
||||
if (_send_delay->delay () != 0 || _thru_delay->delay () != _delay_out - _delay_in) {
|
||||
QueueUpdate (); /* EMIT SIGNAL */
|
||||
}
|
||||
}else {
|
||||
if (_thru_delay->delay () != 0 || _send_delay->delay () != _delay_in - _delay_out) {
|
||||
QueueUpdate (); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool changed;
|
||||
if (_delay_out > _delay_in) {
|
||||
changed = _thru_delay->set_delay(_delay_out - _delay_in);
|
||||
@ -175,10 +190,7 @@ Send::update_delaylines ()
|
||||
_send_delay->set_delay(_delay_in - _delay_out);
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
// TODO -- ideally postpone for effective no-op changes
|
||||
// (in case both _delay_out and _delay_in are changed by the
|
||||
// same amount in a single latency-update cycle).
|
||||
if (changed && !AudioEngine::instance()->in_process_thread ()) {
|
||||
ChangedLatency (); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
@ -195,7 +207,7 @@ Send::set_delay_in (samplecnt_t delay)
|
||||
string_compose ("Send::set_delay_in %1: (%2) - %3 = %4\n",
|
||||
name (), _delay_in, _delay_out, _delay_in - _delay_out));
|
||||
|
||||
update_delaylines ();
|
||||
update_delaylines (false);
|
||||
}
|
||||
|
||||
void
|
||||
@ -209,7 +221,7 @@ Send::set_delay_out (samplecnt_t delay, size_t /*bus*/)
|
||||
string_compose ("Send::set_delay_out %1: %2 - (%3) = %4\n",
|
||||
name (), _delay_in, _delay_out, _delay_in - _delay_out));
|
||||
|
||||
update_delaylines ();
|
||||
update_delaylines (true);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -204,6 +204,7 @@ Session::Session (AudioEngine &eng,
|
||||
, _worst_route_latency (0)
|
||||
, _io_latency (0)
|
||||
, _send_latency_changes (0)
|
||||
, _update_send_delaylines (false)
|
||||
, _have_captured (false)
|
||||
, _capture_duration (0)
|
||||
, _capture_xruns (0)
|
||||
@ -484,6 +485,7 @@ Session::Session (AudioEngine &eng,
|
||||
EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
|
||||
|
||||
LatentSend::ChangedLatency.connect_same_thread (*this, boost::bind (&Session::send_latency_compensation_change, this));
|
||||
LatentSend::QueueUpdate.connect_same_thread (*this, boost::bind (&Session::update_send_delaylines, this));
|
||||
Latent::DisableSwitchChanged.connect_same_thread (*this, boost::bind (&Session::queue_latency_recompute, this));
|
||||
|
||||
Controllable::ControlTouched.connect_same_thread (*this, boost::bind (&Session::controllable_touched, this, _1));
|
||||
@ -6665,6 +6667,13 @@ Session::send_latency_compensation_change ()
|
||||
++_send_latency_changes;
|
||||
}
|
||||
|
||||
void
|
||||
Session::update_send_delaylines ()
|
||||
{
|
||||
/* called in rt-thread, if send latency changed */
|
||||
_update_send_delaylines = true;
|
||||
}
|
||||
|
||||
bool
|
||||
Session::update_route_latency (bool playback, bool apply_to_delayline, bool* delayline_update_needed)
|
||||
{
|
||||
|
@ -130,6 +130,13 @@ Session::process (pframes_t nframes)
|
||||
}
|
||||
}
|
||||
|
||||
if (_update_send_delaylines) {
|
||||
boost::shared_ptr<RouteList> r = routes.reader ();
|
||||
for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
|
||||
(*i)->update_send_delaylines ();
|
||||
}
|
||||
}
|
||||
|
||||
if (_rt_emit_pending) {
|
||||
if (!_rt_thread_active) {
|
||||
emit_route_signals ();
|
||||
|
Loading…
Reference in New Issue
Block a user