Update Slavable API
authorRobin Gareus <robin@gareus.org>
Thu, 22 Jun 2017 19:06:12 +0000 (21:06 +0200)
committerRobin Gareus <robin@gareus.org>
Thu, 22 Jun 2017 20:04:10 +0000 (22:04 +0200)
Do not use AutomationType to identify parameters, use complete
Evoral::Parameter and Automatable.

For "batch connections", a Slavables needs to implement an API to return
the relevant controls.

This is only a first step towards a more generic Master/Slave framework.

libs/ardour/ardour/automatable.h
libs/ardour/ardour/route.h
libs/ardour/ardour/slavable.h
libs/ardour/ardour/slavable_automation_control.h
libs/ardour/ardour/types.h
libs/ardour/ardour/vca.h
libs/ardour/route.cc
libs/ardour/route_group.cc
libs/ardour/slavable.cc
libs/ardour/slavable_automation_control.cc
libs/ardour/vca.cc

index 8adfb88aaeea999fce649ac31a8d36e9382f9d8d..1acb8a60dcd11ca6cee52d8c61f49e092aadaf32 100644 (file)
@@ -117,6 +117,8 @@ public:
 
        framepos_t _last_automation_snapshot;
 
+       SlavableControlList slavables () const { return SlavableControlList(); }
+
 private:
        PBD::ScopedConnectionList _control_connections; ///< connections to our controls' signals
 };
index fad986f936287a0acaa4d6ec8d669e2916a851b1..d5611c6fe9257dd5b479cae5c52ce612461c8837 100644 (file)
@@ -686,6 +686,8 @@ protected:
 
        boost::shared_ptr<Processor> the_instrument_unlocked() const;
 
+       SlavableControlList slavables () const;
+
 private:
        int64_t _track_number;
 
index 15d3e41991b21405f273fffb366aec5b7af6c015..6e584b2128f4717ea931878c0acf7f742d42b65a 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "evoral/Parameter.hpp"
 
+#include "ardour/types.h"
 #include "ardour/libardour_visibility.h"
 
 class XMLNode;
@@ -39,33 +40,39 @@ namespace ARDOUR {
 class VCA;
 class VCAManager;
 class AutomationControl;
+class SlavableAutomationControl;
 
 class LIBARDOUR_API Slavable
 {
-    public:
+public:
        Slavable ();
        virtual ~Slavable() {}
 
        XMLNode& get_state () const;
        int set_state (XMLNode const&, int);
 
-       void assign (boost::shared_ptr<VCA>, bool loading);
+       void assign (boost::shared_ptr<VCA>);
        void unassign (boost::shared_ptr<VCA>);
 
        PBD::Signal2<void,boost::shared_ptr<VCA>,bool> AssignmentChange;
 
-       virtual boost::shared_ptr<AutomationControl> automation_control (const Evoral::Parameter& id) = 0;
+       virtual boost::shared_ptr<AutomationControl> automation_control (const Evoral::Parameter&) = 0;
 
        static std::string xml_node_name;
 
        /* signal sent VCAManager once assignment is possible */
        static PBD::Signal1<void,VCAManager*> Assign;
 
-    protected:
-       virtual int assign_controls (boost::shared_ptr<VCA>, bool loading);
-       virtual int unassign_controls (boost::shared_ptr<VCA>);
+protected:
+       virtual SlavableControlList slavables () const = 0;
+
+private:
+       bool assign_controls (boost::shared_ptr<VCA>);
+       void unassign_controls (boost::shared_ptr<VCA>);
+
+       bool assign_control (boost::shared_ptr<VCA>, boost::shared_ptr<SlavableAutomationControl>);
+       void unassign_control (boost::shared_ptr<VCA>, boost::shared_ptr<SlavableAutomationControl>);
 
-    private:
        mutable Glib::Threads::RWLock master_lock;
        std::set<uint32_t> _masters;
        PBD::ScopedConnection assign_connection;
@@ -73,7 +80,6 @@ class LIBARDOUR_API Slavable
 
        int do_assign (VCAManager* s);
        void weak_unassign (boost::weak_ptr<VCA>);
-
 };
 
 } // namespace ARDOUR
index 5057ef407090174752696285842565d08ce1fae1..eaa43416166847f83d955296be17c3425d76a8b0 100644 (file)
@@ -40,7 +40,7 @@ public:
 
        double get_value () const;
 
-       void add_master (boost::shared_ptr<AutomationControl>, bool loading);
+       void add_master (boost::shared_ptr<AutomationControl>);
        void remove_master (boost::shared_ptr<AutomationControl>);
        void clear_masters ();
        bool slaved_to (boost::shared_ptr<AutomationControl>) const;
