provide route solo isolate and solo safe automation controls
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 1 Feb 2016 02:49:18 +0000 (21:49 -0500)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 1 Feb 2016 02:49:18 +0000 (21:49 -0500)
libs/ardour/ardour/route.h
libs/ardour/route.cc
libs/ardour/route_controls.cc

index a75ef5f6a63ec603fcff229b15ae180e7fc75295..dce7caed02b73eb08a8dd81e360391b4adf8f6ad 100644 (file)
@@ -417,6 +417,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
                void set_value (double val, PBD::Controllable::GroupControlDisposition group_override) {
                        boost::shared_ptr<Route> r = _route.lock();
                        if (r) {
+                               /* Route must mediate group control */
                                r->set_control ((AutomationType) parameter().type(), val, group_override);
                        }
                }
@@ -469,6 +470,28 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
                void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
        };
 
+       class LIBARDOUR_API SoloIsolateControllable : public RouteAutomationControl {
+       public:
+               SoloIsolateControllable (std::string name, boost::shared_ptr<Route>);
+               void set_value (double, PBD::Controllable::GroupControlDisposition group_override);
+               /* currently no automation, so no need for set_value_unchecked() */
+               double get_value () const;
+       private:
+               void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
+               static ParameterDescriptor get_descriptor ();
+       };
+
+       class LIBARDOUR_API SoloSafeControllable : public RouteAutomationControl {
+       public:
+               SoloSafeControllable (std::string name, boost::shared_ptr<Route>);
+               void set_value (double, PBD::Controllable::GroupControlDisposition group_override);
+               /* currently no automation, so no need for set_value_unchecked() */
+               double get_value () const;
+       private:
+               void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
+               static ParameterDescriptor get_descriptor ();
+       };
+
        void set_control (AutomationType, double val, PBD::Controllable::GroupControlDisposition group_override);
 
        boost::shared_ptr<SoloControllable> solo_control() const {
@@ -487,6 +510,21 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
                return _phase_control;
        }
 
+       boost::shared_ptr<SoloIsolateControllable> solo_isolate_control() const {
+               return _solo_isolate_control;
+       }
+
+       boost::shared_ptr<SoloSafeControllable> solo_safe_control() const {
+               return _solo_safe_control;
+       }
+
+       boost::shared_ptr<AutomationControl> monitoring_control() const {
+               /* tracks override this to provide actual monitoring control;
+                  busses have no possible choices except input monitoring.
+               */
+               return boost::shared_ptr<AutomationControl> ();
+       }
+
        /* Route doesn't own these items, but sub-objects that it does own have them
           and to make UI code a bit simpler, we provide direct access to them
           here.
@@ -692,6 +730,8 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
        boost::shared_ptr<MuteControllable> _mute_control;
        boost::shared_ptr<MuteMaster> _mute_master;
        boost::shared_ptr<PhaseControllable> _phase_control;
+       boost::shared_ptr<SoloIsolateControllable> _solo_isolate_control;
+       boost::shared_ptr<SoloSafeControllable> _solo_safe_control;
 
        virtual void act_on_mute () {}
 
index da0183304ce4681a89b3fe275ac61f4afb9756b8..4dce24d9fbe45bee27014377e9d0c16644fca485 100644 (file)
@@ -139,6 +139,9 @@ Route::init ()
        _mute_control.reset (new MuteControllable (X_("mute"), shared_from_this ()));
        _phase_control.reset (new PhaseControllable (X_("phase"), shared_from_this ()));
 
+       _solo_isolate_control.reset (new SoloIsolateControllable (X_("solo-iso"), shared_from_this ()));
+       _solo_safe_control.reset (new SoloSafeControllable (X_("solo-safe"), shared_from_this ()));
+
        _solo_control->set_flags (Controllable::Flag (_solo_control->flags() | Controllable::Toggle));
        _mute_control->set_flags (Controllable::Flag (_mute_control->flags() | Controllable::Toggle));
        _phase_control->set_flags (Controllable::Flag (_phase_control->flags() | Controllable::Toggle));
@@ -827,7 +830,8 @@ Route::set_solo_safe (bool yn, Controllable::GroupControlDisposition /* group_ov
 {
        if (_solo_safe != yn) {
                _solo_safe = yn;
-               solo_safe_changed ();
+               solo_safe_changed (); /* EMIT SIGNAL */
+               _solo_safe_control->Changed(); /* EMIT SIGNAL */
        }
 }
 
@@ -1083,6 +1087,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) */
 
        solo_isolated_changed (); /* EMIT SIGNAL */
+       _solo_isolate_control->Changed(); /* EMIT SIGNAL */
 }
 
 bool
