diff options
-rw-r--r-- | gtk2_ardour/route_ui.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/vca_master_strip.cc | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/mute_control.h | 5 | ||||
-rw-r--r-- | libs/ardour/ardour/mute_master.h | 8 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/slavable_automation_control.h | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/solo_control.h | 19 | ||||
-rw-r--r-- | libs/ardour/ardour/stripable.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/vca.h | 2 | ||||
-rw-r--r-- | libs/ardour/midi_track.cc | 4 | ||||
-rw-r--r-- | libs/ardour/mute_control.cc | 21 | ||||
-rw-r--r-- | libs/ardour/mute_master.cc | 22 | ||||
-rw-r--r-- | libs/ardour/route.cc | 2 | ||||
-rw-r--r-- | libs/ardour/session.cc | 45 | ||||
-rw-r--r-- | libs/ardour/slavable_automation_control.cc | 2 | ||||
-rw-r--r-- | libs/ardour/solo_control.cc | 49 | ||||
-rw-r--r-- | libs/ardour/vca.cc | 2 | ||||
-rw-r--r-- | libs/surfaces/faderport/faderport.cc | 2 |
18 files changed, 130 insertions, 69 deletions
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 67de68aa69..bfd3ed1006 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -1228,7 +1228,7 @@ RouteUI::mute_active_state (Session* s, boost::shared_ptr<Route> r) if (r->mute_control()->muted_by_self ()) { /* full mute */ return Gtkmm2ext::ExplicitActive; - } else if (r->muted_by_others_soloing () || r->muted_by_others()) { + } else if (r->muted_by_others_soloing () || r->muted_by_masters ()) { /* this will reflect both solo mutes AND master mutes */ return Gtkmm2ext::ImplicitActive; } else { @@ -1241,7 +1241,7 @@ RouteUI::mute_active_state (Session* s, boost::shared_ptr<Route> r) if (r->mute_control()->muted_by_self()) { /* full mute */ return Gtkmm2ext::ExplicitActive; - } else if (r->muted_by_others()) { + } else if (r->muted_by_masters ()) { /* this shows only master mutes, not mute-by-others-soloing */ return Gtkmm2ext::ImplicitActive; } else { diff --git a/gtk2_ardour/vca_master_strip.cc b/gtk2_ardour/vca_master_strip.cc index 6f43228424..c1615edab7 100644 --- a/gtk2_ardour/vca_master_strip.cc +++ b/gtk2_ardour/vca_master_strip.cc @@ -237,10 +237,9 @@ VCAMasterStrip::set_solo_text () void VCAMasterStrip::mute_changed () { - std::cerr << "Mute changed for " << _vca->number() << std::endl; if (_vca->mute_control()->muted_by_self()) { mute_button.set_active_state (ExplicitActive); - } else if (_vca->mute_control()->muted_by_others()) { + } else if (_vca->mute_control()->muted_by_masters ()) { mute_button.set_active_state (ImplicitActive); } else { mute_button.set_active_state (Gtkmm2ext::Off); diff --git a/libs/ardour/ardour/mute_control.h b/libs/ardour/ardour/mute_control.h index 431236692e..5332fd4fa7 100644 --- a/libs/ardour/ardour/mute_control.h +++ b/libs/ardour/ardour/mute_control.h @@ -56,9 +56,12 @@ class LIBARDOUR_API MuteControl : public SlavableAutomationControl bool muted () const; bool muted_by_self () const; + bool muted_by_masters () const; + bool muted_by_self_or_masters () const { + return muted_by_self() || muted_by_masters (); + } bool muted_by_others_soloing () const; - bool muted_by_others () const; void set_mute_points (MuteMaster::MutePoint); MuteMaster::MutePoint mute_points () const; diff --git a/libs/ardour/ardour/mute_master.h b/libs/ardour/ardour/mute_master.h index 7a72e79607..6f5999efb4 100644 --- a/libs/ardour/ardour/mute_master.h +++ b/libs/ardour/ardour/mute_master.h @@ -52,7 +52,9 @@ class LIBARDOUR_API MuteMaster : public SessionHandleRef, public PBD::Stateful bool muted_by_self () const { return _muted_by_self && (_mute_point != MutePoint (0)); } bool muted_by_self_at (MutePoint mp) const { return _muted_by_self && (_mute_point & mp); } - bool muted_by_others_at (MutePoint mp) const; + bool muted_by_others_soloing_at (MutePoint mp) const; + bool muted_by_masters () const { return _muted_by_masters && (_mute_point != MutePoint (0)); } + bool muted_by_masters_at (MutePoint mp) const { return _muted_by_masters && (_mute_point & mp); } gain_t mute_gain_at (MutePoint) const; @@ -69,7 +71,7 @@ class LIBARDOUR_API MuteMaster : public SessionHandleRef, public PBD::Stateful void set_soloed_by_others (bool yn) { _soloed_by_others = yn; } void set_solo_ignore (bool yn) { _solo_ignore = yn; } - void set_muted_by_others (bool); + void set_muted_by_masters (bool); PBD::Signal0<void> MutePointChanged; @@ -83,7 +85,7 @@ class LIBARDOUR_API MuteMaster : public SessionHandleRef, public PBD::Stateful bool _soloed_by_self; bool _soloed_by_others; bool _solo_ignore; - bool _muted_by_others; + bool _muted_by_masters; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 9f66b95b6c..d93883b600 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -460,7 +460,7 @@ public: bool can_be_muted_by_others () const { return !is_master(); } bool muted () const { return _mute_control->muted(); } - bool muted_by_others () const { return _mute_control->muted_by_others(); } + bool muted_by_masters () const { return _mute_control->muted_by_masters(); } bool muted_by_self () const { return _mute_control->muted_by_self(); } bool muted_by_others_soloing () const; diff --git a/libs/ardour/ardour/slavable_automation_control.h b/libs/ardour/ardour/slavable_automation_control.h index 5e95cba22b..98745e025d 100644 --- a/libs/ardour/ardour/slavable_automation_control.h +++ b/libs/ardour/ardour/slavable_automation_control.h @@ -45,6 +45,11 @@ class SlavableAutomationControl : public AutomationControl return get_masters_value_locked (); } + /* for toggled/boolean controls, returns a count of the number of + masters currently enabled. For other controls, returns zero. + */ + int32_t get_boolean_masters () const; + std::vector<PBD::ID> masters () const; PBD::Signal0<void> MasterStatusChange; @@ -96,7 +101,6 @@ class SlavableAutomationControl : public AutomationControl double get_value_locked() const; void actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override); void update_boolean_masters_records (boost::shared_ptr<AutomationControl>); - int32_t get_boolean_masters () const; virtual void master_changed (bool from_self, GroupControlDisposition gcd, boost::shared_ptr<AutomationControl>); virtual void recompute_masters_ratios (double val) { /* do nothing by default */} diff --git a/libs/ardour/ardour/solo_control.h b/libs/ardour/ardour/solo_control.h index 78ce7c56be..bcb01344a4 100644 --- a/libs/ardour/ardour/solo_control.h +++ b/libs/ardour/ardour/solo_control.h @@ -74,6 +74,14 @@ class LIBARDOUR_API SoloControl : public SlavableAutomationControl } bool soloed() const { return self_soloed() || soloed_by_others(); } + /* The session object needs to respond to solo + changes, but to do so accurately it needs to know if we transition + into or out of solo. The normal Changed signal doesn't make that + possible. + */ + + int32_t transitioned_into_solo () const { return _transition_into_solo; } + void clear_all_solo_state (); int set_state (XMLNode const&, int); @@ -86,11 +94,12 @@ class LIBARDOUR_API SoloControl : public SlavableAutomationControl void post_add_master (boost::shared_ptr<AutomationControl>); private: - Soloable& _soloable; - Muteable& _muteable; - bool _self_solo; - uint32_t _soloed_by_others_upstream; - uint32_t _soloed_by_others_downstream; + Soloable& _soloable; + Muteable& _muteable; + bool _self_solo; + uint32_t _soloed_by_others_upstream; + uint32_t _soloed_by_others_downstream; + int32_t _transition_into_solo; void set_self_solo (bool yn); void set_mute_master_solo (); diff --git a/libs/ardour/ardour/stripable.h b/libs/ardour/ardour/stripable.h index f68cb07b91..cee6075a51 100644 --- a/libs/ardour/ardour/stripable.h +++ b/libs/ardour/ardour/stripable.h @@ -140,7 +140,6 @@ class Stripable : public SessionObject { virtual boost::shared_ptr<AutomationControl> master_send_enable_controllable () const = 0; virtual bool muted_by_others_soloing () const = 0; - virtual bool muted_by_others () const = 0; }; diff --git a/libs/ardour/ardour/vca.h b/libs/ardour/ardour/vca.h index 1b7aa8fed8..38fba07bc7 100644 --- a/libs/ardour/ardour/vca.h +++ b/libs/ardour/ardour/vca.h @@ -57,10 +57,8 @@ class LIBARDOUR_API VCA : public Stripable, public Soloable, public Muteable, pu bool can_solo() const { return true; } bool is_safe () const { return false; } - bool muted () const; bool can_be_muted_by_others () const { return true; } bool muted_by_others_soloing() const { return false; } - bool muted_by_others() const { return false; } static std::string default_name_template (); static int next_vca_number (); diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 7c1b3a9399..f078f1afc2 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -920,7 +920,7 @@ MidiTrack::act_on_mute () return; } - if (muted() || _mute_master->muted_by_others_at(MuteMaster::AllPoints)) { + if (muted() || _mute_master->muted_by_others_soloing_at (MuteMaster::AllPoints)) { /* only send messages for channels we are using */ uint16_t mask = _playback_filter.get_channel_mask(); @@ -947,7 +947,7 @@ void MidiTrack::monitoring_changed (bool self, Controllable::GroupControlDisposition gcd) { Track::monitoring_changed (self, gcd); - + /* monitoring state changed, so flush out any on notes at the * port level. */ diff --git a/libs/ardour/mute_control.cc b/libs/ardour/mute_control.cc index 26280d5cd5..d44189e36b 100644 --- a/libs/ardour/mute_control.cc +++ b/libs/ardour/mute_control.cc @@ -51,6 +51,7 @@ MuteControl::post_add_master (boost::shared_ptr<AutomationControl> m) */ if (!muted_by_self() && !get_boolean_masters()) { + _muteable.mute_master()->set_muted_by_masters (true); Changed (false, Controllable::NoGroup); } } @@ -61,7 +62,7 @@ MuteControl::pre_remove_master (boost::shared_ptr<AutomationControl> 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; } @@ -92,16 +93,18 @@ void MuteControl::master_changed (bool self_change, Controllable::GroupControlDisposition gcd, boost::shared_ptr<AutomationControl> m) { bool send_signal = false; - const double changed_master_value = m->get_value(); boost::shared_ptr<MuteControl> mc = boost::dynamic_pointer_cast<MuteControl> (m); - if (changed_master_value) { + 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; } } @@ -117,8 +120,7 @@ double MuteControl::get_value () const { if (slaved ()) { - Glib::Threads::RWLock::ReaderLock lm (master_lock); - return get_masters_value_locked (); + return get_masters_value (); } if (_list && boost::dynamic_pointer_cast<AutomationList>(_list)->automation_playback()) { @@ -149,7 +151,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() || get_masters_value (); } bool @@ -159,7 +165,8 @@ MuteControl::muted_by_self () const } bool -MuteControl::muted_by_others () const +MuteControl::muted_by_masters () const { return get_masters_value (); } + diff --git a/libs/ardour/mute_master.cc b/libs/ardour/mute_master.cc index 89691fc058..32f50bd573 100644 --- a/libs/ardour/mute_master.cc +++ b/libs/ardour/mute_master.cc @@ -43,7 +43,7 @@ MuteMaster::MuteMaster (Session& s, const std::string&) , _soloed_by_self (false) , _soloed_by_others (false) , _solo_ignore (false) - , _muted_by_others (0) + , _muted_by_masters (0) { if (Config->get_mute_affects_pre_fader ()) { @@ -89,22 +89,22 @@ MuteMaster::mute_gain_at (MutePoint mp) const if (Config->get_solo_mute_override()) { if (_soloed_by_self) { gain = GAIN_COEFF_UNITY; - } else if (muted_by_self_at (mp)) { + } else if (muted_by_self_at (mp) || muted_by_masters_at (mp)) { gain = GAIN_COEFF_ZERO; } else { - if (muted_by_others_at (mp) && !_soloed_by_others) { + if (!_soloed_by_others && muted_by_others_soloing_at (mp)) { gain = Config->get_solo_mute_gain (); } else { gain = GAIN_COEFF_UNITY; } } } else { - if (muted_by_self_at (mp)) { + if (muted_by_self_at (mp) || muted_by_masters_at (mp)) { gain = GAIN_COEFF_ZERO; } else if (_soloed_by_self || _soloed_by_others) { gain = GAIN_COEFF_UNITY; } else { - if (muted_by_others_at (mp)) { + if (muted_by_others_soloing_at (mp)) { gain = Config->get_solo_mute_gain (); } else { gain = GAIN_COEFF_UNITY; @@ -164,14 +164,16 @@ MuteMaster::get_state() } bool -MuteMaster::muted_by_others_at (MutePoint mp) const +MuteMaster::muted_by_others_soloing_at (MutePoint mp) const { - return (!_solo_ignore && (_muted_by_others || _session.soloing()) && (_mute_point & mp)); + /* note: this is currently called with the assumption that the owner is + not soloed. it does not test for this condition. + */ + return (!_solo_ignore && _session.soloing()) && (_mute_point & mp); } void -MuteMaster::set_muted_by_others (bool yn) +MuteMaster::set_muted_by_masters (bool yn) { - _muted_by_others = yn; - std::cerr << this << " set muted by others to " << yn << std::endl; + _muted_by_masters = yn; } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 7da7e42abf..0605378959 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -5485,8 +5485,6 @@ Route::muted_by_others_soloing () const return false; } - /* XXX something needed here re: mute-overrides-solo */ - return _session.soloing() && !_solo_control->soloed() && !_solo_isolate_control->solo_isolated(); } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index e42efae882..6c0e341a30 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3406,7 +3406,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool boost::weak_ptr<Route> wpr (*x); boost::shared_ptr<Route> r (*x); - r->solo_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr)); + r->solo_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2,wpr)); r->solo_isolate_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, wpr)); r->mute_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this)); @@ -3772,9 +3772,9 @@ Session::route_solo_isolated_changed (boost::weak_ptr<Route> wpr) } void -Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr) +Session::route_solo_changed (bool self_solo_changed, Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr) { - DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change)); + DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_changed)); boost::shared_ptr<Route> route (wpr.lock()); @@ -3787,20 +3787,27 @@ Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDi return; } - if (!self_solo_change) { - // session doesn't care about changes to soloed-by-others + DEBUG_TRACE (DEBUG::Solo, string_compose ("%1: self %2 masters %3 transition %4\n", route->name(), route->self_soloed(), route->solo_control()->get_masters_value(), route->solo_control()->transitioned_into_solo())); + + if (route->solo_control()->transitioned_into_solo() == 0) { + /* route solo changed by upstream/downstream; not interesting + to Session. + */ + DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 not self-soloed nor soloed by master (%2), ignoring\n", route->name(), route->solo_control()->get_masters_value())); return; } - boost::shared_ptr<RouteList> r = routes.reader (); - int32_t delta; - - if (route->self_soloed()) { - delta = 1; - } else { - delta = -1; + if (route->solo_control()->transitioned_into_solo() == 0) { + /* reason for being soloed changed (e.g. master went away, we + * took over the master state), but actual status did + * not. nothing to do. + */ + DEBUG_TRACE (DEBUG::Solo, string_compose ("%1: solo change was change in reason, not status\n", route->name())); } + boost::shared_ptr<RouteList> r = routes.reader (); + int32_t delta = route->solo_control()->transitioned_into_solo (); + /* the route may be a member of a group that has shared-solo * semantics. If so, then all members of that group should follow the * solo of the changed route. But ... this is optional, controlled by a @@ -3907,11 +3914,11 @@ Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDi sends are involved. */ DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 feeds %2 via sends only %3 sboD %4 sboU %5\n", - route->name(), - (*i)->name(), - via_sends_only, - route->soloed_by_others_downstream(), - route->soloed_by_others_upstream())); + route->name(), + (*i)->name(), + via_sends_only, + route->soloed_by_others_downstream(), + route->soloed_by_others_upstream())); if (!via_sends_only) { //NB. Triggers Invert Push, which handles soloed by downstream DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta)); @@ -3964,13 +3971,13 @@ Session::update_route_solo_state (boost::shared_ptr<RouteList> r) for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((*i)->can_solo()) { if (Config->get_solo_control_is_listen_control()) { - if ((*i)->self_soloed()) { + if ((*i)->self_soloed() || (*i)->solo_control()->get_masters_value()) { listeners++; something_listening = true; } } else { (*i)->set_listen (false); - if ((*i)->can_solo() && (*i)->self_soloed()) { + if ((*i)->can_solo() && ((*i)->self_soloed() || (*i)->solo_control()->get_masters_value())) { something_soloed = true; } } diff --git a/libs/ardour/slavable_automation_control.cc b/libs/ardour/slavable_automation_control.cc index 78a1cc192d..03662c1a26 100644 --- a/libs/ardour/slavable_automation_control.cc +++ b/libs/ardour/slavable_automation_control.cc @@ -199,7 +199,7 @@ SlavableAutomationControl::update_boolean_masters_records (boost::shared_ptr<Aut really) which have more than a simple scalar value. For example, the master may be a mute control which can be muted_by_self() and/or - muted_by_others(). When either of those two + muted_by_masters(). When either of those two conditions changes, Changed() will be emitted, even though ::get_value() will return the same value each time (1.0 if either are true, 0.0 if neither is). diff --git a/libs/ardour/solo_control.cc b/libs/ardour/solo_control.cc index b9346406a5..8514da36ec 100644 --- a/libs/ardour/solo_control.cc +++ b/libs/ardour/solo_control.cc @@ -36,6 +36,7 @@ SoloControl::SoloControl (Session& session, std::string const & name, Soloable& , _self_solo (false) , _soloed_by_others_upstream (0) , _soloed_by_others_downstream (0) + , _transition_into_solo (false) { _list->set_interpolation (Evoral::ControlList::Discrete); /* solo changes must be synchronized by the process cycle */ @@ -48,17 +49,29 @@ SoloControl::set_self_solo (bool yn) DEBUG_TRACE (DEBUG::Solo, string_compose ("%1: set SELF solo => %2\n", name(), yn)); _self_solo = yn; set_mute_master_solo (); + + _transition_into_solo = 0; + + if (yn) { + if (get_masters_value() == 0) { + _transition_into_solo = 1; + } + } else { + if (get_masters_value() == 0) { + _transition_into_solo = -1; + } + } } void SoloControl::set_mute_master_solo () { - _muteable.mute_master()->set_soloed_by_self (self_soloed()); + _muteable.mute_master()->set_soloed_by_self (self_soloed() || get_masters_value()); if (Config->get_solo_control_is_listen_control()) { _muteable.mute_master()->set_soloed_by_others (false); } else { - _muteable.mute_master()->set_soloed_by_others (soloed_by_others_downstream() || soloed_by_others_upstream()); + _muteable.mute_master()->set_soloed_by_others (soloed_by_others_downstream() || soloed_by_others_upstream() || get_masters_value()); } } @@ -85,6 +98,7 @@ SoloControl::mod_solo_by_others_downstream (int32_t delta) DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 SbD delta %2 = %3\n", name(), delta, _soloed_by_others_downstream)); set_mute_master_solo (); + _transition_into_solo = 0; Changed (false, Controllable::UseGroup); /* EMIT SIGNAL */ } @@ -139,6 +153,7 @@ SoloControl::mod_solo_by_others_upstream (int32_t delta) } set_mute_master_solo (); + _transition_into_solo = 0; Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */ } @@ -194,7 +209,7 @@ SoloControl::clear_all_solo_state () _soloed_by_others_downstream = 0; set_self_solo (false); - + _transition_into_solo = 0; /* Session does not need to propagate */ Changed (false, Controllable::UseGroup); /* EMIT SIGNAL */ } @@ -239,15 +254,18 @@ void SoloControl::master_changed (bool /*from self*/, GroupControlDisposition, boost::shared_ptr<AutomationControl> m) { bool send_signal = false; - const double changed_master_value = m->get_value(); - if (changed_master_value) { + _transition_into_solo = 0; + + if (m->get_value()) { /* this master is now enabled */ if (!self_soloed() && get_boolean_masters() == 0) { send_signal = true; + _transition_into_solo = 1; } } else { if (!self_soloed() && get_boolean_masters() == 1) { + _transition_into_solo = -1; send_signal = true; } } @@ -255,8 +273,10 @@ SoloControl::master_changed (bool /*from self*/, GroupControlDisposition, boost: update_boolean_masters_records (m); if (send_signal) { - Changed (false, Controllable::NoGroup); + set_mute_master_solo (); + Changed (false, Controllable::UseGroup); } + } void @@ -271,6 +291,7 @@ SoloControl::post_add_master (boost::shared_ptr<AutomationControl> m) */ if (!self_soloed() && !get_boolean_masters()) { + _transition_into_solo = 1; Changed (false, Controllable::NoGroup); } } @@ -289,7 +310,21 @@ SoloControl::pre_remove_master (boost::shared_ptr<AutomationControl> m) if (m->get_value()) { if (!self_soloed() && (get_boolean_masters() == 1)) { - Changed (false, Controllable::NoGroup); + /* we're not self-soloed, this master is, and we're + removing + it. SlavableAutomationControl::remove_master() will + ensure that we reset our own value after actually + removing the master, so that our state does not + change (this is a precondition of the + SlavableAutomationControl API). This will emit + Changed(), and we need to make sure that any + listener knows that there has been no transition. + */ + _transition_into_solo = 0; + } else { + _transition_into_solo = 1; } + } else { + _transition_into_solo = 0; } } diff --git a/libs/ardour/vca.cc b/libs/ardour/vca.cc index edad50ebdb..f746da8ff3 100644 --- a/libs/ardour/vca.cc +++ b/libs/ardour/vca.cc @@ -146,5 +146,3 @@ VCA::set_state (XMLNode const& node, int version) return 0; } - - diff --git a/libs/surfaces/faderport/faderport.cc b/libs/surfaces/faderport/faderport.cc index 1df2fc4865..1cc47b52e1 100644 --- a/libs/surfaces/faderport/faderport.cc +++ b/libs/surfaces/faderport/faderport.cc @@ -1227,7 +1227,7 @@ FaderPort::map_mute () if (_current_route->muted()) { stop_blinking (Mute); get_button (Mute).set_led_state (_output_port, true); - } else if (_current_route->mute_control()->muted_by_others()) { + } else if (_current_route->muted_by_others_soloing () || _current_route->muted_by_masters()) { start_blinking (Mute); } else { stop_blinking (Mute); |