index 258bbb191f9dae7fa17b7a20ffea8a5afb038ea4..bcabf32b4eaf784206ef3dca0b605f84a717343c 100644 (file)
@@ -55,6 +55,7 @@ namespace ARDOUR {
        class Stripable;
        class VCA;
        class AutomationControl;
+       class SlavableAutomationControl;
 
        typedef float    Sample;
        typedef float    pan_t;
@@ -588,6 +589,7 @@ namespace ARDOUR {
        typedef std::list<boost::weak_ptr  <Route> > WeakRouteList;
        typedef std::list<boost::weak_ptr  <Stripable> > WeakStripableList;
        typedef std::list<boost::shared_ptr<AutomationControl> > ControlList;
+       typedef std::list<boost::shared_ptr<SlavableAutomationControl> > SlavableControlList;
 
        typedef std::list<boost::shared_ptr<VCA> > VCAList;
 
index fa0b08a2cf55aa83cf5ffd8a03393f134709421c..73dd6a917f6cda6548f664e5a7c5234b0d8aca8d 100644 (file)
@@ -146,6 +146,9 @@ class LIBARDOUR_API VCA : public Stripable,
        boost::shared_ptr<AutomationControl> eq_lpf_controllable () const { return boost::shared_ptr<AutomationControl>(); }
        boost::shared_ptr<AutomationControl> filter_enable_controllable () const { return boost::shared_ptr<AutomationControl>(); }
 
+       protected:
+       SlavableControlList slavables () const;
+
   private:
        int32_t _number;
 
index 58be7c2756d9d906e0888e7d6aad616efa2b8762..63ac12a1cf10fed4ad19a879b7f54a0daec6d5a0 100644 (file)
@@ -5516,3 +5516,13 @@ Route::automation_control_recurse (PBD::ID const & id) const
 
        return boost::shared_ptr<AutomationControl> ();
 }
+
+SlavableControlList
+Route::slavables () const
+{
+       SlavableControlList rv;
+       rv.push_back (_gain_control);
+       rv.push_back (_mute_control);
+       rv.push_back (_solo_control);
+       return rv;
+}
index 004e64b6fedc9c60a18fee179fdffe9b9eb97516..a309e28981e75f4771d523251c7375cad14e4628 100644 (file)
@@ -187,7 +187,7 @@ RouteGroup::add (boost::shared_ptr<Route> r)
        boost::shared_ptr<VCA> vca (group_master.lock());
 
        if (vca) {
-               r->assign  (vca, false);
+               r->assign (vca);
        }
 
        _session.set_dirty ();
@@ -656,7 +656,7 @@ RouteGroup::assign_master (boost::shared_ptr<VCA> master)
        }
 
        for (RouteList::iterator r = routes->begin(); r != routes->end(); ++r) {
-               (*r)->assign (master, false);
+               (*r)->assign (master);
        }
 
        group_master = master;
index cb34630522926d0cbaa9d195954264f09749a968..7d8109eac62ee1e3f454d79df7369f7aa3207592 100644 (file)
@@ -82,18 +82,6 @@ Slavable::set_state (XMLNode const& node, int version)
        return 0;
 }
 
-
-/* Gain, solo & mute are currently the only controls that are
- * automatically slaved to the master's own equivalent controls.
- */
-
-static AutomationType auto_slave_types[] = {
-       GainAutomation,
-       SoloAutomation,
-       MuteAutomation,
-       NullAutomation
-};
-
 int
 Slavable::do_assign (VCAManager* manager)
 {
@@ -117,18 +105,12 @@ Slavable::do_assign (VCAManager* manager)
        if (!vcas.empty()) {
 
                for (std::vector<boost::shared_ptr<VCA> >::iterator v = vcas.begin(); v != vcas.end(); ++v) {
-                       assign (*v, true);
+                       assign (*v);
                }
 
-               for (uint32_t n = 0; auto_slave_types[n] != NullAutomation; ++n) {
-
-                       boost::shared_ptr<SlavableAutomationControl> slave;
-
-                       slave = boost::dynamic_pointer_cast<SlavableAutomationControl> (automation_control (auto_slave_types[n]));
-
-                       if (slave) {
-                               slave->use_saved_master_ratios ();
-                       }
+               SlavableControlList scl = slavables ();
+               for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) {
+                               (*i)->use_saved_master_ratios ();
                }
        }
 
@@ -138,12 +120,12 @@ Slavable::do_assign (VCAManager* manager)
 }
 
 void
