From 5531c834963726d5a35db078e17a7508f2b9d72d Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 11 Mar 2016 10:34:51 -0500 Subject: change API of Controllable::Changed signal to include (from_self, GroupControlDisposition) This allows the signal to convey more information, which may be required by some handlers of a control's Changed signal --- libs/ardour/ardour/monitor_processor.h | 6 ++--- libs/ardour/ardour/proxy_controllable.h | 2 +- libs/ardour/ardour/route.h | 1 - libs/ardour/ardour/session.h | 14 +++++----- libs/ardour/automation_control.cc | 39 +++++++++++++++++++++++++--- libs/ardour/monitor_processor.cc | 4 +-- libs/ardour/route.cc | 44 +++++++++++++------------------- libs/ardour/route_controls.cc | 7 +++-- libs/ardour/session.cc | 45 +++++++++++++++++++++++++-------- libs/ardour/session_state.cc | 2 +- libs/ardour/track.cc | 8 +++--- 11 files changed, 109 insertions(+), 63 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/ardour/monitor_processor.h b/libs/ardour/ardour/monitor_processor.h index e971d0a018..cef12b33d9 100644 --- a/libs/ardour/ardour/monitor_processor.h +++ b/libs/ardour/ardour/monitor_processor.h @@ -54,11 +54,11 @@ public: /* Controllable API */ - void set_value (double v, PBD::Controllable::GroupControlDisposition group_override) { + void set_value (double v, PBD::Controllable::GroupControlDisposition gcd) { T newval = (T) v; if (newval != _value) { _value = std::max (_lower, std::min (_upper, newval)); - Changed(); /* EMIT SIGNAL */ + Changed (true, gcd); /* EMIT SIGNAL */ } } @@ -84,7 +84,7 @@ public: MPControl& operator=(const T& v) { if (v != _value) { _value = std::max (_lower, std::min (_upper, v)); - Changed (); /* EMIT SIGNAL */ + Changed (true, PBD::Controllable::UseGroup); /* EMIT SIGNAL */ } return *this; } diff --git a/libs/ardour/ardour/proxy_controllable.h b/libs/ardour/ardour/proxy_controllable.h index c60f5f1b74..22761d7dba 100644 --- a/libs/ardour/ardour/proxy_controllable.h +++ b/libs/ardour/ardour/proxy_controllable.h @@ -40,7 +40,7 @@ class LIBARDOUR_API ProxyControllable : public PBD::Controllable { , _getter (getter) {} - void set_value (double v, PBD::Controllable::GroupControlDisposition /*group_override*/) { if (_setter (v)) { Changed(); /* EMIT SIGNAL */ } } + void set_value (double v, PBD::Controllable::GroupControlDisposition gcd) { if (_setter (v)) { Changed (true, gcd); /* EMIT SIGNAL */ } } double get_value () const { return _getter (); } double internal_to_user (double i) const { return accurate_coefficient_to_dB (i);} diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index b976e63c69..0afafe82eb 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -526,7 +526,6 @@ public: /* Pretend to change value, but do not affect actual route mute. */ void set_superficial_value(bool muted); - private: boost::weak_ptr _route; void _set_value (double, PBD::Controllable::GroupControlDisposition group_override); diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index b3852b631d..18507ee5d9 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -67,7 +67,6 @@ #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" @@ -166,7 +165,7 @@ private: }; /** Ardour Session */ -class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager, public SessionSoloNotifications +class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager { public: enum RecordState { @@ -1684,13 +1683,12 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop void reassign_track_numbers (); uint32_t _track_number_decimals; - /* solo/mute/notifications (see SessionSoloNotifications object) */ + /* solo/mute/notifications */ - 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()); diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index d7b645d8ae..2ac6574528 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -113,20 +113,22 @@ AutomationControl::get_value() const * @param value `user' value */ void -AutomationControl::set_value (double value, PBD::Controllable::GroupControlDisposition /* group_override */) +AutomationControl::set_value (double value, PBD::Controllable::GroupControlDisposition gcd) { bool to_list = _list && ((AutomationList*)_list.get())->automation_write(); Control::set_double (value, _session.transport_frame(), to_list); - Changed(); /* EMIT SIGNAL */ + cerr << "AC was set to " << value << endl; + + Changed (true, gcd); } void AutomationControl::set_list (boost::shared_ptr list) { Control::set_list (list); - Changed(); /* EMIT SIGNAL */ + Changed (true, Controllable::NoGroup); } void @@ -268,6 +270,7 @@ void AutomationControl::add_master (boost::shared_ptr m) { double current_value; + double new_value; std::pair res; { @@ -291,15 +294,28 @@ AutomationControl::add_master (boost::shared_ptr m) /* Store the connection inside the MasterRecord, so that when we destroy it, the connection is destroyed and we no longer hear about changes to the AutomationControl. + + Note that we fix the "from_self" argument that will + be given to our own Changed signal to "false", + because the change came from the master. */ - m->Changed.connect_same_thread (res.first->second.connection, boost::bind (&PBD::Signal0::operator(), &Changed)); + + m->Changed.connect_same_thread (res.first->second.connection, boost::bind (&PBD::Signal2::operator(), &Changed, false, _2)); } + + new_value = get_value_locked (); } if (res.second) { MasterStatusChange (); /* EMIT SIGNAL */ } + + if (new_value != current_value) { + /* effective value changed by master */ + Changed (false, Controllable::NoGroup); + } + } void @@ -315,6 +331,7 @@ void AutomationControl::remove_master (boost::shared_ptr m) { double current_value; + double new_value; Masters::size_type erased = 0; { @@ -324,29 +341,43 @@ AutomationControl::remove_master (boost::shared_ptr m) if (erased) { recompute_masters_ratios (current_value); } + new_value = get_value_locked (); } if (erased) { MasterStatusChange (); /* EMIT SIGNAL */ } + + if (new_value != current_value) { + Changed (false, Controllable::NoGroup); + } } void AutomationControl::clear_masters () { + double current_value; + double new_value; bool had_masters = false; { Glib::Threads::RWLock::WriterLock lm (master_lock); + current_value = get_value_locked (); if (!_masters.empty()) { had_masters = true; } _masters.clear (); + new_value = get_value_locked (); } if (had_masters) { MasterStatusChange (); /* EMIT SIGNAL */ } + + if (new_value != current_value) { + Changed (false, Controllable::NoGroup); + } + } bool diff --git a/libs/ardour/monitor_processor.cc b/libs/ardour/monitor_processor.cc index c7a79ee2f5..e5c58009af 100644 --- a/libs/ardour/monitor_processor.cc +++ b/libs/ardour/monitor_processor.cc @@ -37,11 +37,11 @@ using namespace std; /* specialize for bool because of set_value() semantics */ namespace ARDOUR { - template<> void MPControl::set_value (double v, PBD::Controllable::GroupControlDisposition /*group_override*/) { + template<> void MPControl::set_value (double v, PBD::Controllable::GroupControlDisposition gcd) { bool newval = fabs (v) >= 0.5; if (newval != _value) { _value = newval; - Changed(); /* EMIT SIGNAL */ + Changed (true, gcd); /* EMIT SIGNAL */ } } } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 569f00fbc7..c9b9aff3ac 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -416,9 +416,9 @@ Route::inc_gain (gain_t factor) } void -Route::set_gain (gain_t val, Controllable::GroupControlDisposition group_override) +Route::set_gain (gain_t val, Controllable::GroupControlDisposition gcd) { - if (use_group (group_override, &RouteGroup::is_gain)) { + if (use_group (gcd, &RouteGroup::is_gain)) { if (_route_group->is_relative()) { @@ -442,13 +442,13 @@ Route::set_gain (gain_t val, Controllable::GroupControlDisposition group_overrid if (factor > 0.0f) { factor = _route_group->get_max_factor(factor); if (factor == 0.0f) { - _amp->gain_control()->Changed(); /* EMIT SIGNAL */ + _amp->gain_control()->Changed (true, gcd); /* EMIT SIGNAL */ return; } } else { factor = _route_group->get_min_factor(factor); if (factor == 0.0f) { - _amp->gain_control()->Changed(); /* EMIT SIGNAL */ + _amp->gain_control()->Changed (true, gcd); /* EMIT SIGNAL */ return; } } @@ -830,8 +830,8 @@ Route::set_listen (bool yn, Controllable::GroupControlDisposition group_override } _mute_master->set_soloed_by_others (false); - _session.listen_changed (group_override, shared_from_this()); - _solo_control->Changed(); /* EMIT SIGNAL */ + /* first argument won't matter because solo <=> listen right now */ + _solo_control->Changed (false, group_override); /* EMIT SIGNAL */ } } } @@ -847,11 +847,11 @@ Route::listening_via_monitor () const } void -Route::set_solo_safe (bool yn, Controllable::GroupControlDisposition /* group_override */) +Route::set_solo_safe (bool yn, Controllable::GroupControlDisposition gcd) { if (_solo_safe != yn) { _solo_safe = yn; - _solo_safe_control->Changed(); /* EMIT SIGNAL */ + _solo_safe_control->Changed (true, gcd); /* EMIT SIGNAL */ } } @@ -893,8 +893,7 @@ Route::clear_all_solo_state () if (emit_changed) { set_mute_master_solo (); - _session.solo_changed (false, Controllable::UseGroup, shared_from_this()); - _solo_control->Changed (); /* EMIT SIGNAL */ + _solo_control->Changed (false, Controllable::UseGroup); /* EMIT SIGNAL */ } } @@ -921,8 +920,7 @@ Route::set_solo (bool yn, Controllable::GroupControlDisposition group_override) if (self_soloed() != yn) { set_self_solo (yn); - _session.solo_changed (true, group_override, shared_from_this()); - _solo_control->Changed (); /* EMIT SIGNAL */ + _solo_control->Changed (true, group_override); /* EMIT SIGNAL */ } assert (Config->get_solo_control_is_listen_control() || !_monitor_send || !_monitor_send->active()); @@ -999,8 +997,7 @@ Route::mod_solo_by_others_upstream (int32_t delta) } set_mute_master_solo (); - _session.solo_changed (false, Controllable::UseGroup, shared_from_this()); - _solo_control->Changed (); /* EMIT SIGNAL */ + _solo_control->Changed (false, Controllable::UseGroup); /* EMIT SIGNAL */ } void @@ -1022,8 +1019,7 @@ 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 (); - _session.solo_changed (false, Controllable::UseGroup, shared_from_this()); - _solo_control->Changed (); /* EMIT SIGNAL */ + _solo_control->Changed (false, Controllable::UseGroup); /* EMIT SIGNAL */ } void @@ -1053,8 +1049,7 @@ Route::mod_solo_isolated_by_upstream (bool yn) if (solo_isolated() != old) { /* solo isolated status changed */ _mute_master->set_solo_ignore (solo_isolated()); - _session.solo_isolated_changed (shared_from_this()); - _solo_isolate_control->Changed(); /* EMIT SIGNAL */ + _solo_isolate_control->Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */ } } @@ -1110,8 +1105,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) */ - _session.solo_isolated_changed (shared_from_this()); - _solo_isolate_control->Changed(); /* EMIT SIGNAL */ + _solo_isolate_control->Changed (true, group_override); /* EMIT SIGNAL */ } bool @@ -1127,8 +1121,7 @@ Route::set_mute_points (MuteMaster::MutePoint mp) mute_points_changed (); /* EMIT SIGNAL */ if (_mute_master->muted_by_self()) { - _session.mute_changed (); - _mute_control->Changed (); /* EMIT SIGNAL */ + _mute_control->Changed (true, Controllable::UseGroup); /* EMIT SIGNAL */ } } @@ -1147,8 +1140,7 @@ Route::set_mute (bool yn, Controllable::GroupControlDisposition group_override) */ act_on_mute (); /* tell everyone else */ - _session.mute_changed (); - _mute_control->Changed (); /* EMIT SIGNAL */ + _mute_control->Changed (true, Controllable::NoGroup); /* EMIT SIGNAL */ } } @@ -4647,7 +4639,7 @@ Route::set_phase_invert (uint32_t c, bool yn) { if (_phase_invert[c] != yn) { _phase_invert[c] = yn; - _phase_control->Changed(); /* EMIT SIGNAL */ + _phase_control->Changed (true, Controllable::NoGroup); /* EMIT SIGNAL */ _session.set_dirty (); } } @@ -4657,7 +4649,7 @@ Route::set_phase_invert (boost::dynamic_bitset<> p) { if (_phase_invert != p) { _phase_invert = p; - _phase_control->Changed (); /* EMIT SIGNAL */ + _phase_control->Changed (true, Controllable::NoGroup); /* EMIT SIGNAL */ _session.set_dirty (); } } diff --git a/libs/ardour/route_controls.cc b/libs/ardour/route_controls.cc index 0e6edec758..5992014563 100644 --- a/libs/ardour/route_controls.cc +++ b/libs/ardour/route_controls.cc @@ -158,9 +158,13 @@ Route::SoloControllable::set_value_unchecked (double val) double Route::SoloControllable::get_value () const { + std::cerr << "RSC get value\n"; + if (slaved()) { + std::cerr << "slaved solo control, get master value ... "; Glib::Threads::RWLock::ReaderLock lm (master_lock); - return get_masters_value_locked () ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO; + double v = get_masters_value_locked () ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO; + std::cerr << v << std::endl; } if (_list && ((AutomationList*)_list.get())->automation_playback()) { @@ -385,4 +389,3 @@ Route::SoloSafeControllable::get_value () const return r->solo_safe() ? 1.0 : 0.0; } - diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 417edf83b7..ee70d2a40f 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3411,12 +3411,10 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool boost::weak_ptr wpr (*x); boost::shared_ptr r (*x); - /* 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->solo_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr)); + r->solo_isolate_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, wpr)); + r->mute_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this)); + 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)); @@ -3694,14 +3692,20 @@ 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::shared_ptr route) +Session::route_listen_changed (Controllable::GroupControlDisposition group_override, boost::weak_ptr wpr) { + boost::shared_ptr route (wpr.lock()); + + if (!route) { + return; + } + if (route->listening_via_monitor ()) { if (Config->get_exclusive_solo()) { @@ -3745,8 +3749,14 @@ Session::_route_listen_changed (Controllable::GroupControlDisposition group_over } void -Session::_route_solo_isolated_changed (boost::shared_ptr route) +Session::route_solo_isolated_changed (boost::weak_ptr wpr) { + boost::shared_ptr route (wpr.lock()); + + if (!route) { + return; + } + bool send_changed = false; if (route->solo_isolated()) { @@ -3767,10 +3777,23 @@ Session::_route_solo_isolated_changed (boost::shared_ptr route) } void -Session::_route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::shared_ptr route) +Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::weak_ptr wpr) { + cerr << "route solo change (self ? " << self_solo_change << endl; + DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change)); + boost::shared_ptr route (wpr.lock()); + + if (!route) { + return; + } + + if (Config->get_solo_control_is_listen_control()) { + route_listen_changed (group_override, wpr); + return; + } + if (!self_solo_change) { // session doesn't care about changes to soloed-by-others return; @@ -3924,7 +3947,7 @@ Session::_route_solo_changed (bool self_solo_change, Controllable::GroupControlD 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_control()->Changed (); /* EMIT SIGNAL */ + (*i)->mute_control()->Changed (false, Controllable::NoGroup); } SoloChanged (); /* EMIT SIGNAL */ diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 45d6f6efce..4d5ffbffa7 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -3875,7 +3875,7 @@ Session::config_changed (std::string p, bool ours) } else if (p == "solo-control-is-listen-control") { solo_control_mode_changed (); } else if (p == "solo-mute-gain") { - _solo_cut_control->Changed(); + _solo_cut_control->Changed (true, Controllable::NoGroup); } else if (p == "timecode-offset" || p == "timecode-offset-negative") { last_timecode_valid = false; } else if (p == "playback-buffer-seconds") { diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 414f545f72..8aebf09259 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -291,7 +291,7 @@ Track::prep_record_enabled (bool yn, Controllable::GroupControlDisposition group } void -Track::set_record_enabled (bool yn, Controllable::GroupControlDisposition group_override) +Track::set_record_enabled (bool yn, Controllable::GroupControlDisposition gcd) { if (_diskstream->record_safe ()) { return; @@ -305,14 +305,14 @@ Track::set_record_enabled (bool yn, Controllable::GroupControlDisposition group_ return; } - if (use_group (group_override, &RouteGroup::is_recenable)) { + if (use_group (gcd, &RouteGroup::is_recenable)) { _route_group->apply (&Track::set_record_enabled, yn, Controllable::NoGroup); return; } _diskstream->set_record_enabled (yn); - _rec_enable_control->Changed (); + _rec_enable_control->Changed (true, gcd); } bool @@ -1151,7 +1151,7 @@ Track::set_monitoring (MonitorChoice mc, Controllable::GroupControlDisposition g } MonitoringChanged (); /* EMIT SIGNAL */ - _monitoring_control->Changed (); /* EMIT SIGNAL */ + _monitoring_control->Changed (true, gcd); } } -- cgit v1.2.3