Add categorization of opcodes
This commit is contained in:
parent
b528f54db1
commit
acbbb8354a
3 changed files with 60 additions and 0 deletions
|
|
@ -6,11 +6,14 @@
|
|||
|
||||
#include "Opcode.h"
|
||||
#include "StringViewHelpers.h"
|
||||
#include "absl/strings/ascii.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include <cctype>
|
||||
|
||||
sfz::Opcode::Opcode(absl::string_view inputOpcode, absl::string_view inputValue)
|
||||
: opcode(trim(inputOpcode))
|
||||
, value(trim(inputValue))
|
||||
, category(identifyCategory(inputOpcode))
|
||||
{
|
||||
size_t nextCharIndex { 0 };
|
||||
int parameterPosition { 0 };
|
||||
|
|
@ -34,3 +37,31 @@ sfz::Opcode::Opcode(absl::string_view inputOpcode, absl::string_view inputValue)
|
|||
if (nextCharIndex != opcode.npos)
|
||||
lettersOnlyHash = hashNoAmpersand(opcode.substr(nextCharIndex), lettersOnlyHash);
|
||||
}
|
||||
|
||||
static absl::string_view extractBackInteger(absl::string_view opcodeName)
|
||||
{
|
||||
size_t n = opcodeName.size();
|
||||
size_t i = n;
|
||||
while (i > 0 && absl::ascii_isdigit(opcodeName[i - 1])) --i;
|
||||
return opcodeName.substr(i);
|
||||
}
|
||||
|
||||
sfz::OpcodeCategory sfz::Opcode::identifyCategory(absl::string_view name)
|
||||
{
|
||||
sfz::OpcodeCategory category = kOpcodeNormal;
|
||||
|
||||
if (!name.empty() && absl::ascii_isdigit(name.back())) {
|
||||
absl::string_view part = name;
|
||||
part.remove_suffix(extractBackInteger(name).size());
|
||||
if (absl::EndsWith(part, "_oncc") || absl::EndsWith(part, "_cc"))
|
||||
category = kOpcodeOnCcN;
|
||||
else if (absl::EndsWith(part, "_curvecc"))
|
||||
category = kOpcodeCurveCcN;
|
||||
else if (absl::EndsWith(part, "_stepcc"))
|
||||
category = kOpcodeStepCcN;
|
||||
else if (absl::EndsWith(part, "_smoothcc"))
|
||||
category = kOpcodeSmoothCcN;
|
||||
}
|
||||
|
||||
return category;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,22 @@
|
|||
#include "absl/strings/numbers.h"
|
||||
|
||||
namespace sfz {
|
||||
/**
|
||||
* @brief A category which an opcode may belong to.
|
||||
*/
|
||||
enum OpcodeCategory {
|
||||
//! An ordinary opcode
|
||||
kOpcodeNormal,
|
||||
//! A region opcode which matches *_onccN or *_ccN
|
||||
kOpcodeOnCcN,
|
||||
//! A region opcode which matches *_curveccN
|
||||
kOpcodeCurveCcN,
|
||||
//! A region opcode which matches *_stepccN
|
||||
kOpcodeStepCcN,
|
||||
//! A region opcode which matches *_smoothccN
|
||||
kOpcodeSmoothCcN,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Opcode description class. The class parses the parameters
|
||||
* of the opcode on construction.
|
||||
|
|
@ -33,6 +49,9 @@ struct Opcode {
|
|||
uint64_t lettersOnlyHash { Fnv1aBasis };
|
||||
// This is to handle the integer parameters of some opcodes
|
||||
std::vector<uint16_t> parameters;
|
||||
OpcodeCategory category;
|
||||
private:
|
||||
static OpcodeCategory identifyCategory(absl::string_view name);
|
||||
LEAK_DETECTOR(Opcode);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -138,3 +138,13 @@ TEST_CASE("[Opcode] Note values")
|
|||
REQUIRE(noteValue);
|
||||
REQUIRE(*noteValue == 61);
|
||||
}
|
||||
|
||||
TEST_CASE("[Opcode] Categories")
|
||||
{
|
||||
REQUIRE(sfz::Opcode("sample", "").category == sfz::kOpcodeNormal);
|
||||
REQUIRE(sfz::Opcode("amplitude_oncc11", "").category == sfz::kOpcodeOnCcN);
|
||||
REQUIRE(sfz::Opcode("cutoff_cc22", "").category == sfz::kOpcodeOnCcN);
|
||||
REQUIRE(sfz::Opcode("lfo01_pitch_curvecc33", "").category == sfz::kOpcodeCurveCcN);
|
||||
REQUIRE(sfz::Opcode("pan_stepcc44", "").category == sfz::kOpcodeStepCcN);
|
||||
REQUIRE(sfz::Opcode("noise_level_smoothcc55", "").category == sfz::kOpcodeSmoothCcN);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue