summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-03-09 10:26:09 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2016-05-31 15:30:40 -0400
commit8eb45c518dd61594ca059c3751ca9de0f71ecb15 (patch)
tree37ccef2cbb6bd620aaebf7ebbcc91a5aced37a9b
parent91f8c0be5424b615a33ef3e6e418ba3a1ace4613 (diff)
rearrange AutomationControl and RouteAutomationControl to get more shared logic and consistent master/slave behaviour
-rw-r--r--libs/ardour/ardour/automation_control.h1
-rw-r--r--libs/ardour/ardour/route.h22
-rw-r--r--libs/ardour/automation_control.cc37
-rw-r--r--libs/ardour/route.cc12
-rw-r--r--libs/ardour/route_controls.cc46
5 files changed, 86 insertions, 32 deletions
diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h
index de476288f0..9462a79748 100644
--- a/libs/ardour/ardour/automation_control.h
+++ b/libs/ardour/ardour/automation_control.h
@@ -158,6 +158,7 @@ public:
void master_going_away (boost::weak_ptr<AutomationControl>);
virtual void recompute_masters_ratios (double val) { /* do nothing by default */}
+ virtual double get_masters_value_locked () const;
double get_value_locked() const;
};
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index f819ddac63..8902665170 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -477,6 +477,18 @@ public:
boost::weak_ptr<Route> _route;
};
+ class BooleanRouteAutomationControl : public RouteAutomationControl {
+ public:
+ BooleanRouteAutomationControl (const std::string& name,
+ AutomationType atype,
+ boost::shared_ptr<AutomationList> alist,
+ boost::shared_ptr<Route> route)
+ : RouteAutomationControl (name, atype, alist, route) {}
+ protected:
+ double get_masters_value_locked() const;
+
+ };
+
class GainControllable : public GainControl {
public:
GainControllable (Session& session,
@@ -501,7 +513,7 @@ public:
boost::weak_ptr<Route> _route;
};
- class SoloControllable : public RouteAutomationControl {
+ class SoloControllable : public BooleanRouteAutomationControl {
public:
SoloControllable (std::string name, boost::shared_ptr<Route>);
void set_value (double, PBD::Controllable::GroupControlDisposition group_override);
@@ -511,7 +523,7 @@ public:
void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
- struct MuteControllable : public RouteAutomationControl {
+ struct MuteControllable : public BooleanRouteAutomationControl {
public:
MuteControllable (std::string name, boost::shared_ptr<Route>);
void set_value (double, PBD::Controllable::GroupControlDisposition group_override);
@@ -526,7 +538,7 @@ public:
void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
- class LIBARDOUR_API PhaseControllable : public RouteAutomationControl {
+ class LIBARDOUR_API PhaseControllable : public BooleanRouteAutomationControl {
public:
PhaseControllable (std::string name, boost::shared_ptr<Route>);
void set_value (double, PBD::Controllable::GroupControlDisposition group_override);
@@ -539,7 +551,7 @@ public:
void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
- class LIBARDOUR_API SoloIsolateControllable : public RouteAutomationControl {
+ class LIBARDOUR_API SoloIsolateControllable : public BooleanRouteAutomationControl {
public:
SoloIsolateControllable (std::string name, boost::shared_ptr<Route>);
void set_value (double, PBD::Controllable::GroupControlDisposition group_override);
@@ -549,7 +561,7 @@ public:
void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
- class LIBARDOUR_API SoloSafeControllable : public RouteAutomationControl {
+ class LIBARDOUR_API SoloSafeControllable : public BooleanRouteAutomationControl {
public:
SoloSafeControllable (std::string name, boost::shared_ptr<Route>);
void set_value (double, PBD::Controllable::GroupControlDisposition group_override);
diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc
index 4317a18788..d7b645d8ae 100644
--- a/libs/ardour/automation_control.cc
+++ b/libs/ardour/automation_control.cc
@@ -69,18 +69,17 @@ AutomationControl::writable() const
return true;
}
-/** Get the current effective `user' value based on automation state */
double
-AutomationControl::get_value() const
+AutomationControl::get_masters_value_locked () const
{
- bool from_list = _list && ((AutomationList*)_list.get())->automation_playback();
+ gain_t v = 1.0;
- if (!from_list) {
- Glib::Threads::RWLock::ReaderLock lm (master_lock);
- return get_value_locked ();
- } else {
- return Control::get_double (from_list, _session.transport_frame());
+ for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
+ /* get current master value, scale by our current ratio with that master */
+ v *= mr->second.master()->get_value () * mr->second.ratio();
}
+
+ return min (_desc.upper, v);
}
double
@@ -92,17 +91,22 @@ AutomationControl::get_value_locked() const
return Control::get_double (false, _session.transport_frame());
}
- gain_t v = 1.0;
-
- for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
- /* get current master value, scale by our current ratio with that master */
- v *= mr->second.master()->get_value () * mr->second.ratio();
- }
-
- return min (_desc.upper, v);
+ return get_masters_value_locked ();
}
+/** Get the current effective `user' value based on automation state */
+double
+AutomationControl::get_value() const
+{
+ bool from_list = _list && ((AutomationList*)_list.get())->automation_playback();
+ if (!from_list) {
+ Glib::Threads::RWLock::ReaderLock lm (master_lock);
+ return get_value_locked ();
+ } else {
+ return Control::get_double (from_list, _session.transport_frame());
+ }
+}
/** Set the value and do the right thing based on automation state
* (e.g. record if necessary, etc.)
@@ -358,4 +362,3 @@ AutomationControl::slaved () const
Glib::Threads::RWLock::ReaderLock lm (master_lock);
return !_masters.empty();
}
-
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 641bc8ef83..94111e602e 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -5899,8 +5899,8 @@ void
Route::vca_assign (boost::shared_ptr<VCA> vca)
{
_gain_control->add_master (vca->gain_control());
- vca->add_solo_target (shared_from_this());
- vca->add_mute_target (shared_from_this());
+ _solo_control->add_master (vca->solo_control());
+ _mute_control->add_master (vca->mute_control());
}
void
@@ -5909,10 +5909,12 @@ Route::vca_unassign (boost::shared_ptr<VCA> vca)
if (!vca) {
/* unassign from all */
_gain_control->clear_masters ();
- /* XXXX need to remove from solo/mute target lists */
+ _solo_control->clear_masters ();
+ _mute_control->clear_masters ();
} else {
_gain_control->remove_master (vca->gain_control());
- vca->remove_solo_target (shared_from_this());
- vca->remove_mute_target (shared_from_this());
+ _solo_control->remove_master (vca->solo_control());
+ _mute_control->remove_master (vca->mute_control());
+
}
}
diff --git a/libs/ardour/route_controls.cc b/libs/ardour/route_controls.cc
index 5ab7524f84..0e6edec758 100644
--- a/libs/ardour/route_controls.cc
+++ b/libs/ardour/route_controls.cc
@@ -94,6 +94,26 @@ Route::RouteAutomationControl::RouteAutomationControl (const std::string& name,
{
}
+double
+Route::BooleanRouteAutomationControl::get_masters_value_locked () const
+{
+ /* masters (read/write) lock must be held */
+
+ /* if any master is enabled (val > 0.0) then we consider the master
+ value to be 1.0
+ */
+
+ for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
+ if (mr->second.master()->get_value()) {
+ return 1.0;
+ }
+ }
+
+ return 0.0;
+}
+
+
+
Route::GainControllable::GainControllable (Session& s, AutomationType atype, boost::shared_ptr<Route> r)
: GainControl (s, Evoral::Parameter(atype))
, _route (r)
@@ -102,7 +122,7 @@ Route::GainControllable::GainControllable (Session& s, AutomationType atype, boo
}
Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<Route> r)
- : RouteAutomationControl (name, SoloAutomation, boost::shared_ptr<AutomationList>(), r)
+ : BooleanRouteAutomationControl (name, SoloAutomation, boost::shared_ptr<AutomationList>(), r)
{
boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloAutomation)));
gl->set_interpolation(Evoral::ControlList::Discrete);
@@ -138,7 +158,18 @@ Route::SoloControllable::set_value_unchecked (double val)
double
Route::SoloControllable::get_value () const
{
+ if (slaved()) {
+ Glib::Threads::RWLock::ReaderLock lm (master_lock);
+ return get_masters_value_locked () ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
+ }
+
+ if (_list && ((AutomationList*)_list.get())->automation_playback()) {
+ // Playing back automation, get the value from the list
+ return AutomationControl::get_value();
+ }
+
boost::shared_ptr<Route> r = _route.lock ();
+
if (!r) {
return 0;
}
@@ -151,7 +182,7 @@ Route::SoloControllable::get_value () const
}
Route::MuteControllable::MuteControllable (std::string name, boost::shared_ptr<Route> r)
- : RouteAutomationControl (name, MuteAutomation, boost::shared_ptr<AutomationList>(), r)
+ : BooleanRouteAutomationControl (name, MuteAutomation, boost::shared_ptr<AutomationList>(), r)
, _route (r)
{
boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MuteAutomation)));
@@ -221,6 +252,11 @@ Route::MuteControllable::_set_value (double val, Controllable::GroupControlDispo
double
Route::MuteControllable::get_value () const
{
+ if (slaved()) {
+ Glib::Threads::RWLock::ReaderLock lm (master_lock);
+ return get_masters_value_locked () ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
+ }
+
if (_list && ((AutomationList*)_list.get())->automation_playback()) {
// Playing back automation, get the value from the list
return AutomationControl::get_value();
@@ -232,7 +268,7 @@ Route::MuteControllable::get_value () const
}
Route::PhaseControllable::PhaseControllable (std::string name, boost::shared_ptr<Route> r)
- : RouteAutomationControl (name, PhaseAutomation, boost::shared_ptr<AutomationList>(), r)
+ : BooleanRouteAutomationControl (name, PhaseAutomation, boost::shared_ptr<AutomationList>(), r)
, _current_phase (0)
{
boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(PhaseAutomation)));
@@ -276,7 +312,7 @@ Route::PhaseControllable::channel () const
}
Route::SoloIsolateControllable::SoloIsolateControllable (std::string name, boost::shared_ptr<Route> r)
- : RouteAutomationControl (name, SoloIsolateAutomation, boost::shared_ptr<AutomationList>(), r)
+ : BooleanRouteAutomationControl (name, SoloIsolateAutomation, boost::shared_ptr<AutomationList>(), r)
{
boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloIsolateAutomation)));
gl->set_interpolation(Evoral::ControlList::Discrete);
@@ -314,7 +350,7 @@ Route::SoloIsolateControllable::_set_value (double val, PBD::Controllable::Group
}
Route::SoloSafeControllable::SoloSafeControllable (std::string name, boost::shared_ptr<Route> r)
- : RouteAutomationControl (name, SoloSafeAutomation, boost::shared_ptr<AutomationList>(), r)
+ : BooleanRouteAutomationControl (name, SoloSafeAutomation, boost::shared_ptr<AutomationList>(), r)
{
boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloSafeAutomation)));
gl->set_interpolation(Evoral::ControlList::Discrete);