From 1c0c9b40b73180537da7630b6a219baf85886da6 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 9 Mar 2016 13:11:53 -0500 Subject: new API for route solo/mute state mgmt Route now calls back into Session when solo/mute/listen state changes. All other interested parties must use the Route::{solo,mute,...}_control()->Changed() to be notified of changes. The Session requires more information than the Changed signal can provide, in order to propagate solo/mute changes across the entire Session correctly. Note that this uses an experimental use of CRTP to isolate a public API within Session --- libs/ardour/ardour/route.h | 6 --- libs/ardour/ardour/session.h | 15 ++++--- libs/ardour/ardour/session_solo_notifications.h | 53 +++++++++++++++++++++++++ libs/ardour/midi_track.cc | 1 - libs/ardour/route.cc | 27 +++++++------ libs/ardour/session.cc | 38 ++++++------------ 6 files changed, 89 insertions(+), 51 deletions(-) create mode 100644 libs/ardour/ardour/session_solo_notifications.h (limited to 'libs') diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 8902665170..b976e63c69 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -350,14 +350,8 @@ public: framecnt_t signal_latency() const { return _signal_latency; } PBD::Signal0 active_changed; - PBD::Signal0 phase_invert_changed; PBD::Signal0 denormal_protection_changed; - PBD::Signal1 listen_changed; - PBD::Signal2 solo_changed; - PBD::Signal0 solo_safe_changed; - PBD::Signal0 solo_isolated_changed; PBD::Signal0 comment_changed; - PBD::Signal0 mute_changed; PBD::Signal0 mute_points_changed; /** track numbers - assigned by session diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 2976fec8f3..b3852b631d 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -67,6 +67,7 @@ #include "ardour/rc_configuration.h" #include "ardour/session_configuration.h" #include "ardour/session_event.h" +#include "ardour/session_solo_notifications.h" #include "ardour/interpolation.h" #include "ardour/plugin.h" #include "ardour/route.h" @@ -165,7 +166,7 @@ private: }; /** Ardour Session */ -class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager +class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager, public SessionSoloNotifications { public: enum RecordState { @@ -1683,12 +1684,14 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop void reassign_track_numbers (); uint32_t _track_number_decimals; - /* mixer stuff */ + /* solo/mute/notifications (see SessionSoloNotifications object) */ + + friend class SessionSoloNotifications; + void _route_listen_changed (PBD::Controllable::GroupControlDisposition, boost::shared_ptr); + void _route_mute_changed (); + void _route_solo_changed (bool self_solo_change, PBD::Controllable::GroupControlDisposition group_override, boost::shared_ptr); + void _route_solo_isolated_changed (boost::shared_ptr); - void route_listen_changed (PBD::Controllable::GroupControlDisposition, boost::weak_ptr); - void route_mute_changed (); - void route_solo_changed (bool self_solo_change, PBD::Controllable::GroupControlDisposition group_override, boost::weak_ptr); - void route_solo_isolated_changed (boost::weak_ptr); void update_route_solo_state (boost::shared_ptr r = boost::shared_ptr()); void listen_position_changed (); diff --git a/libs/ardour/ardour/session_solo_notifications.h b/libs/ardour/ardour/session_solo_notifications.h new file mode 100644 index 0000000000..bfb2e7d333 --- /dev/null +++ b/libs/ardour/ardour/session_solo_notifications.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2016 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __libardour_session_solo_notifications_h__ +#define __libardour_session_solo_notifications_h__ + +#include +#include "pbd/controllable.h" + +namespace ARDOUR { + +class Route; + +template +class SessionSoloNotifications +{ + public: + void solo_changed (bool self_solo_change, PBD::Controllable::GroupControlDisposition gcd, boost::shared_ptr route) { + static_cast(this)->_route_solo_changed (self_solo_change, gcd, route); + } + + void listen_changed (PBD::Controllable::GroupControlDisposition gcd, boost::shared_ptr route) { + static_cast(this)->_route_listen_changed (gcd, route); + } + + void mute_changed () { + static_cast(this)->_route_mute_changed (); + } + + void solo_isolated_changed (boost::shared_ptr route) { + static_cast(this)->_route_solo_isolated_changed (route); + } +}; + +} /* namespace */ + +#endif /* __libardour_session_solo_notifications_h__ */ diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 3d1d8d0093..9a38f9f05a 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -999,4 +999,3 @@ MidiTrack::monitoring_state () const } return ms; } - diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 94111e602e..569f00fbc7 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -830,7 +830,8 @@ Route::set_listen (bool yn, Controllable::GroupControlDisposition group_override } _mute_master->set_soloed_by_others (false); - listen_changed (group_override); /* EMIT SIGNAL */ + _session.listen_changed (group_override, shared_from_this()); + _solo_control->Changed(); /* EMIT SIGNAL */ } } } @@ -850,7 +851,6 @@ Route::set_solo_safe (bool yn, Controllable::GroupControlDisposition /* group_ov { if (_solo_safe != yn) { _solo_safe = yn; - solo_safe_changed (); /* EMIT SIGNAL */ _solo_safe_control->Changed(); /* EMIT SIGNAL */ } } @@ -893,7 +893,8 @@ Route::clear_all_solo_state () if (emit_changed) { set_mute_master_solo (); - solo_changed (false, Controllable::UseGroup); /* EMIT SIGNAL */ + _session.solo_changed (false, Controllable::UseGroup, shared_from_this()); + _solo_control->Changed (); /* EMIT SIGNAL */ } } @@ -920,7 +921,7 @@ Route::set_solo (bool yn, Controllable::GroupControlDisposition group_override) if (self_soloed() != yn) { set_self_solo (yn); - solo_changed (true, group_override); /* EMIT SIGNAL */ + _session.solo_changed (true, group_override, shared_from_this()); _solo_control->Changed (); /* EMIT SIGNAL */ } @@ -998,7 +999,8 @@ Route::mod_solo_by_others_upstream (int32_t delta) } set_mute_master_solo (); - solo_changed (false, Controllable::UseGroup); /* EMIT SIGNAL */ + _session.solo_changed (false, Controllable::UseGroup, shared_from_this()); + _solo_control->Changed (); /* EMIT SIGNAL */ } void @@ -1020,7 +1022,8 @@ 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, Controllable::UseGroup); /* EMIT SIGNAL */ + _session.solo_changed (false, Controllable::UseGroup, shared_from_this()); + _solo_control->Changed (); /* EMIT SIGNAL */ } void @@ -1050,7 +1053,8 @@ Route::mod_solo_isolated_by_upstream (bool yn) if (solo_isolated() != old) { /* solo isolated status changed */ _mute_master->set_solo_ignore (solo_isolated()); - solo_isolated_changed (); /* EMIT SIGNAL */ + _session.solo_isolated_changed (shared_from_this()); + _solo_isolate_control->Changed(); /* EMIT SIGNAL */ } } @@ -1106,7 +1110,7 @@ Route::set_solo_isolated (bool yn, Controllable::GroupControlDisposition group_o /* XXX should we back-propagate as well? (April 2010: myself and chris goddard think not) */ - solo_isolated_changed (); /* EMIT SIGNAL */ + _session.solo_isolated_changed (shared_from_this()); _solo_isolate_control->Changed(); /* EMIT SIGNAL */ } @@ -1123,7 +1127,7 @@ Route::set_mute_points (MuteMaster::MutePoint mp) mute_points_changed (); /* EMIT SIGNAL */ if (_mute_master->muted_by_self()) { - mute_changed (); /* EMIT SIGNAL */ + _session.mute_changed (); _mute_control->Changed (); /* EMIT SIGNAL */ } } @@ -1143,7 +1147,7 @@ Route::set_mute (bool yn, Controllable::GroupControlDisposition group_override) */ act_on_mute (); /* tell everyone else */ - mute_changed (); /* EMIT SIGNAL */ + _session.mute_changed (); _mute_control->Changed (); /* EMIT SIGNAL */ } } @@ -4643,7 +4647,6 @@ Route::set_phase_invert (uint32_t c, bool yn) { if (_phase_invert[c] != yn) { _phase_invert[c] = yn; - phase_invert_changed (); /* EMIT SIGNAL */ _phase_control->Changed(); /* EMIT SIGNAL */ _session.set_dirty (); } @@ -4654,7 +4657,7 @@ Route::set_phase_invert (boost::dynamic_bitset<> p) { if (_phase_invert != p) { _phase_invert = p; - phase_invert_changed (); /* EMIT SIGNAL */ + _phase_control->Changed (); /* EMIT SIGNAL */ _session.set_dirty (); } } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 86d698a2cb..417edf83b7 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3411,10 +3411,12 @@ 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->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, wpr)); - r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this)); + /* we don't connect to control Changed signals for + * solo/mute/listen. The Route calls back to use, via + * the SessionSoloNotifications API, passing us more + * information than would be available from a control Changed signal. + */ + r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2)); r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1)); @@ -3692,20 +3694,14 @@ Session::remove_route (boost::shared_ptr route) } void -Session::route_mute_changed () +Session::_route_mute_changed () { set_dirty (); } void -Session::route_listen_changed (Controllable::GroupControlDisposition group_override, boost::weak_ptr wpr) +Session::_route_listen_changed (Controllable::GroupControlDisposition group_override, boost::shared_ptr route) { - boost::shared_ptr route = wpr.lock(); - if (!route) { - error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_listen_changed")) << endmsg; - return; - } - if (route->listening_via_monitor ()) { if (Config->get_exclusive_solo()) { @@ -3747,17 +3743,10 @@ Session::route_listen_changed (Controllable::GroupControlDisposition group_overr update_route_solo_state (); } + void -Session::route_solo_isolated_changed (boost::weak_ptr wpr) +Session::_route_solo_isolated_changed (boost::shared_ptr route) { - boost::shared_ptr route = wpr.lock (); - - if (!route) { - /* should not happen */ - error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_isolated_changed")) << endmsg; - return; - } - bool send_changed = false; if (route->solo_isolated()) { @@ -3778,7 +3767,7 @@ Session::route_solo_isolated_changed (boost::weak_ptr wpr) } void -Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::weak_ptr wpr) +Session::_route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::shared_ptr route) { DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change)); @@ -3787,9 +3776,6 @@ Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDi return; } - boost::shared_ptr route = wpr.lock (); - assert (route); - boost::shared_ptr r = routes.reader (); int32_t delta; @@ -3938,7 +3924,7 @@ Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDi for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) { DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name())); (*i)->act_on_mute (); - (*i)->mute_changed (); + (*i)->mute_control()->Changed (); /* EMIT SIGNAL */ } SoloChanged (); /* EMIT SIGNAL */ -- cgit v1.2.3