- return _monitor_send->active ();
- } else {
- return false;
- }
-}
-
-void
-Route::set_solo_safe (bool yn, Controllable::GroupControlDisposition /* group_override */)
-{
- if (_solo_safe != yn) {
- _solo_safe = yn;
- solo_safe_changed (); /* EMIT SIGNAL */
- _solo_safe_control->Changed(); /* EMIT SIGNAL */
- }
-}
-
-bool
-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;
-
-#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;
-
- {
- PBD::Unwinder<bool> uw (_solo_safe, false);
- set_solo (false, Controllable::NoGroup);
- }
-
- if (emit_changed) {
- set_mute_master_solo ();
- solo_changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
- }
-}
-
-void
-Route::set_solo (bool yn, Controllable::GroupControlDisposition group_override)
-{
- DEBUG_TRACE (DEBUG::Solo, string_compose ("%1: set solo => %2, grp ? %3 currently self-soloed ? %4\n",
- name(), yn, enum_2_string(group_override), self_soloed()));
-
- if (_solo_safe) {
- DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 ignore solo change due to solo-safe\n", name()));
- return;
- }
-
- if (is_master() || is_monitor() || is_auditioner()) {
- DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 ignore solo change (master, monitor or auditioner)\n", name()));
- return;
- }
-
- if (use_group (group_override, &RouteGroup::is_solo)) {
- _route_group->foreach_route (boost::bind (&Route::set_solo, _1, yn, Controllable::ForGroup));
- return;
- }
-
- if (self_soloed() != yn) {
- set_self_solo (yn);
- solo_changed (true, group_override); /* EMIT SIGNAL */
- _solo_control->Changed (); /* EMIT SIGNAL */
- }
-
- assert (Config->get_solo_control_is_listen_control() || !_monitor_send || !_monitor_send->active());
-
- /* XXX TRACKS DEVELOPERS: THIS LOGIC SUGGESTS THAT YOU ARE NOT AWARE OF
- Config->get_solo_mute_overrride().
- */
-
- if (yn && Profile->get_trx()) {
- set_mute (false, Controllable::UseGroup);
- }
-}
-
-void
-Route::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 ();
-}
-
-void
-Route::mod_solo_by_others_upstream (int32_t delta)
-{
- DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 mod solo-by-upstream by %2, current up = %3 down = %4\n",
- name(), delta, _soloed_by_others_upstream, _soloed_by_others_downstream));
-
- uint32_t old_sbu = _soloed_by_others_upstream;
-
- if (delta < 0) {
- if (_soloed_by_others_upstream >= (uint32_t) abs (delta)) {
- _soloed_by_others_upstream += delta;
- } else {
- _soloed_by_others_upstream = 0;
- }
- } else {
- _soloed_by_others_upstream += delta;
- }
-
- DEBUG_TRACE (DEBUG::Solo, string_compose (
- "%1 SbU delta %2 = %3 old = %4 sbd %5 ss %6 exclusive %7\n",
- name(), delta, _soloed_by_others_upstream, old_sbu,
- _soloed_by_others_downstream, _self_solo, Config->get_exclusive_solo()));
-
- /* push the inverse solo change to everything that feeds us.
-
- This is important for solo-within-group. When we solo 1 track out of N that
- feed a bus, that track will cause mod_solo_by_upstream (+1) to be called
- on the bus. The bus then needs to call mod_solo_by_downstream (-1) on all
- tracks that feed it. This will silence them if they were audible because
- of a bus solo, but the newly soloed track will still be audible (because
- it is self-soloed).
-
- but .. do this only when we are being told to solo-by-upstream (i.e delta = +1),
- not in reverse.
- */
-
- if ((_self_solo || _soloed_by_others_downstream) &&
- ((old_sbu == 0 && _soloed_by_others_upstream > 0) ||
- (old_sbu > 0 && _soloed_by_others_upstream == 0))) {
-
- if (delta > 0 || !Config->get_exclusive_solo()) {
- DEBUG_TRACE (DEBUG::Solo, string_compose("\t ... INVERT push from %1\n", _name));
- for (FedBy::iterator i = _fed_by.begin(); i != _fed_by.end(); ++i) {
- if (i->sends_only) {
- continue;
- }
- boost::shared_ptr<Route> sr = i->r.lock();
- if (sr) {
- sr->mod_solo_by_others_downstream (-delta);
- }
- }
- }
- }
-
- set_mute_master_solo ();
- solo_changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
-}
-
-void
-Route::mod_solo_by_others_downstream (int32_t delta)
-{
- DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 mod solo-by-downstream by %2, current up = %3 down = %4\n",
- name(), delta, _soloed_by_others_upstream, _soloed_by_others_downstream));
-
- if (delta < 0) {
- if (_soloed_by_others_downstream >= (uint32_t) abs (delta)) {
- _soloed_by_others_downstream += delta;