diff --git a/libs/ardour/ardour/internal_send.h b/libs/ardour/ardour/internal_send.h index 7e814a3a41..a355ac22a0 100644 --- a/libs/ardour/ardour/internal_send.h +++ b/libs/ardour/ardour/internal_send.h @@ -45,6 +45,7 @@ public: bool can_support_io_configuration (const ChanCount& in, ChanCount& out); bool configure_io (ChanCount in, ChanCount out); int set_block_size (pframes_t); + bool actually_active() const { return _active; } std::shared_ptr source_route() const { return _send_from; } std::shared_ptr target_route() const { return _send_to; } diff --git a/libs/ardour/internal_return.cc b/libs/ardour/internal_return.cc index a9cfe32d38..a805f71f06 100644 --- a/libs/ardour/internal_return.cc +++ b/libs/ardour/internal_return.cc @@ -48,7 +48,7 @@ InternalReturn::run (BufferSet& bufs, samplepos_t /*start_sample*/, samplepos_t } for (auto & send : _sends) { - if (send->active () && (!send->source_route() || send->source_route()->active())) { + if ((send->active() || send->actually_active()) && (!send->source_route() || send->source_route()->active())) { bufs.merge_from (send->get_buffers(), nframes); } } diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc index 07a1495520..8f0c077ed8 100644 --- a/libs/ardour/internal_send.cc +++ b/libs/ardour/internal_send.cc @@ -49,6 +49,8 @@ using namespace std; PBD::Signal InternalSend::CycleStart; +#define GAIN_COEFF_DELTA (1e-5) + InternalSend::InternalSend (Session& s, std::shared_ptr p, std::shared_ptr mm, @@ -213,7 +215,20 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa { automation_run (start_sample, nframes); - if (!check_active() || !_send_to) { + /* Do not use check_active() here, because we need to continue running + * until the gain has gone to zero. + */ + + if (!_send_to) { + _meter->reset (); + return; + } + + /* main gain control: * mute & bypass/enable */ + const gain_t tgain = target_gain (); + const bool converged = fabsf (_current_gain - tgain) < GAIN_COEFF_DELTA; + + if ((tgain == GAIN_COEFF_ZERO) && converged) { _meter->reset (); return; } @@ -317,9 +332,6 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa } } - /* main gain control: * mute & bypass/enable */ - gain_t tgain = target_gain (); - if (tgain != _current_gain) { /* target gain has changed, fade in/out */ _current_gain = Amp::apply_gain (mixbufs, _session.nominal_sample_rate (), nframes, _current_gain, tgain); @@ -353,7 +365,9 @@ 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 */ + if (converged) { + _active = _pending_active; + } } void