Add the derived name helper for opcodes

This commit is contained in:
Jean Pierre Cimalando 2020-05-03 16:12:34 +02:00
parent acbbb8354a
commit 3a43998142
3 changed files with 69 additions and 1 deletions

View file

@ -8,7 +8,9 @@
#include "StringViewHelpers.h" #include "StringViewHelpers.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/match.h" #include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include <cctype> #include <cctype>
#include <cassert>
sfz::Opcode::Opcode(absl::string_view inputOpcode, absl::string_view inputValue) sfz::Opcode::Opcode(absl::string_view inputOpcode, absl::string_view inputValue)
: opcode(trim(inputOpcode)) : opcode(trim(inputOpcode))
@ -46,6 +48,52 @@ static absl::string_view extractBackInteger(absl::string_view opcodeName)
return opcodeName.substr(i); return opcodeName.substr(i);
} }
std::string sfz::Opcode::getDerivedName(sfz::OpcodeCategory newCategory, unsigned number) const
{
std::string derivedName(opcode);
switch (category) {
case kOpcodeNormal:
break;
case kOpcodeOnCcN:
case kOpcodeCurveCcN:
case kOpcodeStepCcN:
case kOpcodeSmoothCcN:
{
// when the input is cc, first delete the suffix `_*cc`
size_t pos = opcode.rfind('_');
assert(pos != opcode.npos);
derivedName.resize(pos);
}
break;
}
// helper to extract the cc number optionally if the next part needs it
auto ccNumberSuffix = [this, number]() -> std::string {
return (number != ~0u) ? std::to_string(number) :
std::string(extractBackInteger(opcode));
};
switch (newCategory) {
case kOpcodeNormal:
break;
case kOpcodeOnCcN:
absl::StrAppend(&derivedName, "_oncc", ccNumberSuffix());
break;
case kOpcodeCurveCcN:
absl::StrAppend(&derivedName, "_curvecc", ccNumberSuffix());
break;
case kOpcodeStepCcN:
absl::StrAppend(&derivedName, "_stepcc", ccNumberSuffix());
break;
case kOpcodeSmoothCcN:
absl::StrAppend(&derivedName, "_smoothcc", ccNumberSuffix());
break;
}
return derivedName;
}
sfz::OpcodeCategory sfz::Opcode::identifyCategory(absl::string_view name) sfz::OpcodeCategory sfz::Opcode::identifyCategory(absl::string_view name)
{ {
sfz::OpcodeCategory category = kOpcodeNormal; sfz::OpcodeCategory category = kOpcodeNormal;

View file

@ -10,7 +10,7 @@
#include "Range.h" #include "Range.h"
#include "SfzHelpers.h" #include "SfzHelpers.h"
#include "StringViewHelpers.h" #include "StringViewHelpers.h"
#include <absl/types/optional.h> #include "absl/types/optional.h"
#include "absl/meta/type_traits.h" #include "absl/meta/type_traits.h"
#include <string_view> #include <string_view>
#include <vector> #include <vector>
@ -50,6 +50,16 @@ struct Opcode {
// This is to handle the integer parameters of some opcodes // This is to handle the integer parameters of some opcodes
std::vector<uint16_t> parameters; std::vector<uint16_t> parameters;
OpcodeCategory category; OpcodeCategory category;
/*
* @brief Get the derived opcode name to convert it to another category.
*
* @param newCategory category to convert to
* @param number optional CC number, needed if destination is CC and source is not
* @return derived opcode name
*/
std::string getDerivedName(OpcodeCategory newCategory, unsigned number = ~0u) const;
private: private:
static OpcodeCategory identifyCategory(absl::string_view name); static OpcodeCategory identifyCategory(absl::string_view name);
LEAK_DETECTOR(Opcode); LEAK_DETECTOR(Opcode);

View file

@ -148,3 +148,13 @@ TEST_CASE("[Opcode] Categories")
REQUIRE(sfz::Opcode("pan_stepcc44", "").category == sfz::kOpcodeStepCcN); REQUIRE(sfz::Opcode("pan_stepcc44", "").category == sfz::kOpcodeStepCcN);
REQUIRE(sfz::Opcode("noise_level_smoothcc55", "").category == sfz::kOpcodeSmoothCcN); REQUIRE(sfz::Opcode("noise_level_smoothcc55", "").category == sfz::kOpcodeSmoothCcN);
} }
TEST_CASE("[Opcode] Derived names")
{
REQUIRE(sfz::Opcode("sample", "").getDerivedName(sfz::kOpcodeNormal) == "sample");
REQUIRE(sfz::Opcode("cutoff_cc22", "").getDerivedName(sfz::kOpcodeNormal) == "cutoff");
REQUIRE(sfz::Opcode("lfo01_pitch_curvecc33", "").getDerivedName(sfz::kOpcodeOnCcN) == "lfo01_pitch_oncc33");
REQUIRE(sfz::Opcode("pan_stepcc44", "").getDerivedName(sfz::kOpcodeCurveCcN) == "pan_curvecc44");
REQUIRE(sfz::Opcode("noise_level_smoothcc55", "").getDerivedName(sfz::kOpcodeStepCcN) == "noise_level_stepcc55");
REQUIRE(sfz::Opcode("sample", "").getDerivedName(sfz::kOpcodeSmoothCcN, 66) == "sample_smoothcc66");
}