diff options
author | Robin Gareus <robin@gareus.org> | 2015-10-05 00:08:55 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2015-10-05 00:08:55 +0200 |
commit | 58d59177bbc0cc936d80efd5ec2e0a8ed368c106 (patch) | |
tree | 1c0a513672e266f48ed113286b32b603ff3aaa80 /libs | |
parent | e21e7f70405567781d669a83345a0f416785040d (diff) |
fix various stuck-solo cases:
* solo groups
* cancel-solo
* SIP <> AFL/PFL changes
The optimized plural-form route_solo_changed() relied on the false
premise that solo-groups and port-connections are disjoint sets.
-=-
e.g. "cancel all solo" calls set_solo(get_routes(), false);
Since All routes are affected, the "non_solo_change" set is empty, and
no changes were propagated up/downstream.
Routes that indirectly change state as group-members, wrongly end up in
the "non_solo_change" list instead of the "solo_change" list.
If a route feeds another in the same group, no changes were propagated.
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/session.h | 3 | ||||
-rw-r--r-- | libs/ardour/session.cc | 124 | ||||
-rw-r--r-- | libs/ardour/session_rtevents.cc | 9 |
3 files changed, 4 insertions, 132 deletions
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 2bc992bb10..2e6024badb 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1536,12 +1536,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop /* mixer stuff */ - bool solo_update_disabled; - void route_listen_changed (void *src, boost::weak_ptr<Route>); void route_mute_changed (void *src); void route_solo_changed (bool self_solo_change, void *src, boost::weak_ptr<Route>); - void routes_solo_changed (boost::shared_ptr<RouteList> solo_change_routes); void route_solo_isolated_changed (void *src, boost::weak_ptr<Route>); void update_route_solo_state (boost::shared_ptr<RouteList> r = boost::shared_ptr<RouteList>()); diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 791c8d2656..fd7458fec9 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -264,7 +264,6 @@ Session::Session (AudioEngine &eng, , _route_deletion_in_progress (false) , destructive_index (0) , _track_number_decimals(1) - , solo_update_disabled (false) , default_fade_steepness (0) , default_fade_msecs (0) , _total_free_4k_blocks (0) @@ -3553,120 +3552,6 @@ Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr) } void -Session::routes_solo_changed (boost::shared_ptr<RouteList> solo_change_routes) -{ - if (solo_update_disabled) { - // We know already - DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n"); - return; - } - - if (solo_change_routes->empty() ) { - return; - } - - boost::shared_ptr<RouteList> non_solo_change_routes (new RouteList); - boost::shared_ptr<RouteList> r = routes.reader (); - int32_t delta; - - std::set_difference (r->begin(), r->end(), - solo_change_routes->begin(), solo_change_routes->end(), - std::back_inserter(*non_solo_change_routes) ); - - DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta)); - - solo_update_disabled = true; - RouteList uninvolved; - - for (RouteList::iterator route = solo_change_routes->begin(); route != solo_change_routes->end(); ++route) { - - if ((*route)->self_soloed() ) { - delta = 1; - } else { - delta = -1; - } - - DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", (*route)->name())); - - for (RouteList::iterator i = non_solo_change_routes->begin(); i != non_solo_change_routes->end(); ++i) { - bool via_sends_only; - bool in_signal_flow; - - if ((*i) == *route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ) { - continue; - } - - in_signal_flow = false; - - DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed from %1\n", (*i)->name())); - - if ((*i)->feeds (*route, &via_sends_only)) { - DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a feed from %1\n", (*i)->name())); - if (!via_sends_only) { - if (!(*route)->soloed_by_others_upstream()) { - (*i)->mod_solo_by_others_downstream (delta); - } - } else { - DEBUG_TRACE (DEBUG::Solo, string_compose ("\tthere is a send-only feed from %1\n", (*i)->name())); - } - in_signal_flow = true; - } else { - DEBUG_TRACE (DEBUG::Solo, string_compose ("\tno feed from %1\n", (*i)->name())); - } - - DEBUG_TRACE (DEBUG::Solo, string_compose ("check feed to %1\n", (*i)->name())); - - if ((*route)->feeds (*i, &via_sends_only)) { - /* propagate solo upstream only if routing other than - sends is involved, but do consider the other route - (*i) to be part of the signal flow even if only - 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())); - if (!via_sends_only) { - if (!(*route)->soloed_by_others_downstream()) { - DEBUG_TRACE (DEBUG::Solo, string_compose ("\tmod %1 by %2\n", (*i)->name(), delta)); - (*i)->mod_solo_by_others_upstream (delta); - } else { - DEBUG_TRACE (DEBUG::Solo, "\talready soloed by others downstream\n"); - } - } else { - DEBUG_TRACE (DEBUG::Solo, string_compose ("\tfeed to %1 ignored, sends-only\n", (*i)->name())); - } - in_signal_flow = true; - } else { - DEBUG_TRACE (DEBUG::Solo, "\tno feed to\n"); - } - - if (!in_signal_flow) { - uninvolved.push_back (*i); - } - } - } - solo_update_disabled = false; - DEBUG_TRACE (DEBUG::Solo, "propagation complete\n"); - - update_route_solo_state (); - - /* now notify that the mute state of the routes not involved in the signal - pathway of the just-solo-changed route may have altered. - */ - - for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) { - DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1\n", (*i)->name() )); - (*i)->mute_changed (this); - } - - SoloChanged (); /* EMIT SIGNAL */ - set_dirty(); -} - -void Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr) { DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change)); @@ -3676,12 +3561,6 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p return; } - if (solo_update_disabled) { - // We know already - DEBUG_TRACE (DEBUG::Solo, "solo update disabled - changed ignored\n"); - return; - } - boost::shared_ptr<Route> route = wpr.lock (); assert (route); @@ -3712,8 +3591,6 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p DEBUG_TRACE (DEBUG::Solo, string_compose ("propagate solo change, delta = %1\n", delta)); - solo_update_disabled = true; - RouteList uninvolved; DEBUG_TRACE (DEBUG::Solo, string_compose ("%1\n", route->name())); @@ -3779,7 +3656,6 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p } } - solo_update_disabled = false; DEBUG_TRACE (DEBUG::Solo, "propagation complete\n"); update_route_solo_state (r); diff --git a/libs/ardour/session_rtevents.cc b/libs/ardour/session_rtevents.cc index 5e20421cca..db334932f1 100644 --- a/libs/ardour/session_rtevents.cc +++ b/libs/ardour/session_rtevents.cc @@ -62,18 +62,17 @@ Session::set_solo (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeve void Session::rt_set_solo (boost::shared_ptr<RouteList> rl, bool yn, bool /* group_override */) { - solo_update_disabled = true; - for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { if (!(*i)->is_auditioner()) { (*i)->set_solo (yn, this); } } - solo_update_disabled = false; - routes_solo_changed (rl); - set_dirty(); + /* XXX boost::shared_ptr<RouteList> goes out of scope here and is likley free()ed in RT context + * because boost's shared_ptr does reference counting and free/delete in the dtor. + * (this also applies to other rt_ methods here) + */ } void |