Optimize automation-event process splitting
[ardour.git] / libs / ardour / chan_mapping.cc
index bc6c4051fc75c6b33202c499af7e547739d9dbbd..1840af0d25a1aabfd96092bc093cfc3a3e2c70aa 100644 (file)
 
 #include <stdint.h>
 #include <iostream>
+#include "ardour/types_convert.h"
 #include "ardour/chan_mapping.h"
 
+#include "pbd/i18n.h"
+
+static const char* state_node_name = "Channelmap";
+
 using namespace std;
 
 namespace ARDOUR {
 
 ChanMapping::ChanMapping(ChanCount identity)
 {
-       if (identity == ChanCount::INFINITE) {
-               return;
-       }
-
        for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
                for (size_t i = 0; i < identity.get(*t); ++i) {
                        set(*t, i, i);
@@ -40,9 +41,30 @@ ChanMapping::ChanMapping(ChanCount identity)
        }
 }
 
-ChanMapping::ChanMapping (const ChanMapping& other )
-       : _mappings (other._mappings)
+ChanMapping::ChanMapping (const ChanMapping& other)
+{
+       const ChanMapping::Mappings& mp (other.mappings());
+       for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+               for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+                       set (tm->first, i->first, i->second);
+               }
+       }
+}
+
+ChanMapping::ChanMapping (const XMLNode& node)
 {
+       XMLNodeConstIterator iter = node.children().begin();
+       for ( ; iter != node.children().end(); ++iter) {
+               if ((*iter)->name() == X_(state_node_name)) {
+                       DataType type(DataType::NIL);
+                       uint32_t from;
+                       uint32_t to;
+                       (*iter)->get_property("type", type);
+                       (*iter)->get_property("from", from);
+                       (*iter)->get_property("to", to);
+                       set(type, from, to);
+               }
+       }
 }
 
 uint32_t
@@ -62,11 +84,31 @@ ChanMapping::get(DataType t, uint32_t from, bool* valid) const
        return m->second;
 }
 
+uint32_t
+ChanMapping::get_src(DataType t, uint32_t to, bool* valid) const
+{
+       Mappings::const_iterator tm = _mappings.find(t);
+       if (tm == _mappings.end()) {
+               if (valid) { *valid = false; }
+               return -1;
+       }
+       for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+               if (i->second == to) {
+                       if (valid) { *valid = true; }
+                       return i->first;
+               }
+       }
+       if (valid) { *valid = false; }
+       return -1;
+}
+
+
+
 void
 ChanMapping::set(DataType t, uint32_t from, uint32_t to)
 {
        assert(t != DataType::NIL);
-       Mappings::iterator tm = _mappings.find(t);
+       Mappings::iterator tm = _mappings.find (t);
        if (tm == _mappings.end()) {
                tm = _mappings.insert(std::make_pair(t, TypeMapping())).first;
        }
@@ -77,7 +119,7 @@ void
 ChanMapping::unset(DataType t, uint32_t from)
 {
        assert(t != DataType::NIL);
-       Mappings::iterator tm = _mappings.find(t);
+       Mappings::iterator tm = _mappings.find (t);
        if (tm == _mappings.end()) {
                return;
        }
@@ -89,10 +131,10 @@ void
 ChanMapping::offset_from(DataType t, int32_t delta)
 {
        Mappings::iterator tm = _mappings.find(t);
-       if (tm != _mappings.end()) {
+       if (tm != _mappings.end ()) {
                TypeMapping new_map;
                for (TypeMapping::iterator m = tm->second.begin(); m != tm->second.end(); ++m) {
-                       new_map.insert(make_pair(m->first + delta, m->second));
+                       new_map.insert (make_pair (m->first + delta, m->second));
                }
                tm->second = new_map;
        }
@@ -110,11 +152,29 @@ ChanMapping::offset_to(DataType t, int32_t delta)
        }
 }
 
+XMLNode*
+ChanMapping::state(const std::string& name) const
+{
+       XMLNode* node = new XMLNode (name);
+       const Mappings& mp (mappings());
+       for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+               for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+                       XMLNode* n = new XMLNode(X_(state_node_name));
+                       n->set_property("type", tm->first.to_string());
+                       n->set_property("from", i->first);
+                       n->set_property("to", i->second);
+                       node->add_child_nocopy(*n);
+               }
+       }
+       return node;
+}
+
 bool
 ChanMapping::is_subset (const ChanMapping& superset) const
 {
-       for (ARDOUR::ChanMapping::Mappings::const_iterator tm = mappings().begin(); tm != mappings().end(); ++tm) {
-               for (ARDOUR::ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+       const Mappings& mp (mappings());
+       for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+               for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
                        bool valid;
                        if (i->second != superset.get (tm->first, i->first, &valid)) {
                                return false;
@@ -130,9 +190,10 @@ ChanMapping::is_subset (const ChanMapping& superset) const
 bool
 ChanMapping::is_monotonic () const
 {
-       for (ARDOUR::ChanMapping::Mappings::const_iterator tm = mappings().begin(); tm != mappings().end(); ++tm) {
+       const Mappings& mp (mappings());
+       for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
                uint32_t prev = UINT32_MAX;
-               for (ARDOUR::ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+               for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
                        // set keys are strictly weak ordered
                        if (i->first < i->second || i->second == prev) {
                                return false;
@@ -146,8 +207,9 @@ ChanMapping::is_monotonic () const
 bool
 ChanMapping::is_identity (ChanCount offset) const
 {
-       for (ARDOUR::ChanMapping::Mappings::const_iterator tm = mappings().begin(); tm != mappings().end(); ++tm) {
-               for (ARDOUR::ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+       const Mappings& mp (mappings());
+       for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+               for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
                        if (i->first + offset.get (tm->first) != i->second) {
                                return false;
                        }
@@ -156,12 +218,37 @@ ChanMapping::is_identity (ChanCount offset) const
        return true;
 }
 
+uint32_t
+ChanMapping::n_total () const
+{
+       // fast version of count().n_total();
+       uint32_t rv = 0;
+       const Mappings& mp (mappings());
+       for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+               rv += tm->second.size ();
+       }
+       return rv;
+}
+
+ChanCount
+ChanMapping::count () const
+{
+       ChanCount rv;
+       const Mappings& mp (mappings());
+       for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+               rv.set (tm->first, tm->second.size ());
+       }
+       return rv;
+}
+
+
+
 } // namespace ARDOUR
 
 std::ostream& operator<<(std::ostream& o, const ARDOUR::ChanMapping& cm)
 {
-       for (ARDOUR::ChanMapping::Mappings::const_iterator tm = cm.mappings().begin();
-                       tm != cm.mappings().end(); ++tm) {
+       const ARDOUR::ChanMapping::Mappings& mp (cm.mappings());
+       for (ARDOUR::ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
                o << tm->first.to_string() << endl;
                for (ARDOUR::ChanMapping::TypeMapping::const_iterator i = tm->second.begin();
                                i != tm->second.end(); ++i) {
@@ -171,4 +258,3 @@ std::ostream& operator<<(std::ostream& o, const ARDOUR::ChanMapping& cm)
 
        return o;
 }
-