rearrange AutomationControl and RouteAutomationControl to get more shared logic and consistent master/slave behaviour
This commit is contained in:
parent
91f8c0be54
commit
8eb45c518d
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -69,6 +69,31 @@ AutomationControl::writable() const
|
||||
return true;
|
||||
}
|
||||
|
||||
double
|
||||
AutomationControl::get_masters_value_locked () const
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
double
|
||||
AutomationControl::get_value_locked() const
|
||||
{
|
||||
/* read or write masters lock must be held */
|
||||
|
||||
if (_masters.empty()) {
|
||||
return Control::get_double (false, _session.transport_frame());
|
||||
}
|
||||
|
||||
return get_masters_value_locked ();
|
||||
}
|
||||
|
||||
/** Get the current effective `user' value based on automation state */
|
||||
double
|
||||
AutomationControl::get_value() const
|
||||
@ -83,27 +108,6 @@ AutomationControl::get_value() const
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
AutomationControl::get_value_locked() const
|
||||
{
|
||||
/* read or write masters lock must be held */
|
||||
|
||||
if (_masters.empty()) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Set the value and do the right thing based on automation state
|
||||
* (e.g. record if necessary, etc.)
|
||||
* @param value `user' value
|
||||
@ -358,4 +362,3 @@ AutomationControl::slaved () const
|
||||
Glib::Threads::RWLock::ReaderLock lm (master_lock);
|
||||
return !_masters.empty();
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user