X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fardour%2Fmute_control.cc;h=5b38547366778081b9a479abf216780f1d869fca;hb=c8c6bca6587450ff64303dbc994a4cd28d6ce7aa;hp=a639cbda7a848f153660659497e78b0f9781d75b;hpb=e1bcd70712b1aa35fa59d812d679576c88171d0f;p=ardour.git diff --git a/libs/ardour/mute_control.cc b/libs/ardour/mute_control.cc index a639cbda7a..5b38547366 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; @@ -39,10 +39,45 @@ MuteControl::MuteControl (Session& session, std::string const & name, Muteable& set_flags (Controllable::Flag (flags() | Controllable::RealTime)); } +void +MuteControl::post_add_master (boost::shared_ptr m) +{ + if (m->get_value()) { + + /* boolean masters records are not updated until AFTER + * ::post_add_master() is called, so we can use them to check + * on whether any master was already enabled before the new + * one was added. + */ + + if (!muted_by_self() && !get_boolean_masters()) { + _muteable.mute_master()->set_muted_by_masters (true); + Changed (false, Controllable::NoGroup); + } + } +} + +void +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_masters (false); + /* Changed will be emitted in SlavableAutomationControl::clear_masters() */ + return; + } + + if (m->get_value()) { + if (!muted_by_self() && (get_boolean_masters() == 1)) { + Changed (false, Controllable::NoGroup); + } + } +} + void MuteControl::actually_set_value (double val, Controllable::GroupControlDisposition gcd) { - if (muted() != bool (val)) { + if (muted_by_self() != bool (val)) { _muteable.mute_master()->set_muted_by_self (val); /* allow the Muteable to respond to the mute change @@ -51,15 +86,41 @@ MuteControl::actually_set_value (double val, Controllable::GroupControlDispositi _muteable.act_on_mute (); } - AutomationControl::actually_set_value (val, gcd); + SlavableAutomationControl::actually_set_value (val, gcd); +} + +void +MuteControl::master_changed (bool self_change, Controllable::GroupControlDisposition gcd, boost::shared_ptr m) +{ + bool send_signal = false; + boost::shared_ptr mc = boost::dynamic_pointer_cast (m); + + if (m->get_value()) { + /* this master is now enabled */ + if (!muted_by_self() && get_boolean_masters() == 0) { + _muteable.mute_master()->set_muted_by_masters (true); + send_signal = true; + } + } else { + /* this master is disabled and there was only 1 enabled before */ + if (!muted_by_self() && get_boolean_masters() == 1) { + _muteable.mute_master()->set_muted_by_masters (false); + send_signal = true; + } + } + + update_boolean_masters_records (m); + + if (send_signal) { + Changed (false, Controllable::NoGroup); + } } double MuteControl::get_value () const { - if (slaved()) { - Glib::Threads::RWLock::ReaderLock lm (master_lock); - return get_masters_value_locked () ? 1.0 : 0.0; + if (slaved ()) { + return muted_by_self() || get_masters_value (); } if (_list && boost::dynamic_pointer_cast(_list)->automation_playback()) { @@ -67,7 +128,7 @@ MuteControl::get_value () const return AutomationControl::get_value(); } - return muted() ? 1.0 : 0.0; + return muted(); } void @@ -89,12 +150,45 @@ MuteControl::mute_points () const bool MuteControl::muted () const +{ + /* 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() || get_masters_value (); +} + +bool +MuteControl::muted_by_self () const { return _muteable.mute_master()->muted_by_self(); } bool -MuteControl::muted_by_others () const +MuteControl::muted_by_masters () const +{ + return get_masters_value (); +} + +bool +MuteControl::muted_by_others_soloing () const +{ + return _muteable.muted_by_others_soloing (); +} + +void +MuteControl::automation_run (framepos_t start, pframes_t) { - return _muteable.mute_master()->muted_by_others () || get_masters_value(); + if (!list() || !automation_playback()) { + return; + } + + bool valid = false; + const float mute = list()->rt_safe_eval (start, valid); + + if (mute >= 0.5 && !muted()) { + set_value_unchecked (1.0); // mute + } else if (mute < 0.5 && muted ()) { + set_value_unchecked (0.0); // unmute + } }