Ensure label entries to be unique for their cc/note

This commit is contained in:
Jean Pierre Cimalando 2020-09-16 11:13:37 +02:00
parent 1b104fd6d6
commit 111af1b648
2 changed files with 34 additions and 5 deletions

View file

@ -7,6 +7,7 @@
#pragma once
#include <absl/types/optional.h>
#include <absl/strings/string_view.h>
#include <absl/algorithm/container.h>
//#include <string>
#include <array>
#include <cmath>
@ -202,6 +203,34 @@ inline CXX14_CONSTEXPR Type vaGain(Type cutoff, Type sampleRate)
return std::tan(cutoff / sampleRate * pi<Type>());
}
/**
* @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 <class P, class T, class U>
bool insertPairUniquely(std::vector<P>& 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

View file

@ -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<Opcode>& members)
@ -336,12 +336,12 @@ void sfz::Synth::handleControlOpcodes(const std::vector<Opcode>& 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<uint8_t>(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) {