X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmute_control.cc;h=89d18746f764d3f940f1d4b4ec536949cbf416f4;hb=3d183dc462a82c5ee0b4fb77a226f0e49d9736f7;hp=e14ba36e8799ace607aa4bfee85198d2e4cfd438;hpb=3fe50951e4341853dddc79dc2be007c9f87dbb9b;p=ardour.git diff --git a/libs/ardour/mute_control.cc b/libs/ardour/mute_control.cc index e14ba36e87..89d18746f7 100644 --- a/libs/ardour/mute_control.cc +++ b/libs/ardour/mute_control.cc @@ -22,7 +22,7 @@ #include "ardour/session.h" #include "ardour/mute_control.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace ARDOUR; using namespace std; @@ -51,7 +51,8 @@ MuteControl::post_add_master (boost::shared_ptr m) */ if (!muted_by_self() && !get_boolean_masters()) { - Changed (false, Controllable::NoGroup); + _muteable.mute_master()->set_muted_by_masters (true); + Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */ } } } @@ -61,14 +62,15 @@ MuteControl::pre_remove_master (boost::shared_ptr m) { if (!m) { /* null control ptr means we're removing all masters */ - _muteable.mute_master()->set_muted_by_others (false); + _muteable.mute_master()->set_muted_by_masters (false); /* Changed will be emitted in SlavableAutomationControl::clear_masters() */ return; } - if (m->get_value()) { - if (!muted_by_self() && (muted_by_others() == 1)) { - Changed (false, Controllable::NoGroup); + if (m->get_value() && get_boolean_masters() == 1) { + _muteable.mute_master()->set_muted_by_masters (false); + if (!muted_by_self()) { + Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */ } } } @@ -88,43 +90,40 @@ MuteControl::actually_set_value (double val, Controllable::GroupControlDispositi SlavableAutomationControl::actually_set_value (val, gcd); } -void -MuteControl::master_changed (bool self_change, Controllable::GroupControlDisposition gcd, boost::shared_ptr m) +bool +MuteControl::handle_master_change (boost::shared_ptr m) { bool send_signal = false; - const double changed_master_value = m->get_value(); boost::shared_ptr mc = boost::dynamic_pointer_cast (m); - - if (m) { - cerr << "master changed, self ? " << self_change << " self muted = " - << mc->muted_by_self() << " others " << mc->muted_by_others() - << endl; + if (!mc) { + return false; } - if (changed_master_value) { + if (m->get_value()) { /* this master is now enabled */ - if (!muted_by_self() && get_boolean_masters() == 0) { - send_signal = true; + if (get_boolean_masters() == 0) { + _muteable.mute_master()->set_muted_by_masters (true); + if (!muted_by_self()) { + send_signal = true; + } } } else { - if (!muted_by_self() && get_boolean_masters() == 1) { - send_signal = true; + /* this master is disabled and there was only 1 enabled before */ + if (get_boolean_masters() == 1) { + _muteable.mute_master()->set_muted_by_masters (false); + if (!muted_by_self()) { + send_signal = true; + } } } - - update_boolean_masters_records (m); - - if (send_signal) { - Changed (false, Controllable::NoGroup); - } + return send_signal; } double MuteControl::get_value () const { if (slaved ()) { - Glib::Threads::RWLock::ReaderLock lm (master_lock); - return get_masters_value_locked (); + return muted_by_self() || muted_by_masters (); } if (_list && boost::dynamic_pointer_cast(_list)->automation_playback()) { @@ -132,7 +131,7 @@ MuteControl::get_value () const return AutomationControl::get_value(); } - return muted() ? 1.0 : 0.0; + return muted(); } void @@ -155,7 +154,11 @@ MuteControl::mute_points () const bool MuteControl::muted () const { - return muted_by_self() || muted_by_others(); + /* have to get (self-muted) value from somewhere. could be our own + Control, or the Muteable that we sort-of proxy for. Since this + method is called by ::get_value(), use the latter to avoid recursion. + */ + return _muteable.mute_master()->muted_by_self() || muted_by_masters (); } bool @@ -165,7 +168,49 @@ MuteControl::muted_by_self () const } bool -MuteControl::muted_by_others () const +MuteControl::muted_by_masters () const { - return get_masters_value (); + return _muteable.mute_master()->muted_by_masters (); +} + +bool +MuteControl::muted_by_others_soloing () const +{ + return _muteable.muted_by_others_soloing (); +} + +void +MuteControl::automation_run (framepos_t start, pframes_t len) +{ + boolean_automation_run (start, len); + + bool valid = false; + bool mute = false; + + if (list() && automation_playback()) { + mute = list()->rt_safe_eval (start, valid) >= 0.5; + } + + if (!valid) { + return; + } + + if (muted_by_masters ()) { + /* already muted, no need to check further, + * except we need to up update implicit/explict mute + */ + if (muted_by_self () != mute) { + set_value_unchecked (mute ? 1. : 0.); + Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */ + } + return; + } + + if (mute && !muted()) { + set_value_unchecked (1.0); // mute + Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */ + } else if (!mute && muted()) { + set_value_unchecked (0.0); // unmute + Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */ + } }