From: Robin Gareus Date: Tue, 6 Oct 2015 23:44:02 +0000 (+0200) Subject: implement solo group override X-Git-Tag: 4.3~76 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;ds=sidebyside;h=477d1f3f42b125b42271c873277dff2236a297ae;p=ardour.git implement solo group override --- diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index cf7ec90fd1..94d8837246 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -158,7 +158,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou /* controls use set_solo() to modify this route's solo state */ - void set_solo (bool yn, void *src); + void set_solo (bool yn, void *src, bool group_override = false); bool soloed () const { return self_soloed () || soloed_by_others (); } void clear_all_solo_state (); @@ -173,7 +173,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou void set_solo_safe (bool yn, void *src); bool solo_safe() const; - void set_listen (bool yn, void* src); + void set_listen (bool yn, void* src, bool group_override = false); bool listening_via_monitor () const; void enable_monitor_send (); @@ -286,8 +286,8 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou PBD::Signal0 active_changed; PBD::Signal0 phase_invert_changed; PBD::Signal0 denormal_protection_changed; - PBD::Signal1 listen_changed; - PBD::Signal2 solo_changed; + PBD::Signal2 listen_changed; + PBD::Signal3 solo_changed; PBD::Signal1 solo_safe_changed; PBD::Signal1 solo_isolated_changed; PBD::Signal1 comment_changed; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 144b3c8670..4e9be4d02e 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1536,9 +1536,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop /* mixer stuff */ - void route_listen_changed (void *src, boost::weak_ptr); + void route_listen_changed (bool leave_group_alone, boost::weak_ptr); void route_mute_changed (void *src); - void route_solo_changed (bool self_solo_change, void *src, boost::weak_ptr); + void route_solo_changed (bool self_solo_change, bool leave_group_alone, boost::weak_ptr); void route_solo_isolated_changed (void *src, boost::weak_ptr); void update_route_solo_state (boost::shared_ptr r = boost::shared_ptr()); diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index b3444e0b90..eb98a2388f 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -764,14 +764,19 @@ Route::passthru_silence (framepos_t start_frame, framepos_t end_frame, pframes_t } void -Route::set_listen (bool yn, void* src) +Route::set_listen (bool yn, void* src, bool group_override) { if (_solo_safe) { return; } - if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_solo()) { - _route_group->foreach_route (boost::bind (&Route::set_listen, _1, yn, _route_group)); + bool group_active = _route_group && _route_group->is_active() && _route_group->is_solo(); + if (group_override && _route_group) { + group_active = !group_active; + } + + if (_route_group && src != _route_group && group_active) { + _route_group->foreach_route (boost::bind (&Route::set_listen, _1, yn, _route_group, group_override)); return; } @@ -786,7 +791,7 @@ Route::set_listen (bool yn, void* src) } _mute_master->set_soloed_by_others (false); - listen_changed (src); /* EMIT SIGNAL */ + listen_changed (src, group_active); /* EMIT SIGNAL */ } } } @@ -848,12 +853,12 @@ Route::clear_all_solo_state () if (emit_changed) { set_mute_master_solo (); - solo_changed (false, this); /* EMIT SIGNAL */ + solo_changed (false, this, false); /* EMIT SIGNAL */ } } void -Route::set_solo (bool yn, void *src) +Route::set_solo (bool yn, void *src, bool group_override) { if (_solo_safe) { DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 ignore solo change due to solo-safe\n", name())); @@ -865,8 +870,13 @@ Route::set_solo (bool yn, void *src) return; } - if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_solo()) { - _route_group->foreach_route (boost::bind (&Route::set_solo, _1, yn, _route_group)); + // explicit XOR + bool group_active = _route_group && _route_group->is_active() && _route_group->is_solo(); + if (group_override && _route_group) { + group_active = !group_active; + } + if (_route_group && src != _route_group && group_active) { + _route_group->foreach_route (boost::bind (&Route::set_solo, _1, yn, _route_group, group_override)); return; } @@ -876,7 +886,7 @@ Route::set_solo (bool yn, void *src) if (self_soloed() != yn) { set_self_solo (yn); set_mute_master_solo (); - solo_changed (true, src); /* EMIT SIGNAL */ + solo_changed (true, src, group_active); /* EMIT SIGNAL */ _solo_control->Changed (); /* EMIT SIGNAL */ } @@ -953,7 +963,7 @@ Route::mod_solo_by_others_upstream (int32_t delta) } set_mute_master_solo (); - solo_changed (false, this); /* EMIT SIGNAL */ + solo_changed (false, this, false); /* EMIT SIGNAL */ } void @@ -975,7 +985,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); /* EMIT SIGNAL */ + solo_changed (false, this, false); /* EMIT SIGNAL */ } void diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 9d0c4f9662..e22fe57c99 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3206,8 +3206,8 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool boost::weak_ptr wpr (*x); boost::shared_ptr r (*x); - r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr)); - r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr)); + r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _2, wpr)); + r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _3, wpr)); r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr)); r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1)); r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2)); @@ -3490,11 +3490,11 @@ Session::route_mute_changed (void* /*src*/) } void -Session::route_listen_changed (void* /*src*/, boost::weak_ptr wpr) +Session::route_listen_changed (bool leave_group_alone, boost::weak_ptr wpr) { boost::shared_ptr route = wpr.lock(); if (!route) { - error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg; + error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_listen_changed")) << endmsg; return; } @@ -3503,7 +3503,6 @@ Session::route_listen_changed (void* /*src*/, boost::weak_ptr wpr) if (Config->get_exclusive_solo()) { /* new listen: disable all other listen, except solo-grouped channels */ RouteGroup* rg = route->route_group (); - bool leave_group_alone = (rg && rg->is_active() && rg->is_solo()); boost::shared_ptr r = routes.reader (); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() || (leave_group_alone && ((*i)->route_group() == rg))) { @@ -3553,7 +3552,7 @@ Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr wpr) } void -Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr wpr) +Session::route_solo_changed (bool self_solo_change, bool leave_group_alone, boost::weak_ptr wpr) { DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change)); @@ -3575,8 +3574,6 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p } RouteGroup* rg = route->route_group (); - bool leave_group_alone = (rg && rg->is_active() && rg->is_solo()); - if (delta == 1 && Config->get_exclusive_solo()) { /* new solo: disable all other solos, but not the group if its solo-enabled */ diff --git a/libs/ardour/session_rtevents.cc b/libs/ardour/session_rtevents.cc index d001b239ba..2b24b59970 100644 --- a/libs/ardour/session_rtevents.cc +++ b/libs/ardour/session_rtevents.cc @@ -77,13 +77,12 @@ Session::set_solo (boost::shared_ptr rl, bool yn, SessionEvent::RTeve queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo)); } - void -Session::rt_set_solo (boost::shared_ptr rl, bool yn, bool /* group_override */) +Session::rt_set_solo (boost::shared_ptr rl, bool yn, bool group_override) { for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { if (!(*i)->is_auditioner()) { - (*i)->set_solo (yn, this); + (*i)->set_solo (yn, this, group_override); } } @@ -132,11 +131,11 @@ Session::set_listen (boost::shared_ptr rl, bool yn, SessionEvent::RTe } void -Session::rt_set_listen (boost::shared_ptr rl, bool yn, bool /*group_override*/ ) +Session::rt_set_listen (boost::shared_ptr rl, bool yn, bool group_override) { for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { if (!(*i)->is_auditioner()) { - (*i)->set_listen (yn, this); + (*i)->set_listen (yn, this, group_override); } }