/* session must mediate group control */
rl.reset (new RouteList);
rl->push_back (shared_from_this());
- _session.set_mute (rl, !muted(), Session::rt_cleanup, group_override);
+ _session.set_mute (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
return;
break;
{
}
-Route::RouteAutomationControl::RouteAutomationControl (const std::string& name,
- AutomationType atype,
- const ParameterDescriptor& desc,
- boost::shared_ptr<AutomationList> alist,
- boost::shared_ptr<Route> r)
- : AutomationControl (r->session(), Evoral::Parameter (atype), desc, alist, name)
- , _route (r)
+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)
}
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);
set_list (gl);
}
+void
+Route::SoloControllable::master_changed (bool from_self, PBD::Controllable::GroupControlDisposition gcd)
+{
+ boost::shared_ptr<Route> r = _route.lock ();
+
+ if (!r) {
+ return;
+ }
+
+ bool master_soloed;
+
+ {
+ Glib::Threads::RWLock::ReaderLock lm (master_lock);
+ master_soloed = (bool) get_masters_value_locked ();
+ }
+
+ /* Master is considered equivalent to an upstream solo control, not
+ * direct control over self-soloed.
+ */
+
+ r->mod_solo_by_others_upstream (master_soloed ? 1 : -1);
+
+ AutomationControl::master_changed (false, gcd);
+}
+
void
Route::SoloControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
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;
}
}
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)));
const bool to_list = _list && ((AutomationList*)_list.get ())->automation_write ();
const double where = _session.audible_frame ();
+
if (to_list) {
/* Note that we really need this:
* if (as == Touch && _list->in_new_write_pass ()) {
Control::set_double (muted, where, to_list);
}
+void
+Route::MuteControllable::master_changed (bool from_self, PBD::Controllable::GroupControlDisposition gcd)
+{
+ bool master_muted;
+
+ {
+ Glib::Threads::RWLock::ReaderLock lm (master_lock);
+ master_muted = (bool) get_masters_value_locked ();
+ }
+
+ boost::shared_ptr<Route> r (_route.lock());
+ if (r) {
+ r->mute_master()->mod_muted_by_others (master_muted ? 1 : -1);
+ }
+
+ AutomationControl::master_changed (false, gcd);
+}
+
void
Route::MuteControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
double
Route::MuteControllable::get_value () const
{
+ if (slaved()) {
+ Glib::Threads::RWLock::ReaderLock lm (master_lock);
+ return get_masters_value_locked () ? 1.0 : 0.0;
+ }
+
if (_list && ((AutomationList*)_list.get())->automation_playback()) {
// Playing back automation, get the value from the list
return AutomationControl::get_value();
// Not playing back automation, get the actual route mute value
boost::shared_ptr<Route> r = _route.lock ();
- return (r && r->muted()) ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
+ return (r && r->muted()) ? 1.0 : 0.0;
}
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)));
gl->set_interpolation(Evoral::ControlList::Discrete);
Route::PhaseControllable::get_value () const
{
boost::shared_ptr<Route> r = _route.lock ();
+ if (!r) {
+ return 0.0;
+ }
return (double) r->phase_invert (_current_phase);
}
}
Route::SoloIsolateControllable::SoloIsolateControllable (std::string name, boost::shared_ptr<Route> r)
- : RouteAutomationControl (name, SoloIsolateAutomation, get_descriptor(), 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);
r->set_solo_isolated (val >= 0.5 ? true : false);
}
-ParameterDescriptor
-Route::SoloIsolateControllable::get_descriptor()
-{
- ParameterDescriptor desc;
- desc.type = SoloIsolateAutomation;
- desc.toggled = true;
- return desc;
-}
-
Route::SoloSafeControllable::SoloSafeControllable (std::string name, boost::shared_ptr<Route> r)
- : RouteAutomationControl (name, SoloSafeAutomation, get_descriptor(), 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);
return r->solo_safe() ? 1.0 : 0.0;
}
-
-ParameterDescriptor
-Route::SoloSafeControllable::get_descriptor()
-{
- ParameterDescriptor desc;
- desc.type = SoloSafeAutomation;
- desc.toggled = true;
- return desc;
-}