add a "reset all solo state" safeguard
authorRobin Gareus <robin@gareus.org>
Tue, 6 Oct 2015 18:05:38 +0000 (20:05 +0200)
committerRobin Gareus <robin@gareus.org>
Tue, 6 Oct 2015 18:05:38 +0000 (20:05 +0200)
libs/ardour/ardour/route.h
libs/ardour/ardour/session.h
libs/ardour/route.cc
libs/ardour/session_rtevents.cc

index 915618037f7bffec14e464f921c7964b9a7db12e..cf7ec90fd1dfe37d29d403fe25ba5b9dc1ecbea9 100644 (file)
@@ -160,6 +160,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
 
        void set_solo (bool yn, void *src);
        bool soloed () const { return self_soloed () || soloed_by_others (); }
+       void clear_all_solo_state ();
 
        bool soloed_by_others () const { return _soloed_by_others_upstream||_soloed_by_others_downstream; }
        bool soloed_by_others_upstream () const { return _soloed_by_others_upstream; }
index c627998913c9bffc3b6a58e3c2b2f36508a9d461..144b3c8670923ebdd45a36901ecef1dfb3e3abb9 100644 (file)
@@ -736,6 +736,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        static const SessionEvent::RTeventCallback rt_cleanup;
 
        void set_solo (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+       void clear_all_solo_state (boost::shared_ptr<RouteList>);
        void set_just_one_solo (boost::shared_ptr<Route>, bool, SessionEvent::RTeventCallback after = rt_cleanup);
        void set_mute (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
        void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
@@ -1774,6 +1775,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        }
 
        void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+       void rt_clear_all_solo_state (boost::shared_ptr<RouteList>, bool yn, bool group_override);
        void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, bool /* ignored*/ );
        void rt_set_mute (boost::shared_ptr<RouteList>, bool yn, bool group_override);
        void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, bool group_override);
index aa7a7ee9f82ac9ef89c3e52f9add2f7c9159f522..7f21a6fdc3d24e0c20bab9c71e25a132583d21ce 100644 (file)
@@ -815,6 +815,42 @@ Route::solo_safe() const
        return _solo_safe;
 }
 
+void
+Route::clear_all_solo_state ()
+{
+       // ideally this function will never do anything, it only exists to forestall Murphy
+       bool emit_changed = false;
+       bool old_safe = _solo_safe;
+
+#ifndef NDEBUG
+       // these are really debug messages, but of possible interest.
+       if (_self_solo) {
+               PBD::info << string_compose (_("Cleared Explicit solo: %1\n"), name());
+       }
+       if (_soloed_by_others_upstream || _soloed_by_others_downstream) {
+               PBD::info << string_compose (_("Cleared Implicit solo: %1 up:%2 down:%3\n"),
+                               name(), _soloed_by_others_upstream, _soloed_by_others_downstream);
+       }
+#endif
+
+       if (!_self_solo && (_soloed_by_others_upstream || _soloed_by_others_downstream)) {
+               // if self-soled, set_solo() will do signal emission
+               emit_changed = true;
+       }
+
+       _soloed_by_others_upstream = 0;
+       _soloed_by_others_downstream = 0;
+
+       _solo_safe = false; // allow set_solo() to do its job;
+       set_solo (false, this);
+       _solo_safe = old_safe;
+
+       if (emit_changed) {
+               set_mute_master_solo ();
+               solo_changed (false, this); /* EMIT SIGNAL */
+       }
+}
+
 void
 Route::set_solo (bool yn, void *src)
 {
@@ -916,7 +952,7 @@ Route::mod_solo_by_others_upstream (int32_t delta)
        }
 
        set_mute_master_solo ();
-       solo_changed (false, this);
+       solo_changed (false, this); /* EMIT SIGNAL */
 }
 
 void
@@ -938,7 +974,7 @@ Route::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 ();
-       solo_changed (false, this);
+       solo_changed (false, this); /* EMIT SIGNAL */
 }
 
 void
@@ -968,7 +1004,7 @@ Route::mod_solo_isolated_by_upstream (bool yn, void* src)
        if (solo_isolated() != old) {
                /* solo isolated status changed */
                _mute_master->set_solo_ignore (solo_isolated());
-               solo_isolated_changed (src);
+               solo_isolated_changed (src); /* EMIT SIGNAL */
        }
 }
 
@@ -1024,7 +1060,7 @@ Route::set_solo_isolated (bool yn, void *src)
 
        /* XXX should we back-propagate as well? (April 2010: myself and chris goddard think not) */
 
-       solo_isolated_changed (src);
+       solo_isolated_changed (src); /* EMIT SIGNAL */
 }
 
 bool
index 189385e2ee8281fb55c0cd637c61a7b772b6e8f7..d001b239baa62c8c183d0fb1548d2aeb1296f9e1 100644 (file)
@@ -53,12 +53,31 @@ Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, b
        set_dirty();
 }
 
+void
+Session::clear_all_solo_state (boost::shared_ptr<RouteList> rl)
+{
+       queue_event (get_rt_event (rl, false, rt_cleanup, false, &Session::rt_clear_all_solo_state));
+}
+
+void
+Session::rt_clear_all_solo_state (boost::shared_ptr<RouteList> rl, bool /* yn */, bool /* group_override */)
+{
+       for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+               if ((*i)->is_auditioner()) {
+                       continue;
+               }
+               (*i)->clear_all_solo_state();
+       }
+       set_dirty();
+}
+
 void
 Session::set_solo (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
 {
        queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo));
 }
 
+
 void
 Session::rt_set_solo (boost::shared_ptr<RouteList> rl, bool yn, bool /* group_override */)
 {