diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2016-03-09 10:26:09 -0500 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2016-05-31 15:30:40 -0400 |
commit | 8eb45c518dd61594ca059c3751ca9de0f71ecb15 (patch) | |
tree | 37ccef2cbb6bd620aaebf7ebbcc91a5aced37a9b | |
parent | 91f8c0be5424b615a33ef3e6e418ba3a1ace4613 (diff) |
rearrange AutomationControl and RouteAutomationControl to get more shared logic and consistent master/slave behaviour
-rw-r--r-- | libs/ardour/ardour/automation_control.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 22 | ||||
-rw-r--r-- | libs/ardour/automation_control.cc | 37 | ||||
-rw-r--r-- | libs/ardour/route.cc | 12 | ||||
-rw-r--r-- | libs/ardour/route_controls.cc | 46 |
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); |