diff options
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/send.h | 14 | ||||
-rw-r--r-- | libs/ardour/internal_send.cc | 8 | ||||
-rw-r--r-- | libs/ardour/send.cc | 73 |
3 files changed, 75 insertions, 20 deletions
diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index c0111936e5..8d9cdaa0af 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -67,11 +67,13 @@ class LIBARDOUR_API Send : public Delivery bool configure_io (ChanCount in, ChanCount out); /* latency compensation */ - void set_output_latency (samplecnt_t cnt); - void set_delay_in (samplecnt_t); - void set_delay_out (samplecnt_t); + void set_delay_in (samplecnt_t); // should only be called by Route::update_signal_latency + void set_delay_out (samplecnt_t); // should only be called by InternalReturn::set_playback_offset (via Route::update_signal_latency) samplecnt_t get_delay_in () const { return _delay_in; } samplecnt_t get_delay_out () const { return _delay_out; } + samplecnt_t signal_latency () const; + + static PBD::Signal0<void> ChangedLatency; void activate (); void deactivate (); @@ -86,14 +88,18 @@ class LIBARDOUR_API Send : public Delivery boost::shared_ptr<GainControl> _gain_control; boost::shared_ptr<Amp> _amp; boost::shared_ptr<PeakMeter> _meter; - boost::shared_ptr<DelayLine> _delayline; + boost::shared_ptr<DelayLine> _send_delay; + boost::shared_ptr<DelayLine> _thru_delay; private: /* disallow copy construction */ Send (const Send&); + void panshell_changed (); void snd_output_changed (IOChange, void*); + void update_delaylines (); + int set_state_2X (XMLNode const &, int); uint32_t _bitslot; diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc index 10ad17a406..72e58b6056 100644 --- a/libs/ardour/internal_send.cc +++ b/libs/ardour/internal_send.cc @@ -100,9 +100,7 @@ InternalSend::use_target (boost::shared_ptr<Route> sendto) _meter->configure_io (ChanCount (DataType::AUDIO, pan_outs()), ChanCount (DataType::AUDIO, pan_outs())); - if (_delayline) { - _delayline->configure_io (ChanCount (DataType::AUDIO, pan_outs()), ChanCount (DataType::AUDIO, pan_outs())); - } + _send_delay->configure_io (ChanCount (DataType::AUDIO, pan_outs()), ChanCount (DataType::AUDIO, pan_outs())); reset_panner (); @@ -252,7 +250,7 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa _amp->setup_gain_automation (start_sample, end_sample, nframes); _amp->run (mixbufs, start_sample, end_sample, speed, nframes, true); - _delayline->run (mixbufs, start_sample, end_sample, speed, nframes, true); + _send_delay->run (mixbufs, start_sample, end_sample, speed, nframes, true); /* consider metering */ @@ -264,6 +262,8 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa } } + _thru_delay->run (bufs, start_sample, end_sample, speed, nframes, true); + /* target will pick up our output when it is ready */ out: diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index ae442d5715..7fd88aebac 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -46,6 +46,8 @@ using namespace ARDOUR; using namespace PBD; using namespace std; +PBD::Signal0<void> Send::ChangedLatency; + string Send::name_and_id_new_send (Session& s, Role r, uint32_t& bitslot, bool ignore_bitslot) { @@ -96,7 +98,8 @@ Send::Send (Session& s, boost::shared_ptr<Pannable> p, boost::shared_ptr<MuteMas _amp.reset (new Amp (_session, _("Fader"), _gain_control, true)); _meter.reset (new PeakMeter (_session, name())); - _delayline.reset (new DelayLine (_session, "Send-" + name())); + _send_delay.reset (new DelayLine (_session, "Send-" + name())); + _thru_delay.reset (new DelayLine (_session, "Thru-" + name())); if (panner_shell()) { panner_shell()->Changed.connect_same_thread (*this, boost::bind (&Send::panshell_changed, this)); @@ -130,17 +133,56 @@ Send::deactivate () Processor::deactivate (); } +samplecnt_t +Send::signal_latency () const +{ + if (!_pending_active) { + return 0; + } + if (_user_latency) { + return _user_latency; + } + if (_delay_out > _delay_in) { + return _delay_out - _delay_in; + } + return 0; +} + void -Send::set_output_latency (samplecnt_t cnt) +Send::update_delaylines () { - Processor::set_output_latency (cnt); - set_delay_in (cnt); + if (_role == Listen) { + /* Don't align monitor-listen (just yet). + * They're present on each route, may change positions + * and could potentially signficiantly increase worst-case + * Latency: In PFL mode all tracks/busses would additionally be + * aligned at PFL position. + * + * We should only align active monitor-sends when at least one is active. + */ + return; + } + + bool changed; + if (_delay_out > _delay_in) { + changed = _thru_delay->set_delay(_delay_out - _delay_in); + _send_delay->set_delay(0); + } else { + changed = _thru_delay->set_delay(0); + _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). + ChangedLatency (); /* EMIT SIGNAL */ + } } void Send::set_delay_in (samplecnt_t delay) { - if (!_delayline) return; if (_delay_in == delay) { return; } @@ -149,13 +191,13 @@ Send::set_delay_in (samplecnt_t delay) DEBUG_TRACE (DEBUG::LatencyCompensation, string_compose ("Send::set_delay_in %1: (%2) - %3 = %4\n", name (), _delay_in, _delay_out, _delay_in - _delay_out)); - _delayline->set_delay(_delay_in - _delay_out); + + update_delaylines (); } void Send::set_delay_out (samplecnt_t delay) { - if (!_delayline) return; if (_delay_out == delay) { return; } @@ -163,7 +205,8 @@ Send::set_delay_out (samplecnt_t delay) DEBUG_TRACE (DEBUG::LatencyCompensation, string_compose ("Send::set_delay_out %1: %2 - (%3) = %4\n", name (), _delay_in, _delay_out, _delay_in - _delay_out)); - _delayline->set_delay(_delay_in - _delay_out); + + update_delaylines (); } void @@ -195,7 +238,7 @@ Send::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, do _amp->setup_gain_automation (start_sample, end_sample, nframes); _amp->run (sendbufs, start_sample, end_sample, speed, nframes, true); - _delayline->run (sendbufs, start_sample, end_sample, speed, nframes, true); + _send_delay->run (sendbufs, start_sample, end_sample, speed, nframes, true); /* deliver to outputs */ @@ -211,6 +254,8 @@ Send::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, do } } + _thru_delay->run (bufs, start_sample, end_sample, speed, nframes, true); + /* _active was set to _pending_active by Delivery::run() */ } @@ -289,7 +334,8 @@ Send::set_state (const XMLNode& node, int version) } } - _delayline->set_name ("Send-" + name()); + _send_delay->set_name ("Send-" + name()); + _thru_delay->set_name ("Thru-" + name()); return 0; } @@ -356,8 +402,11 @@ Send::configure_io (ChanCount in, ChanCount out) return false; } - if (_delayline && !_delayline->configure_io (ChanCount (DataType::AUDIO, pan_outs()), ChanCount (DataType::AUDIO, pan_outs()))) { - cerr << "send delayline config failed\n"; + if (!_thru_delay->configure_io (in, out)) { + return false; + } + + if (!_send_delay->configure_io (ChanCount (DataType::AUDIO, pan_outs()), ChanCount (DataType::AUDIO, pan_outs()))) { return false; } |