diff --git a/shared/helper/adm_equality_helpers.h b/shared/helper/adm_equality_helpers.h new file mode 100644 index 00000000..c71ce586 --- /dev/null +++ b/shared/helper/adm_equality_helpers.h @@ -0,0 +1,97 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace adm { +namespace helpers { + +std::optional static_ds_block(adm::AudioChannelFormat const& cf) { + using namespace adm; + if (cf.get() == TypeDefinition::DIRECT_SPEAKERS) { + auto blocks = cf.getElements(); + if (blocks.size() == 1) { + return blocks.front(); + } + } + return {}; +} + +namespace equality { + using namespace adm; + + enum class CompareHasResult { Neither, Both, Mismatch }; + + template CompareHasResult compareHas(Parent const& lhs, Parent const& rhs) { + bool hasProp = lhs.template has(); + if (hasProp != rhs.template has()) + return CompareHasResult::Mismatch; + if (hasProp) + return CompareHasResult::Both; + return CompareHasResult::Neither; + } + + template bool equals(T const& lhs, T const& rhs) { + return std::equal_to{}(lhs, rhs); + } + + template bool propertyMatch(Parent const& lhs, Parent const& rhs) { + switch (compareHas(lhs, rhs)) { + case CompareHasResult::Mismatch: + return false; + case CompareHasResult::Neither: + return true; + case CompareHasResult::Both: + return equals(lhs.template get(), rhs.template get()); + default: + return false; // just to keep compiler warnings away + } + } + + template bool propertiesMatch(Parent const& lhs, Parent const& rhs) { + return (propertyMatch(lhs, rhs) && ...); + } + + template<> bool equals(Gain const& lhs, Gain const& rhs) { + return lhs.get() == rhs.get(); + } + + template<> bool equals(SpeakerLabels const& lhs, SpeakerLabels const& rhs) { + return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + } + + template<> bool equals(HeadphoneVirtualise const& lhs, HeadphoneVirtualise const& rhs) { + return propertiesMatch(lhs, rhs); + } + + template<> bool equals(ScreenEdgeLock const& lhs, ScreenEdgeLock const& rhs) { + return propertiesMatch(lhs, rhs); + } + + template<> bool equals(SphericalSpeakerPosition const& lhs, SphericalSpeakerPosition const& rhs) { + return propertiesMatch(lhs, rhs); + } + + template<> bool equals(CartesianSpeakerPosition const& lhs, CartesianSpeakerPosition const& rhs) { + return propertiesMatch(lhs, rhs); + } + + bool isEquivalentByProperties(std::shared_ptr cfA, std::shared_ptr cfB) { + if (compareHas(*cfA, *cfB) != CompareHasResult::Both) { + return false; + } + // TODO: only support matching up DS AudioChannelFormats for now + auto bfA = adm::helpers::static_ds_block(*cfA); + auto bfB = adm::helpers::static_ds_block(*cfB); + if(bfA && bfB) { + return propertiesMatch(*bfA, *bfB); + } + return false; + } +} + +} +} \ No newline at end of file diff --git a/shared/helper/adm_preset_definitions_helper.cpp b/shared/helper/adm_preset_definitions_helper.cpp index bb7bf650..1d59c81c 100644 --- a/shared/helper/adm_preset_definitions_helper.cpp +++ b/shared/helper/adm_preset_definitions_helper.cpp @@ -2,13 +2,12 @@ #include #include #include -#include #include #include -#include #include #include #include +#include namespace { std::vector splitString(const std::string& input, char delimiter, size_t maxElements) { @@ -30,19 +29,6 @@ namespace { return result; } - - template - bool matchingProp(const Elm& elmA, const Elm& elmB) { - bool hasProp = elmA.template has(); - if (hasProp != elmB.template has()) - return false; - if (hasProp) { - auto valA = elmA.template get(); - auto valB = elmB.template get(); - if (valA != valB) return false; - } - return true; - } } std::shared_ptr AdmPresetDefinitionsHelper::getSingleton() @@ -217,7 +203,7 @@ std::shared_ptr AdmPresetDefin } // Custom CF's must be matched by properties, because they won't have consistent ID's else { - if (!isEquivalentByProperties(pfDataCfDatas[i]->channelFormat, cfsToFind[i].second)) { + if (!adm::helpers::equality::isEquivalentByProperties(pfDataCfDatas[i]->channelFormat, cfsToFind[i].second)) { matching = false; break; } @@ -303,99 +289,6 @@ void AdmPresetDefinitionsHelper::recursePackFormatsForChannelFormats(std::shared } } -bool AdmPresetDefinitionsHelper::isEquivalentByProperties(std::shared_ptr cfA, std::shared_ptr cfB) -{ - auto td = cfA->get(); - if (td != cfB->get()) - return false; - - // TODO: only support matching up DS AudioChannelFormats for now - if (td == adm::TypeDefinition::DIRECT_SPEAKERS) { - auto bfsA = cfA->getElements(); - auto bfsB = cfB->getElements(); - if (bfsA.size() != 1 || bfsB.size() != 1) - return false; - auto bfA = bfsA[0]; - auto bfB = bfsB[0]; - - auto slsA = bfA.get(); - auto slsB = bfB.get(); - if (slsA.size() != slsB.size()) - return false; - for (int i = 0; i < slsA.size(); ++i) { - if (slsA[i] != slsB[i]) - return false; - } - - if (!matchingProp(bfA, bfB)) return false; - if (!matchingProp(bfA, bfB)) return false; - - if (bfA.has() != bfB.has()) - return false; - if (bfA.has()) { - if (bfA.get().get() != bfB.get().get()) - return false; - } - - if (bfA.has() != bfB.has()) - return false; - if (bfA.has()) { - auto hpvA = bfA.get(); - auto hpvB = bfB.get(); - if (!matchingProp(hpvA, hpvB)) return false; - if (!matchingProp(hpvA, hpvB)) return false; - } - - if (bfA.has() && bfB.has()) { - - auto spA = bfA.get(); - auto spB = bfB.get(); - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - - auto selA = spA.get(); - auto selB = spB.get(); - if (!matchingProp(selA, selB)) return false; - if (!matchingProp(selA, selB)) return false; - - } - else if (bfA.has() && bfB.has()) { - - auto spA = bfA.get(); - auto spB = bfB.get(); - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - if (!matchingProp(spA, spB)) return false; - - auto selA = spA.get(); - auto selB = spB.get(); - if (!matchingProp(selA, selB)) return false; - if (!matchingProp(selA, selB)) return false; - - } - else { - return false; - } - - return true; - } - - return false; -} - AdmPresetDefinitionsHelper::ChannelFormatData::ChannelFormatData(std::shared_ptr cf, std::shared_ptr fromPackFormat) diff --git a/shared/helper/adm_preset_definitions_helper.h b/shared/helper/adm_preset_definitions_helper.h index b28b9e05..8759dfdd 100644 --- a/shared/helper/adm_preset_definitions_helper.h +++ b/shared/helper/adm_preset_definitions_helper.h @@ -108,7 +108,6 @@ class AdmPresetDefinitionsHelper { private: void populateElementRelationshipsFor(adm::TypeDescriptor); void recursePackFormatsForChannelFormats(std::shared_ptr fromPackFormat, std::shared_ptr forPackFormatData); - bool isEquivalentByProperties(std::shared_ptr cfA, std::shared_ptr cfB); std::shared_ptr presetDefinitions; std::vector> typeDefinitionDatas{ 6, nullptr }; // last elm index 5 (highest TD) }; \ No newline at end of file