From 4b45dcc70cfe7d403d23b68f9f737a33e328e8a3 Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Sun, 31 Dec 2023 07:10:02 +0100 Subject: [PATCH] Cleanup region parsing --- src/sfizz/EGDescription.h | 8 +--- src/sfizz/Region.cpp | 95 +++++++++++++++------------------------ 2 files changed, 37 insertions(+), 66 deletions(-) diff --git a/src/sfizz/EGDescription.h b/src/sfizz/EGDescription.h index 0337a305..16feb5ca 100644 --- a/src/sfizz/EGDescription.h +++ b/src/sfizz/EGDescription.h @@ -75,13 +75,7 @@ struct EGDescription { CCMap> ccRelease { ModifierCurvePair{ Default::egTime, Default::curveCC } }; CCMap> ccStart { ModifierCurvePair{ Default::egPercentMod, Default::curveCC } }; CCMap> ccSustain { ModifierCurvePair{ Default:: egPercentMod, Default::curveCC } }; - //CCMap ccAttack; - //CCMap ccDecay; - //CCMap ccDelay; - //CCMap ccHold; - //CCMap ccRelease; - //CCMap ccStart; - //CCMap ccSustain; + bool dynamic { false }; /** diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 8fe46f57..cd951098 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -5,6 +5,7 @@ // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz #include "Region.h" +#include "Defaults.h" #include "Opcode.h" #include "MathHelpers.h" #include "utility/SwapAndPop.h" @@ -1059,6 +1060,16 @@ bool sfz::Region::parseLFOOpcode(const Opcode& opcode, absl::optional +bool parseEGModifierCurveHelper(const sfz::Opcode& opcode, sfz::CCMap>& ccMap, sfz::OpcodeSpec spec, Member member) +{ + if (opcode.parameters.back() >= sfz::config::numCCs) + return false; + + ccMap[opcode.parameters.back()].*member = opcode.read(spec); + return true; +} + bool sfz::Region::parseEGOpcode(const Opcode& opcode, EGDescription& eg) { #define case_any_eg(param) \ @@ -1066,6 +1077,14 @@ bool sfz::Region::parseEGOpcode(const Opcode& opcode, EGDescription& eg) case hash("pitcheg_" param): \ case hash("fileg_" param) \ + auto setModifier = [&opcode] (auto& ccMap, auto& spec) -> bool { + return parseEGModifierCurveHelper(opcode, ccMap, spec, &ModifierCurvePair::modifier); + }; + + auto setCurve = [&opcode] (auto& ccMap) -> bool { + return parseEGModifierCurveHelper(opcode, ccMap, Default::curveCC, &ModifierCurvePair::curve); + }; + switch (opcode.lettersOnlyHash) { case_any_eg("attack"): eg.attack = opcode.read(Default::egTime); @@ -1107,102 +1126,60 @@ bool sfz::Region::parseEGOpcode(const Opcode& opcode, EGDescription& eg) eg.vel2sustain = opcode.read(Default::egPercentMod); break; case_any_eg("attack_oncc&"): // also attackcc& - if (opcode.parameters.back() >= config::numCCs) + if (!setModifier(eg.ccAttack, Default::egTimeMod)) return false; - - eg.ccAttack[opcode.parameters.back()].modifier = opcode.read(Default::egTimeMod); - break; - case_any_eg("attack_curvecc&"): // also attackcc& - if (opcode.parameters.back() >= config::numCCs) + case_any_eg("attack_curvecc&"): + if (!setCurve(eg.ccAttack)) return false; - - eg.ccAttack[opcode.parameters.back()].curve = opcode.read(Default::curveCC); - break; case_any_eg("decay_oncc&"): // also decaycc& - if (opcode.parameters.back() >= config::numCCs) + if (!setModifier(eg.ccDecay, Default::egTimeMod)) return false; - - eg.ccDecay[opcode.parameters.back()].modifier = opcode.read(Default::egTimeMod); - break; - case_any_eg("decay_curvecc&"): // also attackcc& - if (opcode.parameters.back() >= config::numCCs) + case_any_eg("decay_curvecc&"): + if (!setCurve(eg.ccDecay)) return false; - - eg.ccDecay[opcode.parameters.back()].curve = opcode.read(Default::curveCC); - break; case_any_eg("delay_oncc&"): // also delaycc& - if (opcode.parameters.back() >= config::numCCs) + if (!setModifier(eg.ccDelay, Default::egTimeMod)) return false; - - eg.ccDelay[opcode.parameters.back()].modifier = opcode.read(Default::egTimeMod); - break; - case_any_eg("delay_curvecc&"): // also attackcc& - if (opcode.parameters.back() >= config::numCCs) + case_any_eg("delay_curvecc&"): + if (!setCurve(eg.ccDelay)) return false; - - eg.ccDelay[opcode.parameters.back()].curve = opcode.read(Default::curveCC); - break; case_any_eg("hold_oncc&"): // also holdcc& - if (opcode.parameters.back() >= config::numCCs) + if (!setModifier(eg.ccHold, Default::egTimeMod)) return false; - - eg.ccHold[opcode.parameters.back()].modifier = opcode.read(Default::egTimeMod); - break; case_any_eg("hold_curvecc&"): // also attackcc& - if (opcode.parameters.back() >= config::numCCs) + if (!setCurve(eg.ccHold)) return false; - - eg.ccHold[opcode.parameters.back()].curve = opcode.read(Default::curveCC); - break; case_any_eg("release_oncc&"): // also releasecc& - if (opcode.parameters.back() >= config::numCCs) + if (!setModifier(eg.ccRelease, Default::egTimeMod)) return false; - - eg.ccRelease[opcode.parameters.back()].modifier = opcode.read(Default::egTimeMod); - break; case_any_eg("release_curvecc&"): // also attackcc& - if (opcode.parameters.back() >= config::numCCs) + if (!setCurve(eg.ccRelease)) return false; - - eg.ccRelease[opcode.parameters.back()].curve = opcode.read(Default::curveCC); - break; case_any_eg("start_oncc&"): // also startcc& - if (opcode.parameters.back() >= config::numCCs) + if (!setModifier(eg.ccStart, Default::egPercentMod)) return false; - - eg.ccStart[opcode.parameters.back()].modifier = opcode.read(Default::egPercentMod); - break; case_any_eg("start_curvecc&"): // also startcc& - if (opcode.parameters.back() >= config::numCCs) + if (!setCurve(eg.ccStart)) return false; - - eg.ccStart[opcode.parameters.back()].curve = opcode.read(Default::curveCC); - break; case_any_eg("sustain_oncc&"): // also sustaincc& - if (opcode.parameters.back() >= config::numCCs) + if (!setModifier(eg.ccSustain, Default::egPercentMod)) return false; - - eg.ccSustain[opcode.parameters.back()].modifier = opcode.read(Default::egPercentMod); - break; case_any_eg("sustain_curvecc&"): // also attackcc& - if (opcode.parameters.back() >= config::numCCs) + if (!setCurve(eg.ccSustain)) return false; - - eg.ccSustain[opcode.parameters.back()].curve = opcode.read(Default::curveCC); - break; case_any_eg("dynamic"):