Remove opcode limits

This commit is contained in:
Jean Pierre Cimalando 2021-03-19 17:51:45 +01:00
parent d183c8c5a7
commit 0196fb57ad
16 changed files with 250 additions and 250 deletions

View file

@ -17,135 +17,133 @@ using UInt32Spec = const OpcodeSpec<uint32_t>;
using BoolSpec = const OpcodeSpec<bool>;
template <class Enum> using ESpec = const OpcodeSpec<Enum>;
FloatSpec delay { 0.0f, {0.0f, 100.0f}, 0 };
FloatSpec delayRandom { 0.0f, {0.0f, 100.0f}, 0 };
FloatSpec delayMod { 0.0f, {0.0f, 100.0f}, 0 };
Int64Spec offset { 0, {0, uint32_t_max}, 0 };
Int64Spec offsetMod { 0, {0, uint32_t_max}, 0 };
Int64Spec offsetRandom { 0, {0, uint32_t_max}, 0 };
UInt32Spec sampleEnd { uint32_t_max, {0, uint32_t_max}, kEnforceLowerBound };
UInt32Spec sampleCount { 0, {0, uint32_t_max}, 0 };
UInt32Spec loopStart { 0, {0, uint32_t_max}, 0 };
UInt32Spec loopEnd { uint32_t_max, {0, uint32_t_max}, 0 };
UInt32Spec loopCount { 0, {0, uint32_t_max}, 0 };
FloatSpec loopCrossfade { 1e-3, {1e-3, 1.0f}, 0 };
FloatSpec delay { 0.0f, {0.0f, 100.0f}, kPermissiveBounds };
FloatSpec delayRandom { 0.0f, {0.0f, 100.0f}, kPermissiveBounds };
FloatSpec delayMod { 0.0f, {0.0f, 100.0f}, kPermissiveBounds };
Int64Spec offset { 0, {0, uint32_t_max}, kPermissiveBounds };
Int64Spec offsetMod { 0, {0, uint32_t_max}, kPermissiveBounds };
Int64Spec offsetRandom { 0, {0, uint32_t_max}, kPermissiveBounds };
UInt32Spec sampleEnd { uint32_t_max, {0, uint32_t_max}, kEnforceBounds };
UInt32Spec sampleCount { 0, {0, uint32_t_max}, kEnforceUpperBound };
UInt32Spec loopStart { 0, {0, uint32_t_max}, kEnforceUpperBound };
UInt32Spec loopEnd { uint32_t_max, {0, uint32_t_max}, kEnforceUpperBound };
UInt32Spec loopCount { 0, {0, uint32_t_max}, kEnforceUpperBound };
FloatSpec loopCrossfade { 1e-3, {1e-3, 1.0f}, kEnforceLowerBound|kPermissiveUpperBound };
ESpec<OscillatorEnabled> oscillator { OscillatorEnabled::Auto, {OscillatorEnabled::Auto, OscillatorEnabled::On}, 0 };
FloatSpec oscillatorPhase { 0.0f, {-1000.0f, 1000.0f}, 0 };
FloatSpec oscillatorPhase { 0.0f, {-1000.0f, 1000.0f}, kPermissiveBounds };
Int32Spec oscillatorMode { 0, {0, 2}, 0 };
Int32Spec oscillatorMulti { 1, {1, config::oscillatorsPerVoice}, 0 };
FloatSpec oscillatorDetune { 0.0f, {-12000.0f, 12000.0f}, 0 };
FloatSpec oscillatorDetuneMod { 0.0f, {-12000.0f, 12000.0f}, 0 };
FloatSpec oscillatorModDepth { 0.0f, {0.0f, 10000.0f}, kNormalizePercent };
FloatSpec oscillatorModDepthMod { 0.0f, {0.0f, 10000.0f}, kNormalizePercent };
Int32Spec oscillatorMulti { 1, {1, config::oscillatorsPerVoice}, kEnforceBounds };
FloatSpec oscillatorDetune { 0.0f, {-12000.0f, 12000.0f}, kPermissiveBounds };
FloatSpec oscillatorDetuneMod { 0.0f, {-12000.0f, 12000.0f}, kPermissiveBounds };
FloatSpec oscillatorModDepth { 0.0f, {0.0f, 10000.0f}, kNormalizePercent|kPermissiveBounds };
FloatSpec oscillatorModDepthMod { 0.0f, {0.0f, 10000.0f}, kNormalizePercent|kPermissiveBounds };
Int32Spec oscillatorQuality { 1, {0, 3}, 0 };
UInt32Spec group { 0, {0, uint32_t_max}, 0 };
FloatSpec offTime { 6e-3f, {0.0f, 100.0f}, 0 };
UInt32Spec polyphony { config::maxVoices, {0, config::maxVoices}, 0 };
UInt32Spec notePolyphony { config::maxVoices, {0, config::maxVoices}, 0 };
FloatSpec offTime { 6e-3f, {0.0f, 100.0f}, kPermissiveBounds };
UInt32Spec polyphony { config::maxVoices, {0, config::maxVoices}, kEnforceBounds };
UInt32Spec notePolyphony { config::maxVoices, {0, config::maxVoices}, kEnforceBounds };
UInt8Spec key { 60, {0, 127}, kCanBeNote };
UInt8Spec loKey { 0, {0, 127}, kCanBeNote };
UInt8Spec hiKey { 127, {0, 127}, kCanBeNote };
FloatSpec loCC { 0, {0.0f, 127.0f}, kNormalizeMidi };
FloatSpec hiCC { 127, {0.0f, 127.0f}, kNormalizeMidi };
FloatSpec loVel { 0, {0.0f, 127.0f}, kNormalizeMidi };
FloatSpec hiVel { 127, {0.0f, 127.0f}, kNormalizeMidi };
FloatSpec loChannelAftertouch { 0, {0, 127}, kNormalizeMidi };
FloatSpec hiChannelAftertouch { 127, {0, 127}, kNormalizeMidi };
FloatSpec loBend { -8192, {-8192.0f, 8192.0f}, kNormalizeBend };
FloatSpec hiBend { 8192, {-8192.0f, 8192.0f}, kNormalizeBend };
FloatSpec loNormalized { 0.0f, {0.0f, 1.0f}, 0 };
FloatSpec hiNormalized { 1.0f, {0.0f, 1.0f}, 0 };
FloatSpec loBipolar { -1.0f, {-1.0f, 1.0f}, 0 };
FloatSpec hiBipolar { 1.0f, {-1.0f, 1.0f}, 0 };
FloatSpec loCC { 0, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
FloatSpec hiCC { 127, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
FloatSpec loVel { 0, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
FloatSpec hiVel { 127, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
FloatSpec loChannelAftertouch { 0, {0, 127}, kNormalizeMidi|kPermissiveBounds };
FloatSpec hiChannelAftertouch { 127, {0, 127}, kNormalizeMidi|kPermissiveBounds };
FloatSpec loBend { -8191, {-8192.0f, 8191.0f}, kNormalizeBend|kPermissiveBounds };
FloatSpec hiBend { 8191, {-8192.0f, 8191.0f}, kNormalizeBend|kPermissiveBounds };
FloatSpec loNormalized { 0.0f, {0.0f, 1.0f}, kPermissiveBounds };
FloatSpec hiNormalized { 1.0f, {0.0f, 1.0f}, kPermissiveBounds };
FloatSpec loBipolar { -1.0f, {-1.0f, 1.0f}, kPermissiveBounds };
FloatSpec hiBipolar { 1.0f, {-1.0f, 1.0f}, kPermissiveBounds };
UInt16Spec ccNumber { 0, {0, config::numCCs}, 0 };
UInt16Spec smoothCC { 0, {0, 100}, kPermissiveUpperBound };
UInt8Spec curveCC { 0, {0, 255}, 0 };
UInt8Spec sustainCC { 64, {0, 127}, 0 };
FloatSpec sustainThreshold { 1.0f, {0.0f, 127.0f}, kNormalizeMidi };
BoolSpec checkSustain { true, {0, 1}, 0 };
BoolSpec checkSostenuto { true, {0, 1}, 0 };
FloatSpec loBPM { 0.0f, {0.0f, 500.0f}, 0 };
FloatSpec hiBPM { 500.0f, {0.0f, 500.0f}, 0 };
FloatSpec sustainThreshold { 1.0f, {0.0f, 127.0f}, kNormalizeMidi|kPermissiveBounds };
BoolSpec checkSustain { true, {0, 1}, kEnforceBounds };
BoolSpec checkSostenuto { true, {0, 1}, kEnforceBounds };
FloatSpec loBPM { 0.0f, {0.0f, 500.0f}, kPermissiveBounds };
FloatSpec hiBPM { 500.0f, {0.0f, 500.0f}, kPermissiveBounds };
UInt8Spec sequence { 1, {1, 100}, 0 };
FloatSpec volume { 0.0f, {-144.0f, 48.0f}, 0 };
FloatSpec volumeMod { 0.0f, {-144.0f, 48.0f}, 0 };
FloatSpec amplitude { 100.0f, {0.0f, 10000.0f}, kNormalizePercent };
FloatSpec amplitudeMod { 0.0f, {0.0f, 10000.0f}, 0 };
FloatSpec pan { 0.0f, {-100.0f, 100.0f}, kNormalizePercent };
FloatSpec panMod { 0.0f, {-200.0f, 200.0f}, 0 };
FloatSpec position { 0.0f, {-100.0f, 100.0f}, kNormalizePercent };
FloatSpec positionMod { 0.0f, {-200.0f, 200.0f}, 0 };
FloatSpec width { 100.0f, {-100.0f, 100.0f}, kNormalizePercent };
FloatSpec widthMod { 0.0f, {-200.0f, 200.0f}, 0 };
FloatSpec crossfadeIn { 0.0f, {0.0f, 127.0f}, kNormalizeMidi };
FloatSpec crossfadeInNorm { 0.0f, {0.0f, 1.0f}, 0 };
FloatSpec crossfadeOut { 127.0f, {0.0f, 127.0f}, kNormalizeMidi };
FloatSpec crossfadeOutNorm { 1.0f, {0.0f, 1.0f}, 0 };
FloatSpec ampKeytrack { 0.0f, {-96.0f, 12.0f}, 0 };
FloatSpec ampVeltrack { 100.0f, {-100.0f, 100.0f}, kNormalizePercent };
FloatSpec ampVelcurve { 0.0f, {0.0f, 1.0f}, 0 };
FloatSpec ampRandom { 0.0f, {-24.0f, 24.0f}, 0 };
BoolSpec rtDead { false, {false, true}, 0 };
FloatSpec rtDecay { 0.0f, {0.0f, 200.0f}, 0 };
FloatSpec filterCutoff { 0.0f, {0.0f, 20000.0f}, kEnforceUpperBound };
FloatSpec filterCutoffMod { 0.0f, {-12000.0f, 12000.0f}, 0 };
FloatSpec filterResonance { 0.0f, {0.0f, 96.0f}, 0 };
FloatSpec filterResonanceMod { 0.0f, {0.0f, 96.0f}, 0 };
FloatSpec filterGain { 0.0f, {-96.0f, 96.0f}, 0 };
FloatSpec filterGainMod { 0.0f, {-96.0f, 96.0f}, 0 };
FloatSpec filterRandom { 0.0f, {-12000.0f, 12000.0f}, 0 };
Int32Spec filterKeytrack { 0, {0, 1200}, 0 };
Int32Spec filterVeltrack { 0, {-12000, 12000}, 0 };
FloatSpec eqBandwidth { 1.0f, {0.001f, 4.0f}, 0 };
FloatSpec eqBandwidthMod { 0.0f, {-4.0f, 4.0f}, 0 };
FloatSpec eqFrequency { 0.0f, {0.0f, 20000.0f}, kEnforceUpperBound };
FloatSpec eqFrequencyMod { 0.0f, {-20000.0f, 20000.0f}, 0 };
FloatSpec eqGain { 0.0f, {-96.0f, 96.0f}, 0 };
FloatSpec eqGainMod { 0.0f, {-96.0f, 96.0f}, 0 };
FloatSpec eqVel2Frequency { 0.0f, {-30000.0f, 30000.0f}, 0 };
FloatSpec eqVel2Gain { 0.0f, {-96.0f, 96.0f}, 0 };
Int32Spec pitchKeytrack { 100, {-1200, 1200}, 0 };
FloatSpec pitchRandom { 0.0f, {-12000.0f, 12000.0f}, 0 };
Int32Spec pitchVeltrack { 0, {-12000, 12000}, 0 };
Int32Spec transpose { 0, {-127, 127}, 0 };
FloatSpec pitch { 0.0f, {-2400.0f, 2400.0f}, 0 };
FloatSpec pitchMod { 0.0f, {-2400.0f, 2400.0f}, 0 };
FloatSpec bendUp { 200.0f, {-12000.0f, 12000.0f}, 0 };
FloatSpec bendDown { -200.0f, {-12000.0f, 12000.0f}, 0 };
FloatSpec bendStep { 1.0f, {1.0f, 1200.0f}, 0 };
FloatSpec ampLFODepth { 0.0f, {-10.0f, 10.0f}, 0 };
FloatSpec pitchLFODepth { 0.0f, {-1200.0f, 1200.0f}, 0 };
FloatSpec filLFODepth { 0.0f, {-1200.0f, 1200.0f}, 0 };
FloatSpec lfoFreq { 0.0f, {0.0f, 100.0f}, 0 };
FloatSpec lfoFreqMod { 0.0f, {-100.0f, 100.0f}, 0 };
FloatSpec lfoBeats { 0.0f, {0.0f, 1000.0f}, 0 };
FloatSpec lfoBeatsMod { 0.0f, {-1000.0f, 1000.0f}, 0 };
FloatSpec lfoPhase { 0.0f, {0.0f, 1.0f}, kWrapPhase };
FloatSpec lfoDelay { 0.0f, {0.0f, 30.0f}, 0 };
FloatSpec lfoFade { 0.0f, {0.0f, 30.0f}, 0 };
UInt32Spec lfoCount { 0, {0, 1000}, 0 };
UInt32Spec lfoSteps { 0, {0, static_cast<unsigned>(config::maxLFOSteps)}, 0 };
FloatSpec lfoStepX { 0.0f, {-100.0f, 100.0f}, kNormalizePercent };
FloatSpec volume { 0.0f, {-144.0f, 48.0f}, kPermissiveBounds };
FloatSpec volumeMod { 0.0f, {-144.0f, 48.0f}, kPermissiveBounds };
FloatSpec amplitude { 100.0f, {0.0f, 10000.0f}, kNormalizePercent|kPermissiveBounds };
FloatSpec amplitudeMod { 0.0f, {0.0f, 10000.0f}, kPermissiveBounds };
FloatSpec pan { 0.0f, {-100.0f, 100.0f}, kNormalizePercent|kPermissiveBounds };
FloatSpec panMod { 0.0f, {-200.0f, 200.0f}, kPermissiveBounds };
FloatSpec position { 0.0f, {-100.0f, 100.0f}, kNormalizePercent|kPermissiveBounds };
FloatSpec positionMod { 0.0f, {-200.0f, 200.0f}, kPermissiveBounds };
FloatSpec width { 100.0f, {-100.0f, 100.0f}, kNormalizePercent|kPermissiveBounds };
FloatSpec widthMod { 0.0f, {-200.0f, 200.0f}, kPermissiveBounds };
FloatSpec ampKeytrack { 0.0f, {-96.0f, 12.0f}, kPermissiveBounds };
FloatSpec ampVeltrack { 100.0f, {-100.0f, 100.0f}, kNormalizePercent|kPermissiveBounds };
FloatSpec ampVelcurve { 0.0f, {0.0f, 1.0f}, kPermissiveBounds };
FloatSpec ampRandom { 0.0f, {-24.0f, 24.0f}, kPermissiveBounds };
BoolSpec rtDead { false, {false, true}, kEnforceBounds };
FloatSpec rtDecay { 0.0f, {0.0f, 200.0f}, kEnforceLowerBound|kPermissiveUpperBound };
FloatSpec filterCutoff { 0.0f, {0.0f, 20000.0f}, kPermissiveBounds };
FloatSpec filterCutoffMod { 0.0f, {-12000.0f, 12000.0f}, kPermissiveBounds };
FloatSpec filterResonance { 0.0f, {0.0f, 96.0f}, kPermissiveBounds };
FloatSpec filterResonanceMod { 0.0f, {0.0f, 96.0f}, kPermissiveBounds };
FloatSpec filterGain { 0.0f, {-96.0f, 96.0f}, kPermissiveBounds };
FloatSpec filterGainMod { 0.0f, {-96.0f, 96.0f}, kPermissiveBounds };
FloatSpec filterRandom { 0.0f, {-12000.0f, 12000.0f}, kPermissiveBounds };
FloatSpec filterKeytrack { 0, {0, 1200}, kPermissiveBounds };
FloatSpec filterVeltrack { 0, {-12000, 12000}, kPermissiveBounds };
FloatSpec eqBandwidth { 1.0f, {0.001f, 4.0f}, kPermissiveBounds };
FloatSpec eqBandwidthMod { 0.0f, {-4.0f, 4.0f}, kPermissiveBounds };
FloatSpec eqFrequency { 0.0f, {0.0f, 20000.0f}, kPermissiveBounds };
FloatSpec eqFrequencyMod { 0.0f, {-20000.0f, 20000.0f}, kPermissiveBounds };
FloatSpec eqGain { 0.0f, {-96.0f, 96.0f}, kPermissiveBounds };
FloatSpec eqGainMod { 0.0f, {-96.0f, 96.0f}, kPermissiveBounds };
FloatSpec eqVel2Frequency { 0.0f, {-30000.0f, 30000.0f}, kPermissiveBounds };
FloatSpec eqVel2Gain { 0.0f, {-96.0f, 96.0f}, kPermissiveBounds };
FloatSpec pitchKeytrack { 100, {-1200, 1200}, kPermissiveBounds };
FloatSpec pitchRandom { 0.0f, {-12000.0f, 12000.0f}, kPermissiveBounds };
FloatSpec pitchVeltrack { 0, {-12000, 12000}, kPermissiveBounds };
FloatSpec transpose { 0, {-127, 127}, kPermissiveBounds };
FloatSpec pitch { 0.0f, {-2400.0f, 2400.0f}, kPermissiveBounds };
FloatSpec pitchMod { 0.0f, {-2400.0f, 2400.0f}, kPermissiveBounds };
FloatSpec bendUp { 200.0f, {-12000.0f, 12000.0f}, kPermissiveBounds };
FloatSpec bendDown { -200.0f, {-12000.0f, 12000.0f}, kPermissiveBounds };
FloatSpec bendStep { 1.0f, {1.0f, 1200.0f}, kEnforceLowerBound|kPermissiveBounds };
FloatSpec ampLFODepth { 0.0f, {-10.0f, 10.0f}, kPermissiveBounds };
FloatSpec pitchLFODepth { 0.0f, {-1200.0f, 1200.0f}, kPermissiveBounds };
FloatSpec filLFODepth { 0.0f, {-1200.0f, 1200.0f}, kPermissiveBounds };
FloatSpec lfoFreq { 0.0f, {0.0f, 100.0f}, kPermissiveBounds };
FloatSpec lfoFreqMod { 0.0f, {-100.0f, 100.0f}, kPermissiveBounds };
FloatSpec lfoBeats { 0.0f, {0.0f, 1000.0f}, kPermissiveBounds };
FloatSpec lfoBeatsMod { 0.0f, {-1000.0f, 1000.0f}, kPermissiveBounds };
FloatSpec lfoPhase { 0.0f, {0.0f, 1.0f}, kWrapPhase|kPermissiveBounds };
FloatSpec lfoDelay { 0.0f, {0.0f, 30.0f}, kPermissiveBounds };
FloatSpec lfoFade { 0.0f, {0.0f, 30.0f}, kPermissiveBounds };
UInt32Spec lfoCount { 0, {0, 1000}, kEnforceLowerBound|kPermissiveUpperBound };
UInt32Spec lfoSteps { 0, {0, static_cast<unsigned>(config::maxLFOSteps)}, kEnforceBounds };
FloatSpec lfoStepX { 0.0f, {-100.0f, 100.0f}, kNormalizePercent|kPermissiveBounds };
ESpec<LFOWave> lfoWave { LFOWave::Triangle, {LFOWave::Triangle, LFOWave::RandomSH}, 0 };
FloatSpec lfoOffset { 0.0f, {-1.0f, 1.0f}, 0 };
FloatSpec lfoRatio { 1.0f, {0.0f, 100.0f}, 0 };
FloatSpec lfoScale { 1.0f, {0.0f, 1.0f}, 0 };
FloatSpec egTime { 0.0f, {0.0f, 100.0f}, 0 };
FloatSpec egRelease { 0.001f, {0.0f, 100.0f}, 0 };
FloatSpec egTimeMod { 0.0f, {-100.0f, 100.0f}, 0 };
FloatSpec egPercent { 0.0f, {0.0f, 100.0f}, 0 };
FloatSpec egPercentMod { 0.0f, {-100.0f, 100.0f}, 0 };
FloatSpec egDepth { 0.0f, {-12000.0f, 12000.0f}, 0 };
FloatSpec egVel2Depth { 0.0f, {-12000.0f, 12000.0f}, 0 };
BoolSpec flexEGAmpeg { false, {0, 1}, 0 };
Int32Spec flexEGDynamic { 0, {0, 1}, 0 };
Int32Spec flexEGSustain { 0, {0, 100}, 0 };
FloatSpec flexEGPointTime { 0.0f, {0.0f, 100.0f}, 0 };
FloatSpec flexEGPointLevel { 0.0f, {-1.0f, 1.0f}, 0 };
FloatSpec flexEGPointShape { 0.0f, {-100.0f, 100.0f}, 0 };
Int32Spec sampleQuality { 1, {1, 10}, 0 };
Int32Spec octaveOffset { 0, {-10, 10}, 0 };
Int32Spec noteOffset { 0, {-127, 127}, 0 };
FloatSpec lfoOffset { 0.0f, {-1.0f, 1.0f}, kPermissiveBounds };
FloatSpec lfoRatio { 1.0f, {0.0f, 100.0f}, kPermissiveBounds };
FloatSpec lfoScale { 1.0f, {0.0f, 1.0f}, kPermissiveBounds };
FloatSpec egTime { 0.0f, {0.0f, 100.0f}, kPermissiveBounds };
FloatSpec egRelease { 0.001f, {0.0f, 100.0f}, kPermissiveBounds };
FloatSpec egTimeMod { 0.0f, {-100.0f, 100.0f}, kPermissiveBounds };
FloatSpec egPercent { 0.0f, {0.0f, 100.0f}, kPermissiveBounds };
FloatSpec egPercentMod { 0.0f, {-100.0f, 100.0f}, kPermissiveBounds };
FloatSpec egDepth { 0.0f, {-12000.0f, 12000.0f}, kPermissiveBounds };
FloatSpec egVel2Depth { 0.0f, {-12000.0f, 12000.0f}, kPermissiveBounds };
BoolSpec flexEGAmpeg { false, {0, 1}, kEnforceBounds };
BoolSpec flexEGDynamic { 0, {0, 1}, kEnforceBounds };
Int32Spec flexEGSustain { 0, {0, 100}, kEnforceLowerBound|kPermissiveUpperBound };
FloatSpec flexEGPointTime { 0.0f, {0.0f, 100.0f}, kPermissiveBounds };
FloatSpec flexEGPointLevel { 0.0f, {-1.0f, 1.0f}, kPermissiveBounds };
FloatSpec flexEGPointShape { 0.0f, {-100.0f, 100.0f}, kPermissiveBounds };
Int32Spec sampleQuality { 1, {0, 10}, 0 };
Int32Spec octaveOffset { 0, {-10, 10}, kPermissiveBounds };
Int32Spec noteOffset { 0, {-127, 127}, kPermissiveBounds };
// TODO: effect opcode flags
FloatSpec effect { 0.0f, {0.0f, 100.0f}, kNormalizePercent };
FloatSpec effectPercent { 0.0f, {0.0f, 100.0f}, 0 };
ESpec<LFOWave> apanWaveform { LFOWave::Triangle, {LFOWave::Triangle, LFOWave::Saw}, 0 };
@ -174,6 +172,7 @@ FloatSpec lofiBitred { 0.0f, {0.0f, 100.0f}, 0 };
FloatSpec lofiDecim { 0.0f, {0.0f, 100.0f}, 0 };
FloatSpec rectify { 0.0f, {0.0f, 100.0f}, 0 };
UInt32Spec stringsNumber { maxStrings, {0, maxStrings}, 0 };
ESpec<Trigger> trigger { Trigger::attack, {Trigger::attack, Trigger::release_key}, 0};
ESpec<CrossfadeCurve> crossfadeCurve { CrossfadeCurve::power, {CrossfadeCurve::gain, CrossfadeCurve::power}, 0};
ESpec<OffMode> offMode { OffMode::fast, {OffMode::fast, OffMode::time}, 0};

View file

@ -88,11 +88,11 @@ struct OpcodeSpec
if (!(flags & needsOperation))
return input;
else if (flags & kNormalizePercent)
return static_cast<U>(normalizePercents(input));
return static_cast<U>(input / U(100));
else if (flags & kNormalizeMidi)
return static_cast<U>(normalize7Bits(input));
return static_cast<U>(input / U(127));
else if (flags & kNormalizeBend)
return static_cast<U>(normalizeBend(input));
return static_cast<U>(input / U(8191));
else if (flags & kDb2Mag)
return static_cast<U>(db2mag(input));
else // just in case
@ -177,10 +177,6 @@ namespace Default
extern const OpcodeSpec<float> positionMod;
extern const OpcodeSpec<float> width;
extern const OpcodeSpec<float> widthMod;
extern const OpcodeSpec<float> crossfadeIn;
extern const OpcodeSpec<float> crossfadeInNorm;
extern const OpcodeSpec<float> crossfadeOut;
extern const OpcodeSpec<float> crossfadeOutNorm;
extern const OpcodeSpec<float> ampKeytrack;
extern const OpcodeSpec<float> ampVeltrack;
extern const OpcodeSpec<float> ampVelcurve;
@ -194,8 +190,8 @@ namespace Default
extern const OpcodeSpec<float> filterGain;
extern const OpcodeSpec<float> filterGainMod;
extern const OpcodeSpec<float> filterRandom;
extern const OpcodeSpec<int32_t> filterKeytrack;
extern const OpcodeSpec<int32_t> filterVeltrack;
extern const OpcodeSpec<float> filterKeytrack;
extern const OpcodeSpec<float> filterVeltrack;
extern const OpcodeSpec<float> eqBandwidth;
extern const OpcodeSpec<float> eqBandwidthMod;
extern const OpcodeSpec<float> eqFrequency;
@ -204,10 +200,10 @@ namespace Default
extern const OpcodeSpec<float> eqGainMod;
extern const OpcodeSpec<float> eqVel2Frequency;
extern const OpcodeSpec<float> eqVel2Gain;
extern const OpcodeSpec<int32_t> pitchKeytrack;
extern const OpcodeSpec<float> pitchKeytrack;
extern const OpcodeSpec<float> pitchRandom;
extern const OpcodeSpec<int32_t> pitchVeltrack;
extern const OpcodeSpec<int32_t> transpose;
extern const OpcodeSpec<float> pitchVeltrack;
extern const OpcodeSpec<float> transpose;
extern const OpcodeSpec<float> pitch;
extern const OpcodeSpec<float> pitchMod;
extern const OpcodeSpec<float> bendUp;
@ -238,7 +234,7 @@ namespace Default
extern const OpcodeSpec<float> egDepth;
extern const OpcodeSpec<float> egVel2Depth;
extern const OpcodeSpec<bool> flexEGAmpeg;
extern const OpcodeSpec<int32_t> flexEGDynamic;
extern const OpcodeSpec<bool> flexEGDynamic;
extern const OpcodeSpec<int32_t> flexEGSustain;
extern const OpcodeSpec<float> flexEGPointTime;
extern const OpcodeSpec<float> flexEGPointLevel;

View file

@ -17,9 +17,9 @@ struct FilterDescription
float cutoff { Default::filterCutoff };
float resonance { Default::filterCutoff };
float gain { Default::filterGain };
int keytrack { Default::filterKeytrack };
float keytrack { Default::filterKeytrack };
uint8_t keycenter { Default::key };
int veltrack { Default::filterVeltrack };
float veltrack { Default::filterVeltrack };
float random { Default::filterRandom };
FilterType type { FilterType::kFilterLpf2p };
};

View file

@ -35,7 +35,7 @@ void sfz::FilterHolder::setup(const Region& region, unsigned filterId, int noteN
}
const auto keytrack = description->keytrack * (noteNumber - description->keycenter);
baseCutoff *= centsFactor(keytrack);
const auto veltrack = static_cast<float>(description->veltrack) * velocity;
const auto veltrack = description->veltrack * velocity;
baseCutoff *= centsFactor(veltrack);
baseCutoff = Default::filterCutoff.bounds.clamp(baseCutoff);

View file

@ -31,7 +31,7 @@ private:
};
struct FlexEGDescription {
int dynamic { Default::flexEGDynamic }; // whether parameters can be modulated while EG runs
bool 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<FlexEGPoint> points;
// ARIA

View file

@ -362,18 +362,14 @@ void LFO::generatePhase(unsigned nth, absl::Span<float> phases)
for (size_t i = 0; i < numFrames; ++i) {
phases[i] = phase;
float incr = ratio * samplePeriod * baseFreq;
phase += incr;
int numWraps = (int)phase;
phase -= numWraps;
phase = wrapPhase(phase + incr);
}
}
else {
for (size_t i = 0; i < numFrames; ++i) {
phases[i] = phase;
float incr = ratio * samplePeriod * (baseFreq + freqMod[i]);
phase += incr;
int numWraps = (int)phase;
phase -= numWraps;
phase = wrapPhase(phase + incr);
}
}
}

View file

@ -15,14 +15,14 @@ namespace sfz {
/**
* @brief Compute a crossfade in value with respect to a crossfade range (note, velocity, cc, ...)
*/
template <class T, class U>
float crossfadeIn(const sfz::Range<T>& crossfadeRange, U value, CrossfadeCurve curve)
template <class T, bool C, class U>
float crossfadeIn(const sfz::Range<T, C>& crossfadeRange, U value, CrossfadeCurve curve)
{
if (value < crossfadeRange.getStart())
return 0.0f;
const auto length = static_cast<float>(crossfadeRange.length());
if (length == 0.0f)
if (length <= 0.0f)
return 1.0f;
else if (value < crossfadeRange.getEnd()) {
@ -39,14 +39,14 @@ float crossfadeIn(const sfz::Range<T>& crossfadeRange, U value, CrossfadeCurve c
/**
* @brief Compute a crossfade out value with respect to a crossfade range (note, velocity, cc, ...)
*/
template <class T, class U>
float crossfadeOut(const sfz::Range<T>& crossfadeRange, U value, CrossfadeCurve curve)
template <class T, bool C, class U>
float crossfadeOut(const sfz::Range<T, C>& crossfadeRange, U value, CrossfadeCurve curve)
{
if (value > crossfadeRange.getEnd())
return 0.0f;
const auto length = static_cast<float>(crossfadeRange.length());
if (length == 0.0f)
if (length <= 0.0f)
return 1.0f;
else if (value > crossfadeRange.getStart()) {

View file

@ -222,7 +222,8 @@ absl::optional<T> readFloat_(OpcodeSpec<T> spec, absl::string_view v)
if (spec.flags & kWrapPhase)
returnedValue = wrapPhase(returnedValue);
else if (returnedValue > static_cast<int64_t>(spec.bounds.getEnd())) {
if (returnedValue > static_cast<int64_t>(spec.bounds.getEnd())) {
if (spec.flags & kEnforceUpperBound)
return spec.bounds.getEnd();
else if (!(spec.flags & kPermissiveUpperBound))

View file

@ -32,6 +32,12 @@ public:
{
}
constexpr Range(const Range<Type, !Checked>& other)
: Range(other.getStart(), other.getEnd())
{
}
constexpr Type getStart() const noexcept { return _start; }
constexpr Type getEnd() const noexcept { return _end; }
/**
@ -149,27 +155,27 @@ template <class T> using UncheckedRange = Range<T, false>;
}
template <class Type>
bool operator==(const sfz::Range<Type>& lhs, const sfz::Range<Type>& rhs)
template <class Type, bool C1, bool C2>
bool operator==(const sfz::Range<Type, C1>& lhs, const sfz::Range<Type, C2>& rhs)
{
return (lhs.getStart() == rhs.getStart()) && (lhs.getEnd() == rhs.getEnd());
}
template <class Type>
bool operator!=(const sfz::Range<Type>& lhs, const sfz::Range<Type>& rhs)
template <class Type, bool C1, bool C2>
bool operator!=(const sfz::Range<Type, C1>& lhs, const sfz::Range<Type, C2>& rhs)
{
return (lhs.getStart() != rhs.getStart()) || (lhs.getEnd() != rhs.getEnd());
}
template <class Type>
bool operator==(const sfz::Range<Type>& lhs, const std::pair<Type, Type>& rhs)
template <class Type, bool C>
bool operator==(const sfz::Range<Type, C>& lhs, const std::pair<Type, Type>& rhs)
{
return (lhs.getStart() == rhs.first) && (lhs.getEnd() == rhs.second);
}
template <class Type>
bool operator==(const std::pair<Type, Type>& lhs, const sfz::Range<Type>& rhs)
template <class Type, bool C>
bool operator==(const std::pair<Type, Type>& lhs, const sfz::Range<Type, C>& rhs)
{
return rhs == lhs;
}

View file

@ -194,13 +194,18 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
keyRange.setStart(opcode.read(Default::loKey));
break;
case hash("hikey"):
triggerOnNote = (opcode.value != "-1");
keyRange.setEnd(opcode.read(Default::hiKey));
{
absl::optional<uint8_t> optValue = opcode.readOptional(Default::hiKey);
triggerOnNote = optValue != absl::nullopt;
uint8_t value = optValue.value_or(Default::hiKey);
keyRange.setEnd(value);
}
break;
case hash("key"):
triggerOnNote = (opcode.value != "-1");
{
auto value = opcode.read(Default::key);
absl::optional<uint8_t> optValue = opcode.readOptional(Default::key);
triggerOnNote = optValue != absl::nullopt;
uint8_t value = optValue.value_or(Default::key);
keyRange.setStart(value);
keyRange.setEnd(value);
pitchKeycenter = value;
@ -1491,7 +1496,7 @@ bool sfz::Region::registerNoteOn(int noteNumber, float velocity, float randValue
velocity = midiState.getLastVelocity();
const bool velOk = velocityRange.containsWithEnd(velocity);
const bool randOk = randRange.contains(randValue) || (randValue == 1.0f && randRange.getEnd() == 1.0f);
const bool randOk = randRange.contains(randValue) || (randValue >= 1.0f && randRange.isValid() && randRange.getEnd() >= 1.0f);
const bool firstLegatoNote = (trigger == Trigger::first && midiState.getActiveNotes() == 1);
const bool attackTrigger = (trigger == Trigger::attack);
const bool notFirstLegatoNote = (trigger == Trigger::legato && midiState.getActiveNotes() > 1);
@ -1513,7 +1518,7 @@ bool sfz::Region::registerNoteOff(int noteNumber, float velocity, float randValu
const bool keyOk = keyRange.containsWithEnd(noteNumber);
const bool velOk = velocityRange.containsWithEnd(velocity);
const bool randOk = randRange.contains(randValue);
const bool randOk = randRange.contains(randValue) || (randValue >= 1.0f && randRange.isValid() && randRange.getEnd() >= 1.0f);
if (!(velOk && keyOk && randOk))
return false;
@ -1587,7 +1592,7 @@ float sfz::Region::getBasePitchVariation(float noteNumber, float velocity) const
ASSERT(velocity >= 0.0f && velocity <= 1.0f);
fast_real_distribution<float> pitchDistribution { 0.0f, pitchRandom };
auto pitchVariationInCents = pitchKeytrack * (noteNumber - pitchKeycenter); // note difference with pitch center
float pitchVariationInCents = pitchKeytrack * (noteNumber - pitchKeycenter); // note difference with pitch center
pitchVariationInCents += pitch; // sample tuning
pitchVariationInCents += config::centPerSemitone * transpose; // sample transpose
pitchVariationInCents += velocity * pitchVeltrack; // track velocity

View file

@ -364,7 +364,7 @@ struct Region {
uint32_t sampleEnd { Default::sampleEnd }; // end
absl::optional<uint32_t> sampleCount {}; // count
absl::optional<LoopMode> loopMode {}; // loopmode
Range<uint32_t> loopRange { Default::loopStart, Default::loopEnd }; //loopstart and loopend
UncheckedRange<uint32_t> loopRange { Default::loopStart, Default::loopEnd }; //loopstart and loopend
absl::optional<uint32_t> loopCount {}; // count
float loopCrossfade { Default::loopCrossfade }; // loop_crossfade
@ -389,14 +389,14 @@ struct Region {
bool rtDead { Default::rtDead };
// Region logic: key mapping
Range<uint8_t> keyRange { Default::loKey, Default::hiKey }; //lokey, hikey and key
Range<float> velocityRange { Default::loVel, Default::hiVel }; // hivel and lovel
UncheckedRange<uint8_t> keyRange { Default::loKey, Default::hiKey }; //lokey, hikey and key
UncheckedRange<float> velocityRange { Default::loVel, Default::hiVel }; // hivel and lovel
// Region logic: MIDI conditions
Range<float> bendRange { Default::loBend, Default::hiBend }; // hibend and lobend
CCMap<Range<float>> ccConditions {{ Default::loCC, Default::hiCC }};
UncheckedRange<float> bendRange { Default::loBend, Default::hiBend }; // hibend and lobend
CCMap<UncheckedRange<float>> ccConditions {{ Default::loCC, Default::hiCC }};
absl::optional<uint8_t> lastKeyswitch {}; // sw_last
absl::optional<Range<uint8_t>> lastKeyswitchRange {}; // sw_last
absl::optional<UncheckedRange<uint8_t>> lastKeyswitchRange {}; // sw_last
absl::optional<std::string> keyswitchLabel {};
absl::optional<uint8_t> upKeyswitch {}; // sw_up
absl::optional<uint8_t> downKeyswitch {}; // sw_down
@ -409,15 +409,15 @@ struct Region {
float sustainThreshold { Default::sustainThreshold }; // sustain_cc
// Region logic: internal conditions
Range<float> aftertouchRange { Default::loChannelAftertouch, Default::hiChannelAftertouch }; // hichanaft and lochanaft
Range<float> bpmRange { Default::loBPM, Default::hiBPM }; // hibpm and lobpm
Range<float> randRange { Default::loNormalized, Default::hiNormalized }; // hirand and lorand
UncheckedRange<float> aftertouchRange { Default::loChannelAftertouch, Default::hiChannelAftertouch }; // hichanaft and lochanaft
UncheckedRange<float> bpmRange { Default::loBPM, Default::hiBPM }; // hibpm and lobpm
UncheckedRange<float> 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 }; // trigger
CCMap<Range<float>> ccTriggers {{ Default::loCC, Default::hiCC }}; // on_loccN on_hiccN
CCMap<UncheckedRange<float>> ccTriggers {{ Default::loCC, Default::hiCC }}; // on_loccN on_hiccN
// Performance parameters: amplifier
float volume { Default::volume }; // volume
@ -431,15 +431,15 @@ struct Region {
std::vector<std::pair<uint8_t, float>> velocityPoints; // amp_velcurve_N
absl::optional<Curve> velCurve {};
float ampRandom { Default::ampRandom }; // amp_random
Range<uint8_t> crossfadeKeyInRange { Default::crossfadeKeyInRange };
Range<uint8_t> crossfadeKeyOutRange { Default::crossfadeKeyOutRange };
Range<float> crossfadeVelInRange { Default::crossfadeVelInRange };
Range<float> crossfadeVelOutRange { Default::crossfadeVelOutRange };
UncheckedRange<uint8_t> crossfadeKeyInRange { Default::crossfadeKeyInRange };
UncheckedRange<uint8_t> crossfadeKeyOutRange { Default::crossfadeKeyOutRange };
UncheckedRange<float> crossfadeVelInRange { Default::crossfadeVelInRange };
UncheckedRange<float> crossfadeVelOutRange { Default::crossfadeVelOutRange };
CrossfadeCurve crossfadeKeyCurve { Default::crossfadeCurve };
CrossfadeCurve crossfadeVelCurve { Default::crossfadeCurve };
CrossfadeCurve crossfadeCCCurve { Default::crossfadeCurve };
CCMap<Range<float>> crossfadeCCInRange { Default::crossfadeCCInRange }; // xfin_loccN xfin_hiccN
CCMap<Range<float>> crossfadeCCOutRange { Default::crossfadeCCOutRange }; // xfout_loccN xfout_hiccN
CCMap<UncheckedRange<float>> crossfadeCCInRange { Default::crossfadeCCInRange }; // xfin_loccN xfin_hiccN
CCMap<UncheckedRange<float>> crossfadeCCOutRange { Default::crossfadeCCOutRange }; // xfout_loccN xfout_hiccN
float rtDecay { Default::rtDecay }; // rt_decay
float globalAmplitude { 1.0 }; // global_amplitude
@ -456,10 +456,10 @@ struct Region {
// Performance parameters: pitch
uint8_t pitchKeycenter { Default::key }; // pitch_keycenter
bool pitchKeycenterFromSample { false };
int pitchKeytrack { Default::pitchKeytrack }; // pitch_keytrack
float pitchKeytrack { Default::pitchKeytrack }; // pitch_keytrack
float pitchRandom { Default::pitchRandom }; // pitch_random
int pitchVeltrack { Default::pitchVeltrack }; // pitch_veltrack
int transpose { Default::transpose }; // transpose
float pitchVeltrack { Default::pitchVeltrack }; // pitch_veltrack
float transpose { Default::transpose }; // transpose
float pitch { Default::pitch }; // tune
float bendUp { Default::bendUp };
float bendDown { Default::bendDown };

View file

@ -168,7 +168,7 @@ constexpr float normalizeVelocity(T velocity)
template <class T>
constexpr float normalizePercents(T percentValue)
{
return percentValue * 0.01f;
return percentValue / 100.0f;
}
/**

View file

@ -598,6 +598,10 @@ void Synth::Impl::finalizeSfzLoad()
if (region->loopRange.getEnd() == Default::loopEnd)
region->loopRange.setEnd(region->sampleEnd);
// if range is invalid, disable the loop
if (!region->loopRange.isValid())
region->loopMode = absl::nullopt;
if (fileInformation->numChannels == 2)
region->hasStereoSample = true;
@ -750,7 +754,7 @@ void Synth::Impl::finalizeSfzLoad()
// cache the set of keys assigned
for (const RegionPtr& regionPtr : regions_) {
Range<uint8_t> keyRange = regionPtr->keyRange;
UncheckedRange<uint8_t> keyRange = regionPtr->keyRange;
unsigned loKey = keyRange.getStart();
unsigned hiKey = keyRange.getEnd();
for (unsigned key = loKey; key <= hiKey; ++key)
@ -761,7 +765,7 @@ void Synth::Impl::finalizeSfzLoad()
if (absl::optional<uint8_t> sw = regionPtr->lastKeyswitch) {
swLastSlots_.set(*sw);
}
else if (absl::optional<Range<uint8_t>> swRange = regionPtr->lastKeyswitchRange) {
else if (absl::optional<UncheckedRange<uint8_t>> swRange = regionPtr->lastKeyswitchRange) {
unsigned loKey = swRange->getStart();
unsigned hiKey = swRange->getEnd();
for (unsigned key = loKey; key <= hiKey; ++key)

View file

@ -23,7 +23,7 @@ TEST_CASE("[Direct Region Tests] amp_velcurve")
region.parseOpcode({ "amp_velcurve_6", "0.4" });
REQUIRE(region.velocityPoints.back() == std::pair<uint8_t, float>(6, 0.4f));
region.parseOpcode({ "amp_velcurve_127", "-1.0" });
REQUIRE(region.velocityPoints.back() == std::pair<uint8_t, float>(127, 0.0f));
REQUIRE(region.velocityPoints.back() == std::pair<uint8_t, float>(127, -1.0f));
region.parseOpcode({ "amp_velcurve_008", "0.3" });
REQUIRE(region.velocityPoints.back() == std::pair<uint8_t, float>(8, 0.3f));
region.parseOpcode({ "amp_velcurve_064", "0.9" });

View file

@ -31,14 +31,12 @@ TEST_CASE("[Values] Delay")
synth.dispatchMessage(client, 0, "/region0/delay", "", nullptr);
synth.dispatchMessage(client, 0, "/region1/delay", "", nullptr);
synth.dispatchMessage(client, 0, "/region2/delay", "", nullptr);
// TODO: activate for the new region parser ; ignore the second value
// synth.dispatchMessage(client, 0, "/region3/delay", "", nullptr);
synth.dispatchMessage(client, 0, "/region3/delay", "", nullptr);
std::vector<std::string> expected {
"/region0/delay,f : { 0 }",
"/region1/delay,f : { 1 }",
"/region2/delay,f : { 0 }",
// TODO: activate for the new region parser ; ignore the second value
// "/region3/delay,f : { 1 }",
"/region2/delay,f : { -1 }",
"/region3/delay,f : { -1 }",
};
REQUIRE(messageList == expected);
}
@ -54,12 +52,12 @@ TEST_CASE("[Values] Delay")
synth.dispatchMessage(client, 0, "/region0/delay_random", "", nullptr);
synth.dispatchMessage(client, 0, "/region1/delay_random", "", nullptr);
synth.dispatchMessage(client, 0, "/region2/delay_random", "", nullptr);
// synth.dispatchMessage(client, 0, "/region3/delay_random", "", nullptr);
synth.dispatchMessage(client, 0, "/region3/delay_random", "", nullptr);
std::vector<std::string> expected {
"/region0/delay_random,f : { 0 }",
"/region1/delay_random,f : { 1 }",
"/region2/delay_random,f : { 0 }",
// "/region3/delay_random,f : { 1 }",
"/region2/delay_random,f : { -1 }",
"/region3/delay_random,f : { -1 }",
};
REQUIRE(messageList == expected);
}
@ -76,14 +74,13 @@ TEST_CASE("[Values] Delay")
synth.dispatchMessage(client, 0, "/region1/delay_cc12", "", nullptr);
synth.dispatchMessage(client, 0, "/region2/delay_cc12", "", nullptr);
synth.dispatchMessage(client, 0, "/region3/delay_cc14", "", nullptr);
// TODO: activate for the new region parser ; ignore the second value
// synth.dispatchMessage(client, 0, "/region3/delay_cc12", "", nullptr);
synth.dispatchMessage(client, 0, "/region3/delay_cc12", "", nullptr);
std::vector<std::string> expected {
"/region0/delay_cc12,f : { 0 }",
"/region1/delay_cc12,f : { 1.5 }",
"/region2/delay_cc12,f : { 0 }",
"/region2/delay_cc12,f : { -1.5 }",
"/region3/delay_cc14,f : { 3 }",
// "/region3/delay_cc12,f : { 2 }",
"/region3/delay_cc12,f : { -12 }",
};
REQUIRE(messageList == expected);
}
@ -131,14 +128,12 @@ TEST_CASE("[Values] Offset")
synth.dispatchMessage(client, 0, "/region0/offset", "", nullptr);
synth.dispatchMessage(client, 0, "/region1/offset", "", nullptr);
synth.dispatchMessage(client, 0, "/region2/offset", "", nullptr);
// TODO: activate for the new region parser ; ignore the second value
// synth.dispatchMessage(client, 0, "/region3/offset", "", nullptr);
synth.dispatchMessage(client, 0, "/region3/offset", "", nullptr);
std::vector<std::string> expected {
"/region0/offset,h : { 0 }",
"/region1/offset,h : { 12 }",
"/region2/offset,h : { 0 }",
// TODO: activate for the new region parser ; ignore the second value
// "/region3/offset,f : { 12 }",
"/region2/offset,h : { -1 }",
"/region3/offset,h : { -1 }",
};
REQUIRE(messageList == expected);
}
@ -154,13 +149,12 @@ TEST_CASE("[Values] Offset")
synth.dispatchMessage(client, 0, "/region0/offset_random", "", nullptr);
synth.dispatchMessage(client, 0, "/region1/offset_random", "", nullptr);
synth.dispatchMessage(client, 0, "/region2/offset_random", "", nullptr);
// TODO: activate for the new region parser ; ignore the second value
// synth.dispatchMessage(client, 0, "/region3/offset_random", "", nullptr);
synth.dispatchMessage(client, 0, "/region3/offset_random", "", nullptr);
std::vector<std::string> expected {
"/region0/offset_random,h : { 0 }",
"/region1/offset_random,h : { 1 }",
"/region2/offset_random,h : { 0 }",
// "/region3/offset_random,f : { 1 }",
"/region2/offset_random,h : { -1 }",
"/region3/offset_random,h : { -1 }",
};
REQUIRE(messageList == expected);
}
@ -177,14 +171,13 @@ TEST_CASE("[Values] Offset")
synth.dispatchMessage(client, 0, "/region1/offset_cc12", "", nullptr);
synth.dispatchMessage(client, 0, "/region2/offset_cc12", "", nullptr);
synth.dispatchMessage(client, 0, "/region3/offset_cc14", "", nullptr);
// TODO: activate for the new region parser ; ignore the second value
// synth.dispatchMessage(client, 0, "/region3/offset_cc12", "", nullptr);
synth.dispatchMessage(client, 0, "/region3/offset_cc12", "", nullptr);
std::vector<std::string> expected {
"/region0/offset_cc12,h : { 0 }",
"/region1/offset_cc12,h : { 12 }",
"/region2/offset_cc12,h : { 0 }",
"/region2/offset_cc12,h : { -12 }",
"/region3/offset_cc14,h : { 14 }",
// "/region3/offset_cc12,h : { 12 }",
"/region3/offset_cc12,h : { -12 }",
};
REQUIRE(messageList == expected);
}
@ -465,7 +458,7 @@ TEST_CASE("[Values] Off time")
std::vector<std::string> expected {
"/region0/off_time,f : { 0.006 }",
"/region1/off_time,f : { 0.1 }",
"/region2/off_time,f : { 0.006 }",
"/region2/off_time,f : { -1 }",
};
REQUIRE(messageList == expected);
}
@ -556,8 +549,8 @@ TEST_CASE("[Values] Velocity range")
std::vector<std::string> expected {
"/region0/vel_range,ff : { 0, 1 }",
"/region1/vel_range,ff : { 0.267717, 0.472441 }",
"/region2/vel_range,ff : { 0, 0.472441 }",
"/region3/vel_range,ff : { 0, 1 }",
"/region2/vel_range,ff : { -0.023622, 0.472441 }",
"/region3/vel_range,ff : { 0, -0.00787402 }",
};
REQUIRE(messageList == expected);
}
@ -582,7 +575,7 @@ TEST_CASE("[Values] Bend range")
"/region0/bend_range,ff : { -1, 1 }",
"/region1/bend_range,ff : { 0.108778, 0.24417 }",
"/region2/bend_range,ff : { -0.108778, 0.108778 }",
"/region3/bend_range,ff : { -1, 1 }",
"/region3/bend_range,ff : { -1, -1.22085 }",
};
REQUIRE(messageList == expected);
}
@ -612,7 +605,7 @@ TEST_CASE("[Values] CC condition range")
"/region1/cc_range1,ff : { 0, 0.425197 }",
"/region2/cc_range1,ff : { 0, 0.425197 }",
"/region2/cc_range2,ff : { 0.015748, 0.0787402 }",
"/region3/cc_range1,ff : { 0.0787402, 1 }",
"/region3/cc_range1,ff : { 0.0787402, -0.00787402 }",
};
REQUIRE(messageList == expected);
}
@ -635,7 +628,7 @@ TEST_CASE("[Values] CC condition range")
"/region1/cc_range1,ff : { 0, 0.1 }",
"/region2/cc_range1,ff : { 0, 0.1 }",
"/region2/cc_range2,ff : { 0.1, 0.2 }",
"/region3/cc_range1,ff : { 0.1, 1 }",
"/region3/cc_range1,ff : { 0.1, -0.1 }",
};
REQUIRE(messageList == expected);
}
@ -658,7 +651,7 @@ TEST_CASE("[Values] CC condition range")
"/region1/cc_range1,ff : { 0, 0.1 }",
"/region2/cc_range1,ff : { 0, 0.1 }",
"/region2/cc_range2,ff : { 0.1, 0.2 }",
"/region3/cc_range1,ff : { 0.1, 1 }",
"/region3/cc_range1,ff : { 0.1, -0.1 }",
};
REQUIRE(messageList == expected);
}
@ -871,9 +864,9 @@ TEST_CASE("[Values] Aftertouch range")
std::vector<std::string> expected {
"/region0/chanaft_range,ff : { 0, 1 }",
"/region1/chanaft_range,ff : { 0.267717, 0.472441 }",
"/region2/chanaft_range,ff : { 0, 0.472441 }",
"/region3/chanaft_range,ff : { 0.15748, 1 }",
"/region4/chanaft_range,ff : { 0.0787402, 0.0787402 }",
"/region2/chanaft_range,ff : { -0.023622, 0.472441 }",
"/region3/chanaft_range,ff : { 0.15748, -0.00787402 }",
"/region4/chanaft_range,ff : { 0.15748, 0.0787402 }",
};
REQUIRE(messageList == expected);
}
@ -899,9 +892,9 @@ TEST_CASE("[Values] BPM range")
std::vector<std::string> expected {
"/region0/bpm_range,ff : { 0, 500 }",
"/region1/bpm_range,ff : { 34.1, 60.2 }",
"/region2/bpm_range,ff : { 0, 60 }",
"/region3/bpm_range,ff : { 20, 500 }",
"/region4/bpm_range,ff : { 10, 10 }",
"/region2/bpm_range,ff : { -3, 60 }",
"/region3/bpm_range,ff : { 20, -1 }",
"/region4/bpm_range,ff : { 20, 10 }",
};
REQUIRE(messageList == expected);
}
@ -927,9 +920,9 @@ TEST_CASE("[Values] Rand range")
std::vector<std::string> expected {
"/region0/rand_range,ff : { 0, 1 }",
"/region1/rand_range,ff : { 0.2, 0.4 }",
"/region2/rand_range,ff : { 0, 0.4 }",
"/region3/rand_range,ff : { 0.2, 1 }",
"/region4/rand_range,ff : { 0.1, 0.1 }",
"/region2/rand_range,ff : { -0.1, 0.4 }",
"/region3/rand_range,ff : { 0.2, -0.1 }",
"/region4/rand_range,ff : { 0.2, 0.1 }",
};
REQUIRE(messageList == expected);
}
@ -1568,7 +1561,7 @@ TEST_CASE("[Values] Amp Veltrack")
std::vector<std::string> expected {
"/region0/amp_veltrack,f : { 100 }",
"/region1/amp_veltrack,f : { 10.1 }",
"/region2/amp_veltrack,f : { 100 }",
"/region2/amp_veltrack,f : { -132 }",
};
REQUIRE(messageList == expected);
}
@ -1623,7 +1616,7 @@ TEST_CASE("[Values] Crossfade key range")
"/region1/xfin_key_range,ii : { 10, 40 }",
"/region2/xfin_key_range,ii : { 60, 83 }",
"/region3/xfin_key_range,ii : { 0, 40 }",
"/region4/xfin_key_range,ii : { 0, 0 }",
"/region4/xfin_key_range,ii : { 10, 0 }",
};
REQUIRE(messageList == expected);
}
@ -1646,7 +1639,7 @@ TEST_CASE("[Values] Crossfade key range")
"/region0/xfout_key_range,ii : { 127, 127 }",
"/region1/xfout_key_range,ii : { 10, 40 }",
"/region2/xfout_key_range,ii : { 60, 83 }",
"/region3/xfout_key_range,ii : { 40, 40 }",
"/region3/xfout_key_range,ii : { 127, 40 }",
"/region4/xfout_key_range,ii : { 10, 127 }",
};
REQUIRE(messageList == expected);
@ -1676,8 +1669,8 @@ TEST_CASE("[Values] Crossfade velocity range")
std::vector<std::string> expected {
"/region0/xfin_vel_range,ff : { 0, 0 }",
"/region1/xfin_vel_range,ff : { 0.0787402, 0.314961 }",
"/region2/xfin_vel_range,ff : { 0, 0.314961 }",
"/region3/xfin_vel_range,ff : { 0, 0 }",
"/region2/xfin_vel_range,ff : { -0.0787402, 0.314961 }",
"/region3/xfin_vel_range,ff : { 0.0787402, 1.10236 }",
};
REQUIRE(messageList == expected);
}
@ -1697,8 +1690,8 @@ TEST_CASE("[Values] Crossfade velocity range")
std::vector<std::string> expected {
"/region0/xfout_vel_range,ff : { 1, 1 }",
"/region1/xfout_vel_range,ff : { 0.0787402, 0.314961 }",
"/region2/xfout_vel_range,ff : { 0.314961, 0.314961 }",
"/region3/xfout_vel_range,ff : { 0.0787402, 1 }",
"/region2/xfout_vel_range,ff : { -0.0787402, 0.314961 }",
"/region3/xfout_vel_range,ff : { 0.0787402, 1.10236 }",
};
REQUIRE(messageList == expected);
}
@ -1797,8 +1790,8 @@ TEST_CASE("[Values] Crossfade CC range")
std::vector<std::string> expected {
"/region0/xfin_cc_range4,N : { }",
"/region1/xfin_cc_range4,ff : { 0.0787402, 0.314961 }",
"/region2/xfin_cc_range4,ff : { 0, 0.314961 }",
"/region3/xfin_cc_range4,ff : { 0, 0 }",
"/region2/xfin_cc_range4,ff : { -0.0787402, 0.314961 }",
"/region3/xfin_cc_range4,ff : { 0.0787402, 1.10236 }",
};
REQUIRE(messageList == expected);
}
@ -1818,8 +1811,8 @@ TEST_CASE("[Values] Crossfade CC range")
std::vector<std::string> expected {
"/region0/xfout_cc_range4,N : { }",
"/region1/xfout_cc_range4,ff : { 0.0787402, 0.314961 }",
"/region2/xfout_cc_range4,ff : { 0.314961, 0.314961 }",
"/region3/xfout_cc_range4,ff : { 0.0787402, 1 }",
"/region2/xfout_cc_range4,ff : { -0.0787402, 0.314961 }",
"/region3/xfout_cc_range4,ff : { 0.0787402, 1.10236 }",
};
REQUIRE(messageList == expected);
}
@ -1977,8 +1970,8 @@ TEST_CASE("[Values] Transpose")
"/region0/transpose,i : { 0 }",
"/region1/transpose,i : { 10 }",
"/region2/transpose,i : { -4 }",
"/region3/transpose,i : { 0 }",
"/region4/transpose,i : { 0 }",
"/region3/transpose,i : { -400 }",
"/region4/transpose,i : { 400 }",
};
REQUIRE(messageList == expected);
}
@ -2427,7 +2420,7 @@ TEST_CASE("[Values] Sustain low")
std::vector<std::string> expected {
"/region0/sustain_lo,f : { 0.00787402 }",
"/region1/sustain_lo,f : { 0.0787402 }",
"/region2/sustain_lo,f : { 0.00787402 }",
"/region2/sustain_lo,f : { -0.00787402 }",
};
REQUIRE(messageList == expected);
}
@ -2538,7 +2531,7 @@ TEST_CASE("[Values] Oscillator detune/mod depth")
"/region2/oscillator_detune,f : { -1200.2 }",
"/region0/oscillator_mod_depth,f : { 0 }",
"/region3/oscillator_mod_depth,f : { 1564.75 }",
"/region4/oscillator_mod_depth,f : { 0 }",
"/region4/oscillator_mod_depth,f : { -2.2 }",
};
REQUIRE(messageList == expected);
}
@ -2903,14 +2896,14 @@ TEST_CASE("[Values] Filter value bounds")
SECTION("Cutoff")
{
synth.loadSfzString(fs::current_path() / "tests/TestFiles/value_tests.sfz", R"(
<region> sample=kick.wav cutoff=20000000 // Clamp the value
<region> sample=kick.wav cutoff=100000
<region> sample=kick.wav cutoff=50 cutoff=-100
)");
synth.dispatchMessage(client, 0, "/region0/filter0/cutoff", "", nullptr);
synth.dispatchMessage(client, 0, "/region1/filter0/cutoff", "", nullptr);
std::vector<std::string> expected {
"/region0/filter0/cutoff,f : { 20000 }",
"/region1/filter0/cutoff,f : { 0 }",
"/region0/filter0/cutoff,f : { 100000 }",
"/region1/filter0/cutoff,f : { -100 }",
};
REQUIRE(messageList == expected);
}
@ -2922,7 +2915,7 @@ TEST_CASE("[Values] Filter value bounds")
)");
synth.dispatchMessage(client, 0, "/region0/filter0/resonance", "", nullptr);
std::vector<std::string> expected {
"/region0/filter0/resonance,f : { 0 }",
"/region0/filter0/resonance,f : { -5 }",
};
REQUIRE(messageList == expected);
}
@ -3109,14 +3102,14 @@ TEST_CASE("[Values] EQ value bounds")
SECTION("Frequency")
{
synth.loadSfzString(fs::current_path() / "tests/TestFiles/value_tests.sfz", R"(
<region> sample=kick.wav eq1_freq=20000000 // Clamp the value
<region> sample=kick.wav eq1_freq=100000
<region> sample=kick.wav eq1_freq=50 eq1_freq=-100
)");
synth.dispatchMessage(client, 0, "/region0/eq0/frequency", "", nullptr);
synth.dispatchMessage(client, 0, "/region1/eq0/frequency", "", nullptr);
std::vector<std::string> expected {
"/region0/eq0/frequency,f : { 20000 }",
"/region1/eq0/frequency,f : { 50 }",
"/region0/eq0/frequency,f : { 100000 }",
"/region1/eq0/frequency,f : { -100 }",
};
REQUIRE(messageList == expected);
}
@ -3128,7 +3121,7 @@ TEST_CASE("[Values] EQ value bounds")
)");
synth.dispatchMessage(client, 0, "/region0/eq0/bandwidth", "", nullptr);
std::vector<std::string> expected {
"/region0/eq0/bandwidth,f : { 1 }",
"/region0/eq0/bandwidth,f : { -5 }",
};
REQUIRE(messageList == expected);
}

View file

@ -33,8 +33,8 @@ private:
sfz::ModKey target_;
};
template<class T>
void almostEqualRanges(const sfz::Range<T>& lhs, const sfz::Range<T>& rhs)
template<class Range>
void almostEqualRanges(const Range& lhs, const Range& rhs)
{
REQUIRE(lhs.getStart() == Approx(rhs.getStart()));
REQUIRE(lhs.getEnd() == Approx(rhs.getEnd()));