extend channel-map
add tests for identity matrix, monotonic, subset, which are handy to verify if inplace processing is possible. add `unset()` for upcoming GUI work.
This commit is contained in:
parent
234b06a18c
commit
e0dbb95b72
|
@ -42,14 +42,14 @@ public:
|
||||||
ChanMapping(ARDOUR::ChanCount identity);
|
ChanMapping(ARDOUR::ChanCount identity);
|
||||||
ChanMapping(const ChanMapping&);
|
ChanMapping(const ChanMapping&);
|
||||||
|
|
||||||
uint32_t get(DataType t, uint32_t from, bool* valid);
|
uint32_t get(DataType t, uint32_t from, bool* valid) const;
|
||||||
|
|
||||||
/** get buffer mapping for given data type and pin
|
/** get buffer mapping for given data type and pin
|
||||||
* @param type data type
|
* @param type data type
|
||||||
* @param from pin
|
* @param from pin
|
||||||
* @returns mapped buffer number (or ChanMapping::Invalid)
|
* @returns mapped buffer number (or ChanMapping::Invalid)
|
||||||
*/
|
*/
|
||||||
uint32_t get(DataType t, uint32_t from) { return get (t, from, NULL); }
|
uint32_t get(DataType t, uint32_t from) const { return get (t, from, NULL); }
|
||||||
/** set buffer mapping for given data type
|
/** set buffer mapping for given data type
|
||||||
* @param type data type
|
* @param type data type
|
||||||
* @param from pin
|
* @param from pin
|
||||||
|
@ -59,6 +59,30 @@ public:
|
||||||
void offset_from(DataType t, int32_t delta);
|
void offset_from(DataType t, int32_t delta);
|
||||||
void offset_to(DataType t, int32_t delta);
|
void offset_to(DataType t, int32_t delta);
|
||||||
|
|
||||||
|
/** remove mapping
|
||||||
|
* @param type data type
|
||||||
|
* @param from source to remove from mapping
|
||||||
|
*/
|
||||||
|
void unset(DataType t, uint32_t from);
|
||||||
|
|
||||||
|
/** Test mapping matrix for identity
|
||||||
|
* @param offset per data-type offset to take into account
|
||||||
|
* @returns true if the mapping is a channel identity map
|
||||||
|
*/
|
||||||
|
bool is_identity (ARDOUR::ChanCount offset = ARDOUR::ChanCount()) const;
|
||||||
|
|
||||||
|
/** Test if this mapping is monotonic (useful to see if inplace processing is feasible)
|
||||||
|
* @returns true if the map is a strict monotonic set
|
||||||
|
*/
|
||||||
|
bool is_monotonic () const;
|
||||||
|
|
||||||
|
|
||||||
|
/** Test if this mapping is a subset
|
||||||
|
* @param superset to test against
|
||||||
|
* @returns true if all mapping are also present in the superset
|
||||||
|
*/
|
||||||
|
bool is_subset (const ChanMapping& superset) const;
|
||||||
|
|
||||||
typedef std::map<uint32_t, uint32_t> TypeMapping;
|
typedef std::map<uint32_t, uint32_t> TypeMapping;
|
||||||
typedef std::map<DataType, TypeMapping> Mappings;
|
typedef std::map<DataType, TypeMapping> Mappings;
|
||||||
|
|
||||||
|
|
|
@ -46,14 +46,14 @@ ChanMapping::ChanMapping (const ChanMapping& other )
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
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 (tm == _mappings.end()) {
|
||||||
if (valid) { *valid = false; }
|
if (valid) { *valid = false; }
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
TypeMapping::iterator m = tm->second.find(from);
|
TypeMapping::const_iterator m = tm->second.find(from);
|
||||||
if (m == tm->second.end()) {
|
if (m == tm->second.end()) {
|
||||||
if (valid) { *valid = false; }
|
if (valid) { *valid = false; }
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -73,6 +73,17 @@ ChanMapping::set(DataType t, uint32_t from, uint32_t to)
|
||||||
tm->second.insert(std::make_pair(from, to));
|
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 */
|
/** Offset the 'from' field of every mapping for type @a t by @a delta */
|
||||||
void
|
void
|
||||||
ChanMapping::offset_from(DataType t, int32_t delta)
|
ChanMapping::offset_from(DataType t, int32_t delta)
|
||||||
|
@ -99,6 +110,52 @@ ChanMapping::offset_to(DataType t, int32_t delta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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
|
||||||
|
{
|
||||||
|
for (ARDOUR::ChanMapping::Mappings::const_iterator tm = mappings().begin(); tm != mappings().end(); ++tm) {
|
||||||
|
uint32_t prev = UINT32_MAX;
|
||||||
|
for (ARDOUR::ChanMapping::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
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
if (i->first + offset.get (tm->first) != i->second) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ARDOUR
|
} // namespace ARDOUR
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& o, const ARDOUR::ChanMapping& cm)
|
std::ostream& operator<<(std::ostream& o, const ARDOUR::ChanMapping& cm)
|
||||||
|
|
|
@ -181,7 +181,7 @@ LuaBindings::common (lua_State* L)
|
||||||
|
|
||||||
.beginClass <ChanMapping> ("ChanMapping")
|
.beginClass <ChanMapping> ("ChanMapping")
|
||||||
.addVoidConstructor ()
|
.addVoidConstructor ()
|
||||||
.addFunction ("get", static_cast<uint32_t(ChanMapping::*)(DataType, uint32_t)>(&ChanMapping::get))
|
.addFunction ("get", static_cast<uint32_t(ChanMapping::*)(DataType, uint32_t) const>(&ChanMapping::get))
|
||||||
.addFunction ("set", &ChanMapping::set)
|
.addFunction ("set", &ChanMapping::set)
|
||||||
.addConst ("Invalid", 4294967295) // UINT32_MAX
|
.addConst ("Invalid", 4294967295) // UINT32_MAX
|
||||||
.endClass ()
|
.endClass ()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user