/* 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 ();
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 ();
PBD::Signal0<void> active_changed;
PBD::Signal0<void> phase_invert_changed;
PBD::Signal0<void> denormal_protection_changed;
- PBD::Signal1<void,void*> listen_changed;
- PBD::Signal2<void,bool,void*> solo_changed;
+ PBD::Signal2<void,void*,bool> listen_changed;
+ PBD::Signal3<void,bool,void*,bool> solo_changed;
PBD::Signal1<void,void*> solo_safe_changed;
PBD::Signal1<void,void*> solo_isolated_changed;
PBD::Signal1<void,void*> comment_changed;
/* mixer stuff */
- void route_listen_changed (void *src, boost::weak_ptr<Route>);
+ void route_listen_changed (bool leave_group_alone, 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 route_solo_changed (bool self_solo_change, bool leave_group_alone, boost::weak_ptr<Route>);
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>());
}
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;
}
}
_mute_master->set_soloed_by_others (false);
- listen_changed (src); /* EMIT SIGNAL */
+ listen_changed (src, group_active); /* EMIT SIGNAL */
}
}
}
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()));
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;
}
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 */
}
}
set_mute_master_solo ();
- solo_changed (false, this); /* EMIT SIGNAL */
+ solo_changed (false, this, false); /* EMIT SIGNAL */
}
void
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
boost::weak_ptr<Route> wpr (*x);
boost::shared_ptr<Route> 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));
}
void
-Session::route_listen_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
+Session::route_listen_changed (bool leave_group_alone, boost::weak_ptr<Route> wpr)
{
boost::shared_ptr<Route> 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;
}
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<RouteList> 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))) {
}
void
-Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_ptr<Route> wpr)
+Session::route_solo_changed (bool self_solo_change, bool leave_group_alone, boost::weak_ptr<Route> wpr)
{
DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
}
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 */
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 */)
+Session::rt_set_solo (boost::shared_ptr<RouteList> 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);
}
}
}
void
-Session::rt_set_listen (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_override*/ )
+Session::rt_set_listen (boost::shared_ptr<RouteList> 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);
}
}