index 38571b9b8b63b5f2ce02a3e024460c8e2f13297c..ee4c453c35e8fa0eaf453b82cdf446844bef3c89 100644 (file)
@@ -41,13 +41,11 @@ Route::set_control (AutomationType type, double val, PBD::Controllable::GroupCon
        case GainAutomation:
                /* route must mediate group control */
                set_gain (val, group_override);
-               return;
                break;
 
        case TrimAutomation:
                /* route must mediate group control */
                set_trim (val, group_override);
-               return;
                break;
 
        case RecEnableAutomation:
@@ -55,7 +53,6 @@ Route::set_control (AutomationType type, double val, PBD::Controllable::GroupCon
                rl.reset (new RouteList);
                rl->push_back (shared_from_this());
                _session.set_record_enabled (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
-               return;
                break;
 
        case SoloAutomation:
@@ -65,10 +62,8 @@ Route::set_control (AutomationType type, double val, PBD::Controllable::GroupCon
                if (Config->get_solo_control_is_listen_control()) {
                        _session.set_listen (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
                } else {
-                       _session.set_solo (rl, val >= 0.5 ? true : false);
+                       _session.set_solo (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
                }
-
-               return;
                break;
 
        case MuteAutomation:
@@ -135,22 +130,11 @@ Route::SoloControllable::set_value (double val, PBD::Controllable::GroupControlD
 void
 Route::SoloControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
 {
-       const bool bval = ((val >= 0.5) ? true : false);
-
-       boost::shared_ptr<RouteList> rl (new RouteList);
-
        boost::shared_ptr<Route> r = _route.lock ();
        if (!r) {
                return;
        }
-
-       rl->push_back (r);
-
-       if (Config->get_solo_control_is_listen_control()) {
-               _session.set_listen (rl, bval, Session::rt_cleanup, group_override);
-       } else {
-               _session.set_solo (rl, bval, Session::rt_cleanup, group_override);
-       }
+       r->set_control (SoloAutomation, val, group_override);
 }
 
 void
@@ -227,23 +211,20 @@ Route::MuteControllable::set_value_unchecked (double val)
 void
 Route::MuteControllable::_set_value (double val, Controllable::GroupControlDisposition group_override)
 {
-       const bool bval = ((val >= 0.5) ? true : false);
-
        boost::shared_ptr<Route> r = _route.lock ();
+
        if (!r) {
                return;
        }
 
        if (_list && ((AutomationList*)_list.get())->automation_playback()) {
                // Set superficial/automation value to drive controller (and possibly record)
+               const bool bval = ((val >= 0.5) ? true : false);
                set_superficial_value (bval);
                // Playing back automation, set route mute directly
                r->set_mute (bval, Controllable::NoGroup);
        } else {
-               // Set from user, queue mute event
-               boost::shared_ptr<RouteList> rl (new RouteList);
-               rl->push_back (r);
-               _session.set_mute (rl, bval, Session::rt_cleanup, group_override);
+               r->set_control (MuteAutomation, val, group_override);
        }
 }
 
@@ -300,3 +281,95 @@ Route::PhaseControllable::channel () const
        return _current_phase;
 }
 
+Route::SoloIsolateControllable::SoloIsolateControllable (std::string name, boost::shared_ptr<Route> r)
+       : RouteAutomationControl (name, SoloIsolateAutomation, get_descriptor(), boost::shared_ptr<AutomationList>(), r)
+{
+       boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloIsolateAutomation)));
+       gl->set_interpolation(Evoral::ControlList::Discrete);
+       set_list (gl);
+}
+
+
+double
+Route::SoloIsolateControllable::get_value () const
+{
+       boost::shared_ptr<Route> r = _route.lock ();
+       if (!r) {
+               return 0.0; /* "false" */
+       }
+
+       return r->solo_isolated() ? 1.0 : 0.0;
+}
+
+void
+Route::SoloIsolateControllable::set_value (double val, PBD::Controllable::GroupControlDisposition gcd)
+{
+       _set_value (val, gcd);
+}
+
+void
+Route::SoloIsolateControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition)
+{
+       boost::shared_ptr<Route> r = _route.lock ();
+       if (!r) {
+               return;
+       }
+
+       /* no group semantics yet */
+       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)
+{
+       boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(SoloSafeAutomation)));
+       gl->set_interpolation(Evoral::ControlList::Discrete);
+       set_list (gl);
+}
+
+void
+Route::SoloSafeControllable::set_value (double val, PBD::Controllable::GroupControlDisposition gcd)
+{
+       _set_value (val, gcd);
+}
+
+void
+Route::SoloSafeControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition)
+{
+       boost::shared_ptr<Route> r = _route.lock ();
+       if (!r) {
+               return;
+       }
+
+       /* no group semantics yet */
+       r->set_solo_safe (val >= 0.5 ? true : false);
+}
+
+double
+Route::SoloSafeControllable::get_value () const
+{
+       boost::shared_ptr<Route> r = _route.lock ();
+       if (!r) {
+               return 0.0; /* "false" */
+       }
+
+       return r->solo_safe() ? 1.0 : 0.0;
+}
+
+ParameterDescriptor
+Route::SoloSafeControllable::get_descriptor()
+{
+       ParameterDescriptor desc;
+       desc.type = SoloSafeAutomation;
+       desc.toggled = true;
+       return desc;
+}