diff --git a/src/sfizz/Curve.cpp b/src/sfizz/Curve.cpp index b4dcb93f..1f1c792b 100644 --- a/src/sfizz/Curve.cpp +++ b/src/sfizz/Curve.cpp @@ -40,11 +40,7 @@ Curve Curve::buildCurveFromHeader( if (index >= NumValues) continue; - auto valueOpt = opc.read(fullRange); - if (!valueOpt) - continue; - - setPoint(static_cast(index), *valueOpt); + setPoint(static_cast(index), opc.read(fullRange)); } curve.fill(itp, fillStatus); @@ -267,12 +263,8 @@ void CurveSet::addCurveFromHeader(absl::Span members) int curveIndex = -1; Curve::Interpolator itp = Curve::Interpolator::Linear; - if (const Opcode* opc = findOpcode(hash("curve_index"))) { - if (auto opt = opc->read(Default::curveCC)) - curveIndex = *opt; - else - DBG("Invalid value for curve index: " << opc->value); - } + if (const Opcode* opc = findOpcode(hash("curve_index"))) + curveIndex = opc->read(Default::curveCC); #if 0 // potential sfizz extension if (const Opcode* opc = findOpcode(hash("sfizz:curve_interpolator"))) { diff --git a/src/sfizz/Defaults.cpp b/src/sfizz/Defaults.cpp index 622b72f4..ee712e58 100644 --- a/src/sfizz/Defaults.cpp +++ b/src/sfizz/Defaults.cpp @@ -1,150 +1,163 @@ #include "Defaults.h" +#include "MathHelpers.h" +#include "SfzHelpers.h" namespace sfz { namespace Default { constexpr auto uint32_t_max = std::numeric_limits::max(); -extern const OpcodeSpec delay { 0.0f, Range(0.0f, 100.0f), kEnforceLowerBound }; -extern const OpcodeSpec delayRandom { 0.0f, Range(0.0f, 100.0f), kEnforceLowerBound }; -extern const OpcodeSpec offset { 0, Range(0, uint32_t_max), kEnforceLowerBound }; -extern const OpcodeSpec offsetMod { 0, Range(0, uint32_t_max), kEnforceLowerBound }; -extern const OpcodeSpec offsetRandom { 0, Range(0, uint32_t_max), kEnforceLowerBound }; -extern const OpcodeSpec sampleEnd { uint32_t_max, Range(0, uint32_t_max), kEnforceLowerBound | kEnforceUpperBound }; -extern const OpcodeSpec sampleCount { 0, Range(0, uint32_t_max), 0 }; -extern const OpcodeSpec loopRange { 0, Range(0, uint32_t_max), 0 }; -extern const OpcodeSpec loopCrossfade { 1e-3, Range(1e-3, 1.0f), kEnforceLowerBound | kEnforceUpperBound }; +extern const OpcodeSpec delay { 0.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec delayRandom { 0.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec offset { 0, Range(0, uint32_t_max), 0 }; +extern const OpcodeSpec offsetMod { 0, Range(0, uint32_t_max), 0 }; +extern const OpcodeSpec offsetRandom { 0, Range(0, uint32_t_max), 0 }; +extern const OpcodeSpec sampleEnd { uint32_t_max, Range(0, uint32_t_max), kEnforceLowerBound }; +extern const OpcodeSpec sampleCount { 1, Range(1, uint32_t_max), 0 }; +extern const OpcodeSpec loopStart { 0, Range(0, uint32_t_max), 0 }; +extern const OpcodeSpec loopEnd { uint32_t_max, Range(0, uint32_t_max), 0 }; +extern const OpcodeSpec loopCrossfade { 1e-3, Range(1e-3, 1.0f), 0 }; extern const OpcodeSpec oscillator { OscillatorEnabled::Auto, Range(OscillatorEnabled::Auto, OscillatorEnabled::On), 0 }; extern const OpcodeSpec oscillatorPhase { 0.0f, Range(0.0f, 1.0f), 0 }; -extern const OpcodeSpec oscillatorMode { 0, Range(0, 2), kIgnoreOOB }; -extern const OpcodeSpec oscillatorMulti { 1, Range(1, config::oscillatorsPerVoice), kIgnoreOOB }; +extern const OpcodeSpec oscillatorMode { 0, Range(0, 2), 0 }; +extern const OpcodeSpec oscillatorMulti { 1, Range(1, config::oscillatorsPerVoice), 0 }; extern const OpcodeSpec oscillatorDetune { 0.0f, Range(-12000.0f, 12000.0f), 0 }; extern const OpcodeSpec oscillatorDetuneMod { 0.0f, Range(-12000.0f, 12000.0f), 0 }; -extern const OpcodeSpec oscillatorModDepth { 0.0f, Range(0.0f, 10000.0f), kEnforceLowerBound }; -extern const OpcodeSpec oscillatorModDepthMod { 0.0f, Range(0.0f, 10000.0f), kEnforceLowerBound }; -extern const OpcodeSpec oscillatorQuality { 1, Range(0, 3), kIgnoreOOB }; +extern const OpcodeSpec oscillatorModDepth { 0.0f, Range(0.0f, 10000.0f), kNormalizePercent }; +extern const OpcodeSpec oscillatorModDepthMod { 0.0f, Range(0.0f, 10000.0f), 0 }; +extern const OpcodeSpec oscillatorQuality { 1, Range(0, 3), 0 }; extern const OpcodeSpec group { 0, Range(0, uint32_t_max), 0 }; -extern const OpcodeSpec offTime { 6e-3f, Range(0.0f, 100.0f), kEnforceLowerBound }; +extern const OpcodeSpec offTime { 6e-3f, Range(0.0f, 100.0f), 0 }; extern const OpcodeSpec polyphony { config::maxVoices, Range(0, config::maxVoices), 0 }; extern const OpcodeSpec notePolyphony { config::maxVoices, Range(0, config::maxVoices), 0 }; -extern const OpcodeSpec key { 60, Range(0, 127), kIgnoreOOB | kCanBeNote }; -extern const OpcodeSpec midi7 { 0, Range(0, 127), kIgnoreOOB }; -extern const OpcodeSpec float7 { 0.0f , Range(0.0f, 127.0f), kIgnoreOOB }; -extern const OpcodeSpec bend { 0.0f, Range(-8192.0f, 8192.0f), kIgnoreOOB }; -extern const OpcodeSpec normalized { 0.0f, Range(0.0f, 1.0f), kIgnoreOOB }; -extern const OpcodeSpec bipolar { 0.0f, Range(-1.0f, 1.0f), kIgnoreOOB }; -extern const OpcodeSpec ccNumber { 0, Range(0, config::numCCs), kIgnoreOOB }; -extern const OpcodeSpec smoothCC { 0, Range(0, 100), kIgnoreOOB }; -extern const OpcodeSpec curveCC { 0, Range(0, 255), kIgnoreOOB }; -extern const OpcodeSpec sustainCC { 64, Range(0, 127), kIgnoreOOB }; -extern const OpcodeSpec sustainThreshold { 0.0039f, Range(0.0f, 1.0f), kIgnoreOOB }; +extern const OpcodeSpec key { 60, Range(0, 127), kCanBeNote }; +extern const OpcodeSpec loKey { 0, Range(0, 127), kCanBeNote }; +extern const OpcodeSpec hiKey { 127, Range(0, 127), kCanBeNote }; +extern const OpcodeSpec loCC { 0.0f , Range(0.0f, 127.0f), kNormalizeMidi }; +extern const OpcodeSpec hiCC { 1.0f , Range(0.0f, 127.0f), kNormalizeMidi }; +extern const OpcodeSpec loVel { 0.0f , Range(0.0f, 127.0f), kNormalizeMidi }; +extern const OpcodeSpec hiVel { 1.0f , Range(0.0f, 127.0f), kNormalizeMidi }; +extern const OpcodeSpec loChannelAftertouch { 0, Range(0, 127), 0 }; +extern const OpcodeSpec hiChannelAftertouch { 127, Range(0, 127), 0 }; +extern const OpcodeSpec loBend { -1.0f, Range(-8192.0f, 8192.0f), kNormalizeBend }; +extern const OpcodeSpec hiBend { 1.0f, Range(-8192.0f, 8192.0f), kNormalizeBend }; +extern const OpcodeSpec loNormalized { 0.0f, Range(0.0f, 1.0f), 0 }; +extern const OpcodeSpec hiNormalized { 1.0f, Range(0.0f, 1.0f), 0 }; +extern const OpcodeSpec loBipolar { -1.0f, Range(-1.0f, 1.0f), 0 }; +extern const OpcodeSpec hiBipolar { 1.0f, Range(-1.0f, 1.0f), 0 }; +extern const OpcodeSpec ccNumber { 0, Range(0, config::numCCs), 0 }; +extern const OpcodeSpec smoothCC { 0, Range(0, 100), 0 }; +extern const OpcodeSpec curveCC { 0, Range(0, 255), 0 }; +extern const OpcodeSpec sustainCC { 64, Range(0, 127), 0 }; +extern const OpcodeSpec sustainThreshold { 0.0039f, Range(0.0f, 127.0f), kNormalizeMidi }; extern const OpcodeSpec checkSustain { true, Range(0, 1), 0 }; extern const OpcodeSpec checkSostenuto { true, Range(0, 1), 0 }; -extern const OpcodeSpec bpm { 0.0f, Range(0.0f, 500.0f), kEnforceLowerBound }; -extern const OpcodeSpec sequence { 1, Range(1, 100), kIgnoreOOB }; +extern const OpcodeSpec loBPM { 0.0f, Range(0.0f, 500.0f), 0 }; +extern const OpcodeSpec hiBPM { 500.0f, Range(0.0f, 500.0f), 0 }; +extern const OpcodeSpec sequence { 1, Range(1, 100), 0 }; extern const OpcodeSpec volume { 0.0f, Range(-144.0f, 48.0f), 0 }; extern const OpcodeSpec volumeMod { 0.0f, Range(-144.0f, 48.0f), 0 }; -extern const OpcodeSpec amplitude { 100.0f, Range(0.0f, 100.0f), kEnforceLowerBound }; -extern const OpcodeSpec amplitudeMod { 0.0f, Range(0.0f, 100.0f), kEnforceLowerBound }; -extern const OpcodeSpec pan { 0.0f, Range(-100.0f, 100.0f), 0 }; -extern const OpcodeSpec panMod { 0.0f, Range(-200.0f, 200.0f), 0 }; -extern const OpcodeSpec position { 0.0f, Range(-100.0f, 100.0f), 0 }; -extern const OpcodeSpec positionMod { 0.0f, Range(-200.0f, 200.0f), 0 }; -extern const OpcodeSpec width { 100.0f, Range(-100.0f, 100.0f), 0 }; -extern const OpcodeSpec widthMod { 0.0f, Range(-200.0f, 200.0f), 0 }; -extern const OpcodeSpec crossfadeIn { 0, Range(0, 127), kEnforceLowerBound | kEnforceUpperBound }; -extern const OpcodeSpec crossfadeInNorm { 0.0f, Range(0.0f, 1.0f), kEnforceLowerBound | kEnforceUpperBound }; -extern const OpcodeSpec crossfadeOut { 127, Range(0, 127), kEnforceLowerBound | kEnforceUpperBound }; -extern const OpcodeSpec crossfadeOutNorm { 1.0f, Range(0.0f, 1.0f), kEnforceLowerBound | kEnforceUpperBound }; +extern const OpcodeSpec amplitude { 100.0f, Range(0.0f, 10000.0f), kNormalizePercent }; +extern const OpcodeSpec amplitudeMod { 0.0f, Range(0.0f, 10000.0f), kNormalizePercent }; +extern const OpcodeSpec pan { 0.0f, Range(-100.0f, 100.0f), kNormalizePercent }; +extern const OpcodeSpec panMod { 0.0f, Range(-200.0f, 200.0f), kNormalizePercent }; +extern const OpcodeSpec position { 0.0f, Range(-100.0f, 100.0f), kNormalizePercent }; +extern const OpcodeSpec positionMod { 0.0f, Range(-200.0f, 200.0f), kNormalizePercent }; +extern const OpcodeSpec width { 100.0f, Range(-100.0f, 100.0f), kNormalizePercent }; +extern const OpcodeSpec widthMod { 0.0f, Range(-200.0f, 200.0f), kNormalizePercent }; +extern const OpcodeSpec crossfadeIn { 0.0f, Range(0.0f, 127.0f), kNormalizeMidi }; +extern const OpcodeSpec crossfadeInNorm { 0.0f, Range(0.0f, 1.0f), 0 }; +extern const OpcodeSpec crossfadeOut { 1.0f, Range(0.0f, 127.0f), kNormalizeMidi }; +extern const OpcodeSpec crossfadeOutNorm { 1.0f, Range(0.0f, 1.0f), 0 }; extern const OpcodeSpec ampKeytrack { 0.0f, Range(-96.0f, 12.0f), 0 }; -extern const OpcodeSpec ampVeltrack { 100.0f, Range(-100.0f, 100.0f), kIgnoreOOB }; -extern const OpcodeSpec ampVelcurve { 0.0f, Range(0.0f, 1.0f), kEnforceLowerBound | kEnforceUpperBound }; -extern const OpcodeSpec ampRandom { 0.0f, Range(0.0f, 24.0f), kEnforceLowerBound }; +extern const OpcodeSpec ampVeltrack { 100.0f, Range(-100.0f, 100.0f), 0 }; +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), kEnforceLowerBound }; -extern const OpcodeSpec filterCutoff { 0.0f, Range(0.0f, 20000.0f), kEnforceLowerBound | kEnforceUpperBound }; -extern const OpcodeSpec filterCutoffMod { 0.0f, Range(-12000.0f, 12000.0f), kEnforceLowerBound }; -extern const OpcodeSpec filterResonance { 0.0f, Range(0.0f, 96.0f), kEnforceLowerBound }; -extern const OpcodeSpec filterResonanceMod { 0.0f, Range(0.0f, 96.0f), kEnforceLowerBound }; +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 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 }; extern const OpcodeSpec filterGain { 0.0f, Range(-96.0f, 96.0f), 0 }; extern const OpcodeSpec filterGainMod { 0.0f, Range(-96.0f, 96.0f), 0 }; -extern const OpcodeSpec filterRandom { 0.0f, Range(0.0f, 12000.0f), kEnforceLowerBound }; -extern const OpcodeSpec filterKeytrack { 0, Range(0, 1200), kEnforceLowerBound }; +extern const OpcodeSpec filterRandom { 0.0f, Range(0.0f, 12000.0f), 0 }; +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), kEnforceLowerBound }; +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), kEnforceLowerBound | kEnforceUpperBound }; +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 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 }; extern const OpcodeSpec eqVel2Gain { 0.0f, Range(-96.0f, 96.0f), 0 }; extern const OpcodeSpec pitchKeytrack { 100, Range(-1200, 1200), 0 }; -extern const OpcodeSpec pitchRandom { 0.0f, Range(0.0f, 12000.0f), kEnforceLowerBound }; +extern const OpcodeSpec pitchRandom { 0.0f, Range(0.0f, 12000.0f), 0 }; extern const OpcodeSpec pitchVeltrack { 0, Range(-12000, 12000), 0 }; -extern const OpcodeSpec transpose { 0, Range(-127, 127), kIgnoreOOB }; +extern const OpcodeSpec transpose { 0, Range(-127, 127), 0 }; extern const OpcodeSpec pitch { 0.0f, Range(-100.0f, 100.0f), 0 }; extern const OpcodeSpec pitchMod { 0.0f, Range(-100.0f, 100.0f), 0 }; extern const OpcodeSpec bendUp { 200.0f, Range(-12000.0f, 12000.0f), 0 }; extern const OpcodeSpec bendDown { -200.0f, Range(-12000.0f, 12000.0f), 0 }; -extern const OpcodeSpec bendStep { 1.0f, Range(1.0f, 1200.0f), kIgnoreOOB }; +extern const OpcodeSpec bendStep { 1.0f, Range(1.0f, 1200.0f), 0 }; extern const OpcodeSpec lfoFreq { 0.0f, Range(0.0f, 100.0f), 0 }; extern const OpcodeSpec lfoFreqMod { 0.0f, Range(-100.0f, 100.0f), 0 }; extern const OpcodeSpec lfoBeats { 0.0f, Range(0.0f, 1000.0f), 0 }; extern const OpcodeSpec lfoBeatsMod { 0.0f, Range(-1000.0f, 1000.0f), 0 }; -extern const OpcodeSpec lfoPhase { 0.0f, Range(0.0f, 1.0f), 0 }; +extern const OpcodeSpec lfoPhase { 0.0f, Range(0.0f, 1.0f), kWrapPhase }; extern const OpcodeSpec lfoDelay { 0.0f, Range(0.0f, 30.0f), 0 }; extern const OpcodeSpec lfoFade { 0.0f, Range(0.0f, 30.0f), 0 }; extern const OpcodeSpec lfoCount { 0, Range(0, 1000), 0 }; extern const OpcodeSpec lfoSteps { 0, Range(0, static_cast(config::maxLFOSteps)), 0 }; -extern const OpcodeSpec lfoStepX { 0.0f, Range(-100.0f, 100.0f), 0 }; -extern const OpcodeSpec lfoWave { 0, Range(0, 15), 0 }; +extern const OpcodeSpec lfoStepX { 0.0f, Range(-100.0f, 100.0f), kNormalizePercent }; +extern const OpcodeSpec lfoWave { LFOWave::Triangle, Range(LFOWave::Triangle, LFOWave::RandomSH), 0 }; extern const OpcodeSpec lfoOffset { 0.0f, Range(-1.0f, 1.0f), 0 }; extern const OpcodeSpec lfoRatio { 1.0f, Range(0.0f, 100.0f), 0 }; extern const OpcodeSpec lfoScale { 1.0f, Range(0.0f, 1.0f), 0 }; -extern const OpcodeSpec egTime { 0.0f, Range(0.0f, 100.0f), kEnforceLowerBound }; -extern const OpcodeSpec egRelease { 0.001f, Range(0.0f, 100.0f), kEnforceLowerBound }; +extern const OpcodeSpec egTime { 0.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec egRelease { 0.001f, Range(0.0f, 100.0f), 0 }; extern const OpcodeSpec egTimeMod { 0.0f, Range(-100.0f, 100.0f), 0 }; -extern const OpcodeSpec egPercent { 0.0f, Range(0.0f, 100.0f), kEnforceLowerBound }; +extern const OpcodeSpec egPercent { 0.0f, Range(0.0f, 100.0f), 0 }; extern const OpcodeSpec egPercentMod { 0.0f, Range(-100.0f, 100.0f), 0 }; extern const OpcodeSpec egDepth { 0.0f, Range(-12000.0f, 12000.0f), 0 }; extern const OpcodeSpec egVel2Depth { 0.0f, Range(-12000.0f, 12000.0f), 0 }; extern const OpcodeSpec flexEGAmpeg { false, Range(0, 1), 0 }; -extern const OpcodeSpec flexEGDynamic { 0, Range(0, 1), kIgnoreOOB }; -extern const OpcodeSpec flexEGSustain { 0, Range(0, 100), kIgnoreOOB }; -extern const OpcodeSpec flexEGPointTime { 0.0f, Range(0.0f, 100.0f), kEnforceLowerBound }; -extern const OpcodeSpec flexEGPointLevel { 0.0f, Range(-1.0f, 1.0f), kIgnoreOOB }; -extern const OpcodeSpec flexEGPointShape { 0.0f, Range(-100.0f, 100.0f), kEnforceLowerBound | kEnforceUpperBound }; -extern const OpcodeSpec sampleQuality { 1, Range(1, 10), kIgnoreOOB }; +extern const OpcodeSpec flexEGDynamic { 0, Range(0, 1), 0 }; +extern const OpcodeSpec flexEGSustain { 0, Range(0, 100), 0 }; +extern const OpcodeSpec flexEGPointTime { 0.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec flexEGPointLevel { 0.0f, Range(-1.0f, 1.0f), 0 }; +extern const OpcodeSpec flexEGPointShape { 0.0f, Range(-100.0f, 100.0f), 0 }; +extern const OpcodeSpec sampleQuality { 1, Range(1, 10), 0 }; extern const OpcodeSpec octaveOffset { 0, Range(-10, 10), 0 }; extern const OpcodeSpec noteOffset { 0, Range(-127, 127), 0 }; -extern const OpcodeSpec effect { 0.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec effect { 0.0f, Range(0.0f, 100.0f), kNormalizePercent }; extern const OpcodeSpec apanWaveform { 0, Range(0, std::numeric_limits::max()), 0 }; -extern const OpcodeSpec apanFrequency { 0.0f, Range(0.0f, std::numeric_limits::max()), kEnforceLowerBound }; -extern const OpcodeSpec apanPhase { 0.5f, Range(0.0f, 1.0f), 0 }; -extern const OpcodeSpec apanLevel { 0.0f, Range(0.0f, 100.0f), kEnforceLowerBound }; -extern const OpcodeSpec distoTone { 100.0f, Range(0.0f, 100.0f), kEnforceLowerBound | kEnforceUpperBound }; -extern const OpcodeSpec distoDepth { 0.0f, Range(0.0f, 100.0f), kEnforceLowerBound | kEnforceUpperBound }; -extern const OpcodeSpec distoStages { 1, Range(1, maxDistoStages), kEnforceLowerBound }; -extern const OpcodeSpec compAttack { 0.005f, Range(0.0f, 10.0f), kEnforceLowerBound }; -extern const OpcodeSpec compRelease { 0.05f, Range(0.0f, 10.0f), kEnforceLowerBound }; +extern const OpcodeSpec apanFrequency { 0.0f, Range(0.0f, std::numeric_limits::max()), 0 }; +extern const OpcodeSpec apanPhase { 0.5f, Range(0.0f, 1.0f), kWrapPhase }; +extern const OpcodeSpec apanLevel { 0.0f, Range(0.0f, 100.0f), kNormalizePercent }; +extern const OpcodeSpec distoTone { 100.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec distoDepth { 0.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec distoStages { 1, Range(1, maxDistoStages), 0 }; +extern const OpcodeSpec compAttack { 0.005f, Range(0.0f, 10.0f), 0 }; +extern const OpcodeSpec compRelease { 0.05f, Range(0.0f, 10.0f), 0 }; extern const OpcodeSpec compSTLink { false, Range(0, 1), 0 }; -extern const OpcodeSpec compThreshold { 0.0f, Range(-100.0f, 0.0f), kIgnoreOOB }; -extern const OpcodeSpec compRatio { 1.0f, Range(1.0f, 50.0f), kIgnoreOOB }; -extern const OpcodeSpec compGain { 0.0f, Range(-100.0f, 100.0f), 0 }; -extern const OpcodeSpec fverbSize { 0.0f, Range(0.0f, 100.0f), kEnforceLowerBound }; -extern const OpcodeSpec fverbPredelay { 0.0f, Range(0.0f, 10.0f), kEnforceLowerBound }; -extern const OpcodeSpec fverbTone { 100.0f, Range(0.0f, 100.0f), kIgnoreOOB }; -extern const OpcodeSpec fverbDamp { 0.0f, Range(0.0f, 100.0f), kIgnoreOOB }; +extern const OpcodeSpec compThreshold { 0.0f, Range(-100.0f, 0.0f), 0 }; +extern const OpcodeSpec compRatio { 1.0f, Range(1.0f, 50.0f), 0 }; +extern const OpcodeSpec compGain { 1.0f, Range(-100.0f, 100.0f), kDb2Mag }; +extern const OpcodeSpec fverbSize { 0.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec fverbPredelay { 0.0f, Range(0.0f, 10.0f), 0 }; +extern const OpcodeSpec fverbTone { 100.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec fverbDamp { 0.0f, Range(0.0f, 100.0f), 0 }; extern const OpcodeSpec gateSTLink { false, Range(0, 1), 0 }; -extern const OpcodeSpec gateAttack { 0.005f, Range(0.0f, 10.0f), kEnforceLowerBound }; -extern const OpcodeSpec gateRelease { 0.05f, Range(0.0f, 10.0f), kEnforceLowerBound }; -extern const OpcodeSpec gateHold { 0.0f, Range(0.0f, 10.0f), kEnforceLowerBound }; -extern const OpcodeSpec gateThreshold { 0.0f, Range(-100.0f, 0.0f), kIgnoreOOB }; -extern const OpcodeSpec lofiBitred { 0.0f, Range(0.0f, 100.0f), kIgnoreOOB }; -extern const OpcodeSpec lofiDecim { 0.0f, Range(0.0f, 100.0f), kIgnoreOOB }; -extern const OpcodeSpec rectify { 0.0f, Range(0.0f, 100.0f), kIgnoreOOB }; -extern const OpcodeSpec stringsNumber { maxStrings, Range(0, maxStrings), kEnforceLowerBound }; +extern const OpcodeSpec gateAttack { 0.005f, Range(0.0f, 10.0f), 0 }; +extern const OpcodeSpec gateRelease { 0.05f, Range(0.0f, 10.0f), 0 }; +extern const OpcodeSpec gateHold { 0.0f, Range(0.0f, 10.0f), 0 }; +extern const OpcodeSpec gateThreshold { 0.0f, Range(-100.0f, 0.0f), 0 }; +extern const OpcodeSpec lofiBitred { 0.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec lofiDecim { 0.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec rectify { 0.0f, Range(0.0f, 100.0f), 0 }; +extern const OpcodeSpec stringsNumber { maxStrings, Range(0, maxStrings), 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}; diff --git a/src/sfizz/Defaults.h b/src/sfizz/Defaults.h index 98d34919..27f5481c 100644 --- a/src/sfizz/Defaults.h +++ b/src/sfizz/Defaults.h @@ -41,20 +41,37 @@ enum class VelocityOverride { current = 0, previous }; enum class CrossfadeCurve { gain = 0, power }; enum class SelfMask { mask = 0, dontMask }; enum class OscillatorEnabled { Auto = -1, Off = 0, On = 1 }; +enum class LFOWave : int { + Triangle, + Sine, + Pulse75, + Square, + Pulse25, + Pulse12_5, + Ramp, + Saw, + // ARIA extra + RandomSH = 12, +}; enum OpcodeFlags : int { - kIgnoreOOB = 1, + kCanBeNote = 1, kEnforceLowerBound = 1 << 1, kEnforceUpperBound = 1 << 2, - kCanBeNote = 1 << 3, + kNormalizePercent = 1 << 3, + kNormalizeMidi = 1 << 4, + kNormalizeBend = 1 << 5, + kWrapPhase = 1 << 6, + kDb2Mag = 1 << 7, }; template struct OpcodeSpec { - T value; + T defaultValue; Range bounds; int flags; + operator T() const { return defaultValue; } }; namespace Default @@ -66,7 +83,8 @@ namespace Default extern const OpcodeSpec offsetRandom; extern const OpcodeSpec sampleEnd; extern const OpcodeSpec sampleCount; - extern const OpcodeSpec loopRange; + extern const OpcodeSpec loopStart; + extern const OpcodeSpec loopEnd; extern const OpcodeSpec loopCrossfade; extern const OpcodeSpec oscillatorPhase; extern const OpcodeSpec oscillator; @@ -82,11 +100,20 @@ namespace Default extern const OpcodeSpec polyphony; extern const OpcodeSpec notePolyphony; extern const OpcodeSpec key; - extern const OpcodeSpec midi7; - extern const OpcodeSpec float7; - extern const OpcodeSpec bend; - extern const OpcodeSpec normalized; - extern const OpcodeSpec bipolar; + extern const OpcodeSpec loKey; + extern const OpcodeSpec hiKey; + extern const OpcodeSpec loVel; + extern const OpcodeSpec hiVel; + extern const OpcodeSpec loCC; + extern const OpcodeSpec hiCC; + extern const OpcodeSpec loBend; + extern const OpcodeSpec hiBend; + extern const OpcodeSpec loNormalized; + extern const OpcodeSpec hiNormalized; + extern const OpcodeSpec loBipolar; + extern const OpcodeSpec hiBipolar; + extern const OpcodeSpec loChannelAftertouch; + extern const OpcodeSpec hiChannelAftertouch; extern const OpcodeSpec ccNumber; extern const OpcodeSpec curveCC; extern const OpcodeSpec smoothCC; @@ -94,7 +121,8 @@ namespace Default extern const OpcodeSpec checkSustain; extern const OpcodeSpec checkSostenuto; extern const OpcodeSpec sustainThreshold; - extern const OpcodeSpec bpm; + extern const OpcodeSpec loBPM; + extern const OpcodeSpec hiBPM; extern const OpcodeSpec sequence; extern const OpcodeSpec volume; extern const OpcodeSpec volumeMod; @@ -106,9 +134,9 @@ namespace Default extern const OpcodeSpec positionMod; extern const OpcodeSpec width; extern const OpcodeSpec widthMod; - extern const OpcodeSpec crossfadeIn; + extern const OpcodeSpec crossfadeIn; extern const OpcodeSpec crossfadeInNorm; - extern const OpcodeSpec crossfadeOut; + extern const OpcodeSpec crossfadeOut; extern const OpcodeSpec crossfadeOutNorm; extern const OpcodeSpec ampKeytrack; extern const OpcodeSpec ampVeltrack; @@ -152,7 +180,7 @@ namespace Default extern const OpcodeSpec lfoCount; extern const OpcodeSpec lfoSteps; extern const OpcodeSpec lfoStepX; - extern const OpcodeSpec lfoWave; + extern const OpcodeSpec lfoWave; extern const OpcodeSpec lfoOffset; extern const OpcodeSpec lfoRatio; extern const OpcodeSpec lfoScale; diff --git a/src/sfizz/EGDescription.h b/src/sfizz/EGDescription.h index 89edfde2..5bf81ca4 100644 --- a/src/sfizz/EGDescription.h +++ b/src/sfizz/EGDescription.h @@ -66,21 +66,21 @@ struct EGDescription { EGDescription& operator=(const EGDescription&) = default; EGDescription& operator=(EGDescription&&) = default; - float attack { Default::egTime.value }; - float decay { Default::egTime.value }; - float delay { Default::egTime.value }; - float hold { Default::egTime.value }; - float release { Default::egTime.value }; + float attack { Default::egTime }; + float decay { Default::egTime }; + float delay { Default::egTime }; + float hold { Default::egTime }; + float release { Default::egTime }; float start { Default::egPercent.bounds.getStart() }; float sustain { Default::egPercent.bounds.getEnd() }; - float depth { Default::egDepth.value }; - float vel2attack { Default::egTimeMod.value }; - float vel2decay { Default::egTimeMod.value }; - float vel2delay { Default::egTimeMod.value }; - float vel2hold { Default::egTimeMod.value }; - float vel2release { Default::egPercentMod.value }; - float vel2sustain { Default::egPercentMod.value }; - float vel2depth { Default::egVel2Depth.value }; + float depth { Default::egDepth }; + float vel2attack { Default::egTimeMod }; + float vel2decay { Default::egTimeMod }; + float vel2delay { Default::egTimeMod }; + float vel2hold { Default::egTimeMod }; + float vel2release { Default::egPercentMod }; + float vel2sustain { Default::egPercentMod }; + float vel2depth { Default::egVel2Depth }; CCMap ccAttack; CCMap ccDecay; diff --git a/src/sfizz/EQDescription.h b/src/sfizz/EQDescription.h index 246d545b..7860d756 100644 --- a/src/sfizz/EQDescription.h +++ b/src/sfizz/EQDescription.h @@ -14,11 +14,11 @@ namespace sfz { struct EQDescription { - float bandwidth { Default::eqBandwidth.value }; - float frequency { Default::eqFrequency.value }; - float gain { Default::eqGain.value }; - float vel2frequency { Default::eqVel2Frequency.value }; - float vel2gain { Default::eqVel2Gain.value }; + float bandwidth { Default::eqBandwidth }; + float frequency { Default::eqFrequency }; + float gain { Default::eqGain }; + float vel2frequency { Default::eqVel2Frequency }; + float vel2gain { Default::eqVel2Gain }; EqType type { EqType::kEqPeak }; }; } diff --git a/src/sfizz/EQPool.h b/src/sfizz/EQPool.h index 63ba5dde..54567b2f 100644 --- a/src/sfizz/EQPool.h +++ b/src/sfizz/EQPool.h @@ -43,9 +43,9 @@ private: Resources& resources; const EQDescription* description; std::unique_ptr eq; - float baseBandwidth { Default::eqBandwidth.value }; - float baseFrequency { Default::eqFrequency.value }; - float baseGain { Default::eqGain.value }; + float baseBandwidth { Default::eqBandwidth }; + float baseFrequency { Default::eqFrequency }; + float baseGain { Default::eqGain }; bool prepared { false }; ModMatrix::TargetId gainTarget; ModMatrix::TargetId frequencyTarget; diff --git a/src/sfizz/Effects.h b/src/sfizz/Effects.h index 838557a8..8cc5d63f 100644 --- a/src/sfizz/Effects.h +++ b/src/sfizz/Effects.h @@ -179,8 +179,8 @@ private: std::vector> _effects; AudioBuffer _inputs { EffectChannels, config::defaultSamplesPerBlock }; AudioBuffer _outputs { EffectChannels, config::defaultSamplesPerBlock }; - float _gainToMain { Default::effect.value }; - float _gainToMix { Default::effect.value }; + float _gainToMain { Default::effect }; + float _gainToMix { Default::effect }; }; } // namespace sfz diff --git a/src/sfizz/FilePool.cpp b/src/sfizz/FilePool.cpp index b86bf76f..50617169 100644 --- a/src/sfizz/FilePool.cpp +++ b/src/sfizz/FilePool.cpp @@ -255,7 +255,7 @@ absl::optional sfz::FilePool::getFileInformation(const Fil if (!fileId.isReverse()) { if (haveInstrumentInfo && instrumentInfo.loop_count > 0) { returnedValue.hasLoop = true; - returnedValue.loopBegin = instrumentInfo.loops[0].start; + returnedValue.loopStart = instrumentInfo.loops[0].start; returnedValue.loopEnd = min(returnedValue.end, instrumentInfo.loops[0].end - 1); } } else { @@ -297,7 +297,7 @@ bool sfz::FilePool::preloadFile(const FileId& fileId, uint32_t maxOffset) noexce const auto factor = static_cast(oversamplingFactor); fileInformation->sampleRate = factor * static_cast(reader->sampleRate()); fileInformation->end = static_cast(factor * fileInformation->end); - fileInformation->loopBegin = static_cast(factor * fileInformation->loopBegin); + fileInformation->loopStart = static_cast(factor * fileInformation->loopStart); fileInformation->loopEnd = static_cast(factor * fileInformation->loopEnd); auto insertedPair = preloadedFiles.insert_or_assign(fileId, { readFromFile(*reader, framesToLoad, oversamplingFactor), @@ -329,7 +329,7 @@ sfz::FileDataHolder sfz::FilePool::loadFile(const FileId& fileId) noexcept const auto factor = static_cast(oversamplingFactor); fileInformation->sampleRate = factor * static_cast(reader->sampleRate()); fileInformation->end = static_cast(factor * fileInformation->end); - fileInformation->loopBegin = static_cast(factor * fileInformation->loopBegin); + fileInformation->loopStart = static_cast(factor * fileInformation->loopStart); fileInformation->loopEnd = static_cast(factor * fileInformation->loopEnd); auto insertedPair = preloadedFiles.insert_or_assign(fileId, { readFromFile(*reader, frames, oversamplingFactor), @@ -461,7 +461,7 @@ void sfz::FilePool::setOversamplingFactor(sfz::Oversampling factor) noexcept FileInformation& information = preloadedFile.second.information; information.sampleRate *= samplerateChange; information.end = static_cast(samplerateChange * information.end); - information.loopBegin = static_cast(samplerateChange * information.loopBegin); + information.loopStart = static_cast(samplerateChange * information.loopStart); information.loopEnd = static_cast(samplerateChange * information.loopEnd); if (preloadedFile.second.status == FileData::Status::Done) { diff --git a/src/sfizz/FilePool.h b/src/sfizz/FilePool.h index 2c77f6d9..6936fb63 100644 --- a/src/sfizz/FilePool.h +++ b/src/sfizz/FilePool.h @@ -51,10 +51,10 @@ using FileAudioBuffer = AudioBuffer; struct FileInformation { - uint32_t end { Default::sampleEnd.value }; + uint32_t end { Default::sampleEnd }; uint32_t maxOffset { 0 }; - uint32_t loopBegin { Default::loopRange.bounds.getStart() }; - uint32_t loopEnd { Default::loopRange.bounds.getEnd() }; + uint32_t loopStart { Default::loopStart }; + uint32_t loopEnd { Default::loopEnd }; bool hasLoop { false }; double sampleRate { config::defaultSampleRate }; int numChannels { 0 }; diff --git a/src/sfizz/FilterDescription.h b/src/sfizz/FilterDescription.h index 7bdc39b6..612d1e58 100644 --- a/src/sfizz/FilterDescription.h +++ b/src/sfizz/FilterDescription.h @@ -14,13 +14,13 @@ namespace sfz { struct FilterDescription { - float cutoff { Default::filterCutoff.value }; - float resonance { Default::filterCutoff.value }; - float gain { Default::filterGain.value }; - int keytrack { Default::filterKeytrack.value }; - uint8_t keycenter { Default::key.value }; - int veltrack { Default::filterVeltrack.value }; - float random { Default::filterRandom.value }; + float cutoff { Default::filterCutoff }; + float resonance { Default::filterCutoff }; + float gain { Default::filterGain }; + int keytrack { Default::filterKeytrack }; + uint8_t keycenter { Default::key }; + int veltrack { Default::filterVeltrack }; + float random { Default::filterRandom }; FilterType type { FilterType::kFilterLpf2p }; }; } diff --git a/src/sfizz/FilterPool.h b/src/sfizz/FilterPool.h index 13ecbb94..ab761124 100644 --- a/src/sfizz/FilterPool.h +++ b/src/sfizz/FilterPool.h @@ -22,7 +22,7 @@ public: * @param noteNumber the triggering note number * @param velocity the triggering note velocity/value */ - void setup(const Region& region, unsigned filterId, int noteNumber = static_cast(Default::key.value), float velocity = 0); + void setup(const Region& region, unsigned filterId, int noteNumber = static_cast(Default::key), float velocity = 0); /** * @brief Process a block of stereo inputs * @@ -45,9 +45,9 @@ private: Resources& resources; const FilterDescription* description; std::unique_ptr filter; - float baseCutoff { Default::filterCutoff.value }; - float baseResonance { Default::filterResonance.value }; - float baseGain { Default::filterGain.value }; + float baseCutoff { Default::filterCutoff }; + float baseResonance { Default::filterResonance }; + float baseGain { Default::filterGain }; ModMatrix::TargetId gainTarget; ModMatrix::TargetId cutoffTarget; ModMatrix::TargetId resonanceTarget; diff --git a/src/sfizz/FlexEGDescription.h b/src/sfizz/FlexEGDescription.h index 7788329d..8ba22069 100644 --- a/src/sfizz/FlexEGDescription.h +++ b/src/sfizz/FlexEGDescription.h @@ -18,24 +18,24 @@ namespace FlexEGs { }; struct FlexEGPoint { - float time { Default::flexEGPointTime.value }; // duration until next step (s) - float level { Default::flexEGPointLevel.value }; // normalized amplitude + float time { Default::flexEGPointTime }; // duration until next step (s) + float level { Default::flexEGPointLevel }; // normalized amplitude void setShape(float shape); float shape() const noexcept { return shape_; } const Curve& curve() const; private: - float shape_ { Default::flexEGPointShape.value }; // 0: linear, positive: exp, negative: log + float shape_ { Default::flexEGPointShape }; // 0: linear, positive: exp, negative: log std::shared_ptr shapeCurve_; }; struct FlexEGDescription { - int dynamic { Default::flexEGDynamic.value }; // whether parameters can be modulated while EG runs - int sustain { Default::flexEGSustain.value }; // index of the sustain point (default to 0 in ARIA) + int dynamic { Default::flexEGDynamic }; // whether parameters can be modulated while EG runs + int sustain { Default::flexEGSustain }; // index of the sustain point (default to 0 in ARIA) std::vector points; // ARIA - bool ampeg { Default::flexEGAmpeg.value }; // replaces the SFZv1 AmpEG (lowest with this bit wins) + bool ampeg { Default::flexEGAmpeg }; // replaces the SFZv1 AmpEG (lowest with this bit wins) }; } // namespace sfz diff --git a/src/sfizz/LFODescription.h b/src/sfizz/LFODescription.h index ea312bca..82859779 100644 --- a/src/sfizz/LFODescription.h +++ b/src/sfizz/LFODescription.h @@ -11,34 +11,21 @@ namespace sfz { -enum class LFOWave : int { - Triangle, - Sine, - Pulse75, - Square, - Pulse25, - Pulse12_5, - Ramp, - Saw, - // ARIA extra - RandomSH = 12, -}; - struct LFODescription { LFODescription(); ~LFODescription(); static const LFODescription& getDefault(); - float freq { Default::lfoFreq.value }; // lfoN_freq - float beats { Default::lfoBeats.value }; // lfoN_beats - float phase0 { Default::lfoPhase.value }; // lfoN_phase - float delay { Default::lfoDelay.value }; // lfoN_delay - float fade { Default::lfoFade.value }; // lfoN_fade - unsigned count { Default::lfoCount.value }; // lfoN_count + float freq { Default::lfoFreq }; // lfoN_freq + float beats { Default::lfoBeats }; // lfoN_beats + float phase0 { Default::lfoPhase }; // lfoN_phase + float delay { Default::lfoDelay }; // lfoN_delay + float fade { Default::lfoFade }; // lfoN_fade + unsigned count { Default::lfoCount }; // lfoN_count struct Sub { - LFOWave wave { static_cast(Default::lfoWave.value) }; // lfoN_wave[X] - float offset { Default::lfoOffset.value }; // lfoN_offset[X] - float ratio { Default::lfoRatio.value }; // lfoN_ratio[X] - float scale { Default::lfoScale.value }; // lfoN_scale[X] + LFOWave wave { Default::lfoWave }; // lfoN_wave[X] + float offset { Default::lfoOffset }; // lfoN_offset[X] + float ratio { Default::lfoRatio }; // lfoN_ratio[X] + float scale { Default::lfoScale }; // lfoN_scale[X] }; struct StepSequence { std::vector steps {}; // lfoN_stepX - normalized to unity diff --git a/src/sfizz/Opcode.cpp b/src/sfizz/Opcode.cpp index 7f5f59d1..a3e747fc 100644 --- a/src/sfizz/Opcode.cpp +++ b/src/sfizz/Opcode.cpp @@ -5,6 +5,7 @@ // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz #include "Opcode.h" +#include "LFODescription.h" #include "StringViewHelpers.h" #include "absl/strings/ascii.h" #include "absl/strings/match.h" @@ -141,30 +142,22 @@ absl::optional readInt_(OpcodeSpec spec, absl::string_view v) if (spec.flags & kEnforceUpperBound) return spec.bounds.getEnd(); - if (spec.flags & kIgnoreOOB) - return {}; - } - - if (returnedValue < static_cast(spec.bounds.getStart())) { + return {}; + } else if (returnedValue < static_cast(spec.bounds.getStart())) { if (spec.flags & kEnforceLowerBound) return spec.bounds.getStart(); - if (spec.flags & kIgnoreOOB) - return {}; + return {}; } - T castValue = static_cast(returnedValue); - if ((castValue != returnedValue) & kIgnoreOOB) - return {}; - - return castValue; + return returnedValue; } #define INSTANTIATE_FOR_INTEGRAL(T) \ template <> \ - absl::optional Opcode::read(OpcodeSpec spec) const \ + T Opcode::read(OpcodeSpec spec) const \ { \ - return readInt_(spec, value); \ + return readInt_(spec, value).value_or(spec.defaultValue); \ } INSTANTIATE_FOR_INTEGRAL(uint8_t) @@ -198,30 +191,37 @@ absl::optional readFloat_(OpcodeSpec spec, absl::string_view v) if (!absl::SimpleAtof(v, &returnedValue)) return absl::nullopt; - if (returnedValue > static_cast(spec.bounds.getEnd())) { + if (spec.flags & kWrapPhase) + returnedValue = wrapPhase(returnedValue); + else if (returnedValue > static_cast(spec.bounds.getEnd())) { if (spec.flags & kEnforceUpperBound) return spec.bounds.getEnd(); - if (spec.flags & kIgnoreOOB) - return {}; - } - - if (returnedValue < static_cast(spec.bounds.getStart())) { + return {}; + } else if (returnedValue < static_cast(spec.bounds.getStart())) { if (spec.flags & kEnforceLowerBound) return spec.bounds.getStart(); - if (spec.flags & kIgnoreOOB) - return {}; + return {}; } + if (spec.flags & kNormalizeMidi) + returnedValue = normalize7Bits(returnedValue); + else if (spec.flags & kNormalizePercent) + returnedValue = normalizePercents(returnedValue); + else if (spec.flags & kNormalizeBend) + returnedValue = normalizeBend(returnedValue); + else if (spec.flags & kDb2Mag) + returnedValue = db2mag(returnedValue); + return returnedValue; } #define INSTANTIATE_FOR_FLOATING_POINT(T) \ template <> \ - absl::optional Opcode::read(OpcodeSpec spec) const \ + T Opcode::read(OpcodeSpec spec) const \ { \ - return readFloat_(spec, value); \ + return readFloat_(spec, value).value_or(spec.defaultValue); \ } INSTANTIATE_FOR_FLOATING_POINT(float) @@ -288,24 +288,21 @@ absl::optional readBooleanFromOpcode(const Opcode& opcode) // ARIA-style booleans? (seen in egN_dynamic=1 for example) // TODO check this const OpcodeSpec fullInt64 { 0, Range::wholeRange(), 0 }; - if (auto value = opcode.read(fullInt64)) - return *value != 0; - - return absl::nullopt; + return opcode.read(fullInt64); } template <> -absl::optional Opcode::read(OpcodeSpec) const +OscillatorEnabled Opcode::read(OpcodeSpec spec) const { auto v = readBooleanFromOpcode(*this); if (!v) - return absl::nullopt; + return spec.defaultValue; return *v ? OscillatorEnabled::On : OscillatorEnabled::Off; } template <> -absl::optional Opcode::read(OpcodeSpec) const +Trigger Opcode::read(OpcodeSpec spec) const { switch (hash(value)) { case hash("attack"): return Trigger::attack; @@ -316,11 +313,11 @@ absl::optional Opcode::read(OpcodeSpec) const } DBG("Unknown trigger value: " << value); - return absl::nullopt; + return spec.defaultValue; } template <> -absl::optional Opcode::read(OpcodeSpec) const +CrossfadeCurve Opcode::read(OpcodeSpec spec) const { switch (hash(value)) { case hash("power"): return CrossfadeCurve::power; @@ -328,11 +325,11 @@ absl::optional Opcode::read(OpcodeSpec) const } DBG("Unknown crossfade power curve: " << value); - return absl::nullopt; + return spec.defaultValue; } template <> -absl::optional Opcode::read(OpcodeSpec) const +OffMode Opcode::read(OpcodeSpec spec) const { switch (hash(value)) { case hash("fast"): return OffMode::fast; @@ -341,11 +338,11 @@ absl::optional Opcode::read(OpcodeSpec) const } DBG("Unknown off mode: " << value); - return absl::nullopt; + return spec.defaultValue; } template <> -absl::optional Opcode::read(OpcodeSpec) const +FilterType Opcode::read(OpcodeSpec spec) const { switch (hash(value)) { case hash("lpf_1p"): return kFilterLpf1p; @@ -374,11 +371,11 @@ absl::optional Opcode::read(OpcodeSpec) const } DBG("Unknown filter type: " << value); - return kFilterNone; + return spec.defaultValue; } template <> -absl::optional Opcode::read(OpcodeSpec) const +EqType Opcode::read(OpcodeSpec spec) const { switch (hash(value)) { case hash("peak"): return kEqPeak; @@ -387,11 +384,11 @@ absl::optional Opcode::read(OpcodeSpec) const } DBG("Unknown EQ type: " << value); - return kEqNone; + return spec.defaultValue; } template <> -absl::optional Opcode::read(OpcodeSpec) const +VelocityOverride Opcode::read(OpcodeSpec spec) const { switch (hash(value)) { case hash("current"): return VelocityOverride::current; @@ -399,11 +396,11 @@ absl::optional Opcode::read(OpcodeSpec) cons } DBG("Unknown velocity override: " << value); - return absl::nullopt; + return spec.defaultValue; } template <> -absl::optional Opcode::read(OpcodeSpec) const +SelfMask Opcode::read(OpcodeSpec spec) const { switch (hash(value)) { case hash("on"): @@ -412,13 +409,25 @@ absl::optional Opcode::read(OpcodeSpec) const } DBG("Unknown velocity override: " << value); - return absl::nullopt; + return spec.defaultValue; } template <> -absl::optional Opcode::read(OpcodeSpec) const +bool Opcode::read(OpcodeSpec spec) const { - return readBooleanFromOpcode(*this); + return readBooleanFromOpcode(*this).value_or(spec.defaultValue); +} + +template <> +LFOWave Opcode::read(OpcodeSpec spec) const +{ + const OpcodeSpec intSpec { + static_cast(spec.defaultValue), + Range(static_cast(spec.bounds.getStart()), static_cast(spec.bounds.getEnd())), + 0 + }; + int value = read(intSpec); + return static_cast(value); } } // namespace sfz diff --git a/src/sfizz/Opcode.h b/src/sfizz/Opcode.h index 51ff6088..3df4ed08 100644 --- a/src/sfizz/Opcode.h +++ b/src/sfizz/Opcode.h @@ -102,7 +102,7 @@ struct Opcode { } template - absl::optional read(OpcodeSpec spec) const; + T read(OpcodeSpec spec) const; private: static OpcodeCategory identifyCategory(absl::string_view name); diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 70d071ef..0f86c802 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -42,7 +42,7 @@ sfz::Region::Region(int regionNumber, const MidiState& midiState, absl::string_v gainToEffect.push_back(1.0); // contribute 100% into the main bus // Default amplitude release - amplitudeEG.release = Default::egRelease.value; + amplitudeEG.release = Default::egRelease; } bool sfz::Region::parseOpcode(const Opcode& rawOpcode) @@ -57,21 +57,19 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) case hash(x "_stepcc&"): \ case hash(x "_smoothcc&") - #define LFO_EG_filter_EQ_target(sourceKey, targetKey, spec) \ - { \ - const auto number = opcode.parameters.front(); \ - if (number == 0) \ - return false; \ - \ - const auto index = opcode.parameters.size() == 2 ? opcode.parameters.back() - 1 : 0; \ - if (!extendIfNecessary(filters, index + 1, Default::numFilters)) \ - return false; \ - \ - if (auto value = opcode.read(spec)) { \ - const ModKey source = ModKey::createNXYZ(sourceKey, id, number - 1); \ - const ModKey target = ModKey::createNXYZ(targetKey, id, index); \ - getOrCreateConnection(source, target).sourceDepth = *value; \ - } \ + #define LFO_EG_filter_EQ_target(sourceKey, targetKey, spec) \ + { \ + const auto number = opcode.parameters.front(); \ + if (number == 0) \ + return false; \ + \ + const auto index = opcode.parameters.size() == 2 ? opcode.parameters.back() - 1 : 0; \ + if (!extendIfNecessary(filters, index + 1, Default::numFilters)) \ + return false; \ + \ + const ModKey source = ModKey::createNXYZ(sourceKey, id, number - 1); \ + const ModKey target = ModKey::createNXYZ(targetKey, id, index); \ + getOrCreateConnection(source, target).sourceDepth = opcode.read(spec); \ } // Sound source: sample playback @@ -91,41 +89,34 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) } break; case hash("sample_quality"): - { - if (opcode.value == "-1") - sampleQuality.reset(); - else if (auto value = opcode.read(Default::sampleQuality)) - sampleQuality = *value; - break; - } + sampleQuality = opcode.read(Default::sampleQuality); break; case hash("direction"): *sampleId = sampleId->reversed(opcode.value == "reverse"); break; case hash("delay"): - delay = opcode.read(Default::delay).value_or(delay); + delay = opcode.read(Default::delay); break; case hash("delay_random"): - delayRandom = opcode.read(Default::delayRandom).value_or(delayRandom); + delayRandom = opcode.read(Default::delayRandom); break; case hash("offset"): - offset = opcode.read(Default::offset).value_or(offset); + offset = opcode.read(Default::offset); break; case hash("offset_random"): - offsetRandom = opcode.read(Default::offsetRandom).value_or(offsetRandom); + offsetRandom = opcode.read(Default::offsetRandom); break; case hash("offset_oncc&"): // also offset_cc& if (opcode.parameters.back() > config::numCCs) return false; - if (auto value = opcode.read(Default::offsetMod)) - offsetCC[opcode.parameters.back()] = *value; + + offsetCC[opcode.parameters.back()] = opcode.read(Default::offsetMod); break; case hash("end"): - sampleEnd = opcode.read(Default::sampleEnd).value_or(sampleEnd); + sampleEnd = opcode.read(Default::sampleEnd); break; case hash("count"): - if (auto value = opcode.read(Default::sampleCount)) - sampleCount = *value; + sampleCount = opcode.read(Default::sampleCount); break; case hash("loop_mode"): // also loopmode switch (hash(opcode.value)) { @@ -146,76 +137,71 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) } break; case hash("loop_end"): // also loopend - if (auto value = opcode.read(Default::loopRange)) - loopRange.setEnd(*value); + loopRange.setEnd(opcode.read(Default::loopEnd)); break; case hash("loop_start"): // also loopstart - if (auto value = opcode.read(Default::loopRange)) - loopRange.setStart(*value); + loopRange.setStart(opcode.read(Default::loopStart)); break; case hash("loop_crossfade"): - loopCrossfade = opcode.read(Default::loopCrossfade).value_or(loopCrossfade); + loopCrossfade = opcode.read(Default::loopCrossfade); break; // Wavetable oscillator case hash("oscillator_phase"): - if (auto value = opcode.read(Default::oscillatorPhase)) - oscillatorPhase = (*value >= 0) ? wrapPhase(*value) : -1.0f; + { + auto phase = opcode.read(Default::oscillatorPhase); + oscillatorPhase = (phase >= 0) ? wrapPhase(phase) : -1.0f; + } break; case hash("oscillator"): - oscillatorEnabled = opcode.read(Default::oscillator).value_or(oscillatorEnabled); + oscillatorEnabled = opcode.read(Default::oscillator); break; case hash("oscillator_mode"): - oscillatorMode = opcode.read(Default::oscillatorMode).value_or(oscillatorMode); + oscillatorMode = opcode.read(Default::oscillatorMode); break; case hash("oscillator_multi"): - oscillatorMulti = opcode.read(Default::oscillatorMulti).value_or(oscillatorMulti); + oscillatorMulti = opcode.read(Default::oscillatorMulti); break; case hash("oscillator_detune"): - oscillatorDetune = opcode.read(Default::oscillatorDetune).value_or(oscillatorDetune); + oscillatorDetune = opcode.read(Default::oscillatorDetune); break; case_any_ccN("oscillator_detune"): processGenericCc(opcode, Default::oscillatorDetuneMod, ModKey::createNXYZ(ModId::OscillatorDetune, id)); break; case hash("oscillator_mod_depth"): - if (auto value = opcode.read(Default::oscillatorModDepth)) - oscillatorModDepth = normalizePercents(*value); + oscillatorModDepth = opcode.read(Default::oscillatorModDepth); break; case_any_ccN("oscillator_mod_depth"): processGenericCc(opcode, Default::oscillatorModDepthMod, ModKey::createNXYZ(ModId::OscillatorModDepth, id)); break; case hash("oscillator_quality"): - if (opcode.value == "-1") - oscillatorQuality.reset(); - else if (auto value = opcode.read(Default::oscillatorQuality)) - oscillatorQuality = *value; + oscillatorQuality = opcode.read(Default::oscillatorQuality); break; // Instrument settings: voice lifecycle case hash("group"): // also polyphony_group - group = opcode.read(Default::group).value_or(group); + group = opcode.read(Default::group); break; case hash("off_by"): // also offby if (opcode.value == "-1") offBy.reset(); - else if (auto value = opcode.read(Default::group)) - offBy = *value; + else + offBy = opcode.read(Default::group); break; case hash("off_mode"): // also offmode - offMode = opcode.read(Default::offMode).value_or(offMode); + offMode = opcode.read(Default::offMode); break; case hash("off_time"): offMode = OffMode::time; - offTime = opcode.read(Default::offTime).value_or(offTime); + offTime = opcode.read(Default::offTime); break; case hash("polyphony"): - polyphony = opcode.read(Default::polyphony).value_or(polyphony); + polyphony = opcode.read(Default::polyphony); break; case hash("note_polyphony"): - if (auto value = opcode.read(Default::notePolyphony)) - notePolyphony = *value; + notePolyphony = opcode.read(Default::notePolyphony); break; case hash("note_selfmask"): switch (hash(opcode.value)) { @@ -230,98 +216,96 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) } break; case hash("rt_dead"): - rtDead = opcode.read(Default::rtDead).value_or(rtDead); + rtDead = opcode.read(Default::rtDead); break; // Region logic: key mapping case hash("lokey"): - if (auto value = opcode.read(Default::key)) { - triggerOnNote = true; - keyRange.setStart(*value); - } + triggerOnNote = true; + keyRange.setStart(opcode.read(Default::loKey)); break; case hash("hikey"): triggerOnNote = (opcode.value != "-1"); - if (auto value = opcode.read(Default::key)) - keyRange.setEnd(*value); + keyRange.setEnd(opcode.read(Default::hiKey)); break; case hash("key"): triggerOnNote = (opcode.value != "-1"); - if (auto value = opcode.read(Default::key)) { - keyRange.setStart(*value); - keyRange.setEnd(*value); - pitchKeycenter = *value; + { + auto value = opcode.read(Default::key); + keyRange.setStart(value); + keyRange.setEnd(value); + pitchKeycenter = value; } break; case hash("lovel"): - if (auto value = opcode.read(Default::midi7)) - velocityRange.setStart(normalizeVelocity(*value)); + velocityRange.setStart(opcode.read(Default::loVel)); break; case hash("hivel"): - if (auto value = opcode.read(Default::midi7)) - velocityRange.setEnd(normalizeVelocity(*value)); + velocityRange.setEnd(opcode.read(Default::hiVel)); break; // Region logic: MIDI conditions case hash("lobend"): - if (auto value = opcode.read(Default::bend)) - bendRange.setStart(normalizeBend(*value)); + bendRange.setStart(opcode.read(Default::loBend)); break; case hash("hibend"): - if (auto value = opcode.read(Default::bend)) - bendRange.setEnd(normalizeBend(*value)); + bendRange.setEnd(opcode.read(Default::hiBend)); break; case hash("locc&"): if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::midi7)) - ccConditions[opcode.parameters.back()].setStart(normalizeCC(*value)); + ccConditions[opcode.parameters.back()].setStart( + opcode.read(Default::loCC) + ); break; case hash("hicc&"): if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::midi7)) - ccConditions[opcode.parameters.back()].setEnd(normalizeCC(*value)); + ccConditions[opcode.parameters.back()].setEnd( + opcode.read(Default::hiCC) + ); break; case hash("lohdcc&"): // also lorealcc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::normalized)) - ccConditions[opcode.parameters.back()].setStart(*value); + ccConditions[opcode.parameters.back()].setStart( + opcode.read(Default::loNormalized) + ); break; case hash("hihdcc&"): // also hirealcc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::normalized)) - ccConditions[opcode.parameters.back()].setEnd(*value); + ccConditions[opcode.parameters.back()].setEnd( + opcode.read(Default::hiNormalized) + ); break; case hash("sw_lokey"): // fallthrough case hash("sw_hikey"): break; case hash("sw_last"): - if (auto value = opcode.read(Default::key)) { - if (!lastKeyswitchRange) { - lastKeyswitch = *value; - keySwitched = false; - } + if (!lastKeyswitchRange) { + lastKeyswitch = opcode.read(Default::key); + keySwitched = false; } break; case hash("sw_lolast"): - if (auto value = opcode.read(Default::key)) { + { + auto value = opcode.read(Default::key); if (!lastKeyswitchRange) - lastKeyswitchRange.emplace(*value, *value); + lastKeyswitchRange.emplace(value, value); else - lastKeyswitchRange->setStart(*value); + lastKeyswitchRange->setStart(value); keySwitched = false; lastKeyswitch = absl::nullopt; } break; case hash("sw_hilast"): - if (auto value = opcode.read(Default::key)) { + { + auto value = opcode.read(Default::key); if (!lastKeyswitchRange) - lastKeyswitchRange.emplace(*value, *value); + lastKeyswitchRange.emplace(value, value); else - lastKeyswitchRange->setEnd(*value); + lastKeyswitchRange->setEnd(value); keySwitched = false; lastKeyswitch = absl::nullopt; @@ -331,256 +315,228 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) keyswitchLabel = opcode.value; break; case hash("sw_down"): - if (auto value = opcode.read(Default::key)) { - downKeyswitch = *value; - keySwitched = false; - } + downKeyswitch = opcode.read(Default::key); + keySwitched = false; break; case hash("sw_up"): - if (auto value = opcode.read(Default::key)) { - upKeyswitch = *value; - } + upKeyswitch = opcode.read(Default::key); break; case hash("sw_previous"): - if (auto value = opcode.read(Default::key)) { - previousKeyswitch = *value; - previousKeySwitched = false; - } + previousKeyswitch = opcode.read(Default::key); + previousKeySwitched = false; break; case hash("sw_vel"): velocityOverride = - opcode.read(Default::velocityOverride).value_or(velocityOverride); + opcode.read(Default::velocityOverride); break; case hash("sustain_cc"): - sustainCC = opcode.read(Default::sustainCC).value_or(sustainCC); + sustainCC = opcode.read(Default::sustainCC); break; case hash("sustain_lo"): - if (auto value = opcode.read(Default::float7)) - sustainThreshold = normalizeCC(*value); + sustainThreshold = normalizeCC(opcode.read(Default::sustainThreshold)); break; case hash("sustain_sw"): - checkSustain = opcode.read(Default::checkSustain).value_or(checkSustain); + checkSustain = opcode.read(Default::checkSustain); break; case hash("sostenuto_sw"): - checkSostenuto = opcode.read(Default::checkSostenuto).value_or(checkSostenuto); + checkSostenuto = opcode.read(Default::checkSostenuto); break; // Region logic: internal conditions case hash("lochanaft"): - if (auto value = opcode.read(Default::midi7)) - aftertouchRange.setStart(*value); + aftertouchRange.setStart(opcode.read(Default::loChannelAftertouch)); break; case hash("hichanaft"): - if (auto value = opcode.read(Default::midi7)) - aftertouchRange.setEnd(*value); + aftertouchRange.setEnd(opcode.read(Default::hiChannelAftertouch)); break; case hash("lobpm"): - if (auto value = opcode.read(Default::bpm)) - bpmRange.setStart(*value); + bpmRange.setStart(opcode.read(Default::loBPM)); break; case hash("hibpm"): - if (auto value = opcode.read(Default::bpm)) - bpmRange.setEnd(*value); + bpmRange.setEnd(opcode.read(Default::hiBPM)); break; case hash("lorand"): - if (auto value = opcode.read(Default::normalized)) - randRange.setStart(*value); + randRange.setStart(opcode.read(Default::loNormalized)); break; case hash("hirand"): - if (auto value = opcode.read(Default::normalized)) - randRange.setEnd(*value); + randRange.setEnd(opcode.read(Default::hiNormalized)); break; case hash("seq_length"): - sequenceLength = opcode.read(Default::sequence).value_or(sequenceLength); + sequenceLength = opcode.read(Default::sequence); break; case hash("seq_position"): - sequencePosition = opcode.read(Default::sequence).value_or(sequencePosition); + sequencePosition = opcode.read(Default::sequence); sequenceSwitched = false; break; // Region logic: triggers case hash("trigger"): - trigger = opcode.read(Default::trigger).value_or(trigger); + trigger = opcode.read(Default::trigger); break; case hash("start_locc&"): // also on_locc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::midi7)) { - triggerOnCC = true; - ccTriggers[opcode.parameters.back()].setStart(normalizeCC(*value)); - } + triggerOnCC = true; + ccTriggers[opcode.parameters.back()].setStart( + opcode.read(Default::loCC) + ); break; case hash("start_hicc&"): // also on_hicc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::midi7)) { - triggerOnCC = true; - ccTriggers[opcode.parameters.back()].setEnd(normalizeCC(*value)); - } + triggerOnCC = true; + ccTriggers[opcode.parameters.back()].setEnd( + opcode.read(Default::hiCC) + ); break; case hash("start_lohdcc&"): // also on_lohdcc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::normalized)) { - triggerOnCC = true; - ccTriggers[opcode.parameters.back()].setStart(*value); - } + triggerOnCC = true; + ccTriggers[opcode.parameters.back()].setStart( + opcode.read(Default::loNormalized) + ); break; case hash("start_hihdcc&"): // also on_hihdcc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::normalized)) { - triggerOnCC = true; - ccTriggers[opcode.parameters.back()].setEnd(*value); - } + ccTriggers[opcode.parameters.back()].setEnd( + opcode.read(Default::hiNormalized) + ); break; // Performance parameters: amplifier case hash("volume"): // also gain - volume = opcode.read(Default::volume).value_or(volume); + volume = opcode.read(Default::volume); break; case_any_ccN("volume"): // also gain processGenericCc(opcode, Default::volumeMod, ModKey::createNXYZ(ModId::Volume, id)); break; case hash("amplitude"): - if (auto value = opcode.read(Default::amplitude)) - amplitude = normalizePercents(*value); + amplitude = opcode.read(Default::amplitude); break; case_any_ccN("amplitude"): processGenericCc(opcode, Default::amplitudeMod, ModKey::createNXYZ(ModId::Amplitude, id)); break; case hash("pan"): - if (auto value = opcode.read(Default::pan)) - pan = normalizePercents(*value); + pan = opcode.read(Default::pan); break; case_any_ccN("pan"): processGenericCc(opcode, Default::panMod, ModKey::createNXYZ(ModId::Pan, id)); break; case hash("position"): - if (auto value = opcode.read(Default::position)) - position = normalizePercents(*value); + position = opcode.read(Default::position); break; case_any_ccN("position"): processGenericCc(opcode, Default::positionMod, ModKey::createNXYZ(ModId::Position, id)); break; case hash("width"): - if (auto value = opcode.read(Default::width)) - width = normalizePercents(*value); + width = opcode.read(Default::width); break; case_any_ccN("width"): processGenericCc(opcode, Default::widthMod, ModKey::createNXYZ(ModId::Width, id)); break; case hash("amp_keycenter"): - ampKeycenter = opcode.read(Default::key).value_or(ampKeycenter); + ampKeycenter = opcode.read(Default::key); break; case hash("amp_keytrack"): - ampKeytrack = opcode.read(Default::ampKeytrack).value_or(ampKeytrack); + ampKeytrack = opcode.read(Default::ampKeytrack); break; case hash("amp_veltrack"): - if (auto value = opcode.read(Default::ampVeltrack)) - ampVeltrack = normalizePercents(*value); + ampVeltrack = opcode.read(Default::ampVeltrack); break; case hash("amp_random"): - ampRandom = opcode.read(Default::ampRandom).value_or(ampRandom); + ampRandom = opcode.read(Default::ampRandom); break; case hash("amp_velcurve_&"): { - auto value = opcode.read(Default::ampVelcurve); if (opcode.parameters.back() > 127) return false; const auto inputVelocity = static_cast(opcode.parameters.back()); - if (value) - velocityPoints.emplace_back(inputVelocity, *value); + velocityPoints.emplace_back(inputVelocity, opcode.read(Default::ampVelcurve)); } break; case hash("xfin_lokey"): - if (auto value = opcode.read(Default::key)) - crossfadeKeyInRange.setStart(*value); + crossfadeKeyInRange.setStart(opcode.read(Default::loKey)); break; case hash("xfin_hikey"): - if (auto value = opcode.read(Default::key)) - crossfadeKeyInRange.setEnd(*value); + crossfadeKeyInRange.setEnd(opcode.read(Default::hiKey)); break; case hash("xfout_lokey"): - if (auto value = opcode.read(Default::key)) - crossfadeKeyOutRange.setStart(*value); + crossfadeKeyOutRange.setStart(opcode.read(Default::loKey)); break; case hash("xfout_hikey"): - if (auto value = opcode.read(Default::key)) - crossfadeKeyOutRange.setEnd(*value); + crossfadeKeyOutRange.setEnd(opcode.read(Default::hiKey)); break; case hash("xfin_lovel"): - if (auto value = opcode.read(Default::crossfadeIn)) - crossfadeVelInRange.setStart(normalizeVelocity(*value)); + crossfadeVelInRange.setStart(opcode.read(Default::loVel)); break; case hash("xfin_hivel"): - if (auto value = opcode.read(Default::crossfadeIn)) - crossfadeVelInRange.setEnd(normalizeVelocity(*value)); + crossfadeVelInRange.setEnd(opcode.read(Default::hiVel)); break; case hash("xfout_lovel"): - if (auto value = opcode.read(Default::crossfadeOut)) - crossfadeVelOutRange.setStart(normalizeVelocity(*value)); + crossfadeVelOutRange.setStart(opcode.read(Default::loVel)); break; case hash("xfout_hivel"): - if (auto value = opcode.read(Default::crossfadeOut)) - crossfadeVelOutRange.setEnd(normalizeVelocity(*value)); + crossfadeVelOutRange.setEnd(opcode.read(Default::hiVel)); break; case hash("xf_keycurve"): - crossfadeKeyCurve = opcode.read(Default::crossfadeCurve).value_or(crossfadeKeyCurve); + crossfadeKeyCurve = opcode.read(Default::crossfadeCurve); break; case hash("xf_velcurve"): - crossfadeVelCurve = opcode.read(Default::crossfadeCurve).value_or(crossfadeVelCurve); + crossfadeVelCurve = opcode.read(Default::crossfadeCurve); break; case hash("xfin_locc&"): if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::crossfadeIn)) - crossfadeCCInRange[opcode.parameters.back()].setStart(normalizeCC(*value)); + crossfadeCCInRange[opcode.parameters.back()].setStart( + opcode.read(Default::loCC) + ); break; case hash("xfin_hicc&"): if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::crossfadeIn)) - crossfadeCCInRange[opcode.parameters.back()].setEnd(normalizeCC(*value)); + crossfadeCCInRange[opcode.parameters.back()].setEnd( + opcode.read(Default::loCC) + ); break; case hash("xfout_locc&"): if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::crossfadeOut)) - crossfadeCCOutRange[opcode.parameters.back()].setStart(normalizeCC(*value)); + crossfadeCCOutRange[opcode.parameters.back()].setStart( + opcode.read(Default::loCC) + ); break; case hash("xfout_hicc&"): if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::crossfadeOut)) - crossfadeCCOutRange[opcode.parameters.back()].setEnd(normalizeCC(*value)); + crossfadeCCOutRange[opcode.parameters.back()].setEnd( + opcode.read(Default::loCC) + ); break; case hash("xf_cccurve"): - crossfadeCCCurve = opcode.read(Default::crossfadeCurve).value_or(crossfadeCCCurve); + crossfadeCCCurve = opcode.read(Default::crossfadeCurve); break; case hash("rt_decay"): - rtDecay = opcode.read(Default::rtDecay).value_or(rtDecay); + rtDecay = opcode.read(Default::rtDecay); break; case hash("global_amplitude"): - if (auto value = opcode.read(Default::amplitude)) - globalAmplitude = normalizePercents(*value); + globalAmplitude = opcode.read(Default::amplitude); break; case hash("master_amplitude"): - if (auto value = opcode.read(Default::amplitude)) - masterAmplitude = normalizePercents(*value); + masterAmplitude = opcode.read(Default::amplitude); break; case hash("group_amplitude"): - if (auto value = opcode.read(Default::amplitude)) - groupAmplitude = normalizePercents(*value); + groupAmplitude = opcode.read(Default::amplitude); break; case hash("global_volume"): - globalVolume = opcode.read(Default::volume).value_or(globalVolume); + globalVolume = opcode.read(Default::volume); break; case hash("master_volume"): - masterVolume = opcode.read(Default::volume).value_or(masterVolume); + masterVolume = opcode.read(Default::volume); break; case hash("group_volume"): - groupVolume = opcode.read(Default::volume).value_or(groupVolume); + groupVolume = opcode.read(Default::volume); break; // Performance parameters: filters @@ -589,8 +545,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto filterIndex = opcode.parameters.empty() ? 0 : (opcode.parameters.back() - 1); if (!extendIfNecessary(filters, filterIndex + 1, Default::numFilters)) return false; - if (auto value = opcode.read(Default::filterCutoff)) - filters[filterIndex].cutoff = *value; + filters[filterIndex].cutoff = opcode.read(Default::filterCutoff); } break; case hash("resonance&"): // also resonance @@ -598,8 +553,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto filterIndex = opcode.parameters.empty() ? 0 : (opcode.parameters.back() - 1); if (!extendIfNecessary(filters, filterIndex + 1, Default::numFilters)) return false; - if (auto value = opcode.read(Default::filterResonance)) - filters[filterIndex].resonance = *value; + filters[filterIndex].resonance = opcode.read(Default::filterResonance); } break; case_any_ccN("cutoff&"): // also cutoff_oncc&, cutoff_cc&, cutoff&_cc& @@ -625,8 +579,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto filterIndex = opcode.parameters.front() - 1; if (!extendIfNecessary(filters, filterIndex + 1, Default::numFilters)) return false; - if (auto value = opcode.read(Default::filterKeytrack)) - filters[filterIndex].keytrack = *value; + filters[filterIndex].keytrack = opcode.read(Default::filterKeytrack); } break; case hash("fil&_keycenter"): // also fil_keycenter @@ -634,8 +587,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto filterIndex = opcode.parameters.front() - 1; if (!extendIfNecessary(filters, filterIndex + 1, Default::numFilters)) return false; - if (auto value = opcode.read(Default::key)) - filters[filterIndex].keycenter = *value; + filters[filterIndex].keycenter = opcode.read(Default::key); } break; case hash("fil&_veltrack"): // also fil_veltrack @@ -643,8 +595,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto filterIndex = opcode.parameters.front() - 1; if (!extendIfNecessary(filters, filterIndex + 1, Default::numFilters)) return false; - if (auto value = opcode.read(Default::filterVeltrack)) - filters[filterIndex].veltrack = *value; + filters[filterIndex].veltrack = opcode.read(Default::filterVeltrack); } break; case hash("fil&_random"): // also fil_random, cutoff_random, cutoff&_random @@ -652,8 +603,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto filterIndex = opcode.parameters.front() - 1; if (!extendIfNecessary(filters, filterIndex + 1, Default::numFilters)) return false; - if (auto value = opcode.read(Default::filterRandom)) - filters[filterIndex].random = *value; + filters[filterIndex].random = opcode.read(Default::filterRandom); } break; case hash("fil&_gain"): // also fil_gain @@ -661,8 +611,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto filterIndex = opcode.parameters.front() - 1; if (!extendIfNecessary(filters, filterIndex + 1, Default::numFilters)) return false; - if (auto value = opcode.read(Default::filterGain)) - filters[filterIndex].gain = *value; + filters[filterIndex].gain = opcode.read(Default::filterGain); } break; case_any_ccN("fil&_gain"): // also fil_gain_oncc& @@ -680,8 +629,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) if (!extendIfNecessary(filters, filterIndex + 1, Default::numFilters)) return false; - filters[filterIndex].type = - opcode.read(Default::filter).value_or(filters[filterIndex].type); + filters[filterIndex].type = opcode.read(Default::filter); } break; @@ -691,8 +639,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto eqIndex = opcode.parameters.front() - 1; if (!extendIfNecessary(equalizers, eqIndex + 1, Default::numEQs)) return false; - if (auto value = opcode.read(Default::eqBandwidth)) - equalizers[eqIndex].bandwidth = *value; + equalizers[eqIndex].bandwidth = opcode.read(Default::eqBandwidth); } break; case_any_ccN("eq&_bw"): // also eq&_bwcc& @@ -709,8 +656,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto eqIndex = opcode.parameters.front() - 1; if (!extendIfNecessary(equalizers, eqIndex + 1, Default::numEQs)) return false; - if (auto value = opcode.read(Default::eqFrequency)) - equalizers[eqIndex].frequency = *value; + equalizers[eqIndex].frequency = opcode.read(Default::eqFrequency); } break; case_any_ccN("eq&_freq"): // also eq&_freqcc& @@ -727,8 +673,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto eqIndex = opcode.parameters.front() - 1; if (!extendIfNecessary(equalizers, eqIndex + 1, Default::numEQs)) return false; - if (auto value = opcode.read(Default::eqVel2Frequency)) - equalizers[eqIndex].vel2frequency = *value; + equalizers[eqIndex].vel2frequency = opcode.read(Default::eqVel2Frequency); } break; case hash("eq&_gain"): @@ -736,8 +681,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto eqIndex = opcode.parameters.front() - 1; if (!extendIfNecessary(equalizers, eqIndex + 1, Default::numEQs)) return false; - if (auto value = opcode.read(Default::eqGain)) - equalizers[eqIndex].gain = *value; + equalizers[eqIndex].gain = opcode.read(Default::eqGain); } break; case_any_ccN("eq&_gain"): // also eq&_gaincc& @@ -754,8 +698,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto eqIndex = opcode.parameters.front() - 1; if (!extendIfNecessary(equalizers, eqIndex + 1, Default::numEQs)) return false; - if (auto value = opcode.read(Default::eqVel2Gain)) - equalizers[eqIndex].vel2gain = *value; + equalizers[eqIndex].vel2gain = opcode.read(Default::eqVel2Gain); } break; case hash("eq&_type"): @@ -765,7 +708,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; equalizers[eqIndex].type = - opcode.read(Default::eq).value_or(equalizers[eqIndex].type); + opcode.read(Default::eq); } break; @@ -776,38 +719,38 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) pitchKeycenterFromSample = true; else { pitchKeycenterFromSample = false; - pitchKeycenter = opcode.read(Default::key).value_or(pitchKeycenter); + pitchKeycenter = opcode.read(Default::key); } break; case hash("pitch_keytrack"): - pitchKeytrack = opcode.read(Default::pitchKeytrack).value_or(pitchKeytrack); + pitchKeytrack = opcode.read(Default::pitchKeytrack); break; case hash("pitch_veltrack"): - pitchVeltrack = opcode.read(Default::pitchVeltrack).value_or(pitchVeltrack); + pitchVeltrack = opcode.read(Default::pitchVeltrack); break; case hash("pitch_random"): - pitchRandom = opcode.read(Default::pitchRandom).value_or(pitchRandom); + pitchRandom = opcode.read(Default::pitchRandom); break; case hash("transpose"): - transpose = opcode.read(Default::transpose).value_or(transpose); + transpose = opcode.read(Default::transpose); break; case hash("pitch"): // also tune - pitch = opcode.read(Default::pitch).value_or(pitch); + pitch = opcode.read(Default::pitch); break; case_any_ccN("pitch"): // also tune processGenericCc(opcode, Default::pitchMod, ModKey::createNXYZ(ModId::Pitch, id)); break; case hash("bend_up"): // also bendup - bendUp = opcode.read(Default::bendUp).value_or(bendUp); + bendUp = opcode.read(Default::bendUp); break; case hash("bend_down"): // also benddown - bendDown = opcode.read(Default::bendDown).value_or(bendDown); + bendDown = opcode.read(Default::bendDown); break; case hash("bend_step"): - bendStep = opcode.read(Default::bendStep).value_or(bendStep); + bendStep = opcode.read(Default::bendStep); break; case hash("bend_smooth"): - bendSmooth = opcode.read(Default::smoothCC).value_or(bendSmooth); + bendSmooth = opcode.read(Default::smoothCC); break; // Modulation: LFO @@ -818,8 +761,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoFreq)) - lfos[lfoNumber - 1].freq = *value; + lfos[lfoNumber - 1].freq = opcode.read(Default::lfoFreq); } break; case_any_ccN("lfo&_freq"): @@ -839,8 +781,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoBeats)) - lfos[lfoNumber - 1].beats = *value; + lfos[lfoNumber - 1].beats = opcode.read(Default::lfoBeats); } break; case_any_ccN("lfo&_beats"): @@ -860,8 +801,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoPhase)) - lfos[lfoNumber - 1].phase0 = wrapPhase(*value); + lfos[lfoNumber - 1].phase0 = opcode.read(Default::lfoPhase); } break; case hash("lfo&_delay"): @@ -871,8 +811,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoDelay)) - lfos[lfoNumber - 1].delay = *value; + lfos[lfoNumber - 1].delay = opcode.read(Default::lfoDelay); } break; case hash("lfo&_fade"): @@ -882,8 +821,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoFade)) - lfos[lfoNumber - 1].fade = *value; + lfos[lfoNumber - 1].fade = opcode.read(Default::lfoFade); } break; case hash("lfo&_count"): @@ -893,8 +831,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoCount)) - lfos[lfoNumber - 1].count = *value; + lfos[lfoNumber - 1].count = opcode.read(Default::lfoCount); } break; case hash("lfo&_steps"): @@ -904,11 +841,9 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoSteps)) { - if (!lfos[lfoNumber - 1].seq) - lfos[lfoNumber - 1].seq = LFODescription::StepSequence(); - lfos[lfoNumber - 1].seq->steps.resize(*value); - } + if (!lfos[lfoNumber - 1].seq) + lfos[lfoNumber - 1].seq = LFODescription::StepSequence(); + lfos[lfoNumber - 1].seq->steps.resize(opcode.read(Default::lfoSteps)); } break; case hash("lfo&_step&"): @@ -919,13 +854,11 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoStepX)) { - if (!lfos[lfoNumber - 1].seq) - lfos[lfoNumber - 1].seq = LFODescription::StepSequence(); - if (!extendIfNecessary(lfos[lfoNumber - 1].seq->steps, stepNumber, Default::numLFOSteps)) - return false; - lfos[lfoNumber - 1].seq->steps[stepNumber - 1] = *value * 0.01f; - } + if (!lfos[lfoNumber - 1].seq) + lfos[lfoNumber - 1].seq = LFODescription::StepSequence(); + if (!extendIfNecessary(lfos[lfoNumber - 1].seq->steps, stepNumber, Default::numLFOSteps)) + return false; + lfos[lfoNumber - 1].seq->steps[stepNumber - 1] = opcode.read(Default::lfoStepX); } break; case hash("lfo&_wave&"): // also lfo&_wave @@ -936,11 +869,9 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoWave)) { - if (!extendIfNecessary(lfos[lfoNumber - 1].sub, subNumber, Default::numLFOSubs)) + if (!extendIfNecessary(lfos[lfoNumber - 1].sub, subNumber, Default::numLFOSubs)) return false; - lfos[lfoNumber - 1].sub[subNumber - 1].wave = static_cast(*value); - } + lfos[lfoNumber - 1].sub[subNumber - 1].wave = opcode.read(Default::lfoWave); } break; case hash("lfo&_offset&"): // also lfo&_offset @@ -951,11 +882,9 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoOffset)) { - if (!extendIfNecessary(lfos[lfoNumber - 1].sub, subNumber, Default::numLFOSubs)) - return false; - lfos[lfoNumber - 1].sub[subNumber - 1].offset = *value; - } + if (!extendIfNecessary(lfos[lfoNumber - 1].sub, subNumber, Default::numLFOSubs)) + return false; + lfos[lfoNumber - 1].sub[subNumber - 1].offset = opcode.read(Default::lfoOffset); } break; case hash("lfo&_ratio&"): // also lfo&_ratio @@ -966,11 +895,9 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoRatio)) { - if (!extendIfNecessary(lfos[lfoNumber - 1].sub, subNumber, Default::numLFOSubs)) - return false; - lfos[lfoNumber - 1].sub[subNumber - 1].ratio = *value; - } + if (!extendIfNecessary(lfos[lfoNumber - 1].sub, subNumber, Default::numLFOSubs)) + return false; + lfos[lfoNumber - 1].sub[subNumber - 1].ratio = opcode.read(Default::lfoRatio); } break; case hash("lfo&_scale&"): // also lfo&_scale @@ -981,11 +908,9 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) return false; - if (auto value = opcode.read(Default::lfoScale)) { - if (!extendIfNecessary(lfos[lfoNumber - 1].sub, subNumber, Default::numLFOSubs)) - return false; - lfos[lfoNumber - 1].sub[subNumber - 1].scale = *value; - } + if (!extendIfNecessary(lfos[lfoNumber - 1].sub, subNumber, Default::numLFOSubs)) + return false; + lfos[lfoNumber - 1].sub[subNumber - 1].scale = opcode.read(Default::lfoScale); } break; @@ -995,11 +920,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto lfoNumber = opcode.parameters.front(); if (lfoNumber == 0) return false; - if (auto value = opcode.read(Default::amplitudeMod)) { - const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Amplitude, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Amplitude, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::amplitudeMod); } break; case hash("lfo&_pan"): @@ -1007,11 +931,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto lfoNumber = opcode.parameters.front(); if (lfoNumber == 0) return false; - if (auto value = opcode.read(Default::panMod)) { - const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Pan, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Pan, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::panMod); } break; case hash("lfo&_width"): @@ -1019,11 +942,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto lfoNumber = opcode.parameters.front(); if (lfoNumber == 0) return false; - if (auto value = opcode.read(Default::widthMod)) { - const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Width, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Width, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::widthMod); } break; case hash("lfo&_position"): // sfizz extension @@ -1031,11 +953,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto lfoNumber = opcode.parameters.front(); if (lfoNumber == 0) return false; - if (auto value = opcode.read(Default::positionMod)) { - const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Position, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Position, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::positionMod); } break; case hash("lfo&_pitch"): @@ -1043,11 +964,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto lfoNumber = opcode.parameters.front(); if (lfoNumber == 0) return false; - if (auto value = opcode.read(Default::pitchMod)) { - const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Pitch, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Pitch, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::pitchMod); } break; case hash("lfo&_volume"): @@ -1055,11 +975,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto lfoNumber = opcode.parameters.front(); if (lfoNumber == 0) return false; - if (auto value = opcode.read(Default::volumeMod)) { - const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Volume, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::LFO, id, lfoNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Volume, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::volumeMod); } break; case hash("lfo&_cutoff&"): @@ -1087,11 +1006,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto egNumber = opcode.parameters.front(); if (egNumber == 0) return false; - if (auto value = opcode.read(Default::amplitudeMod)) { - const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Amplitude, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Amplitude, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::amplitudeMod); } break; case hash("eg&_pan"): @@ -1099,11 +1017,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto egNumber = opcode.parameters.front(); if (egNumber == 0) return false; - if (auto value = opcode.read(Default::panMod)) { - const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Pan, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Pan, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::panMod); } break; case hash("eg&_width"): @@ -1111,11 +1028,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto egNumber = opcode.parameters.front(); if (egNumber == 0) return false; - if (auto value = opcode.read(Default::widthMod)) { - const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Width, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Width, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::widthMod); } break; case hash("eg&_position"): // sfizz extension @@ -1123,11 +1039,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto egNumber = opcode.parameters.front(); if (egNumber == 0) return false; - if (auto value = opcode.read(Default::positionMod)) { - const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Position, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Position, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::positionMod); } break; case hash("eg&_pitch"): @@ -1135,11 +1050,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto egNumber = opcode.parameters.front(); if (egNumber == 0) return false; - if (auto value = opcode.read(Default::pitchMod)) { - const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Pitch, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Pitch, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::pitchMod); } break; case hash("eg&_volume"): @@ -1147,11 +1061,10 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto egNumber = opcode.parameters.front(); if (egNumber == 0) return false; - if (auto value = opcode.read(Default::volumeMod)) { - const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); - const ModKey target = ModKey::createNXYZ(ModId::Volume, id); - getOrCreateConnection(source, target).sourceDepth = *value; - } + const ModKey source = ModKey::createNXYZ(ModId::Envelope, id, egNumber - 1); + const ModKey target = ModKey::createNXYZ(ModId::Volume, id); + getOrCreateConnection(source, target).sourceDepth = + opcode.read(Default::volumeMod); } break; case hash("eg&_cutoff&"): @@ -1180,15 +1093,14 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) return false; if (!extendIfNecessary(flexEGs, egNumber, Default::numFlexEGs)) return false; - if (auto ampeg = opcode.read(Default::flexEGAmpeg)) { - FlexEGDescription& desc = flexEGs[egNumber - 1]; - if (desc.ampeg != *ampeg) { - desc.ampeg = *ampeg; - flexAmpEG = absl::nullopt; - for (size_t i = 0, n = flexEGs.size(); i < n && !flexAmpEG; ++i) { - if (flexEGs[i].ampeg) - flexAmpEG = static_cast(i); - } + auto ampeg = opcode.read(Default::flexEGAmpeg); + FlexEGDescription& desc = flexEGs[egNumber - 1]; + if (desc.ampeg != ampeg) { + desc.ampeg = ampeg; + flexAmpEG = absl::nullopt; + for (size_t i = 0, n = flexEGs.size(); i < n && !flexAmpEG; ++i) { + if (flexEGs[i].ampeg) + flexAmpEG = static_cast(i); } } break; @@ -1271,29 +1183,25 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) break; case hash("pitcheg_depth"): - if (auto value = opcode.read(Default::egDepth)) - getOrCreateConnection( - ModKey::createNXYZ(ModId::PitchEG, id), - ModKey::createNXYZ(ModId::Pitch, id)).sourceDepth = *value; + getOrCreateConnection( + ModKey::createNXYZ(ModId::PitchEG, id), + ModKey::createNXYZ(ModId::Pitch, id)).sourceDepth = opcode.read(Default::egDepth); break; case hash("fileg_depth"): - if (auto value = opcode.read(Default::egDepth)) - getOrCreateConnection( - ModKey::createNXYZ(ModId::FilEG, id), - ModKey::createNXYZ(ModId::FilCutoff, id)).sourceDepth = *value; + getOrCreateConnection( + ModKey::createNXYZ(ModId::FilEG, id), + ModKey::createNXYZ(ModId::FilCutoff, id)).sourceDepth = opcode.read(Default::egDepth); break; case hash("pitcheg_veltodepth"): // also pitcheg_vel2depth - if (auto value = opcode.read(Default::egVel2Depth)) - getOrCreateConnection( - ModKey::createNXYZ(ModId::PitchEG, id), - ModKey::createNXYZ(ModId::Pitch, id)).velToDepth = *value; + getOrCreateConnection( + ModKey::createNXYZ(ModId::PitchEG, id), + ModKey::createNXYZ(ModId::Pitch, id)).velToDepth = opcode.read(Default::egVel2Depth); break; case hash("fileg_veltodepth"): // also fileg_vel2depth - if (auto value = opcode.read(Default::egVel2Depth)) - getOrCreateConnection( - ModKey::createNXYZ(ModId::FilEG, id), - ModKey::createNXYZ(ModId::FilCutoff, id)).velToDepth = *value; + getOrCreateConnection( + ModKey::createNXYZ(ModId::FilEG, id), + ModKey::createNXYZ(ModId::FilCutoff, id)).velToDepth = opcode.read(Default::egVel2Depth); break; // Flex envelopes @@ -1305,7 +1213,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) if (!extendIfNecessary(flexEGs, egNumber, Default::numFlexEGs)) return false; auto& eg = flexEGs[egNumber - 1]; - eg.dynamic = opcode.read(Default::flexEGDynamic).value_or(eg.dynamic); + eg.dynamic = opcode.read(Default::flexEGDynamic); } break; case hash("eg&_sustain"): @@ -1316,7 +1224,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) if (!extendIfNecessary(flexEGs, egNumber, Default::numFlexEGs)) return false; auto& eg = flexEGs[egNumber - 1]; - eg.sustain = opcode.read(Default::flexEGSustain).value_or(eg.sustain); + eg.sustain = opcode.read(Default::flexEGSustain); } break; case hash("eg&_time&"): @@ -1330,8 +1238,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto pointNumber = opcode.parameters[1]; if (!extendIfNecessary(eg.points, pointNumber + 1, Default::numFlexEGPoints)) return false; - if (auto value = opcode.read(Default::flexEGPointTime)) - eg.points[pointNumber].time = *value; + eg.points[pointNumber].time = opcode.read(Default::flexEGPointTime); } break; case hash("eg&_level&"): @@ -1345,8 +1252,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto pointNumber = opcode.parameters[1]; if (!extendIfNecessary(eg.points, pointNumber + 1, Default::numFlexEGPoints)) return false; - if (auto value = opcode.read(Default::flexEGPointLevel)) - eg.points[pointNumber].level = *value; + eg.points[pointNumber].level = opcode.read(Default::flexEGPointLevel); } break; case hash("eg&_shape&"): @@ -1360,8 +1266,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto pointNumber = opcode.parameters[1]; if (!extendIfNecessary(eg.points, pointNumber + 1, Default::numFlexEGPoints)) return false; - if (auto value = opcode.read(Default::flexEGPointShape)) - eg.points[pointNumber].setShape(*value); + eg.points[pointNumber].setShape(opcode.read(Default::flexEGPointShape)); } break; @@ -1370,17 +1275,13 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode) const auto effectNumber = opcode.parameters.back(); if (!effectNumber || effectNumber < 1 || effectNumber > config::maxEffectBuses) break; - auto value = opcode.read(Default::effect); - if (!value) - break; if (static_cast(effectNumber + 1) > gainToEffect.size()) gainToEffect.resize(effectNumber + 1); - gainToEffect[effectNumber] = *value / 100; + gainToEffect[effectNumber] = opcode.read(Default::effect); break; } case hash("sw_default"): - if (auto value = opcode.read(Default::key)) - defaultSwitch = *value; + defaultSwitch = opcode.read(Default::key); break; // Ignored opcodes @@ -1408,98 +1309,91 @@ bool sfz::Region::parseEGOpcode(const Opcode& opcode, EGDescription& eg) switch (opcode.lettersOnlyHash) { case_any_eg("attack"): - eg.attack = opcode.read(Default::egTime).value_or(eg.attack); + eg.attack = opcode.read(Default::egTime); break; case_any_eg("decay"): - eg.decay = opcode.read(Default::egTime).value_or(eg.decay); + eg.decay = opcode.read(Default::egTime); break; case_any_eg("delay"): - eg.delay = opcode.read(Default::egTime).value_or(eg.delay); + eg.delay = opcode.read(Default::egTime); break; case_any_eg("hold"): - eg.hold = opcode.read(Default::egTime).value_or(eg.hold); + eg.hold = opcode.read(Default::egTime); break; case_any_eg("release"): - eg.release = opcode.read(Default::egRelease).value_or(eg.release); + eg.release = opcode.read(Default::egRelease); break; case_any_eg("start"): - eg.start = opcode.read(Default::egPercent).value_or(eg.start); + eg.start = opcode.read(Default::egPercent); break; case_any_eg("sustain"): - eg.sustain = opcode.read(Default::egPercent).value_or(eg.sustain); + eg.sustain = opcode.read(Default::egPercent); break; case_any_eg("veltoattack"): // also vel2attack - eg.vel2attack = opcode.read(Default::egTimeMod).value_or(eg.vel2attack); + eg.vel2attack = opcode.read(Default::egTimeMod); break; case_any_eg("veltodecay"): // also vel2decay - eg.vel2decay = opcode.read(Default::egTimeMod).value_or(eg.vel2decay); + eg.vel2decay = opcode.read(Default::egTimeMod); break; case_any_eg("veltodelay"): // also vel2delay - eg.vel2delay = opcode.read(Default::egTimeMod).value_or(eg.vel2delay); + eg.vel2delay = opcode.read(Default::egTimeMod); break; case_any_eg("veltohold"): // also vel2hold - eg.vel2hold = opcode.read(Default::egTimeMod).value_or(eg.vel2hold); + eg.vel2hold = opcode.read(Default::egTimeMod); break; case_any_eg("veltorelease"): // also vel2release - eg.vel2release = opcode.read(Default::egTimeMod).value_or(eg.vel2release); + eg.vel2release = opcode.read(Default::egTimeMod); break; case_any_eg("veltosustain"): // also vel2sustain - eg.vel2sustain = opcode.read(Default::egPercentMod).value_or(eg.vel2sustain); + eg.vel2sustain = opcode.read(Default::egPercentMod); break; case_any_eg("attack_oncc&"): // also attackcc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::egTimeMod)) - eg.ccAttack[opcode.parameters.back()] = *value; + eg.ccAttack[opcode.parameters.back()] = opcode.read(Default::egTimeMod); break; case_any_eg("decay_oncc&"): // also decaycc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::egTimeMod)) - eg.ccDecay[opcode.parameters.back()] = *value; + eg.ccDecay[opcode.parameters.back()] = opcode.read(Default::egTimeMod); break; case_any_eg("delay_oncc&"): // also delaycc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::egTimeMod)) - eg.ccDelay[opcode.parameters.back()] = *value; + eg.ccDelay[opcode.parameters.back()] = opcode.read(Default::egTimeMod); break; case_any_eg("hold_oncc&"): // also holdcc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::egTimeMod)) - eg.ccHold[opcode.parameters.back()] = *value; + eg.ccHold[opcode.parameters.back()] = opcode.read(Default::egTimeMod); break; case_any_eg("release_oncc&"): // also releasecc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::egTimeMod)) - eg.ccRelease[opcode.parameters.back()] = *value; + eg.ccRelease[opcode.parameters.back()] = opcode.read(Default::egTimeMod); break; case_any_eg("start_oncc&"): // also startcc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::egPercentMod)) - eg.ccStart[opcode.parameters.back()] = *value; + eg.ccStart[opcode.parameters.back()] = opcode.read(Default::egPercentMod); break; case_any_eg("sustain_oncc&"): // also sustaincc& if (opcode.parameters.back() >= config::numCCs) return false; - if (auto value = opcode.read(Default::egPercentMod)) - eg.ccSustain[opcode.parameters.back()] = *value; + eg.ccSustain[opcode.parameters.back()] = opcode.read(Default::egPercentMod); break; default: @@ -1558,21 +1452,21 @@ bool sfz::Region::processGenericCc(const Opcode& opcode, OpcodeSpec spec, ModKey::Parameters p = conn->source.parameters(); switch (opcode.category) { case kOpcodeOnCcN: - conn->sourceDepth = opcode.read(spec).value_or(conn->sourceDepth); + conn->sourceDepth = opcode.read(spec); break; case kOpcodeCurveCcN: - p.curve = opcode.read(Default::curveCC).value_or(p.curve); + p.curve = opcode.read(Default::curveCC); break; case kOpcodeStepCcN: { const float maxStep = max(std::abs(spec.bounds.getStart()), std::abs(spec.bounds.getEnd())); - const OpcodeSpec stepCC { 0.0f, Range(0.0f, maxStep), kEnforceLowerBound | kEnforceUpperBound }; - p.step = opcode.read(stepCC).value_or(p.step); + const OpcodeSpec stepCC { 0.0f, Range(0.0f, maxStep), 0 }; + p.step = opcode.read(stepCC); } break; case kOpcodeSmoothCcN: - p.smooth = opcode.read(Default::smoothCC).value_or(p.smooth); + p.smooth = opcode.read(Default::smoothCC); break; default: assert(false); diff --git a/src/sfizz/Region.h b/src/sfizz/Region.h index 9260b8e7..4a7324f8 100644 --- a/src/sfizz/Region.h +++ b/src/sfizz/Region.h @@ -319,44 +319,44 @@ struct Region { // Sound source: sample playback std::shared_ptr sampleId { new FileId }; // Sample absl::optional sampleQuality {}; - float delay { Default::delay.value }; // delay - float delayRandom { Default::delayRandom.value }; // delay_random - int64_t offset { Default::offset.value }; // offset - int64_t offsetRandom { Default::offsetRandom.value }; // offset_random - CCMap offsetCC { Default::offsetMod.value }; - uint32_t sampleEnd { Default::sampleEnd.value }; // end - absl::optional sampleCount {}; // count + float delay { Default::delay }; // delay + float delayRandom { Default::delayRandom }; // delay_random + int64_t offset { Default::offset }; // offset + int64_t offsetRandom { Default::offsetRandom }; // offset_random + CCMap offsetCC { Default::offsetMod }; + uint32_t sampleEnd { Default::sampleEnd }; // end + uint32_t sampleCount { Default::sampleCount }; // count absl::optional loopMode {}; // loopmode - Range loopRange { Default::loopRange.bounds }; //loopstart and loopend - float loopCrossfade { Default::loopCrossfade.value }; // loop_crossfade + Range loopRange { Default::loopStart, Default::loopEnd }; //loopstart and loopend + float loopCrossfade { Default::loopCrossfade }; // loop_crossfade // Wavetable oscillator - float oscillatorPhase { Default::oscillatorPhase.value }; - OscillatorEnabled oscillatorEnabled { Default::oscillator.value }; // oscillator + float oscillatorPhase { Default::oscillatorPhase }; + OscillatorEnabled oscillatorEnabled { Default::oscillator }; // oscillator bool hasWavetableSample { false }; // (set according to sample file) - int oscillatorMode { Default::oscillatorMode.value }; - int oscillatorMulti { Default::oscillatorMulti.value }; - float oscillatorDetune { Default::oscillatorDetune.value }; - float oscillatorModDepth { Default::oscillatorModDepth.value }; + int oscillatorMode { Default::oscillatorMode }; + int oscillatorMulti { Default::oscillatorMulti }; + float oscillatorDetune { Default::oscillatorDetune }; + float oscillatorModDepth { Default::oscillatorModDepth }; absl::optional oscillatorQuality; // Instrument settings: voice lifecycle - uint32_t group { Default::group.value }; // group + uint32_t group { Default::group }; // group absl::optional offBy {}; // off_by - OffMode offMode { Default::offMode.value }; // off_mode - float offTime { Default::offTime.value }; // off_mode + OffMode offMode { Default::offMode }; // off_mode + float offTime { Default::offTime }; // off_mode absl::optional notePolyphony {}; // note_polyphony uint32_t polyphony { config::maxVoices }; // polyphony - SelfMask selfMask { Default::selfMask.value }; - bool rtDead { Default::rtDead.value }; + SelfMask selfMask { Default::selfMask }; + bool rtDead { Default::rtDead }; // Region logic: key mapping - Range keyRange { Default::key.bounds }; //lokey, hikey and key - Range velocityRange { Default::normalized.bounds }; // hivel and lovel + Range keyRange { Default::loKey, Default::hiKey }; //lokey, hikey and key + Range velocityRange { Default::loVel, Default::hiVel }; // hivel and lovel // Region logic: MIDI conditions - Range bendRange { Default::bipolar.bounds }; // hibend and lobend - CCMap> ccConditions { Default::normalized.bounds }; + Range bendRange { Default::loBend, Default::hiBend }; // hibend and lobend + CCMap> ccConditions {{ Default::loCC, Default::hiCC }}; absl::optional lastKeyswitch {}; // sw_last absl::optional> lastKeyswitchRange {}; // sw_last absl::optional keyswitchLabel {}; @@ -364,45 +364,45 @@ struct Region { absl::optional downKeyswitch {}; // sw_down absl::optional previousKeyswitch {}; // sw_previous absl::optional defaultSwitch {}; - VelocityOverride velocityOverride { Default::velocityOverride.value }; // sw_vel - bool checkSustain { Default::checkSustain.value }; // sustain_sw - bool checkSostenuto { Default::checkSostenuto.value }; // sostenuto_sw - uint16_t sustainCC { Default::sustainCC.value }; // sustain_cc - float sustainThreshold { Default::sustainThreshold.value }; // sustain_cc + VelocityOverride velocityOverride { Default::velocityOverride }; // sw_vel + bool checkSustain { Default::checkSustain }; // sustain_sw + bool checkSostenuto { Default::checkSostenuto }; // sostenuto_sw + uint16_t sustainCC { Default::sustainCC }; // sustain_cc + float sustainThreshold { Default::sustainThreshold }; // sustain_cc // Region logic: internal conditions - Range aftertouchRange { Default::midi7.bounds }; // hichanaft and lochanaft - Range bpmRange { Default::bpm.bounds }; // hibpm and lobpm - Range randRange { Default::normalized.bounds }; // hirand and lorand - uint8_t sequenceLength { Default::sequence.value }; // seq_length - uint8_t sequencePosition { Default::sequence.value }; // seq_position + Range aftertouchRange { Default::loChannelAftertouch, Default::hiChannelAftertouch }; // hichanaft and lochanaft + Range bpmRange { Default::loBPM, Default::hiBPM }; // hibpm and lobpm + Range randRange { Default::loNormalized, Default::hiNormalized }; // hirand and lorand + uint8_t sequenceLength { Default::sequence }; // seq_length + uint8_t sequencePosition { Default::sequence }; // seq_position // Region logic: triggers - Trigger trigger { Default::trigger.value }; // trigger - CCMap> ccTriggers { Default::normalized.bounds }; // on_loccN on_hiccN + Trigger trigger { Default::trigger }; // trigger + CCMap> ccTriggers {{ Default::loCC, Default::hiCC }}; // on_loccN on_hiccN // Performance parameters: amplifier - float volume { Default::volume.value }; // volume - float amplitude { normalizePercents(Default::amplitude.value) }; // amplitude - float pan { normalizePercents(Default::pan.value) }; // pan - float width { normalizePercents(Default::width.value) }; // width - float position { normalizePercents(Default::position.value) }; // position - uint8_t ampKeycenter { Default::key.value }; // amp_keycenter - float ampKeytrack { Default::ampKeytrack.value }; // amp_keytrack - float ampVeltrack { normalizePercents(Default::ampVeltrack.value) }; // amp_veltrack + float volume { Default::volume }; // volume + float amplitude { normalizePercents(Default::amplitude) }; // amplitude + float pan { normalizePercents(Default::pan) }; // pan + float width { normalizePercents(Default::width) }; // width + float position { normalizePercents(Default::position) }; // position + uint8_t ampKeycenter { Default::key }; // amp_keycenter + float ampKeytrack { Default::ampKeytrack }; // amp_keytrack + float ampVeltrack { normalizePercents(Default::ampVeltrack) }; // amp_veltrack std::vector> velocityPoints; // amp_velcurve_N absl::optional velCurve {}; - float ampRandom { Default::ampRandom.value }; // amp_random + float ampRandom { Default::ampRandom }; // amp_random Range crossfadeKeyInRange { Default::crossfadeKeyInRange }; Range crossfadeKeyOutRange { Default::crossfadeKeyOutRange }; Range crossfadeVelInRange { Default::crossfadeVelInRange }; Range crossfadeVelOutRange { Default::crossfadeVelOutRange }; - CrossfadeCurve crossfadeKeyCurve { Default::crossfadeCurve.value }; - CrossfadeCurve crossfadeVelCurve { Default::crossfadeCurve.value }; - CrossfadeCurve crossfadeCCCurve { Default::crossfadeCurve.value }; + CrossfadeCurve crossfadeKeyCurve { Default::crossfadeCurve }; + CrossfadeCurve crossfadeVelCurve { Default::crossfadeCurve }; + CrossfadeCurve crossfadeCCCurve { Default::crossfadeCurve }; CCMap> crossfadeCCInRange { Default::crossfadeCCInRange }; // xfin_loccN xfin_hiccN CCMap> crossfadeCCOutRange { Default::crossfadeCCOutRange }; // xfout_loccN xfout_hiccN - float rtDecay { Default::rtDecay.value }; // rt_decay + float rtDecay { Default::rtDecay }; // rt_decay float globalAmplitude { 1.0 }; // global_amplitude float masterAmplitude { 1.0 }; // master_amplitude @@ -416,17 +416,17 @@ struct Region { std::vector filters; // Performance parameters: pitch - uint8_t pitchKeycenter { Default::key.value }; // pitch_keycenter + uint8_t pitchKeycenter { Default::key }; // pitch_keycenter bool pitchKeycenterFromSample { false }; - int pitchKeytrack { Default::pitchKeytrack.value }; // pitch_keytrack - float pitchRandom { Default::pitchRandom.value }; // pitch_random - int pitchVeltrack { Default::pitchVeltrack.value }; // pitch_veltrack - int transpose { Default::transpose.value }; // transpose - float pitch { Default::pitch.value }; // tune - float bendUp { Default::bendUp.value }; - float bendDown { Default::bendDown.value }; - float bendStep { Default::bendStep.value }; - uint8_t bendSmooth { Default::smoothCC.value }; + int pitchKeytrack { Default::pitchKeytrack }; // pitch_keytrack + float pitchRandom { Default::pitchRandom }; // pitch_random + int pitchVeltrack { Default::pitchVeltrack }; // pitch_veltrack + int transpose { Default::transpose }; // transpose + float pitch { Default::pitch }; // tune + float bendUp { Default::bendUp }; + float bendDown { Default::bendDown }; + float bendStep { Default::bendStep }; + uint8_t bendSmooth { Default::smoothCC }; // Envelopes EGDescription amplitudeEG; diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 76f935d4..fefa48d4 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -191,7 +191,7 @@ void Synth::Impl::buildRegion(const std::vector& regionOpcodes) currentSwitch_ = *lastRegion->defaultSwitch; // There was a combination of group= and polyphony= on a region, so set the group polyphony - if (lastRegion->group != Default::group.value && lastRegion->polyphony != config::maxVoices) { + if (lastRegion->group != Default::group && lastRegion->polyphony != config::maxVoices) { voiceManager_.setGroupPolyphony(lastRegion->group, lastRegion->polyphony); } else { // Just check that there are enough polyphony groups @@ -276,12 +276,10 @@ void Synth::Impl::handleMasterOpcodes(const std::vector& members) switch (member.lettersOnlyHash) { case hash("polyphony"): ASSERT(currentSet_ != nullptr); - if (auto value = member.read(Default::polyphony)) - currentSet_->setPolyphonyLimit(*value); + currentSet_->setPolyphonyLimit(member.read(Default::polyphony)); break; case hash("sw_default"): - if (auto value = member.read(Default::key)) - currentSwitch_ = *value; + currentSwitch_ = member.read(Default::key); break; } } @@ -295,12 +293,10 @@ void Synth::Impl::handleGlobalOpcodes(const std::vector& members) switch (member.lettersOnlyHash) { case hash("polyphony"): ASSERT(currentSet_ != nullptr); - if (auto value = member.read(Default::polyphony)) - currentSet_->setPolyphonyLimit(*value); + currentSet_->setPolyphonyLimit(member.read(Default::polyphony)); break; case hash("sw_default"): - if (auto value = member.read(Default::key)) - currentSwitch_ = *value; + currentSwitch_ = member.read(Default::key); break; case hash("volume"): // FIXME : Probably best not to mess with this and let the host control the volume @@ -320,16 +316,13 @@ void Synth::Impl::handleGroupOpcodes(const std::vector& members, const s switch (member.lettersOnlyHash) { case hash("group"): - if (auto value = member.read(Default::group)) - groupIdx = *value; + groupIdx = member.read(Default::group); break; case hash("polyphony"): - if (auto value = member.read(Default::polyphony)) - maxPolyphony = *value; + maxPolyphony = member.read(Default::polyphony); break; case hash("sw_default"): - if (auto value = member.read(Default::key)) - currentSwitch_ = *value; + currentSwitch_ = member.read(Default::key); break; } }; @@ -358,16 +351,12 @@ void Synth::Impl::handleControlOpcodes(const std::vector& members) switch (member.lettersOnlyHash) { case hash("set_cc&"): if (Default::ccNumber.bounds.containsWithEnd(member.parameters.back())) { - const auto ccValue = member.read(Default::midi7); - if (ccValue) - setDefaultHdcc(member.parameters.back(), normalizeCC(*ccValue)); + setDefaultHdcc(member.parameters.back(), member.read(Default::loCC)); } break; case hash("set_hdcc&"): if (Default::ccNumber.bounds.containsWithEnd(member.parameters.back())) { - const auto ccValue = member.read(Default::normalized); - if (ccValue) - setDefaultHdcc(member.parameters.back(), *ccValue); + setDefaultHdcc(member.parameters.back(), member.read(Default::loNormalized)); } break; case hash("label_cc&"): @@ -385,10 +374,10 @@ void Synth::Impl::handleControlOpcodes(const std::vector& members) DBG("Changing default sample path to " << defaultPath_); break; case hash("note_offset"): - noteOffset_ = member.read(Default::noteOffset).value_or(noteOffset_); + noteOffset_ = member.read(Default::noteOffset); break; case hash("octave_offset"): - octaveOffset_ = member.read(Default::octaveOffset).value_or(octaveOffset_); + octaveOffset_ = member.read(Default::octaveOffset); break; case hash("hint_ram_based"): if (member.value == "1") @@ -451,22 +440,19 @@ void Synth::Impl::handleEffectOpcodes(const std::vector& rawMembers) // note(jpc): gain opcodes are linear volumes in % units case hash("directtomain"): - if (auto valueOpt = opcode.read(Default::effect)) - getOrCreateBus(0).setGainToMain(*valueOpt / 100); + getOrCreateBus(0).setGainToMain(opcode.read(Default::effect)); break; case hash("fx&tomain"): // fx&tomain if (opcode.parameters.front() < 1 || opcode.parameters.front() > config::maxEffectBuses) break; - if (auto valueOpt = opcode.read(Default::effect)) - getOrCreateBus(opcode.parameters.front()).setGainToMain(*valueOpt / 100); + getOrCreateBus(opcode.parameters.front()).setGainToMain(opcode.read(Default::effect)); break; case hash("fx&tomix"): // fx&tomix if (opcode.parameters.front() < 1 || opcode.parameters.front() > config::maxEffectBuses) break; - if (auto valueOpt = opcode.read(Default::effect)) - getOrCreateBus(opcode.parameters.front()).setGainToMix(*valueOpt / 100); + getOrCreateBus(opcode.parameters.front()).setGainToMix(opcode.read(Default::effect)); break; } } @@ -589,10 +575,10 @@ void Synth::Impl::finalizeSfzLoad() region->sampleEnd = std::min(region->sampleEnd, fileInformation->end); if (fileInformation->hasLoop) { - if (region->loopRange.getStart() == Default::loopRange.bounds.getStart()) - region->loopRange.setStart(fileInformation->loopBegin); + if (region->loopRange.getStart() == Default::loopStart) + region->loopRange.setStart(fileInformation->loopStart); - if (region->loopRange.getEnd() == Default::loopRange.bounds.getEnd()) + if (region->loopRange.getEnd() == Default::loopEnd) region->loopRange.setEnd(fileInformation->loopEnd); if (!region->loopMode) @@ -602,7 +588,7 @@ void Synth::Impl::finalizeSfzLoad() if (region->isRelease() && !region->loopMode) region->loopMode = LoopMode::one_shot; - if (region->loopRange.getEnd() == Default::loopRange.bounds.getEnd()) + if (region->loopRange.getEnd() == Default::loopEnd) region->loopRange.setEnd(region->sampleEnd); if (fileInformation->numChannels == 2) @@ -668,13 +654,13 @@ void Synth::Impl::finalizeSfzLoad() // Set the default frequencies on equalizers if needed if (region->equalizers.size() > 0 - && region->equalizers[0].frequency == Default::eqFrequency.value) { + && region->equalizers[0].frequency == Default::eqFrequency) { region->equalizers[0].frequency = Default::defaultEQFreq[0]; if (region->equalizers.size() > 1 - && region->equalizers[1].frequency == Default::eqFrequency.value) { + && region->equalizers[1].frequency == Default::eqFrequency) { region->equalizers[1].frequency = Default::defaultEQFreq[1]; if (region->equalizers.size() > 2 - && region->equalizers[2].frequency == Default::eqFrequency.value) { + && region->equalizers[2].frequency == Default::eqFrequency) { region->equalizers[2].frequency = Default::defaultEQFreq[2]; } } diff --git a/src/sfizz/SynthConfig.h b/src/sfizz/SynthConfig.h index 47d265e6..8fdbd510 100644 --- a/src/sfizz/SynthConfig.h +++ b/src/sfizz/SynthConfig.h @@ -13,7 +13,7 @@ struct SynthConfig { bool freeWheeling { false }; - int liveSampleQuality { Default::sampleQuality.value }; + int liveSampleQuality { Default::sampleQuality }; int freeWheelingSampleQuality { Default::freewheelingQuality }; int currentSampleQuality() const noexcept diff --git a/src/sfizz/SynthMessaging.cpp b/src/sfizz/SynthMessaging.cpp index 62335993..123fac10 100644 --- a/src/sfizz/SynthMessaging.cpp +++ b/src/sfizz/SynthMessaging.cpp @@ -144,11 +144,7 @@ void sfz::Synth::dispatchMessage(Client& client, int delay, const char* path, co MATCH("/region&/count", "") { GET_REGION_OR_BREAK(indices[0]) - if (!region.sampleCount) { - client.receive<'N'>(delay, path, {}); - } else { - client.receive<'h'>(delay, path, *region.sampleCount); - } + client.receive<'h'>(delay, path, region.sampleCount); } break; MATCH("/region&/loop_range", "") { diff --git a/src/sfizz/SynthPrivate.h b/src/sfizz/SynthPrivate.h index bd34ec22..b71e9810 100644 --- a/src/sfizz/SynthPrivate.h +++ b/src/sfizz/SynthPrivate.h @@ -257,8 +257,8 @@ struct Synth::Impl final: public Parser::Listener { // Control opcodes std::string defaultPath_ { "" }; - int noteOffset_ { Default::noteOffset.value }; - int octaveOffset_ { Default::octaveOffset.value }; + int noteOffset_ { Default::noteOffset }; + int octaveOffset_ { Default::octaveOffset }; // Modulation source generators std::unique_ptr genController_; diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index dae62336..8a13834f 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -371,7 +371,7 @@ void Voice::startVoice(Region* region, int delay, const TriggerEvent& event) noe } const float phase = region->getPhase(); const int quality = - region->oscillatorQuality.value_or(Default::oscillatorQuality.value); + region->oscillatorQuality.value_or(Default::oscillatorQuality); for (WavetableOscillator& osc : impl.waveOscillators_) { osc.setWavetable(wave); osc.setPhase(phase); @@ -465,7 +465,7 @@ void Voice::off(int delay, bool fast) noexcept Impl& impl = *impl_; if (!impl.region_->flexAmpEG) { if (impl.region_->offMode == OffMode::fast || fast) { - impl.egAmplitude_.setReleaseTime(Default::offTime.value); + impl.egAmplitude_.setReleaseTime(Default::offTime); } else if (impl.region_->offMode == OffMode::time) { impl.egAmplitude_.setReleaseTime(impl.region_->offTime); } diff --git a/src/sfizz/effects/Apan.cpp b/src/sfizz/effects/Apan.cpp index 9151188a..d100361f 100644 --- a/src/sfizz/effects/Apan.cpp +++ b/src/sfizz/effects/Apan.cpp @@ -81,28 +81,22 @@ namespace fx { for (const Opcode& opc : members) { switch (opc.lettersOnlyHash) { case hash("apan_waveform"): - if (auto value = opc.read(Default::apanWaveform)) - apan->_lfoWave = *value; + apan->_lfoWave = opc.read(Default::apanWaveform); break; case hash("apan_freq"): - if (auto value = opc.read(Default::apanFrequency)) - apan->_lfoFrequency = *value; + apan->_lfoFrequency = opc.read(Default::apanFrequency); break; case hash("apan_phase"): - if (auto value = opc.read(Default::apanPhase)) - apan->_lfoPhaseOffset = wrapPhase(*value); + apan->_lfoPhaseOffset = opc.read(Default::apanPhase); break; case hash("apan_dry"): - if (auto value = opc.read(Default::apanLevel)) - apan->_dry = *value / 100.0f; + apan->_dry = opc.read(Default::apanLevel); break; case hash("apan_wet"): - if (auto value = opc.read(Default::apanLevel)) - apan->_wet = *value / 100.0f; + apan->_wet = opc.read(Default::apanLevel); break; case hash("apan_depth"): - if (auto value = opc.read(Default::apanLevel)) - apan->_depth = *value / 100.0f; + apan->_depth = opc.read(Default::apanLevel); break; } } diff --git a/src/sfizz/effects/Apan.h b/src/sfizz/effects/Apan.h index ac72e524..9e30c144 100644 --- a/src/sfizz/effects/Apan.h +++ b/src/sfizz/effects/Apan.h @@ -52,12 +52,12 @@ namespace fx { sfz::Buffer _lfoOutRight { config::defaultSamplesPerBlock }; // Controls - float _dry { Default::apanLevel.value }; - float _wet { Default::apanLevel.value }; - float _depth { Default::apanLevel.value }; - int _lfoWave { Default::apanWaveform.value }; - float _lfoFrequency { Default::apanFrequency.value }; - float _lfoPhaseOffset { Default::apanPhase.value }; + float _dry { Default::apanLevel }; + float _wet { Default::apanLevel }; + float _depth { Default::apanLevel }; + int _lfoWave { Default::apanWaveform }; + float _lfoFrequency { Default::apanFrequency }; + float _lfoPhaseOffset { Default::apanPhase }; // State float _lfoPhase { 0.0f }; diff --git a/src/sfizz/effects/Compressor.cpp b/src/sfizz/effects/Compressor.cpp index 94f4b242..8fffd680 100644 --- a/src/sfizz/effects/Compressor.cpp +++ b/src/sfizz/effects/Compressor.cpp @@ -31,8 +31,8 @@ namespace fx { struct Compressor::Impl { faustCompressor _compressor[2]; - bool _stlink { Default::compSTLink.value }; - float _inputGain { Default::compGain.value }; + bool _stlink { Default::compSTLink }; + float _inputGain { Default::compGain }; AudioBuffer _tempBuffer2x { 2, _oversampling * config::defaultSamplesPerBlock }; AudioBuffer _gain2x { 2, _oversampling * config::defaultSamplesPerBlock }; hiir::Downsampler2xFpu<12> _downsampler2x[EffectChannels]; @@ -163,35 +163,38 @@ namespace fx { for (const Opcode& opc : members) { switch (opc.lettersOnlyHash) { case hash("comp_attack"): - if (auto value = opc.read(Default::compAttack)) { + { + auto value = opc.read(Default::compAttack); for (size_t c = 0; c < 2; ++c) - impl.set_Attack(c, *value); + impl.set_Attack(c, value); } break; case hash("comp_release"): - if (auto value = opc.read(Default::compRelease)) { + { + auto value = opc.read(Default::compRelease); for (size_t c = 0; c < 2; ++c) - impl.set_Release(c, *value); + impl.set_Release(c, value); } break; case hash("comp_threshold"): - if (auto value = opc.read(Default::compThreshold)) { + { + auto value = opc.read(Default::compThreshold); for (size_t c = 0; c < 2; ++c) - impl.set_Threshold(c, *value); + impl.set_Threshold(c, value); } break; case hash("comp_ratio"): - if (auto value = opc.read(Default::compRatio)) { + { + auto value = opc.read(Default::compRatio); for (size_t c = 0; c < 2; ++c) - impl.set_Ratio(c, *value); + impl.set_Ratio(c, value); } break; case hash("comp_gain"): - if (auto value = opc.read(Default::compGain)) - impl._inputGain = db2mag(*value); + impl._inputGain = opc.read(Default::compGain); break; case hash("comp_stlink"): - impl._stlink = opc.read(Default::compSTLink).value_or(impl._stlink); + impl._stlink = opc.read(Default::compSTLink); break; } } diff --git a/src/sfizz/effects/Disto.cpp b/src/sfizz/effects/Disto.cpp index c3939f9e..946fdae6 100644 --- a/src/sfizz/effects/Disto.cpp +++ b/src/sfizz/effects/Disto.cpp @@ -38,11 +38,11 @@ struct Disto::Impl { enum { maxStages = 4 }; float _samplePeriod { 1.0f / config::defaultSampleRate }; - float _tone { Default::distoTone.value }; - float _depth { Default::distoDepth.value }; - float _dry { Default::effect.value }; - float _wet { Default::effect.value }; - unsigned _numStages = { Default::distoStages.value }; + float _tone { Default::distoTone }; + float _depth { Default::distoDepth }; + float _dry { Default::effect }; + float _wet { Default::effect }; + unsigned _numStages = { Default::distoStages }; float _toneLpfMem[EffectChannels] = {}; faustDisto _stages[EffectChannels][Default::maxDistoStages]; @@ -205,24 +205,19 @@ std::unique_ptr Disto::makeInstance(absl::Span members) for (const Opcode& opc : members) { switch (opc.lettersOnlyHash) { case hash("disto_tone"): - if (auto value = opc.read(Default::distoTone)) - impl._tone = *value; + impl._tone = opc.read(Default::distoTone); break; case hash("disto_depth"): - if (auto value = opc.read(Default::distoDepth)) - impl._depth = *value; + impl._depth = opc.read(Default::distoDepth); break; case hash("disto_stages"): - if (auto value = opc.read(Default::distoStages)) - impl._numStages = *value; + impl._numStages = opc.read(Default::distoStages); break; case hash("disto_dry"): - if (auto value = opc.read(Default::effect)) - impl._dry = *value * 0.01f; + impl._dry = opc.read(Default::effect); break; case hash("disto_wet"): - if (auto value = opc.read(Default::effect)) - impl._wet = *value * 0.01f; + impl._wet = opc.read(Default::effect); break; } } diff --git a/src/sfizz/effects/Eq.cpp b/src/sfizz/effects/Eq.cpp index 751ccc12..25036195 100644 --- a/src/sfizz/effects/Eq.cpp +++ b/src/sfizz/effects/Eq.cpp @@ -70,22 +70,17 @@ namespace fx { for (const Opcode& opc : members) { switch (opc.lettersOnlyHash) { case hash("eq_freq"): - if (auto value = opc.read(Default::eqFrequency)) - desc.frequency = *value; + desc.frequency = opc.read(Default::eqFrequency); break; case hash("eq_bw"): - if (auto value = opc.read(Default::eqBandwidth)) - desc.bandwidth = *value; + desc.bandwidth = opc.read(Default::eqBandwidth); break; case hash("eq_gain"): - if (auto value = opc.read(Default::eqGain)) - desc.gain = *value; + desc.gain = opc.read(Default::eqGain); break; case hash("eq_type"): - { - desc.type = opc.read(Default::eq).value_or(desc.type); - break; - } + desc.type = opc.read(Default::eq); + break; } } diff --git a/src/sfizz/effects/Filter.cpp b/src/sfizz/effects/Filter.cpp index b3765b61..8b2dff72 100644 --- a/src/sfizz/effects/Filter.cpp +++ b/src/sfizz/effects/Filter.cpp @@ -72,22 +72,17 @@ namespace fx { for (const Opcode& opc : members) { switch (opc.lettersOnlyHash) { case hash("filter_cutoff"): - if (auto value = opc.read(Default::filterCutoff)) - desc.cutoff = *value; + desc.cutoff = opc.read(Default::filterCutoff); break; case hash("filter_resonance"): - if (auto value = opc.read(Default::filterResonance)) - desc.resonance = *value; + desc.resonance = opc.read(Default::filterResonance); break; case hash("filter_type"): - { - desc.type = opc.read(Default::filter).value_or(desc.type); - break; - } + desc.type = opc.read(Default::filter); + break; // extension case hash("sfizz:filter_gain"): - if (auto value = opc.read(Default::filterGain)) - desc.gain = *value; + desc.gain = opc.read(Default::filterGain); break; } } diff --git a/src/sfizz/effects/Fverb.cpp b/src/sfizz/effects/Fverb.cpp index c3a1f408..c8ab7938 100644 --- a/src/sfizz/effects/Fverb.cpp +++ b/src/sfizz/effects/Fverb.cpp @@ -180,13 +180,13 @@ namespace fx { std::unique_ptr fx { reverb }; const Impl::Profile* profile = &Impl::largeHall; - float dry { Default::effect.value }; - float wet { Default::effect.value }; - float input { Default::effect.value }; - float size { Default::fverbSize.value }; - float predelay { Default::fverbPredelay.value }; - float tone { Default::fverbTone.value }; - float damp { Default::fverbDamp.value }; + float dry { Default::effect }; + float wet { Default::effect }; + float input { Default::effect }; + float size { Default::fverbSize }; + float predelay { Default::fverbPredelay }; + float tone { Default::fverbTone }; + float damp { Default::fverbDamp }; for (const Opcode& opc : members) { switch (opc.lettersOnlyHash) { @@ -212,25 +212,25 @@ namespace fx { break; case hash("reverb_dry"): - dry = opc.read(Default::effect).value_or(dry); + dry = opc.read(Default::effect); break; case hash("reverb_wet"): - wet = opc.read(Default::effect).value_or(wet); + wet = opc.read(Default::effect); break; case hash("reverb_input"): - input = opc.read(Default::effect).value_or(input); + input = opc.read(Default::effect); break; case hash("reverb_size"): - size = opc.read(Default::fverbSize).value_or(size); + size = opc.read(Default::fverbSize); break; case hash("reverb_predelay"): - predelay = opc.read(Default::fverbPredelay).value_or(predelay); + predelay = opc.read(Default::fverbPredelay); break; case hash("reverb_tone"): - tone = opc.read(Default::fverbTone).value_or(tone); + tone = opc.read(Default::fverbTone); break; case hash("reverb_damp"): - damp = opc.read(Default::fverbDamp).value_or(damp); + damp = opc.read(Default::fverbDamp); break; } } diff --git a/src/sfizz/effects/Gain.cpp b/src/sfizz/effects/Gain.cpp index 7ad9fb9f..aa8d6d03 100644 --- a/src/sfizz/effects/Gain.cpp +++ b/src/sfizz/effects/Gain.cpp @@ -62,8 +62,7 @@ namespace fx { for (const Opcode& opc : members) { switch (opc.lettersOnlyHash) { case hash("gain"): - if (auto value = opc.read(Default::volume)) - gain->_gain = *value; + gain->_gain = opc.read(Default::volume); break; } } diff --git a/src/sfizz/effects/Gate.cpp b/src/sfizz/effects/Gate.cpp index a4a916a3..7bbc158a 100644 --- a/src/sfizz/effects/Gate.cpp +++ b/src/sfizz/effects/Gate.cpp @@ -34,7 +34,7 @@ namespace fx { struct Gate::Impl { faustGate _gate[2]; - bool _stlink { Default::gateSTLink.value }; + bool _stlink { Default::gateSTLink }; float _inputGain = 1.0; AudioBuffer _tempBuffer2x { 2, _oversampling * config::defaultSamplesPerBlock }; AudioBuffer _gain2x { 2, _oversampling * config::defaultSamplesPerBlock }; @@ -166,31 +166,35 @@ namespace fx { for (const Opcode& opc : members) { switch (opc.lettersOnlyHash) { case hash("gate_attack"): - if (auto value = opc.read(Default::gateAttack)) { + { + auto value = opc.read(Default::gateAttack); for (size_t c = 0; c < 2; ++c) - impl.set_Attack(c, *value); + impl.set_Attack(c, value); } break; case hash("gate_hold"): - if (auto value = opc.read(Default::gateHold)) { + { + auto value = opc.read(Default::gateHold); for (size_t c = 0; c < 2; ++c) - impl.set_Hold(c, *value); + impl.set_Hold(c, value); } break; case hash("gate_release"): - if (auto value = opc.read(Default::gateRelease)) { + { + auto value = opc.read(Default::gateRelease); for (size_t c = 0; c < 2; ++c) - impl.set_Release(c, *value); + impl.set_Release(c, value); } break; case hash("gate_threshold"): - if (auto value = opc.read(Default::gateThreshold)) { + { + auto value = opc.read(Default::gateThreshold); for (size_t c = 0; c < 2; ++c) - impl.set_Threshold(c, *value); + impl.set_Threshold(c, value); } break; case hash("gate_stlink"): - impl._stlink = opc.read(Default::gateSTLink).value_or(impl._stlink); + impl._stlink = opc.read(Default::gateSTLink); } } diff --git a/src/sfizz/effects/Lofi.cpp b/src/sfizz/effects/Lofi.cpp index 00a11128..24aaf772 100644 --- a/src/sfizz/effects/Lofi.cpp +++ b/src/sfizz/effects/Lofi.cpp @@ -85,12 +85,10 @@ namespace fx { for (const Opcode& opcode : members) { switch (opcode.lettersOnlyHash) { case hash("bitred"): - if (auto value = opcode.read(Default::lofiBitred)) - lofi->_bitred_depth = *value; + lofi->_bitred_depth = opcode.read(Default::lofiBitred); break; case hash("decim"): - if (auto value = opcode.read(Default::lofiDecim)) - lofi->_decim_depth = *value; + lofi->_decim_depth = opcode.read(Default::lofiDecim); break; } } diff --git a/src/sfizz/effects/Rectify.cpp b/src/sfizz/effects/Rectify.cpp index f8d271dd..5d25be46 100644 --- a/src/sfizz/effects/Rectify.cpp +++ b/src/sfizz/effects/Rectify.cpp @@ -95,8 +95,7 @@ namespace fx { rectify->_full = false; break; case hash("rectify"): - if (auto value = opc.read(Default::rectify)) - rectify->_amount = *value; + rectify->_amount = opc.read(Default::rectify); break; } } diff --git a/src/sfizz/effects/Strings.cpp b/src/sfizz/effects/Strings.cpp index 6538b68a..2ef50f7c 100644 --- a/src/sfizz/effects/Strings.cpp +++ b/src/sfizz/effects/Strings.cpp @@ -132,12 +132,10 @@ namespace fx { for (const Opcode& opc : members) { switch (opc.lettersOnlyHash) { case hash("strings_number"): - if (auto value = opc.read(Default::stringsNumber)) - strings->_numStrings = *value; + strings->_numStrings = opc.read(Default::stringsNumber); break; case hash("strings_wet"): - if (auto value = opc.read(Default::effect)) - strings->_wet = *value; + strings->_wet = opc.read(Default::effect); break; } } diff --git a/src/sfizz/effects/Strings.h b/src/sfizz/effects/Strings.h index f20ae8a8..29121174 100644 --- a/src/sfizz/effects/Strings.h +++ b/src/sfizz/effects/Strings.h @@ -52,7 +52,7 @@ namespace fx { enum { MaximumNumStrings = 88 }; unsigned _numStrings { Default::maxStrings }; - float _wet { Default::effect.value }; + float _wet { Default::effect }; std::unique_ptr _stringsArray; diff --git a/src/sfizz/effects/Width.cpp b/src/sfizz/effects/Width.cpp index 2a3cdc92..98906e52 100644 --- a/src/sfizz/effects/Width.cpp +++ b/src/sfizz/effects/Width.cpp @@ -69,8 +69,7 @@ namespace fx { for (const Opcode& opc : members) { switch (opc.lettersOnlyHash) { case hash("width"): - if (auto value = opc.read(Default::width)) - width->_width = *value; + width->_width = opc.read(Default::width); break; } } diff --git a/tests/OpcodeT.cpp b/tests/OpcodeT.cpp index 61971b39..7439a306 100644 --- a/tests/OpcodeT.cpp +++ b/tests/OpcodeT.cpp @@ -317,8 +317,8 @@ TEST_CASE("[Opcode] opcode read (uint8_t)") SECTION("Ignore") { Opcode opcode { "", "110" }; - OpcodeSpec spec { 0, Range(0, 100), kIgnoreOOB }; - REQUIRE( !opcode.read(spec) ); + OpcodeSpec spec { 0, Range(0, 100), 0 }; + REQUIRE( opcode.read(spec) == spec.defaultValue ); } SECTION("Clamp upper") @@ -345,21 +345,21 @@ TEST_CASE("[Opcode] opcode read (uint8_t)") SECTION("Text after") { Opcode opcode { "", "10garbage" }; - OpcodeSpec spec { 0, Range(20, 100), kEnforceLowerBound }; - REQUIRE( opcode.read(spec) == 20 ); + OpcodeSpec spec { 0, Range(0, 100), 0 }; + REQUIRE( opcode.read(spec) == 10 ); } SECTION("Text before") { Opcode opcode { "", "garbage10" }; - OpcodeSpec spec { 0, Range(20, 100), 0 }; - REQUIRE( !opcode.read(spec) ); + OpcodeSpec spec { 0, Range(0, 100), 0 }; + REQUIRE( opcode.read(spec) == spec.defaultValue ); } SECTION("Can be note") { Opcode opcode { "", "c4" }; - OpcodeSpec spec { 0, Range(20, 100), kCanBeNote }; + OpcodeSpec spec { 0, Range(0, 100), kCanBeNote }; REQUIRE( opcode.read(spec) == 60 ); } } @@ -387,13 +387,6 @@ TEST_CASE("[Opcode] opcode read (int)") REQUIRE( opcode.read(spec) == -16); } - SECTION("Ignore") - { - Opcode opcode { "", "110" }; - OpcodeSpec spec { 0, Range(-100, 100), kIgnoreOOB }; - REQUIRE( !opcode.read(spec) ); - } - SECTION("Clamp upper") { Opcode opcode { "", "110" }; @@ -418,7 +411,7 @@ TEST_CASE("[Opcode] opcode read (int)") SECTION("Text after") { Opcode opcode { "", "10garbage" }; - OpcodeSpec spec { 0, Range(20, 100), kEnforceLowerBound }; + OpcodeSpec spec { 0, Range(20, 100), 0 }; REQUIRE( opcode.read(spec) == 20 ); } @@ -464,8 +457,8 @@ TEST_CASE("[Opcode] opcode read (float)") SECTION("Ignore") { Opcode opcode { "", "110" }; - OpcodeSpec spec { 0.0f, Range(-100.0f, 100.0f), kIgnoreOOB }; - REQUIRE( !opcode.read(spec) ); + OpcodeSpec spec { 0.0f, Range(-100.0f, 100.0f), 0 }; + REQUIRE( opcode.read(spec) == spec.defaultValue ); } SECTION("Clamp upper") diff --git a/tests/RegionValueComputationsT.cpp b/tests/RegionValueComputationsT.cpp index 39412b95..f3b1abca 100644 --- a/tests/RegionValueComputationsT.cpp +++ b/tests/RegionValueComputationsT.cpp @@ -299,15 +299,15 @@ TEST_CASE("[Region] rt_decay") region.parseOpcode({ "rt_decay", "10" }); midiState.noteOnEvent(0, 64, 64_norm); midiState.advanceTime(100); - REQUIRE( region.getBaseVolumedB(64) == Approx(Default::volume.value - 1.0f).margin(0.1) ); + REQUIRE( region.getBaseVolumedB(64) == Approx(Default::volume - 1.0f).margin(0.1) ); region.parseOpcode({ "rt_decay", "20" }); midiState.noteOnEvent(0, 64, 64_norm); midiState.advanceTime(100); - REQUIRE( region.getBaseVolumedB(64) == Approx(Default::volume.value - 2.0f).margin(0.1) ); + REQUIRE( region.getBaseVolumedB(64) == Approx(Default::volume - 2.0f).margin(0.1) ); region.parseOpcode({ "trigger", "attack" }); midiState.noteOnEvent(0, 64, 64_norm); midiState.advanceTime(100); - REQUIRE( region.getBaseVolumedB(64) == Approx(Default::volume.value).margin(0.1) ); + REQUIRE( region.getBaseVolumedB(64) == Approx(Default::volume).margin(0.1) ); } TEST_CASE("[Region] Base delay") diff --git a/tests/RegionValuesT.cpp b/tests/RegionValuesT.cpp index a3e02417..a457607b 100644 --- a/tests/RegionValuesT.cpp +++ b/tests/RegionValuesT.cpp @@ -248,9 +248,9 @@ TEST_CASE("[Values] Count") synth.dispatchMessage(client, 0, "/region1/count", "", nullptr); synth.dispatchMessage(client, 0, "/region2/count", "", nullptr); std::vector expected { - "/region0/count,N : { }", + "/region0/count,h : { 1 }", "/region1/count,h : { 2 }", - "/region2/count,N : { }", + "/region2/count,h : { 1 }", }; REQUIRE(messageList == expected); } @@ -453,7 +453,7 @@ TEST_CASE("[Values] Off time") std::vector expected { "/region0/off_time,f : { 0.006 }", "/region1/off_time,f : { 0.1 }", - "/region2/off_time,f : { 0 }", + "/region2/off_time,f : { 0.006 }", }; REQUIRE(messageList == expected); } @@ -747,7 +747,7 @@ TEST_CASE("[Values] Upswitch") "/region2/sw_up,N : { }", "/region3/sw_up,N : { }", "/region4/sw_up,i : { 60 }", - "/region5/sw_up,i : { 64 }", + "/region5/sw_up,i : { 60 }", }; REQUIRE(messageList == expected); } @@ -778,7 +778,7 @@ TEST_CASE("[Values] Downswitch") "/region2/sw_down,N : { }", "/region3/sw_down,N : { }", "/region4/sw_down,i : { 60 }", - "/region5/sw_down,i : { 64 }", + "/region5/sw_down,i : { 60 }", }; REQUIRE(messageList == expected); } diff --git a/tests/SynthT.cpp b/tests/SynthT.cpp index fa5cb076..78701e5b 100644 --- a/tests/SynthT.cpp +++ b/tests/SynthT.cpp @@ -572,7 +572,7 @@ TEST_CASE("[Synth] sample quality") // default sample quality synth.noteOn(0, 60, 100); REQUIRE(synth.getNumActiveVoices() == 1); - REQUIRE(synth.getVoiceView(0)->getCurrentSampleQuality() == sfz::Default::sampleQuality.value); + REQUIRE(synth.getVoiceView(0)->getCurrentSampleQuality() == sfz::Default::sampleQuality); synth.allSoundOff(); // default sample quality, freewheeling