summaryrefslogtreecommitdiff
path: root/libs/ardour/gain_control.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-02-28 11:57:18 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2016-05-31 15:30:38 -0400
commit405f9fc712836937bf44dba48c64c1741bc4101c (patch)
tree745d26434acb43768b403d5e9cc99b6d24cfc435 /libs/ardour/gain_control.cc
parent3daad049362bed97935d09c1bfebe085ce482f6c (diff)
change VCA model to facilitate Harrison *and* SSL designs
Diffstat (limited to 'libs/ardour/gain_control.cc')
-rw-r--r--libs/ardour/gain_control.cc80
1 files changed, 64 insertions, 16 deletions
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 &param, 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<GainControl> 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<GainControl> 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<GainControl> 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<GainControl> 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 */
+ }
+}