From 183604a66b75611dee7aa1d75ecae0bb0d7c2e4d Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 4 Sep 2022 00:43:00 +0200 Subject: [PATCH] Add polarity invert switch to sends This allows to invert polarity of the signals of all channels on the send path. There is intentionally no per channel control. see https://discourse.ardour.org/t/send-phase-swtich/107564 --- libs/ardour/ardour/delivery.h | 1 + libs/ardour/delivery.cc | 23 +++++++++++++++++++++++ libs/ardour/internal_send.cc | 2 ++ libs/ardour/send.cc | 34 +++++++++++++++++++++++++++++++--- 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/libs/ardour/ardour/delivery.h b/libs/ardour/ardour/delivery.h index cc3b6321c3..72c443d4c5 100644 --- a/libs/ardour/ardour/delivery.h +++ b/libs/ardour/ardour/delivery.h @@ -120,6 +120,7 @@ protected: BufferSet* _output_buffers; gain_t _current_gain; boost::shared_ptr _panshell; + boost::shared_ptr _polarity_control; gain_t target_gain (); diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index ff0c22ff08..09a19e49f4 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -376,6 +376,9 @@ Delivery::state () const node.add_child_nocopy (_panshell->unlinked_pannable()->get_state ()); } } + if (_polarity_control) { + node.add_child_nocopy (_polarity_control->get_state()); + } return node; } @@ -407,6 +410,22 @@ Delivery::set_state (const XMLNode& node, int version) _panshell->unlinked_pannable()->set_state (*pannnode, version); } + if (_polarity_control) { + for (auto const& i : node.children()) { + if (i->name() != Controllable::xml_node_name) { + continue; + } + std::string control_name; + if (!i->get_property (X_("name"), control_name)) { + continue; + } + if (control_name == "polarity-invert") { + _polarity_control->set_state (*i, version); + break; + } + } + } + return 0; } @@ -583,6 +602,10 @@ Delivery::target_gain () desired_gain = GAIN_COEFF_ZERO; } + if (_polarity_control && _polarity_control->get_value () > 0) { + desired_gain *= -1; + } + return desired_gain; } diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc index 86806047f7..923462c35c 100644 --- a/libs/ardour/internal_send.cc +++ b/libs/ardour/internal_send.cc @@ -211,6 +211,8 @@ InternalSend::send_to_going_away () void InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool) { + automation_run (start_sample, nframes); + if (!check_active() || !_send_to) { _meter->reset (); return; diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index ba0be0259e..f183cd98a3 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -108,6 +108,15 @@ Send::Send (Session& s, boost::shared_ptr p, boost::shared_ptr (new AutomationControl (_session, PhaseAutomation, ParameterDescriptor (PhaseAutomation), + boost::shared_ptr(new AutomationList(Evoral::Parameter(PhaseAutomation), time_domain())), + "polarity-invert")); + //_polarity_control->set_flag (Controllable::InlineControl); + add_control (_polarity_control); + } + if (panner_shell()) { panner_shell()->Changed.connect_same_thread (*this, boost::bind (&Send::panshell_changed, this)); panner_shell()->PannableChanged.connect_same_thread (*this, boost::bind (&Send::pannable_changed, this)); @@ -227,6 +236,8 @@ Send::set_delay_out (samplecnt_t delay, size_t /*bus*/) void Send::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool) { + automation_run (start_sample, nframes); + if (_output->n_ports() == ChanCount::ZERO) { _meter->reset (); _active = _pending_active; @@ -298,10 +309,26 @@ Send::set_state (const XMLNode& node, int version) return set_state_2X (node, version); } - XMLNode* gain_node; + for (auto const& i : node.children()) { + if (i->name() != Controllable::xml_node_name) { + continue; + } + if (version < 7000) { + /* old versions had a single Controllable only, and it was + * not always a "gaincontrol" + */ + _gain_control->set_state (*i, version); + break; + } - if ((gain_node = node.child (Controllable::xml_node_name.c_str ())) != 0) { - _gain_control->set_state (*gain_node, version); + std::string control_name; + if (!i->get_property (X_("name"), control_name)) { + continue; + } + if (control_name == "gaincontrol" /* gain_control_name (BusSendLevel) */) { + _gain_control->set_state (*i, version); + break; + } } if (version <= 6000) { @@ -317,6 +344,7 @@ Send::set_state (const XMLNode& node, int version) { XMLNode* processor = node.child ("Processor"); if (processor) { + XMLNode* gain_node; nn = processor; if ((gain_node = nn->child (Controllable::xml_node_name.c_str ())) != 0) { _gain_control->set_state (*gain_node, version);