-Slavable::assign (boost::shared_ptr<VCA> v, bool loading)
+Slavable::assign (boost::shared_ptr<VCA> v)
 {
        assert (v);
        {
                Glib::Threads::RWLock::WriterLock lm (master_lock);
-               if (assign_controls (v, loading) == 0) {
+               if (assign_controls (v)) {
                        _masters.insert (v->number());
                }
 
@@ -175,7 +157,7 @@ Slavable::unassign (boost::shared_ptr<VCA> v)
        {
                Glib::Threads::RWLock::WriterLock lm (master_lock);
 
-               (void) unassign_controls (v);
+               unassign_controls (v);
                if (v) {
                        _masters.erase (v->number());
                } else {
@@ -185,47 +167,49 @@ Slavable::unassign (boost::shared_ptr<VCA> v)
        AssignmentChange (v, false);
 }
 
-int
-Slavable::assign_controls (boost::shared_ptr<VCA> vca, bool loading)
+bool
+Slavable::assign_controls (boost::shared_ptr<VCA> vca)
 {
-       boost::shared_ptr<SlavableAutomationControl> slave;
-       boost::shared_ptr<AutomationControl> master;
-
-       for (uint32_t n = 0; auto_slave_types[n] != NullAutomation; ++n) {
-
-               slave = boost::dynamic_pointer_cast<SlavableAutomationControl> (automation_control (auto_slave_types[n]));
-               master = vca->automation_control (auto_slave_types[n]);
-
-               if (slave && master) {
-                       slave->add_master (master, loading);
-               }
+       bool rv = false;
+       SlavableControlList scl = slavables ();
+       for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) {
+               rv |= assign_control (vca, *i);
        }
-
-       return 0;
+       return rv;
 }
 
-int
+void
 Slavable::unassign_controls (boost::shared_ptr<VCA> vca)
 {
-       boost::shared_ptr<SlavableAutomationControl> slave;
-       boost::shared_ptr<AutomationControl> master;
-
-       for (uint32_t n = 0; auto_slave_types[n] != NullAutomation; ++n) {
+       SlavableControlList scl = slavables ();
+       for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) {
+               unassign_control (vca, *i);
+       }
+}
 
-               slave = boost::dynamic_pointer_cast<SlavableAutomationControl> (automation_control (auto_slave_types[n]));
+bool
+Slavable::assign_control (boost::shared_ptr<VCA> vca, boost::shared_ptr<SlavableAutomationControl> slave)
+{
+       boost::shared_ptr<AutomationControl> master;
+       master = vca->automation_control (slave->parameter());
+       if (!master) {
+               return false;
+       }
+       slave->add_master (master);
+       return true;
+}
 
-               if (!vca) {
-                       /* unassign from all */
-                       if (slave) {
-                               slave->clear_masters ();
-                       }
-               } else {
-                       master = vca->automation_control (auto_slave_types[n]);
-                       if (slave && master) {
-                               slave->remove_master (master);
-                       }
+void
+Slavable::unassign_control (boost::shared_ptr<VCA> vca, boost::shared_ptr<SlavableAutomationControl> slave)
+{
+       if (!vca) {
+               /* unassign from all */
+               slave->clear_masters ();
+       } else {
+               boost::shared_ptr<AutomationControl> master;
+               master = vca->automation_control (slave->parameter());
+               if (master) {
+                       slave->remove_master (master);
                }
        }
-
-       return 0;
 }
index cb88d36fe9c55b023ce9c0e5f5a98b67359f05c6..655863738396d504111ab2f605e7b13a8049c67c 100644 (file)
@@ -183,7 +183,7 @@ SlavableAutomationControl::actually_set_value (double value, PBD::Controllable::
 }
 
 void
-SlavableAutomationControl::add_master (boost::shared_ptr<AutomationControl> m, bool loading)
+SlavableAutomationControl::add_master (boost::shared_ptr<AutomationControl> m)
 {
        std::pair<Masters::iterator,bool> res;
 
index e9b058f6a92038283d50b2a48305ee5f55e01d7b..7be103e9e439af0443c6a435f50b2ac589dc8436 100644 (file)
@@ -207,3 +207,13 @@ VCA::slaved_to (boost::shared_ptr<VCA> vca) const
 
        return _gain_control->slaved_to (vca->gain_control());
 }
+
+SlavableControlList
+VCA::slavables () const
+{
+       SlavableControlList rv;
+       rv.push_back (_gain_control);
+       rv.push_back (_mute_control);
+       rv.push_back (_solo_control);
+       return rv;
+}