fix InternalSend (and InterntalReturn) to allow fade out/MIDI mute

previously, as soon as the Send is disabled, it would short-circuit ::run(),
preventing the fade to zero to take effect. Now, the send will run until the
effective gain reaches zero, and the return will collect data from it until it
is fully deactivated.
This commit is contained in:
Paul Davis 2025-06-19 13:50:37 -06:00
parent 464ea0d31f
commit 66a8776f98
3 changed files with 21 additions and 6 deletions

View file

@ -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<Route> source_route() const { return _send_from; }
std::shared_ptr<Route> target_route() const { return _send_to; }

View file

@ -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);
}
}

View file

@ -49,6 +49,8 @@ using namespace std;
PBD::Signal<void(pframes_t)> InternalSend::CycleStart;
#define GAIN_COEFF_DELTA (1e-5)
InternalSend::InternalSend (Session& s,
std::shared_ptr<Pannable> p,
std::shared_ptr<MuteMaster> 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