fix for metering of a MasterSend (internal send)
Metering for these sends should be effectively PostFader not Output, and should not reflect the impact of solo & mute.
This commit is contained in:
parent
21f4dce2d9
commit
f9a76829f3
@ -240,6 +240,10 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa
|
|||||||
_panshell->run (bufs, mixbufs, start_sample + latency, end_sample + latency, nframes);
|
_panshell->run (bufs, mixbufs, start_sample + latency, end_sample + latency, nframes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No need to handle non-audio if this is the MasterSend */
|
||||||
|
|
||||||
|
if (role() != MasterSend) {
|
||||||
|
|
||||||
/* non-audio data will not have been copied by the panner, do it now
|
/* non-audio data will not have been copied by the panner, do it now
|
||||||
* if there are more buffers available than send buffers, ignore them,
|
* if there are more buffers available than send buffers, ignore them,
|
||||||
* if there are less, copy the last as IO::copy_to_output does. */
|
* if there are less, copy the last as IO::copy_to_output does. */
|
||||||
@ -260,9 +264,10 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (role () == Listen) {
|
} else if (role () == Listen || role() == MasterSend) {
|
||||||
/* We're going to the monitor bus, so discard MIDI data */
|
/* We're going to the monitor or master bus, so discard MIDI data */
|
||||||
|
|
||||||
uint32_t const bufs_audio = bufs.count ().get (DataType::AUDIO);
|
uint32_t const bufs_audio = bufs.count ().get (DataType::AUDIO);
|
||||||
uint32_t const mixbufs_audio = mixbufs.count ().get (DataType::AUDIO);
|
uint32_t const mixbufs_audio = mixbufs.count ().get (DataType::AUDIO);
|
||||||
@ -320,15 +325,51 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* main gain control: * mute & bypass/enable */
|
/* For a master send, we want the meter to be effectively MeterPostFader
|
||||||
|
* rather than MeterOutput. But below, we compute a target gain that
|
||||||
|
* will take mute and solo into account, and apply to mixbufs *before*
|
||||||
|
* metering, which would make metering equivalent to MeterOutput.
|
||||||
|
*
|
||||||
|
* So, for a master send, run our own gain control first (so we see the
|
||||||
|
* effect in the meters), then meter, then apply any mute/solo-driven gain.
|
||||||
|
*
|
||||||
|
* For other internal sends, apply mute/solo-controlled gain, then our
|
||||||
|
* own gain control, then meter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (role() == MasterSend) {
|
||||||
|
|
||||||
|
/* apply fader gain automation before running meter */
|
||||||
|
|
||||||
|
_amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
|
||||||
|
_amp->setup_gain_automation (start_sample + latency, end_sample + latency, nframes);
|
||||||
|
_amp->run (mixbufs, start_sample + latency, end_sample + latency, speed, nframes, true);
|
||||||
|
|
||||||
|
if (_metering) {
|
||||||
|
if (gain_control ()->get_value () == GAIN_COEFF_ZERO) {
|
||||||
|
_meter->reset ();
|
||||||
|
} else {
|
||||||
|
_meter->run (mixbufs, start_sample, end_sample, speed, nframes, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tgain reflects muting and soling */
|
||||||
|
|
||||||
gain_t tgain = target_gain ();
|
gain_t tgain = target_gain ();
|
||||||
|
|
||||||
if (tgain != _current_gain) {
|
if (tgain != _current_gain) {
|
||||||
/* target gain has changed, fade in/out */
|
/* target gain has changed, fade in/out */
|
||||||
_current_gain = Amp::apply_gain (mixbufs, _session.nominal_sample_rate (), nframes, _current_gain, tgain);
|
_current_gain = Amp::apply_gain (mixbufs, _session.nominal_sample_rate (), nframes, _current_gain, tgain);
|
||||||
} else if (tgain == GAIN_COEFF_ZERO) {
|
} else if (tgain == GAIN_COEFF_ZERO) {
|
||||||
/* we were quiet last time, and we're still supposed to be quiet. */
|
/* we were quiet last time, and we're still supposed to be
|
||||||
|
* quiet. Don't do this for a MasterSend, because its meter is
|
||||||
|
* effectively MeterPostFader, not MeterOutput, so we don't
|
||||||
|
* want it to reflect mute/solo-controlled levels.
|
||||||
|
*/
|
||||||
|
if (role() != MasterSend || (gain_control()->get_value() == GAIN_COEFF_ZERO)) {
|
||||||
_meter->reset ();
|
_meter->reset ();
|
||||||
|
}
|
||||||
Amp::apply_simple_gain (mixbufs, nframes, GAIN_COEFF_ZERO);
|
Amp::apply_simple_gain (mixbufs, nframes, GAIN_COEFF_ZERO);
|
||||||
return;
|
return;
|
||||||
} else if (tgain != GAIN_COEFF_UNITY) {
|
} else if (tgain != GAIN_COEFF_UNITY) {
|
||||||
@ -336,15 +377,17 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa
|
|||||||
Amp::apply_simple_gain (mixbufs, nframes, tgain);
|
Amp::apply_simple_gain (mixbufs, nframes, tgain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (role() != MasterSend) {
|
||||||
/* apply fader gain automation */
|
/* apply fader gain automation */
|
||||||
_amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
|
_amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
|
||||||
_amp->setup_gain_automation (start_sample + latency, end_sample + latency, nframes);
|
_amp->setup_gain_automation (start_sample + latency, end_sample + latency, nframes);
|
||||||
_amp->run (mixbufs, start_sample + latency, end_sample + latency, speed, nframes, true);
|
_amp->run (mixbufs, start_sample + latency, end_sample + latency, speed, nframes, true);
|
||||||
|
}
|
||||||
|
|
||||||
_send_delay->run (mixbufs, start_sample, end_sample, speed, nframes, true);
|
_send_delay->run (mixbufs, start_sample, end_sample, speed, nframes, true);
|
||||||
|
|
||||||
/* consider metering */
|
/* consider metering */
|
||||||
if (_metering) {
|
if (_metering && role() != MasterSend) {
|
||||||
if (gain_control ()->get_value () == GAIN_COEFF_ZERO) {
|
if (gain_control ()->get_value () == GAIN_COEFF_ZERO) {
|
||||||
_meter->reset ();
|
_meter->reset ();
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user