From dc6805498116236b77328e06969b1b6ad8eb64a5 Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Thu, 4 Feb 2021 11:52:20 +0100 Subject: [PATCH] Cleanups --- src/sfizz/Defaults.cpp | 7 ++++--- src/sfizz/Defaults.h | 16 ++++++++++++++++ src/sfizz/Opcode.cpp | 30 ++++++++++++++++++++++-------- src/sfizz/Region.cpp | 17 +---------------- tests/RegionValuesT.cpp | 8 ++++---- tests/TestHelpers.h | 2 +- 6 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/sfizz/Defaults.cpp b/src/sfizz/Defaults.cpp index e56171cb..8ac6d3af 100644 --- a/src/sfizz/Defaults.cpp +++ b/src/sfizz/Defaults.cpp @@ -73,7 +73,7 @@ extern const OpcodeSpec ampVelcurve { 0.0f, Range(0.0f, 1.0f), 0 } extern const OpcodeSpec ampRandom { 0.0f, Range(0.0f, 24.0f), 0 }; extern const OpcodeSpec rtDead { false, Range(0, 1), 0 }; extern const OpcodeSpec rtDecay { 0.0f, Range(0.0f, 200.0f), 0 }; -extern const OpcodeSpec filterCutoff { 0.0f, Range(0.0f, 20000.0f), 0 }; +extern const OpcodeSpec filterCutoff { 0.0f, Range(0.0f, 20000.0f), kEnforceUpperBound }; extern const OpcodeSpec filterCutoffMod { 0.0f, Range(-12000.0f, 12000.0f), 0 }; extern const OpcodeSpec filterResonance { 0.0f, Range(0.0f, 96.0f), 0 }; extern const OpcodeSpec filterResonanceMod { 0.0f, Range(0.0f, 96.0f), 0 }; @@ -84,8 +84,8 @@ extern const OpcodeSpec filterKeytrack { 0, Range(0, 1200), 0 }; extern const OpcodeSpec filterVeltrack { 0, Range(-12000, 12000), 0 }; extern const OpcodeSpec eqBandwidth { 1.0f, Range(0.001f, 4.0f), 0 }; extern const OpcodeSpec eqBandwidthMod { 0.0f, Range(-4.0f, 4.0f), 0 }; -extern const OpcodeSpec eqFrequency { 0.0f, Range(0.0f, 30000.0f), 0 }; -extern const OpcodeSpec eqFrequencyMod { 0.0f, Range(-30000.0f, 30000.0f), 0 }; +extern const OpcodeSpec eqFrequency { 0.0f, Range(0.0f, 20000.0f), kEnforceUpperBound }; +extern const OpcodeSpec eqFrequencyMod { 0.0f, Range(-20000.0f, 20000.0f), 0 }; extern const OpcodeSpec eqGain { 0.0f, Range(-96.0f, 96.0f), 0 }; extern const OpcodeSpec eqGainMod { 0.0f, Range(-96.0f, 96.0f), 0 }; extern const OpcodeSpec eqVel2Frequency { 0.0f, Range(-30000.0f, 30000.0f), 0 }; @@ -159,6 +159,7 @@ extern const OpcodeSpec stringsNumber { maxStrings, Range(0, extern const OpcodeSpec trigger { Trigger::attack, Range(Trigger::attack, Trigger::release_key), 0}; extern const OpcodeSpec crossfadeCurve { CrossfadeCurve::power, Range(CrossfadeCurve::gain, CrossfadeCurve::power), 0}; extern const OpcodeSpec offMode { OffMode::fast, Range(OffMode::fast, OffMode::time), 0}; +extern const OpcodeSpec loopMode { LoopMode::no_loop, Range(LoopMode::no_loop, LoopMode::loop_sustain), 0}; extern const OpcodeSpec velocityOverride { VelocityOverride::current, Range(VelocityOverride::current, VelocityOverride::previous), 0}; extern const OpcodeSpec selfMask { SelfMask::mask, Range(SelfMask::mask, SelfMask::dontMask), 0}; extern const OpcodeSpec filter { FilterType::kFilterNone, Range(FilterType::kFilterNone, FilterType::kFilterPeq), 0}; diff --git a/src/sfizz/Defaults.h b/src/sfizz/Defaults.h index 2db5216c..557ae19f 100644 --- a/src/sfizz/Defaults.h +++ b/src/sfizz/Defaults.h @@ -74,6 +74,14 @@ struct OpcodeSpec T defaultInputValue; Range bounds; int flags; + + /** + * @brief Normalizes an input as needed for the spec + * + * @tparam U + * @param input + * @return U + */ template typename std::enable_if::value, U>::type normalizeInput(U input) const { @@ -98,6 +106,13 @@ struct OpcodeSpec return input; } + /** + * @brief Normalizes an input as needed for the spec + * + * @tparam U + * @param input + * @return U + */ template typename std::enable_if::value, U>::type normalizeInput(U input) const { @@ -262,6 +277,7 @@ namespace Default extern const OpcodeSpec stringsNumber; extern const OpcodeSpec trigger; extern const OpcodeSpec offMode; + extern const OpcodeSpec loopMode; extern const OpcodeSpec crossfadeCurve; extern const OpcodeSpec velocityOverride; extern const OpcodeSpec selfMask; diff --git a/src/sfizz/Opcode.cpp b/src/sfizz/Opcode.cpp index 201709de..1628f292 100644 --- a/src/sfizz/Opcode.cpp +++ b/src/sfizz/Opcode.cpp @@ -197,12 +197,12 @@ absl::optional readFloat_(OpcodeSpec spec, absl::string_view v) if (spec.flags & kEnforceUpperBound) return spec.bounds.getEnd(); - return {}; + return absl::nullopt; } else if (returnedValue < static_cast(spec.bounds.getStart())) { if (spec.flags & kEnforceLowerBound) return spec.bounds.getStart(); - return {}; + return absl::nullopt; } return spec.normalizeInput(returnedValue); @@ -223,7 +223,7 @@ absl::optional readNoteValue(absl::string_view value) char noteLetter = absl::ascii_tolower(value.empty() ? '\0' : value.front()); value.remove_prefix(1); if (noteLetter < 'a' || noteLetter > 'g') - return {}; + return absl::nullopt; constexpr int offsetsABCDEFG[] = { 9, 11, 0, 2, 4, 5, 7 }; int noteNumber = offsetsABCDEFG[noteLetter - 'a']; @@ -244,11 +244,11 @@ absl::optional readNoteValue(absl::string_view value) if (absl::StartsWith(value, prefix.first)) { if (prefix.second == +1) { if (validSharpLetters.find(noteLetter) == absl::string_view::npos) - return {}; + return absl::nullopt; } else if (prefix.second == -1) { if (validFlatLetters.find(noteLetter) == absl::string_view::npos) - return {}; + return absl::nullopt; } noteNumber += prefix.second; value.remove_prefix(prefix.first.size()); @@ -258,12 +258,12 @@ absl::optional readNoteValue(absl::string_view value) int octaveNumber; if (!absl::SimpleAtoi(value, &octaveNumber)) - return {}; + return absl::nullopt; noteNumber += (octaveNumber + 1) * 12; if (noteNumber < 0 || noteNumber >= 128) - return {}; + return absl::nullopt; return static_cast(noteNumber); } @@ -293,7 +293,7 @@ absl::optional Opcode::readOptional(OpcodeSpec Opcode::readOptional(OpcodeSpec) const return absl::nullopt; } +template <> +absl::optional Opcode::readOptional(OpcodeSpec) const +{ + switch (hash(value)) { + case hash("no_loop"): return LoopMode::no_loop; + case hash("one_shot"): return LoopMode::one_shot; + case hash("loop_continuous"): return LoopMode::loop_continuous; + case hash("loop_sustain"): return LoopMode::loop_sustain; + } + + DBG("Unknown loop mode: " << value); + return absl::nullopt; +} + template <> absl::optional Opcode::readOptional(OpcodeSpec) const { diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 1355fc67..72324fdb 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -119,22 +119,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) sampleCount = opcode.read(Default::sampleCount); break; case hash("loop_mode"): // also loopmode - switch (hash(opcode.value)) { - case hash("no_loop"): - loopMode = LoopMode::no_loop; - break; - case hash("one_shot"): - loopMode = LoopMode::one_shot; - break; - case hash("loop_continuous"): - loopMode = LoopMode::loop_continuous; - break; - case hash("loop_sustain"): - loopMode = LoopMode::loop_sustain; - break; - default: - DBG("Unkown loop mode:" << opcode.value); - } + loopMode = opcode.readOptional(Default::loopMode); break; case hash("loop_end"): // also loopend loopRange.setEnd(opcode.read(Default::loopEnd)); diff --git a/tests/RegionValuesT.cpp b/tests/RegionValuesT.cpp index c34b6787..dc88297c 100644 --- a/tests/RegionValuesT.cpp +++ b/tests/RegionValuesT.cpp @@ -2891,13 +2891,13 @@ TEST_CASE("[Values] Filter value bounds") SECTION("Cutoff") { synth.loadSfzString(fs::current_path() / "tests/TestFiles/value_tests.sfz", R"( - sample=kick.wav cutoff=20000000 // Ignore the value + sample=kick.wav cutoff=20000000 // Clamp the value sample=kick.wav cutoff=50 cutoff=-100 )"); synth.dispatchMessage(client, 0, "/region0/filter0/cutoff", "", nullptr); synth.dispatchMessage(client, 0, "/region1/filter0/cutoff", "", nullptr); std::vector expected { - "/region0/filter0/cutoff,f : { 0 }", + "/region0/filter0/cutoff,f : { 20000 }", "/region1/filter0/cutoff,f : { 0 }", }; REQUIRE(messageList == expected); @@ -3097,13 +3097,13 @@ TEST_CASE("[Values] EQ value bounds") SECTION("Frequency") { synth.loadSfzString(fs::current_path() / "tests/TestFiles/value_tests.sfz", R"( - sample=kick.wav eq1_freq=20000000 // Ignore + sample=kick.wav eq1_freq=20000000 // Clamp the value sample=kick.wav eq1_freq=50 eq1_freq=-100 )"); synth.dispatchMessage(client, 0, "/region0/eq0/frequency", "", nullptr); synth.dispatchMessage(client, 0, "/region1/eq0/frequency", "", nullptr); std::vector expected { - "/region0/eq0/frequency,f : { 50 }", + "/region0/eq0/frequency,f : { 20000 }", "/region1/eq0/frequency,f : { 50 }", }; REQUIRE(messageList == expected); diff --git a/tests/TestHelpers.h b/tests/TestHelpers.h index 6a5fda7e..0c60fb91 100644 --- a/tests/TestHelpers.h +++ b/tests/TestHelpers.h @@ -5,11 +5,11 @@ // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz #pragma once -#include "catch2/catch.hpp" #include "sfizz/Synth.h" #include "sfizz/Region.h" #include "sfizz/Voice.h" #include "sfizz/Range.h" +#include "catch2/catch.hpp" #include "sfizz/modulations/ModKey.h" class RegionCCView {