X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fchan_mapping.cc;h=f6f0e092c8065acd309bfe7d92c1cf73fb7be600;hb=cf52d6e4b40111eb04b244ec054055a4ec15dbe0;hp=83ded4141cb5d3475fcb612af6bc0ac684192581;hpb=79d63d870186e421957e1f5086a7af7d9549b292;p=ardour.git diff --git a/libs/ardour/chan_mapping.cc b/libs/ardour/chan_mapping.cc index 83ded4141c..f6f0e092c8 100644 --- a/libs/ardour/chan_mapping.cc +++ b/libs/ardour/chan_mapping.cc @@ -23,6 +23,10 @@ #include #include "ardour/chan_mapping.h" +#include "pbd/i18n.h" + +static const char* state_node_name = "Channelmap"; + using namespace std; namespace ARDOUR { @@ -40,20 +44,38 @@ 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)) { + const string& type_str = (*iter)->property("type")->value(); + const string& from_str = (*iter)->property("from")->value(); + const string& to_str = (*iter)->property("to")->value(); + set(DataType(type_str), atol (from_str.c_str()), atol (to_str.c_str())); + } + } } uint32_t -ChanMapping::get(DataType t, uint32_t from, bool* valid) +ChanMapping::get(DataType t, uint32_t from, bool* valid) const { - Mappings::iterator tm = _mappings.find(t); + Mappings::const_iterator tm = _mappings.find(t); if (tm == _mappings.end()) { if (valid) { *valid = false; } return -1; } - TypeMapping::iterator m = tm->second.find(from); + TypeMapping::const_iterator m = tm->second.find(from); if (m == tm->second.end()) { if (valid) { *valid = false; } return -1; @@ -62,26 +84,57 @@ ChanMapping::get(DataType t, uint32_t from, bool* valid) 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; } tm->second.insert(std::make_pair(from, to)); } +void +ChanMapping::unset(DataType t, uint32_t from) +{ + assert(t != DataType::NIL); + Mappings::iterator tm = _mappings.find (t); + if (tm == _mappings.end()) { + return; + } + tm->second.erase(from); +} + /** Offset the 'from' field of every mapping for type @a t by @a delta */ 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; } @@ -99,12 +152,103 @@ 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->add_property("type", tm->first.to_string()); + n->add_property("from", i->first); + n->add_property("to", i->second); + node->add_child_nocopy(*n); + } + } + return node; +} + +bool +ChanMapping::is_subset (const ChanMapping& superset) const +{ + 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; + } + if (!valid) { + return false; + } + } + } + return true; +} + +bool +ChanMapping::is_monotonic () const +{ + const Mappings& mp (mappings()); + for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) { + uint32_t prev = UINT32_MAX; + 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; + } + prev = i->second; + } + } + return true; +} + +bool +ChanMapping::is_identity (ChanCount offset) const +{ + 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; + } + } + } + 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) { @@ -114,4 +258,3 @@ std::ostream& operator<<(std::ostream& o, const ARDOUR::ChanMapping& cm) return o; } -