From 405f9fc712836937bf44dba48c64c1741bc4101c Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sun, 28 Feb 2016 11:57:18 -0500 Subject: change VCA model to facilitate Harrison *and* SSL designs --- libs/ardour/gain_control.cc | 80 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 16 deletions(-) (limited to 'libs/ardour/gain_control.cc') diff --git a/libs/ardour/gain_control.cc b/libs/ardour/gain_control.cc index 5af0e2d397..3021151bdc 100644 --- a/libs/ardour/gain_control.cc +++ b/libs/ardour/gain_control.cc @@ -39,10 +39,17 @@ GainControl::GainControl (Session& session, const Evoral::Parameter ¶m, boos double GainControl::get_value() const { - if (!_master) { - return AutomationControl::get_value(); + Glib::Threads::Mutex::Lock sm (master_lock, Glib::Threads::TRY_LOCK); + + if (sm.locked()) { + if (_masters.empty()) { + return AutomationControl::get_value(); + } + return AutomationControl::get_value() * get_master_gain (); + } else { + /* could not take lock */ + return AutomationControl::get_value (); } - return AutomationControl::get_value() * _master->get_value(); } void @@ -106,25 +113,49 @@ GainControl::get_user_string () const return std::string(theBuf); } -void -GainControl::set_master (boost::shared_ptr m) +gain_t +GainControl::get_master_gain () const { - double old_master_val; + /* Master lock MUST be held */ - if (_master) { - old_master_val = _master->get_value(); - } else { - old_master_val = 1.0; + gain_t g = 1.0; + + for (Masters::const_iterator m = _masters.begin(); m != _masters.end(); ++m) { + g *= (*m)->get_value (); } - _master = m; + return g; +} - double new_master_val; +void +GainControl::add_master (boost::shared_ptr m) +{ + gain_t old_master_val; + gain_t new_master_val; + + { + Glib::Threads::Mutex::Lock lm (master_lock); + old_master_val = get_master_gain (); + _masters.push_back (m); + new_master_val = get_master_gain (); + } - if (_master) { - new_master_val = _master->get_value(); - } else { - new_master_val = 1.0; + if (old_master_val != new_master_val) { + Changed(); /* EMIT SIGNAL */ + } +} + +void +GainControl::remove_master (boost::shared_ptr m) +{ + gain_t old_master_val; + gain_t new_master_val; + + { + Glib::Threads::Mutex::Lock lm (master_lock); + old_master_val = get_master_gain (); + _masters.remove (m); + new_master_val = get_master_gain (); } if (old_master_val != new_master_val) { @@ -132,3 +163,20 @@ GainControl::set_master (boost::shared_ptr m) } } +void +GainControl::clear_masters () +{ + gain_t old_master_val; + gain_t new_master_val; + + { + Glib::Threads::Mutex::Lock lm (master_lock); + old_master_val = get_master_gain (); + _masters.clear (); + new_master_val = get_master_gain (); + } + + if (old_master_val != new_master_val) { + Changed(); /* EMIT SIGNAL */ + } +} -- cgit v1.2.3