diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 822415353e..b6631298d1 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -184,6 +184,9 @@ public: bool is_safe () const { return _solo_safe_control->get_value(); } + bool can_monitor () const { + return can_solo() || is_foldbackbus (); + } void enable_monitor_send (); void set_denormal_protection (bool yn); diff --git a/libs/ardour/ardour/soloable.h b/libs/ardour/ardour/soloable.h index fa474b38a3..4b65aff244 100644 --- a/libs/ardour/ardour/soloable.h +++ b/libs/ardour/ardour/soloable.h @@ -31,6 +31,7 @@ class Soloable { virtual void push_solo_isolate_upstream (int32_t delta) = 0; virtual bool is_safe () const = 0; virtual bool can_solo () const = 0; + virtual bool can_monitor () const = 0; }; } /* namespace */ diff --git a/libs/ardour/ardour/vca.h b/libs/ardour/ardour/vca.h index bf1c02c47d..f1a4c3f4df 100644 --- a/libs/ardour/ardour/vca.h +++ b/libs/ardour/ardour/vca.h @@ -79,6 +79,7 @@ class LIBARDOUR_API VCA : public Stripable, void push_solo_upstream (int32_t) {} void push_solo_isolate_upstream (int32_t) {} bool can_solo() const { return true; } + bool can_monitor() const { return false; } bool is_safe () const { return false; } /* Muteable API */ diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 8661ca89b0..1a68f6ae14 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -3349,7 +3349,6 @@ Route::enable_monitor_send () /* master never sends to monitor section via the normal mechanism */ assert (!is_master ()); assert (!is_monitor ()); - assert (!is_foldbackbus ()); /* make sure we have one */ if (!_monitor_send) { diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 33f9720721..1920704c24 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -1155,7 +1155,7 @@ Session::setup_route_monitor_sends (bool enable, bool need_process_lock) ProcessorChangeBlocker pcb (this, false /* XXX */); for (RouteList::iterator x = rls->begin(); x != rls->end(); ++x) { - if ((*x)->can_solo ()) { + if ((*x)->can_monitor ()) { if (enable) { (*x)->enable_monitor_send (); } else { @@ -3093,7 +3093,7 @@ Session::new_route_from_template (uint32_t how_many, PresentationInfo::order_t i /* set/unset monitor-send */ Glib::Threads::Mutex::Lock lm (_engine.process_lock()); for (RouteList::iterator x = ret.begin(); x != ret.end(); ++x) { - if ((*x)->can_solo ()) { + if ((*x)->can_monitor ()) { if (_monitor_out) { (*x)->enable_monitor_send (); } else { @@ -3258,7 +3258,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool Glib::Threads::Mutex::Lock lm (_engine.process_lock()); for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) { - if ((*x)->can_solo ()) { + if ((*x)->can_monitor ()) { (*x)->enable_monitor_send (); } } @@ -3454,7 +3454,7 @@ Session::remove_routes (boost::shared_ptr routes_to_remove) } /* if the monitoring section had a pointer to this route, remove it */ - if (!deletion_in_progress () && _monitor_out && (*iter)->can_solo ()) { + if (!deletion_in_progress () && _monitor_out && (*iter)->can_monitor ()) { Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); ProcessorChangeBlocker pcb (this, false); (*iter)->remove_monitor_send (); @@ -3571,7 +3571,7 @@ Session::route_listen_changed (Controllable::GroupControlDisposition group_overr continue; } - if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_solo()) { + if ((*i)->solo_isolate_control()->solo_isolated() || !(*i)->can_monitor()) { /* route does not get solo propagated to it */ continue; } @@ -3801,17 +3801,15 @@ Session::update_route_solo_state (boost::shared_ptr r) } for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if ((*i)->can_solo()) { - if (Config->get_solo_control_is_listen_control()) { - if ((*i)->solo_control()->soloed_by_self_or_masters()) { - listeners++; - something_listening = true; - } - } else { - (*i)->set_listen (false); - if ((*i)->can_solo() && (*i)->solo_control()->soloed_by_self_or_masters()) { - something_soloed = true; - } + if ((*i)->can_monitor() && Config->get_solo_control_is_listen_control()) { + if ((*i)->solo_control()->soloed_by_self_or_masters()) { + listeners++; + something_listening = true; + } + } else if ((*i)->can_solo()) { + (*i)->set_listen (false); + if ((*i)->can_solo() && (*i)->solo_control()->soloed_by_self_or_masters()) { + something_soloed = true; } } diff --git a/libs/ardour/solo_control.cc b/libs/ardour/solo_control.cc index f194047559..6497ac319e 100644 --- a/libs/ardour/solo_control.cc +++ b/libs/ardour/solo_control.cc @@ -79,7 +79,7 @@ SoloControl::set_mute_master_solo () void SoloControl::mod_solo_by_others_downstream (int32_t delta) { - if (_soloable.is_safe() || !_soloable.can_solo()) { + if (_soloable.is_safe() || !can_solo()) { return; } @@ -106,7 +106,7 @@ SoloControl::mod_solo_by_others_downstream (int32_t delta) void SoloControl::mod_solo_by_others_upstream (int32_t delta) { - if (_soloable.is_safe() || !_soloable.can_solo()) { + if (_soloable.is_safe() || !can_solo()) { return; } @@ -161,7 +161,7 @@ SoloControl::mod_solo_by_others_upstream (int32_t delta) void SoloControl::actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override) { - if (_soloable.is_safe() || !_soloable.can_solo()) { + if (_soloable.is_safe() || !can_solo()) { return; } @@ -351,5 +351,9 @@ SoloControl::pre_remove_master (boost::shared_ptr m) bool SoloControl::can_solo () const { - return _soloable.can_solo (); + if (Config->get_solo_control_is_listen_control()) { + return _soloable.can_monitor (); + } else { + return _soloable.can_solo (); + } }