summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-03-11 10:34:51 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2016-05-31 15:30:40 -0400
commit5531c834963726d5a35db078e17a7508f2b9d72d (patch)
tree79adf0c05ce8a665e2b239579734bc638d704b3b
parent36784ee94f30213ddbf4360b254e27da7d07c56a (diff)
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
-rw-r--r--libs/ardour/ardour/monitor_processor.h6
-rw-r--r--libs/ardour/ardour/proxy_controllable.h2
-rw-r--r--libs/ardour/ardour/route.h1
-rw-r--r--libs/ardour/ardour/session.h14
-rw-r--r--libs/ardour/automation_control.cc39
-rw-r--r--libs/ardour/monitor_processor.cc4
-rw-r--r--libs/ardour/route.cc44
-rw-r--r--libs/ardour/route_controls.cc7
-rw-r--r--libs/ardour/session.cc45
-rw-r--r--libs/ardour/session_state.cc2
-rw-r--r--libs/ardour/track.cc8
-rw-r--r--libs/pbd/pbd/controllable.h2
12 files changed, 110 insertions, 64 deletions
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> _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<Session>
+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<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>());
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<Evoral::ControlList> list)
{
Control::set_list (list);
- Changed(); /* EMIT SIGNAL */
+ Changed (true, Controllable::NoGroup);
}
void
@@ -268,6 +270,7 @@ void
AutomationControl::add_master (boost::shared_ptr<AutomationControl> m)
{
double current_value;
+ double new_value;
std::pair<Masters::iterator,bool> res;
{
@@ -291,15 +294,28 @@ AutomationControl::add_master (boost::shared_ptr<AutomationControl> 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<void>::operator(), &Changed));
+
+ m->Changed.connect_same_thread (res.first->second.connection, boost::bind (&PBD::Signal2<void,bool,Controllable::GroupControlDisposition>::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<AutomationControl> m)
{
double current_value;
+ double new_value;
Masters::size_type erased = 0;
{
@@ -324,29 +341,43 @@ AutomationControl::remove_master (boost::shared_ptr<AutomationControl> 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<bool>::set_value (double v, PBD::Controllable::GroupControlDisposition /*group_override*/) {
+ template<> void MPControl<bool>::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<Route> wpr (*x);
boost::shared_ptr<Route> 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> 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> route)
+Session::route_listen_changed (Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
{
+ boost::shared_ptr<Route> 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> route)
+Session::route_solo_isolated_changed (boost::weak_ptr<Route> wpr)
{
+ boost::shared_ptr<Route> 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> route)
}
void
-Session::_route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::shared_ptr<Route> route)
+Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> 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> 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);
}
}
diff --git a/libs/pbd/pbd/controllable.h b/libs/pbd/pbd/controllable.h
index cd26ff019f..078671c91b 100644
--- a/libs/pbd/pbd/controllable.h
+++ b/libs/pbd/pbd/controllable.h
@@ -126,7 +126,7 @@ class LIBPBD_API Controllable : public PBD::StatefulDestructible {
static PBD::Signal1<void,Controllable*> Destroyed;
- PBD::Signal0<void> Changed;
+ PBD::Signal2<void,bool,PBD::Controllable::GroupControlDisposition> Changed;
int set_state (const XMLNode&, int version);
XMLNode& get_state ();