Files
ardour/libs/ardour/monitor_processor.cc

222 lines
4.9 KiB
C++

#include "pbd/xml++.h"
#include "ardour/amp.h"
#include "ardour/dB.h"
#include "ardour/monitor_processor.h"
#include "ardour/session.h"
#include "i18n.h"
using namespace ARDOUR;
using namespace std;
MonitorProcessor::MonitorProcessor (Session& s)
: Processor (s, X_("MonitorOut"))
{
solo_cnt = 0;
_cut_all = false;
_dim_all = false;
_dim_level = 0.2;
_solo_boost_level = 1.0;
}
MonitorProcessor::MonitorProcessor (Session& s, const XMLNode& node)
: Processor (s, node)
{
set_state (node, Stateful::loading_state_version);
}
int
MonitorProcessor::set_state (const XMLNode& node, int version)
{
return Processor::set_state (node, version);
}
XMLNode&
MonitorProcessor::state (bool full)
{
XMLNode& node (Processor::state (full));
/* this replaces any existing "type" property */
node.add_property (X_("type"), X_("monitor"));
return node;
}
void
MonitorProcessor::run (BufferSet& bufs, sframes_t /*start_frame*/, sframes_t /*end_frame*/, nframes_t nframes, bool /*result_required*/)
{
uint32_t chn = 0;
gain_t target_gain;
gain_t dim_level_this_time = _dim_level;
gain_t global_cut = (_cut_all ? 0.0f : 1.0f);
gain_t global_dim = (_dim_all ? dim_level_this_time : 1.0f);
gain_t solo_boost;
if (_session.listening() || _session.soloing()) {
solo_boost = _solo_boost_level;
} else {
solo_boost = 1.0;
}
for (BufferSet::audio_iterator b = bufs.audio_begin(); b != bufs.audio_end(); ++b) {
/* don't double-scale by both track dim and global dim coefficients */
gain_t dim_level = (global_dim == 1.0 ? (_dim[chn] ? dim_level_this_time : 1.0) : 1.0);
if (_soloed[chn]) {
target_gain = _polarity[chn] * _cut[chn] * dim_level * global_cut * global_dim * solo_boost;
} else {
if (solo_cnt == 0) {
target_gain = _polarity[chn] * _cut[chn] * dim_level * global_cut * global_dim * solo_boost;
} else {
target_gain = 0.0;
}
}
if (target_gain != current_gain[chn] || target_gain != 1.0f) {
Amp::apply_gain (*b, nframes, current_gain[chn], target_gain);
current_gain[chn] = target_gain;
}
++chn;
}
}
bool
MonitorProcessor::configure_io (ChanCount in, ChanCount out)
{
uint32_t needed = in.n_audio();
while (current_gain.size() > needed) {
current_gain.pop_back ();
_dim.pop_back ();
_cut.pop_back ();
_polarity.pop_back ();
if (_soloed.back()) {
if (solo_cnt > 0) {
--solo_cnt;
}
}
_soloed.pop_back ();
}
while (current_gain.size() < needed) {
current_gain.push_back (1.0);
_dim.push_back (false);
_cut.push_back (1.0);
_polarity.push_back (1.0);
_soloed.push_back (false);
}
return Processor::configure_io (in, out);
}
bool
MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
{
return in == out;
}
void
MonitorProcessor::set_polarity (uint32_t chn, bool invert)
{
if (invert) {
_polarity[chn] = -1.0f;
} else {
_polarity[chn] = 1.0f;
}
}
void
MonitorProcessor::set_dim (uint32_t chn, bool yn)
{
_dim[chn] = yn;
}
void
MonitorProcessor::set_cut (uint32_t chn, bool yn)
{
if (yn) {
_cut[chn] = 0.0f;
} else {
_cut[chn] = 1.0f;
}
}
void
MonitorProcessor::set_solo (uint32_t chn, bool solo)
{
_soloed[chn] = solo;
if (solo) {
solo_cnt++;
} else {
if (solo_cnt > 0) {
solo_cnt--;
}
}
}
void
MonitorProcessor::set_cut_all (bool yn)
{
_cut_all = yn;
}
void
MonitorProcessor::set_dim_all (bool yn)
{
_dim_all = yn;
}
bool
MonitorProcessor::display_to_user () const
{
return false;
}
void
MonitorProcessor::set_dim_level (gain_t val)
{
_dim_level = val;
}
void
MonitorProcessor::set_solo_boost_level (gain_t val)
{
_solo_boost_level = val;
}
bool
MonitorProcessor::soloed (uint32_t chn) const
{
return _soloed[chn];
}
bool
MonitorProcessor::inverted (uint32_t chn) const
{
return _polarity[chn] < 0.0f;
}
bool
MonitorProcessor::cut (uint32_t chn) const
{
return _cut[chn] == 0.0f;
}
bool
MonitorProcessor::dimmed (uint32_t chn) const
{
return _dim[chn];
}