diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 1ec1f06af5..87a79b9233 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -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; diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index 29d2b1af34..e8e3a4d5ec 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -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 ChangedLatency; + static PBD::Signal0 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; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 167419ed9a..7052526a3d 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -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); diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index ee789733a7..27565d9781 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -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 snd = boost::dynamic_pointer_cast (*i)) { + snd->update_delaylines (true); + } + } +} + #ifdef __clang__ __attribute__((annotate("realtime"))) #endif diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index 316feb6f95..d1408c61e0 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -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 LatentSend::ChangedLatency; +PBD::Signal0 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 diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index b3a8c146d6..a93f381f81 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -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) { diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index d8c049c04a..3c41ca7b89 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -130,6 +130,13 @@ Session::process (pframes_t nframes) } } + if (_update_send_delaylines) { + boost::shared_ptr 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 ();