fix possible deadlock replacing processor state.
[ardour.git] / libs / ardour / monitor_processor.cc
index 4264ee77934c9af0b7667a4a9733fbf0f654db2b..e5c58009af764fccd9b0f6e3302039ca8e8b4779 100644 (file)
@@ -37,11 +37,11 @@ using namespace std;
 /* specialize for bool because of set_value() semantics */
 
 namespace ARDOUR {
-       template<> void MPControl<bool>::set_value (double v, PBD::Controllable::GroupControlDisposition /*group_override*/) {
+       template<> void MPControl<bool>::set_value (double v, PBD::Controllable::GroupControlDisposition gcd) {
                 bool newval = fabs (v) >= 0.5;
                 if (newval != _value) {
                         _value = newval;
-                        Changed(); /* EMIT SIGNAL */
+                        Changed (true, gcd); /* EMIT SIGNAL */
                 }
         }
 }
@@ -49,6 +49,7 @@ namespace ARDOUR {
 MonitorProcessor::MonitorProcessor (Session& s)
         : Processor (s, X_("MonitorOut"))
         , solo_cnt (0)
+        , _monitor_active (false)
 
         , _dim_all_ptr (new MPControl<bool> (false, _("monitor dim"), Controllable::Toggle))
         , _cut_all_ptr (new MPControl<bool> (false, _("monitor cut"), Controllable::Toggle))
@@ -111,7 +112,7 @@ MonitorProcessor::set_state (const XMLNode& node, int version)
                 return ret;
         }
 
-        const XMLProperty* prop;
+        XMLProperty const * prop;
 
         if ((prop = node.property (X_("type"))) == 0) {
                 error << string_compose (X_("programming error: %1"), X_("MonitorProcessor XML settings have no type information"))
@@ -218,13 +219,14 @@ MonitorProcessor::set_state (const XMLNode& node, int version)
                 }
         }
 
-        return 0;
+       update_monitor_state ();
+       return 0;
 }
 
 XMLNode&
 MonitorProcessor::state (bool full)
 {
-       LocaleGuard lg (X_("C"));
+       LocaleGuard lg;
         XMLNode& node (Processor::state (full));
         char buf[64];
 
@@ -363,61 +365,68 @@ MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount&
 void
 MonitorProcessor::set_polarity (uint32_t chn, bool invert)
 {
-        if (invert) {
-                _channels[chn]->polarity = -1.0f;
-        } else {
-                _channels[chn]->polarity = 1.0f;
-        }
+       if (invert) {
+               _channels[chn]->polarity = -1.0f;
+       } else {
+               _channels[chn]->polarity = 1.0f;
+       }
+       update_monitor_state ();
 }
 
 void
 MonitorProcessor::set_dim (uint32_t chn, bool yn)
 {
-        _channels[chn]->dim = yn;
+       _channels[chn]->dim = yn;
+       update_monitor_state ();
 }
 
 void
 MonitorProcessor::set_cut (uint32_t chn, bool yn)
 {
-        if (yn) {
-                _channels[chn]->cut = GAIN_COEFF_ZERO;
-        } else {
-                _channels[chn]->cut = GAIN_COEFF_UNITY;
-        }
+       if (yn) {
+               _channels[chn]->cut = GAIN_COEFF_ZERO;
+       } else {
+               _channels[chn]->cut = GAIN_COEFF_UNITY;
+       }
+       update_monitor_state ();
 }
 
 void
 MonitorProcessor::set_solo (uint32_t chn, bool solo)
 {
-        if (solo != _channels[chn]->soloed) {
-                _channels[chn]->soloed = solo;
-
-                if (solo) {
-                        solo_cnt++;
-                } else {
-                        if (solo_cnt > 0) {
-                                solo_cnt--;
-                        }
-                }
-        }
+       if (solo != _channels[chn]->soloed) {
+               _channels[chn]->soloed = solo;
+
+               if (solo) {
+                       solo_cnt++;
+               } else {
+                       if (solo_cnt > 0) {
+                               solo_cnt--;
+                       }
+               }
+       }
+       update_monitor_state ();
 }
 
 void
 MonitorProcessor::set_mono (bool yn)
 {
-        _mono = yn;
+       _mono = yn;
+       update_monitor_state ();
 }
 
 void
 MonitorProcessor::set_cut_all (bool yn)
 {
-        _cut_all = yn;
+       _cut_all = yn;
+       update_monitor_state ();
 }
 
 void
 MonitorProcessor::set_dim_all (bool yn)
 {
-        _dim_all = yn;
+       _dim_all = yn;
+       update_monitor_state ();
 }
 
 bool
@@ -470,6 +479,29 @@ MonitorProcessor::cut_all () const
         return _cut_all;
 }
 
+void
+MonitorProcessor::update_monitor_state ()
+{
+       bool en = false;
+
+       if (_cut_all || _dim_all || _mono) {
+               en = true;
+       }
+
+       const uint32_t nchans = _channels.size();
+       for (uint32_t i = 0; i < nchans && !en; ++i) {
+               if (cut (i) || dimmed (i) || soloed (i) || inverted (i)) {
+                       en = true;
+                       break;
+               }
+       }
+
+       if (_monitor_active != en) {
+               _monitor_active = en;
+               _session.MonitorChanged();
+       }
+}
+
 boost::shared_ptr<Controllable>
 MonitorProcessor::channel_cut_control (uint32_t chn) const
 {