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
This commit is contained in:
parent
8eb45c518d
commit
1c0c9b40b7
|
@ -350,14 +350,8 @@ public:
|
|||
framecnt_t signal_latency() const { return _signal_latency; }
|
||||
|
||||
PBD::Signal0<void> active_changed;
|
||||
PBD::Signal0<void> phase_invert_changed;
|
||||
PBD::Signal0<void> denormal_protection_changed;
|
||||
PBD::Signal1<void,PBD::Controllable::GroupControlDisposition> listen_changed;
|
||||
PBD::Signal2<void,bool,PBD::Controllable::GroupControlDisposition> solo_changed;
|
||||
PBD::Signal0<void> solo_safe_changed;
|
||||
PBD::Signal0<void> solo_isolated_changed;
|
||||
PBD::Signal0<void> comment_changed;
|
||||
PBD::Signal0<void> mute_changed;
|
||||
PBD::Signal0<void> mute_points_changed;
|
||||
|
||||
/** track numbers - assigned by session
|
||||
|
|
|
@ -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<Session>
|
||||
{
|
||||
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<Route>);
|
||||
void _route_mute_changed ();
|
||||
void _route_solo_changed (bool self_solo_change, PBD::Controllable::GroupControlDisposition group_override, boost::shared_ptr<Route>);
|
||||
void _route_solo_isolated_changed (boost::shared_ptr<Route>);
|
||||
|
||||
void route_listen_changed (PBD::Controllable::GroupControlDisposition, boost::weak_ptr<Route>);
|
||||
void route_mute_changed ();
|
||||
void route_solo_changed (bool self_solo_change, PBD::Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route>);
|
||||
void route_solo_isolated_changed (boost::weak_ptr<Route>);
|
||||
void update_route_solo_state (boost::shared_ptr<RouteList> r = boost::shared_ptr<RouteList>());
|
||||
|
||||
void listen_position_changed ();
|
||||
|
|
|
@ -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 <boost/shared_ptr.hpp>
|
||||
#include "pbd/controllable.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class Route;
|
||||
|
||||
template<typename T>
|
||||
class SessionSoloNotifications
|
||||
{
|
||||
public:
|
||||
void solo_changed (bool self_solo_change, PBD::Controllable::GroupControlDisposition gcd, boost::shared_ptr<Route> route) {
|
||||
static_cast<T*>(this)->_route_solo_changed (self_solo_change, gcd, route);
|
||||
}
|
||||
|
||||
void listen_changed (PBD::Controllable::GroupControlDisposition gcd, boost::shared_ptr<Route> route) {
|
||||
static_cast<T*>(this)->_route_listen_changed (gcd, route);
|
||||
}
|
||||
|
||||
void mute_changed () {
|
||||
static_cast<T*>(this)->_route_mute_changed ();
|
||||
}
|
||||
|
||||
void solo_isolated_changed (boost::shared_ptr<Route> route) {
|
||||
static_cast<T*>(this)->_route_solo_isolated_changed (route);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
|
||||
#endif /* __libardour_session_solo_notifications_h__ */
|
|
@ -999,4 +999,3 @@ MidiTrack::monitoring_state () const
|
|||
}
|
||||
return ms;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3411,10 +3411,12 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
|
|||
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->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> route)
|
|||
}
|
||||
|
||||
void
|
||||
Session::route_mute_changed ()
|
||||
Session::_route_mute_changed ()
|
||||
{
|
||||
set_dirty ();
|
||||
}
|
||||
|
||||
void
|
||||
Session::route_listen_changed (Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
|
||||
Session::_route_listen_changed (Controllable::GroupControlDisposition group_override, boost::shared_ptr<Route> route)
|
||||
{
|
||||
boost::shared_ptr<Route> 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<Route> wpr)
|
||||
Session::_route_solo_isolated_changed (boost::shared_ptr<Route> route)
|
||||
{
|
||||
boost::shared_ptr<Route> 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<Route> wpr)
|
|||
}
|
||||
|
||||
void
|
||||
Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
|
||||
Session::_route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::shared_ptr<Route> 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> route = wpr.lock ();
|
||||
assert (route);
|
||||
|
||||
boost::shared_ptr<RouteList> 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 */
|
||||
|
|
Loading…
Reference in New Issue