From 111af1b6488fcd9b28ae1940c7fcf684480b736d Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Wed, 16 Sep 2020 11:13:37 +0200 Subject: [PATCH] Ensure label entries to be unique for their cc/note --- src/sfizz/SfzHelpers.h | 29 +++++++++++++++++++++++++++++ src/sfizz/Synth.cpp | 10 +++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/sfizz/SfzHelpers.h b/src/sfizz/SfzHelpers.h index 31ea49c8..416b2304 100644 --- a/src/sfizz/SfzHelpers.h +++ b/src/sfizz/SfzHelpers.h @@ -7,6 +7,7 @@ #pragma once #include #include +#include //#include #include #include @@ -202,6 +203,34 @@ inline CXX14_CONSTEXPR Type vaGain(Type cutoff, Type sampleRate) return std::tan(cutoff / sampleRate * pi()); } +/** + * @brief Insert an item uniquely into a vector of pairs. + * + * @param pairVector the vector of pairs + * @param key the unique key + * @param value the value + * @param replace whether to replace the value if the key is already present + * @return whether the item was inserted + */ +template +bool insertPairUniquely(std::vector

& pairVector, const T& key, U value, bool replace = true) +{ + bool result = false; + auto it = absl::c_find_if( + pairVector, [&key](const P& pair) { return pair.first == key; }); + if (it != pairVector.end()) { + if (replace) { + it->second = std::move(value); + result = true; + } + } + else { + pairVector.emplace_back(key, std::move(value)); + result = true; + } + return result; +} + /** * @brief From a source view, find the next sfz header and its members and * return them, while updating the source by removing this header diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 32ceccad..bd4f177c 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -233,8 +233,8 @@ void sfz::Synth::clear() hdcc(0, 10, 0.5f); // pan // set default controller labels - ccLabels.emplace_back(7, "Volume"); - ccLabels.emplace_back(10, "Pan"); + insertPairUniquely(ccLabels, 7, "Volume"); + insertPairUniquely(ccLabels, 10, "Pan"); } void sfz::Synth::handleMasterOpcodes(const std::vector& members) @@ -336,12 +336,12 @@ void sfz::Synth::handleControlOpcodes(const std::vector& members) break; case hash("label_cc&"): if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) - ccLabels.emplace_back(member.parameters.back(), std::string(member.value)); + insertPairUniquely(ccLabels, member.parameters.back(), std::string(member.value)); break; case hash("label_key&"): if (member.parameters.back() <= Default::keyRange.getEnd()) { const auto noteNumber = static_cast(member.parameters.back()); - keyLabels.emplace_back(noteNumber, std::string(member.value)); + insertPairUniquely(keyLabels, noteNumber, std::string(member.value)); } break; case hash("default_path"): @@ -545,7 +545,7 @@ void sfz::Synth::finalizeSfzLoad() } if (region->keyswitchLabel && region->keyswitch) - keyswitchLabels.push_back({ *region->keyswitch, *region->keyswitchLabel }); + insertPairUniquely(keyswitchLabels, *region->keyswitch, *region->keyswitchLabel); // Some regions had group number but no "group-level" opcodes handled the polyphony while (polyphonyGroups.size() <= region->group) {