This commit is contained in:
Paul Fd 2021-01-10 19:01:20 +01:00 committed by Paul Ferrand
parent e9941b4337
commit 293e7a935f
40 changed files with 753 additions and 876 deletions

View file

@ -40,11 +40,7 @@ Curve Curve::buildCurveFromHeader(
if (index >= NumValues) if (index >= NumValues)
continue; continue;
auto valueOpt = opc.read(fullRange); setPoint(static_cast<int>(index), opc.read(fullRange));
if (!valueOpt)
continue;
setPoint(static_cast<int>(index), *valueOpt);
} }
curve.fill(itp, fillStatus); curve.fill(itp, fillStatus);
@ -267,12 +263,8 @@ void CurveSet::addCurveFromHeader(absl::Span<const Opcode> members)
int curveIndex = -1; int curveIndex = -1;
Curve::Interpolator itp = Curve::Interpolator::Linear; Curve::Interpolator itp = Curve::Interpolator::Linear;
if (const Opcode* opc = findOpcode(hash("curve_index"))) { if (const Opcode* opc = findOpcode(hash("curve_index")))
if (auto opt = opc->read(Default::curveCC)) curveIndex = opc->read(Default::curveCC);
curveIndex = *opt;
else
DBG("Invalid value for curve index: " << opc->value);
}
#if 0 // potential sfizz extension #if 0 // potential sfizz extension
if (const Opcode* opc = findOpcode(hash("sfizz:curve_interpolator"))) { if (const Opcode* opc = findOpcode(hash("sfizz:curve_interpolator"))) {

View file

@ -1,150 +1,163 @@
#include "Defaults.h" #include "Defaults.h"
#include "MathHelpers.h"
#include "SfzHelpers.h"
namespace sfz { namespace sfz {
namespace Default { namespace Default {
constexpr auto uint32_t_max = std::numeric_limits<uint32_t>::max(); constexpr auto uint32_t_max = std::numeric_limits<uint32_t>::max();
extern const OpcodeSpec<float> delay { 0.0f, Range<float>(0.0f, 100.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> delay { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> delayRandom { 0.0f, Range<float>(0.0f, 100.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> delayRandom { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<int64_t> offset { 0, Range<int64_t>(0, uint32_t_max), kEnforceLowerBound }; extern const OpcodeSpec<int64_t> offset { 0, Range<int64_t>(0, uint32_t_max), 0 };
extern const OpcodeSpec<int64_t> offsetMod { 0, Range<int64_t>(0, uint32_t_max), kEnforceLowerBound }; extern const OpcodeSpec<int64_t> offsetMod { 0, Range<int64_t>(0, uint32_t_max), 0 };
extern const OpcodeSpec<int64_t> offsetRandom { 0, Range<int64_t>(0, uint32_t_max), kEnforceLowerBound }; extern const OpcodeSpec<int64_t> offsetRandom { 0, Range<int64_t>(0, uint32_t_max), 0 };
extern const OpcodeSpec<uint32_t> sampleEnd { uint32_t_max, Range<uint32_t>(0, uint32_t_max), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<uint32_t> sampleEnd { uint32_t_max, Range<uint32_t>(0, uint32_t_max), kEnforceLowerBound };
extern const OpcodeSpec<uint32_t> sampleCount { 0, Range<uint32_t>(0, uint32_t_max), 0 }; extern const OpcodeSpec<uint32_t> sampleCount { 1, Range<uint32_t>(1, uint32_t_max), 0 };
extern const OpcodeSpec<uint32_t> loopRange { 0, Range<uint32_t>(0, uint32_t_max), 0 }; extern const OpcodeSpec<uint32_t> loopStart { 0, Range<uint32_t>(0, uint32_t_max), 0 };
extern const OpcodeSpec<float> loopCrossfade { 1e-3, Range<float>(1e-3, 1.0f), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<uint32_t> loopEnd { uint32_t_max, Range<uint32_t>(0, uint32_t_max), 0 };
extern const OpcodeSpec<float> loopCrossfade { 1e-3, Range<float>(1e-3, 1.0f), 0 };
extern const OpcodeSpec<OscillatorEnabled> oscillator { OscillatorEnabled::Auto, Range<OscillatorEnabled>(OscillatorEnabled::Auto, OscillatorEnabled::On), 0 }; extern const OpcodeSpec<OscillatorEnabled> oscillator { OscillatorEnabled::Auto, Range<OscillatorEnabled>(OscillatorEnabled::Auto, OscillatorEnabled::On), 0 };
extern const OpcodeSpec<float> oscillatorPhase { 0.0f, Range<float>(0.0f, 1.0f), 0 }; extern const OpcodeSpec<float> oscillatorPhase { 0.0f, Range<float>(0.0f, 1.0f), 0 };
extern const OpcodeSpec<int> oscillatorMode { 0, Range<int>(0, 2), kIgnoreOOB }; extern const OpcodeSpec<int> oscillatorMode { 0, Range<int>(0, 2), 0 };
extern const OpcodeSpec<int> oscillatorMulti { 1, Range<int>(1, config::oscillatorsPerVoice), kIgnoreOOB }; extern const OpcodeSpec<int> oscillatorMulti { 1, Range<int>(1, config::oscillatorsPerVoice), 0 };
extern const OpcodeSpec<float> oscillatorDetune { 0.0f, Range<float>(-12000.0f, 12000.0f), 0 }; extern const OpcodeSpec<float> oscillatorDetune { 0.0f, Range<float>(-12000.0f, 12000.0f), 0 };
extern const OpcodeSpec<float> oscillatorDetuneMod { 0.0f, Range<float>(-12000.0f, 12000.0f), 0 }; extern const OpcodeSpec<float> oscillatorDetuneMod { 0.0f, Range<float>(-12000.0f, 12000.0f), 0 };
extern const OpcodeSpec<float> oscillatorModDepth { 0.0f, Range<float>(0.0f, 10000.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> oscillatorModDepth { 0.0f, Range<float>(0.0f, 10000.0f), kNormalizePercent };
extern const OpcodeSpec<float> oscillatorModDepthMod { 0.0f, Range<float>(0.0f, 10000.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> oscillatorModDepthMod { 0.0f, Range<float>(0.0f, 10000.0f), 0 };
extern const OpcodeSpec<int> oscillatorQuality { 1, Range<int>(0, 3), kIgnoreOOB }; extern const OpcodeSpec<int> oscillatorQuality { 1, Range<int>(0, 3), 0 };
extern const OpcodeSpec<uint32_t> group { 0, Range<uint32_t>(0, uint32_t_max), 0 }; extern const OpcodeSpec<uint32_t> group { 0, Range<uint32_t>(0, uint32_t_max), 0 };
extern const OpcodeSpec<float> offTime { 6e-3f, Range<float>(0.0f, 100.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> offTime { 6e-3f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<uint32_t> polyphony { config::maxVoices, Range<uint32_t>(0, config::maxVoices), 0 }; extern const OpcodeSpec<uint32_t> polyphony { config::maxVoices, Range<uint32_t>(0, config::maxVoices), 0 };
extern const OpcodeSpec<uint32_t> notePolyphony { config::maxVoices, Range<uint32_t>(0, config::maxVoices), 0 }; extern const OpcodeSpec<uint32_t> notePolyphony { config::maxVoices, Range<uint32_t>(0, config::maxVoices), 0 };
extern const OpcodeSpec<uint8_t> key { 60, Range<uint8_t>(0, 127), kIgnoreOOB | kCanBeNote }; extern const OpcodeSpec<uint8_t> key { 60, Range<uint8_t>(0, 127), kCanBeNote };
extern const OpcodeSpec<uint8_t> midi7 { 0, Range<uint8_t>(0, 127), kIgnoreOOB }; extern const OpcodeSpec<uint8_t> loKey { 0, Range<uint8_t>(0, 127), kCanBeNote };
extern const OpcodeSpec<float> float7 { 0.0f , Range<float>(0.0f, 127.0f), kIgnoreOOB }; extern const OpcodeSpec<uint8_t> hiKey { 127, Range<uint8_t>(0, 127), kCanBeNote };
extern const OpcodeSpec<float> bend { 0.0f, Range<float>(-8192.0f, 8192.0f), kIgnoreOOB }; extern const OpcodeSpec<float> loCC { 0.0f , Range<float>(0.0f, 127.0f), kNormalizeMidi };
extern const OpcodeSpec<float> normalized { 0.0f, Range<float>(0.0f, 1.0f), kIgnoreOOB }; extern const OpcodeSpec<float> hiCC { 1.0f , Range<float>(0.0f, 127.0f), kNormalizeMidi };
extern const OpcodeSpec<float> bipolar { 0.0f, Range<float>(-1.0f, 1.0f), kIgnoreOOB }; extern const OpcodeSpec<float> loVel { 0.0f , Range<float>(0.0f, 127.0f), kNormalizeMidi };
extern const OpcodeSpec<uint16_t> ccNumber { 0, Range<uint16_t>(0, config::numCCs), kIgnoreOOB }; extern const OpcodeSpec<float> hiVel { 1.0f , Range<float>(0.0f, 127.0f), kNormalizeMidi };
extern const OpcodeSpec<uint8_t> smoothCC { 0, Range<uint8_t>(0, 100), kIgnoreOOB }; extern const OpcodeSpec<uint8_t> loChannelAftertouch { 0, Range<uint8_t>(0, 127), 0 };
extern const OpcodeSpec<uint8_t> curveCC { 0, Range<uint8_t>(0, 255), kIgnoreOOB }; extern const OpcodeSpec<uint8_t> hiChannelAftertouch { 127, Range<uint8_t>(0, 127), 0 };
extern const OpcodeSpec<uint8_t> sustainCC { 64, Range<uint8_t>(0, 127), kIgnoreOOB }; extern const OpcodeSpec<float> loBend { -1.0f, Range<float>(-8192.0f, 8192.0f), kNormalizeBend };
extern const OpcodeSpec<float> sustainThreshold { 0.0039f, Range<float>(0.0f, 1.0f), kIgnoreOOB }; extern const OpcodeSpec<float> hiBend { 1.0f, Range<float>(-8192.0f, 8192.0f), kNormalizeBend };
extern const OpcodeSpec<float> loNormalized { 0.0f, Range<float>(0.0f, 1.0f), 0 };
extern const OpcodeSpec<float> hiNormalized { 1.0f, Range<float>(0.0f, 1.0f), 0 };
extern const OpcodeSpec<float> loBipolar { -1.0f, Range<float>(-1.0f, 1.0f), 0 };
extern const OpcodeSpec<float> hiBipolar { 1.0f, Range<float>(-1.0f, 1.0f), 0 };
extern const OpcodeSpec<uint16_t> ccNumber { 0, Range<uint16_t>(0, config::numCCs), 0 };
extern const OpcodeSpec<uint8_t> smoothCC { 0, Range<uint8_t>(0, 100), 0 };
extern const OpcodeSpec<uint8_t> curveCC { 0, Range<uint8_t>(0, 255), 0 };
extern const OpcodeSpec<uint8_t> sustainCC { 64, Range<uint8_t>(0, 127), 0 };
extern const OpcodeSpec<float> sustainThreshold { 0.0039f, Range<float>(0.0f, 127.0f), kNormalizeMidi };
extern const OpcodeSpec<bool> checkSustain { true, Range<bool>(0, 1), 0 }; extern const OpcodeSpec<bool> checkSustain { true, Range<bool>(0, 1), 0 };
extern const OpcodeSpec<bool> checkSostenuto { true, Range<bool>(0, 1), 0 }; extern const OpcodeSpec<bool> checkSostenuto { true, Range<bool>(0, 1), 0 };
extern const OpcodeSpec<float> bpm { 0.0f, Range<float>(0.0f, 500.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> loBPM { 0.0f, Range<float>(0.0f, 500.0f), 0 };
extern const OpcodeSpec<uint8_t> sequence { 1, Range<uint8_t>(1, 100), kIgnoreOOB }; extern const OpcodeSpec<float> hiBPM { 500.0f, Range<float>(0.0f, 500.0f), 0 };
extern const OpcodeSpec<uint8_t> sequence { 1, Range<uint8_t>(1, 100), 0 };
extern const OpcodeSpec<float> volume { 0.0f, Range<float>(-144.0f, 48.0f), 0 }; extern const OpcodeSpec<float> volume { 0.0f, Range<float>(-144.0f, 48.0f), 0 };
extern const OpcodeSpec<float> volumeMod { 0.0f, Range<float>(-144.0f, 48.0f), 0 }; extern const OpcodeSpec<float> volumeMod { 0.0f, Range<float>(-144.0f, 48.0f), 0 };
extern const OpcodeSpec<float> amplitude { 100.0f, Range<float>(0.0f, 100.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> amplitude { 100.0f, Range<float>(0.0f, 10000.0f), kNormalizePercent };
extern const OpcodeSpec<float> amplitudeMod { 0.0f, Range<float>(0.0f, 100.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> amplitudeMod { 0.0f, Range<float>(0.0f, 10000.0f), kNormalizePercent };
extern const OpcodeSpec<float> pan { 0.0f, Range<float>(-100.0f, 100.0f), 0 }; extern const OpcodeSpec<float> pan { 0.0f, Range<float>(-100.0f, 100.0f), kNormalizePercent };
extern const OpcodeSpec<float> panMod { 0.0f, Range<float>(-200.0f, 200.0f), 0 }; extern const OpcodeSpec<float> panMod { 0.0f, Range<float>(-200.0f, 200.0f), kNormalizePercent };
extern const OpcodeSpec<float> position { 0.0f, Range<float>(-100.0f, 100.0f), 0 }; extern const OpcodeSpec<float> position { 0.0f, Range<float>(-100.0f, 100.0f), kNormalizePercent };
extern const OpcodeSpec<float> positionMod { 0.0f, Range<float>(-200.0f, 200.0f), 0 }; extern const OpcodeSpec<float> positionMod { 0.0f, Range<float>(-200.0f, 200.0f), kNormalizePercent };
extern const OpcodeSpec<float> width { 100.0f, Range<float>(-100.0f, 100.0f), 0 }; extern const OpcodeSpec<float> width { 100.0f, Range<float>(-100.0f, 100.0f), kNormalizePercent };
extern const OpcodeSpec<float> widthMod { 0.0f, Range<float>(-200.0f, 200.0f), 0 }; extern const OpcodeSpec<float> widthMod { 0.0f, Range<float>(-200.0f, 200.0f), kNormalizePercent };
extern const OpcodeSpec<uint8_t> crossfadeIn { 0, Range<uint8_t>(0, 127), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<float> crossfadeIn { 0.0f, Range<float>(0.0f, 127.0f), kNormalizeMidi };
extern const OpcodeSpec<float> crossfadeInNorm { 0.0f, Range<float>(0.0f, 1.0f), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<float> crossfadeInNorm { 0.0f, Range<float>(0.0f, 1.0f), 0 };
extern const OpcodeSpec<uint8_t> crossfadeOut { 127, Range<uint8_t>(0, 127), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<float> crossfadeOut { 1.0f, Range<float>(0.0f, 127.0f), kNormalizeMidi };
extern const OpcodeSpec<float> crossfadeOutNorm { 1.0f, Range<float>(0.0f, 1.0f), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<float> crossfadeOutNorm { 1.0f, Range<float>(0.0f, 1.0f), 0 };
extern const OpcodeSpec<float> ampKeytrack { 0.0f, Range<float>(-96.0f, 12.0f), 0 }; extern const OpcodeSpec<float> ampKeytrack { 0.0f, Range<float>(-96.0f, 12.0f), 0 };
extern const OpcodeSpec<float> ampVeltrack { 100.0f, Range<float>(-100.0f, 100.0f), kIgnoreOOB }; extern const OpcodeSpec<float> ampVeltrack { 100.0f, Range<float>(-100.0f, 100.0f), 0 };
extern const OpcodeSpec<float> ampVelcurve { 0.0f, Range<float>(0.0f, 1.0f), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<float> ampVelcurve { 0.0f, Range<float>(0.0f, 1.0f), 0 };
extern const OpcodeSpec<float> ampRandom { 0.0f, Range<float>(0.0f, 24.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> ampRandom { 0.0f, Range<float>(0.0f, 24.0f), 0 };
extern const OpcodeSpec<bool> rtDead { false, Range<bool>(0, 1), 0 }; extern const OpcodeSpec<bool> rtDead { false, Range<bool>(0, 1), 0 };
extern const OpcodeSpec<float> rtDecay { 0.0f, Range<float>(0.0f, 200.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> rtDecay { 0.0f, Range<float>(0.0f, 200.0f), 0 };
extern const OpcodeSpec<float> filterCutoff { 0.0f, Range<float>(0.0f, 20000.0f), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<float> filterCutoff { 0.0f, Range<float>(0.0f, 20000.0f), 0 };
extern const OpcodeSpec<float> filterCutoffMod { 0.0f, Range<float>(-12000.0f, 12000.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> filterCutoffMod { 0.0f, Range<float>(-12000.0f, 12000.0f), 0 };
extern const OpcodeSpec<float> filterResonance { 0.0f, Range<float>(0.0f, 96.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> filterResonance { 0.0f, Range<float>(0.0f, 96.0f), 0 };
extern const OpcodeSpec<float> filterResonanceMod { 0.0f, Range<float>(0.0f, 96.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> filterResonanceMod { 0.0f, Range<float>(0.0f, 96.0f), 0 };
extern const OpcodeSpec<float> filterGain { 0.0f, Range<float>(-96.0f, 96.0f), 0 }; extern const OpcodeSpec<float> filterGain { 0.0f, Range<float>(-96.0f, 96.0f), 0 };
extern const OpcodeSpec<float> filterGainMod { 0.0f, Range<float>(-96.0f, 96.0f), 0 }; extern const OpcodeSpec<float> filterGainMod { 0.0f, Range<float>(-96.0f, 96.0f), 0 };
extern const OpcodeSpec<float> filterRandom { 0.0f, Range<float>(0.0f, 12000.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> filterRandom { 0.0f, Range<float>(0.0f, 12000.0f), 0 };
extern const OpcodeSpec<int> filterKeytrack { 0, Range<int>(0, 1200), kEnforceLowerBound }; extern const OpcodeSpec<int> filterKeytrack { 0, Range<int>(0, 1200), 0 };
extern const OpcodeSpec<int> filterVeltrack { 0, Range<int>(-12000, 12000), 0 }; extern const OpcodeSpec<int> filterVeltrack { 0, Range<int>(-12000, 12000), 0 };
extern const OpcodeSpec<float> eqBandwidth { 1.0f, Range<float>(0.001f, 4.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> eqBandwidth { 1.0f, Range<float>(0.001f, 4.0f), 0 };
extern const OpcodeSpec<float> eqBandwidthMod { 0.0f, Range<float>(-4.0f, 4.0f), 0 }; extern const OpcodeSpec<float> eqBandwidthMod { 0.0f, Range<float>(-4.0f, 4.0f), 0 };
extern const OpcodeSpec<float> eqFrequency { 0.0f, Range<float>(0.0f, 30000.0f), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<float> eqFrequency { 0.0f, Range<float>(0.0f, 30000.0f), 0 };
extern const OpcodeSpec<float> eqFrequencyMod { 0.0f, Range<float>(-30000.0f, 30000.0f), 0 }; extern const OpcodeSpec<float> eqFrequencyMod { 0.0f, Range<float>(-30000.0f, 30000.0f), 0 };
extern const OpcodeSpec<float> eqGain { 0.0f, Range<float>(-96.0f, 96.0f), 0 }; extern const OpcodeSpec<float> eqGain { 0.0f, Range<float>(-96.0f, 96.0f), 0 };
extern const OpcodeSpec<float> eqGainMod { 0.0f, Range<float>(-96.0f, 96.0f), 0 }; extern const OpcodeSpec<float> eqGainMod { 0.0f, Range<float>(-96.0f, 96.0f), 0 };
extern const OpcodeSpec<float> eqVel2Frequency { 0.0f, Range<float>(-30000.0f, 30000.0f), 0 }; extern const OpcodeSpec<float> eqVel2Frequency { 0.0f, Range<float>(-30000.0f, 30000.0f), 0 };
extern const OpcodeSpec<float> eqVel2Gain { 0.0f, Range<float>(-96.0f, 96.0f), 0 }; extern const OpcodeSpec<float> eqVel2Gain { 0.0f, Range<float>(-96.0f, 96.0f), 0 };
extern const OpcodeSpec<int> pitchKeytrack { 100, Range<int>(-1200, 1200), 0 }; extern const OpcodeSpec<int> pitchKeytrack { 100, Range<int>(-1200, 1200), 0 };
extern const OpcodeSpec<float> pitchRandom { 0.0f, Range<float>(0.0f, 12000.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> pitchRandom { 0.0f, Range<float>(0.0f, 12000.0f), 0 };
extern const OpcodeSpec<int> pitchVeltrack { 0, Range<int>(-12000, 12000), 0 }; extern const OpcodeSpec<int> pitchVeltrack { 0, Range<int>(-12000, 12000), 0 };
extern const OpcodeSpec<int> transpose { 0, Range<int>(-127, 127), kIgnoreOOB }; extern const OpcodeSpec<int> transpose { 0, Range<int>(-127, 127), 0 };
extern const OpcodeSpec<float> pitch { 0.0f, Range<float>(-100.0f, 100.0f), 0 }; extern const OpcodeSpec<float> pitch { 0.0f, Range<float>(-100.0f, 100.0f), 0 };
extern const OpcodeSpec<float> pitchMod { 0.0f, Range<float>(-100.0f, 100.0f), 0 }; extern const OpcodeSpec<float> pitchMod { 0.0f, Range<float>(-100.0f, 100.0f), 0 };
extern const OpcodeSpec<float> bendUp { 200.0f, Range<float>(-12000.0f, 12000.0f), 0 }; extern const OpcodeSpec<float> bendUp { 200.0f, Range<float>(-12000.0f, 12000.0f), 0 };
extern const OpcodeSpec<float> bendDown { -200.0f, Range<float>(-12000.0f, 12000.0f), 0 }; extern const OpcodeSpec<float> bendDown { -200.0f, Range<float>(-12000.0f, 12000.0f), 0 };
extern const OpcodeSpec<float> bendStep { 1.0f, Range<float>(1.0f, 1200.0f), kIgnoreOOB }; extern const OpcodeSpec<float> bendStep { 1.0f, Range<float>(1.0f, 1200.0f), 0 };
extern const OpcodeSpec<float> lfoFreq { 0.0f, Range<float>(0.0f, 100.0f), 0 }; extern const OpcodeSpec<float> lfoFreq { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> lfoFreqMod { 0.0f, Range<float>(-100.0f, 100.0f), 0 }; extern const OpcodeSpec<float> lfoFreqMod { 0.0f, Range<float>(-100.0f, 100.0f), 0 };
extern const OpcodeSpec<float> lfoBeats { 0.0f, Range<float>(0.0f, 1000.0f), 0 }; extern const OpcodeSpec<float> lfoBeats { 0.0f, Range<float>(0.0f, 1000.0f), 0 };
extern const OpcodeSpec<float> lfoBeatsMod { 0.0f, Range<float>(-1000.0f, 1000.0f), 0 }; extern const OpcodeSpec<float> lfoBeatsMod { 0.0f, Range<float>(-1000.0f, 1000.0f), 0 };
extern const OpcodeSpec<float> lfoPhase { 0.0f, Range<float>(0.0f, 1.0f), 0 }; extern const OpcodeSpec<float> lfoPhase { 0.0f, Range<float>(0.0f, 1.0f), kWrapPhase };
extern const OpcodeSpec<float> lfoDelay { 0.0f, Range<float>(0.0f, 30.0f), 0 }; extern const OpcodeSpec<float> lfoDelay { 0.0f, Range<float>(0.0f, 30.0f), 0 };
extern const OpcodeSpec<float> lfoFade { 0.0f, Range<float>(0.0f, 30.0f), 0 }; extern const OpcodeSpec<float> lfoFade { 0.0f, Range<float>(0.0f, 30.0f), 0 };
extern const OpcodeSpec<unsigned> lfoCount { 0, Range<unsigned>(0, 1000), 0 }; extern const OpcodeSpec<unsigned> lfoCount { 0, Range<unsigned>(0, 1000), 0 };
extern const OpcodeSpec<unsigned> lfoSteps { 0, Range<unsigned>(0, static_cast<unsigned>(config::maxLFOSteps)), 0 }; extern const OpcodeSpec<unsigned> lfoSteps { 0, Range<unsigned>(0, static_cast<unsigned>(config::maxLFOSteps)), 0 };
extern const OpcodeSpec<float> lfoStepX { 0.0f, Range<float>(-100.0f, 100.0f), 0 }; extern const OpcodeSpec<float> lfoStepX { 0.0f, Range<float>(-100.0f, 100.0f), kNormalizePercent };
extern const OpcodeSpec<int> lfoWave { 0, Range<int>(0, 15), 0 }; extern const OpcodeSpec<LFOWave> lfoWave { LFOWave::Triangle, Range<LFOWave>(LFOWave::Triangle, LFOWave::RandomSH), 0 };
extern const OpcodeSpec<float> lfoOffset { 0.0f, Range<float>(-1.0f, 1.0f), 0 }; extern const OpcodeSpec<float> lfoOffset { 0.0f, Range<float>(-1.0f, 1.0f), 0 };
extern const OpcodeSpec<float> lfoRatio { 1.0f, Range<float>(0.0f, 100.0f), 0 }; extern const OpcodeSpec<float> lfoRatio { 1.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> lfoScale { 1.0f, Range<float>(0.0f, 1.0f), 0 }; extern const OpcodeSpec<float> lfoScale { 1.0f, Range<float>(0.0f, 1.0f), 0 };
extern const OpcodeSpec<float> egTime { 0.0f, Range<float>(0.0f, 100.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> egTime { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> egRelease { 0.001f, Range<float>(0.0f, 100.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> egRelease { 0.001f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> egTimeMod { 0.0f, Range<float>(-100.0f, 100.0f), 0 }; extern const OpcodeSpec<float> egTimeMod { 0.0f, Range<float>(-100.0f, 100.0f), 0 };
extern const OpcodeSpec<float> egPercent { 0.0f, Range<float>(0.0f, 100.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> egPercent { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> egPercentMod { 0.0f, Range<float>(-100.0f, 100.0f), 0 }; extern const OpcodeSpec<float> egPercentMod { 0.0f, Range<float>(-100.0f, 100.0f), 0 };
extern const OpcodeSpec<float> egDepth { 0.0f, Range<float>(-12000.0f, 12000.0f), 0 }; extern const OpcodeSpec<float> egDepth { 0.0f, Range<float>(-12000.0f, 12000.0f), 0 };
extern const OpcodeSpec<float> egVel2Depth { 0.0f, Range<float>(-12000.0f, 12000.0f), 0 }; extern const OpcodeSpec<float> egVel2Depth { 0.0f, Range<float>(-12000.0f, 12000.0f), 0 };
extern const OpcodeSpec<bool> flexEGAmpeg { false, Range<bool>(0, 1), 0 }; extern const OpcodeSpec<bool> flexEGAmpeg { false, Range<bool>(0, 1), 0 };
extern const OpcodeSpec<int> flexEGDynamic { 0, Range<int>(0, 1), kIgnoreOOB }; extern const OpcodeSpec<int> flexEGDynamic { 0, Range<int>(0, 1), 0 };
extern const OpcodeSpec<int> flexEGSustain { 0, Range<int>(0, 100), kIgnoreOOB }; extern const OpcodeSpec<int> flexEGSustain { 0, Range<int>(0, 100), 0 };
extern const OpcodeSpec<float> flexEGPointTime { 0.0f, Range<float>(0.0f, 100.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> flexEGPointTime { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> flexEGPointLevel { 0.0f, Range<float>(-1.0f, 1.0f), kIgnoreOOB }; extern const OpcodeSpec<float> flexEGPointLevel { 0.0f, Range<float>(-1.0f, 1.0f), 0 };
extern const OpcodeSpec<float> flexEGPointShape { 0.0f, Range<float>(-100.0f, 100.0f), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<float> flexEGPointShape { 0.0f, Range<float>(-100.0f, 100.0f), 0 };
extern const OpcodeSpec<int> sampleQuality { 1, Range<int>(1, 10), kIgnoreOOB }; extern const OpcodeSpec<int> sampleQuality { 1, Range<int>(1, 10), 0 };
extern const OpcodeSpec<int> octaveOffset { 0, Range<int>(-10, 10), 0 }; extern const OpcodeSpec<int> octaveOffset { 0, Range<int>(-10, 10), 0 };
extern const OpcodeSpec<int> noteOffset { 0, Range<int>(-127, 127), 0 }; extern const OpcodeSpec<int> noteOffset { 0, Range<int>(-127, 127), 0 };
extern const OpcodeSpec<float> effect { 0.0f, Range<float>(0.0f, 100.0f), 0 }; extern const OpcodeSpec<float> effect { 0.0f, Range<float>(0.0f, 100.0f), kNormalizePercent };
extern const OpcodeSpec<int> apanWaveform { 0, Range<int>(0, std::numeric_limits<int>::max()), 0 }; extern const OpcodeSpec<int> apanWaveform { 0, Range<int>(0, std::numeric_limits<int>::max()), 0 };
extern const OpcodeSpec<float> apanFrequency { 0.0f, Range<float>(0.0f, std::numeric_limits<float>::max()), kEnforceLowerBound }; extern const OpcodeSpec<float> apanFrequency { 0.0f, Range<float>(0.0f, std::numeric_limits<float>::max()), 0 };
extern const OpcodeSpec<float> apanPhase { 0.5f, Range<float>(0.0f, 1.0f), 0 }; extern const OpcodeSpec<float> apanPhase { 0.5f, Range<float>(0.0f, 1.0f), kWrapPhase };
extern const OpcodeSpec<float> apanLevel { 0.0f, Range<float>(0.0f, 100.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> apanLevel { 0.0f, Range<float>(0.0f, 100.0f), kNormalizePercent };
extern const OpcodeSpec<float> distoTone { 100.0f, Range<float>(0.0f, 100.0f), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<float> distoTone { 100.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> distoDepth { 0.0f, Range<float>(0.0f, 100.0f), kEnforceLowerBound | kEnforceUpperBound }; extern const OpcodeSpec<float> distoDepth { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<unsigned> distoStages { 1, Range<unsigned>(1, maxDistoStages), kEnforceLowerBound }; extern const OpcodeSpec<unsigned> distoStages { 1, Range<unsigned>(1, maxDistoStages), 0 };
extern const OpcodeSpec<float> compAttack { 0.005f, Range<float>(0.0f, 10.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> compAttack { 0.005f, Range<float>(0.0f, 10.0f), 0 };
extern const OpcodeSpec<float> compRelease { 0.05f, Range<float>(0.0f, 10.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> compRelease { 0.05f, Range<float>(0.0f, 10.0f), 0 };
extern const OpcodeSpec<bool> compSTLink { false, Range<bool>(0, 1), 0 }; extern const OpcodeSpec<bool> compSTLink { false, Range<bool>(0, 1), 0 };
extern const OpcodeSpec<float> compThreshold { 0.0f, Range<float>(-100.0f, 0.0f), kIgnoreOOB }; extern const OpcodeSpec<float> compThreshold { 0.0f, Range<float>(-100.0f, 0.0f), 0 };
extern const OpcodeSpec<float> compRatio { 1.0f, Range<float>(1.0f, 50.0f), kIgnoreOOB }; extern const OpcodeSpec<float> compRatio { 1.0f, Range<float>(1.0f, 50.0f), 0 };
extern const OpcodeSpec<float> compGain { 0.0f, Range<float>(-100.0f, 100.0f), 0 }; extern const OpcodeSpec<float> compGain { 1.0f, Range<float>(-100.0f, 100.0f), kDb2Mag };
extern const OpcodeSpec<float> fverbSize { 0.0f, Range<float>(0.0f, 100.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> fverbSize { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> fverbPredelay { 0.0f, Range<float>(0.0f, 10.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> fverbPredelay { 0.0f, Range<float>(0.0f, 10.0f), 0 };
extern const OpcodeSpec<float> fverbTone { 100.0f, Range<float>(0.0f, 100.0f), kIgnoreOOB }; extern const OpcodeSpec<float> fverbTone { 100.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> fverbDamp { 0.0f, Range<float>(0.0f, 100.0f), kIgnoreOOB }; extern const OpcodeSpec<float> fverbDamp { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<bool> gateSTLink { false, Range<bool>(0, 1), 0 }; extern const OpcodeSpec<bool> gateSTLink { false, Range<bool>(0, 1), 0 };
extern const OpcodeSpec<float> gateAttack { 0.005f, Range<float>(0.0f, 10.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> gateAttack { 0.005f, Range<float>(0.0f, 10.0f), 0 };
extern const OpcodeSpec<float> gateRelease { 0.05f, Range<float>(0.0f, 10.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> gateRelease { 0.05f, Range<float>(0.0f, 10.0f), 0 };
extern const OpcodeSpec<float> gateHold { 0.0f, Range<float>(0.0f, 10.0f), kEnforceLowerBound }; extern const OpcodeSpec<float> gateHold { 0.0f, Range<float>(0.0f, 10.0f), 0 };
extern const OpcodeSpec<float> gateThreshold { 0.0f, Range<float>(-100.0f, 0.0f), kIgnoreOOB }; extern const OpcodeSpec<float> gateThreshold { 0.0f, Range<float>(-100.0f, 0.0f), 0 };
extern const OpcodeSpec<float> lofiBitred { 0.0f, Range<float>(0.0f, 100.0f), kIgnoreOOB }; extern const OpcodeSpec<float> lofiBitred { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> lofiDecim { 0.0f, Range<float>(0.0f, 100.0f), kIgnoreOOB }; extern const OpcodeSpec<float> lofiDecim { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<float> rectify { 0.0f, Range<float>(0.0f, 100.0f), kIgnoreOOB }; extern const OpcodeSpec<float> rectify { 0.0f, Range<float>(0.0f, 100.0f), 0 };
extern const OpcodeSpec<unsigned> stringsNumber { maxStrings, Range<unsigned>(0, maxStrings), kEnforceLowerBound }; extern const OpcodeSpec<unsigned> stringsNumber { maxStrings, Range<unsigned>(0, maxStrings), 0 };
extern const OpcodeSpec<Trigger> trigger { Trigger::attack, Range<Trigger>(Trigger::attack, Trigger::release_key), 0}; extern const OpcodeSpec<Trigger> trigger { Trigger::attack, Range<Trigger>(Trigger::attack, Trigger::release_key), 0};
extern const OpcodeSpec<CrossfadeCurve> crossfadeCurve { CrossfadeCurve::power, Range<CrossfadeCurve>(CrossfadeCurve::gain, CrossfadeCurve::power), 0}; extern const OpcodeSpec<CrossfadeCurve> crossfadeCurve { CrossfadeCurve::power, Range<CrossfadeCurve>(CrossfadeCurve::gain, CrossfadeCurve::power), 0};
extern const OpcodeSpec<OffMode> offMode { OffMode::fast, Range<OffMode>(OffMode::fast, OffMode::time), 0}; extern const OpcodeSpec<OffMode> offMode { OffMode::fast, Range<OffMode>(OffMode::fast, OffMode::time), 0};

View file

@ -41,20 +41,37 @@ enum class VelocityOverride { current = 0, previous };
enum class CrossfadeCurve { gain = 0, power }; enum class CrossfadeCurve { gain = 0, power };
enum class SelfMask { mask = 0, dontMask }; enum class SelfMask { mask = 0, dontMask };
enum class OscillatorEnabled { Auto = -1, Off = 0, On = 1 }; 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 { enum OpcodeFlags : int {
kIgnoreOOB = 1, kCanBeNote = 1,
kEnforceLowerBound = 1 << 1, kEnforceLowerBound = 1 << 1,
kEnforceUpperBound = 1 << 2, kEnforceUpperBound = 1 << 2,
kCanBeNote = 1 << 3, kNormalizePercent = 1 << 3,
kNormalizeMidi = 1 << 4,
kNormalizeBend = 1 << 5,
kWrapPhase = 1 << 6,
kDb2Mag = 1 << 7,
}; };
template<class T> template<class T>
struct OpcodeSpec struct OpcodeSpec
{ {
T value; T defaultValue;
Range<T> bounds; Range<T> bounds;
int flags; int flags;
operator T() const { return defaultValue; }
}; };
namespace Default namespace Default
@ -66,7 +83,8 @@ namespace Default
extern const OpcodeSpec<int64_t> offsetRandom; extern const OpcodeSpec<int64_t> offsetRandom;
extern const OpcodeSpec<uint32_t> sampleEnd; extern const OpcodeSpec<uint32_t> sampleEnd;
extern const OpcodeSpec<uint32_t> sampleCount; extern const OpcodeSpec<uint32_t> sampleCount;
extern const OpcodeSpec<uint32_t> loopRange; extern const OpcodeSpec<uint32_t> loopStart;
extern const OpcodeSpec<uint32_t> loopEnd;
extern const OpcodeSpec<float> loopCrossfade; extern const OpcodeSpec<float> loopCrossfade;
extern const OpcodeSpec<float> oscillatorPhase; extern const OpcodeSpec<float> oscillatorPhase;
extern const OpcodeSpec<OscillatorEnabled> oscillator; extern const OpcodeSpec<OscillatorEnabled> oscillator;
@ -82,11 +100,20 @@ namespace Default
extern const OpcodeSpec<uint32_t> polyphony; extern const OpcodeSpec<uint32_t> polyphony;
extern const OpcodeSpec<uint32_t> notePolyphony; extern const OpcodeSpec<uint32_t> notePolyphony;
extern const OpcodeSpec<uint8_t> key; extern const OpcodeSpec<uint8_t> key;
extern const OpcodeSpec<uint8_t> midi7; extern const OpcodeSpec<uint8_t> loKey;
extern const OpcodeSpec<float> float7; extern const OpcodeSpec<uint8_t> hiKey;
extern const OpcodeSpec<float> bend; extern const OpcodeSpec<float> loVel;
extern const OpcodeSpec<float> normalized; extern const OpcodeSpec<float> hiVel;
extern const OpcodeSpec<float> bipolar; extern const OpcodeSpec<float> loCC;
extern const OpcodeSpec<float> hiCC;
extern const OpcodeSpec<float> loBend;
extern const OpcodeSpec<float> hiBend;
extern const OpcodeSpec<float> loNormalized;
extern const OpcodeSpec<float> hiNormalized;
extern const OpcodeSpec<float> loBipolar;
extern const OpcodeSpec<float> hiBipolar;
extern const OpcodeSpec<uint8_t> loChannelAftertouch;
extern const OpcodeSpec<uint8_t> hiChannelAftertouch;
extern const OpcodeSpec<uint16_t> ccNumber; extern const OpcodeSpec<uint16_t> ccNumber;
extern const OpcodeSpec<uint8_t> curveCC; extern const OpcodeSpec<uint8_t> curveCC;
extern const OpcodeSpec<uint8_t> smoothCC; extern const OpcodeSpec<uint8_t> smoothCC;
@ -94,7 +121,8 @@ namespace Default
extern const OpcodeSpec<bool> checkSustain; extern const OpcodeSpec<bool> checkSustain;
extern const OpcodeSpec<bool> checkSostenuto; extern const OpcodeSpec<bool> checkSostenuto;
extern const OpcodeSpec<float> sustainThreshold; extern const OpcodeSpec<float> sustainThreshold;
extern const OpcodeSpec<float> bpm; extern const OpcodeSpec<float> loBPM;
extern const OpcodeSpec<float> hiBPM;
extern const OpcodeSpec<uint8_t> sequence; extern const OpcodeSpec<uint8_t> sequence;
extern const OpcodeSpec<float> volume; extern const OpcodeSpec<float> volume;
extern const OpcodeSpec<float> volumeMod; extern const OpcodeSpec<float> volumeMod;
@ -106,9 +134,9 @@ namespace Default
extern const OpcodeSpec<float> positionMod; extern const OpcodeSpec<float> positionMod;
extern const OpcodeSpec<float> width; extern const OpcodeSpec<float> width;
extern const OpcodeSpec<float> widthMod; extern const OpcodeSpec<float> widthMod;
extern const OpcodeSpec<uint8_t> crossfadeIn; extern const OpcodeSpec<float> crossfadeIn;
extern const OpcodeSpec<float> crossfadeInNorm; extern const OpcodeSpec<float> crossfadeInNorm;
extern const OpcodeSpec<uint8_t> crossfadeOut; extern const OpcodeSpec<float> crossfadeOut;
extern const OpcodeSpec<float> crossfadeOutNorm; extern const OpcodeSpec<float> crossfadeOutNorm;
extern const OpcodeSpec<float> ampKeytrack; extern const OpcodeSpec<float> ampKeytrack;
extern const OpcodeSpec<float> ampVeltrack; extern const OpcodeSpec<float> ampVeltrack;
@ -152,7 +180,7 @@ namespace Default
extern const OpcodeSpec<unsigned> lfoCount; extern const OpcodeSpec<unsigned> lfoCount;
extern const OpcodeSpec<unsigned> lfoSteps; extern const OpcodeSpec<unsigned> lfoSteps;
extern const OpcodeSpec<float> lfoStepX; extern const OpcodeSpec<float> lfoStepX;
extern const OpcodeSpec<int> lfoWave; extern const OpcodeSpec<LFOWave> lfoWave;
extern const OpcodeSpec<float> lfoOffset; extern const OpcodeSpec<float> lfoOffset;
extern const OpcodeSpec<float> lfoRatio; extern const OpcodeSpec<float> lfoRatio;
extern const OpcodeSpec<float> lfoScale; extern const OpcodeSpec<float> lfoScale;

View file

@ -66,21 +66,21 @@ struct EGDescription {
EGDescription& operator=(const EGDescription&) = default; EGDescription& operator=(const EGDescription&) = default;
EGDescription& operator=(EGDescription&&) = default; EGDescription& operator=(EGDescription&&) = default;
float attack { Default::egTime.value }; float attack { Default::egTime };
float decay { Default::egTime.value }; float decay { Default::egTime };
float delay { Default::egTime.value }; float delay { Default::egTime };
float hold { Default::egTime.value }; float hold { Default::egTime };
float release { Default::egTime.value }; float release { Default::egTime };
float start { Default::egPercent.bounds.getStart() }; float start { Default::egPercent.bounds.getStart() };
float sustain { Default::egPercent.bounds.getEnd() }; float sustain { Default::egPercent.bounds.getEnd() };
float depth { Default::egDepth.value }; float depth { Default::egDepth };
float vel2attack { Default::egTimeMod.value }; float vel2attack { Default::egTimeMod };
float vel2decay { Default::egTimeMod.value }; float vel2decay { Default::egTimeMod };
float vel2delay { Default::egTimeMod.value }; float vel2delay { Default::egTimeMod };
float vel2hold { Default::egTimeMod.value }; float vel2hold { Default::egTimeMod };
float vel2release { Default::egPercentMod.value }; float vel2release { Default::egPercentMod };
float vel2sustain { Default::egPercentMod.value }; float vel2sustain { Default::egPercentMod };
float vel2depth { Default::egVel2Depth.value }; float vel2depth { Default::egVel2Depth };
CCMap<float> ccAttack; CCMap<float> ccAttack;
CCMap<float> ccDecay; CCMap<float> ccDecay;

View file

@ -14,11 +14,11 @@ namespace sfz
{ {
struct EQDescription struct EQDescription
{ {
float bandwidth { Default::eqBandwidth.value }; float bandwidth { Default::eqBandwidth };
float frequency { Default::eqFrequency.value }; float frequency { Default::eqFrequency };
float gain { Default::eqGain.value }; float gain { Default::eqGain };
float vel2frequency { Default::eqVel2Frequency.value }; float vel2frequency { Default::eqVel2Frequency };
float vel2gain { Default::eqVel2Gain.value }; float vel2gain { Default::eqVel2Gain };
EqType type { EqType::kEqPeak }; EqType type { EqType::kEqPeak };
}; };
} }

View file

@ -43,9 +43,9 @@ private:
Resources& resources; Resources& resources;
const EQDescription* description; const EQDescription* description;
std::unique_ptr<FilterEq> eq; std::unique_ptr<FilterEq> eq;
float baseBandwidth { Default::eqBandwidth.value }; float baseBandwidth { Default::eqBandwidth };
float baseFrequency { Default::eqFrequency.value }; float baseFrequency { Default::eqFrequency };
float baseGain { Default::eqGain.value }; float baseGain { Default::eqGain };
bool prepared { false }; bool prepared { false };
ModMatrix::TargetId gainTarget; ModMatrix::TargetId gainTarget;
ModMatrix::TargetId frequencyTarget; ModMatrix::TargetId frequencyTarget;

View file

@ -179,8 +179,8 @@ private:
std::vector<std::unique_ptr<Effect>> _effects; std::vector<std::unique_ptr<Effect>> _effects;
AudioBuffer<float> _inputs { EffectChannels, config::defaultSamplesPerBlock }; AudioBuffer<float> _inputs { EffectChannels, config::defaultSamplesPerBlock };
AudioBuffer<float> _outputs { EffectChannels, config::defaultSamplesPerBlock }; AudioBuffer<float> _outputs { EffectChannels, config::defaultSamplesPerBlock };
float _gainToMain { Default::effect.value }; float _gainToMain { Default::effect };
float _gainToMix { Default::effect.value }; float _gainToMix { Default::effect };
}; };
} // namespace sfz } // namespace sfz

View file

@ -255,7 +255,7 @@ absl::optional<sfz::FileInformation> sfz::FilePool::getFileInformation(const Fil
if (!fileId.isReverse()) { if (!fileId.isReverse()) {
if (haveInstrumentInfo && instrumentInfo.loop_count > 0) { if (haveInstrumentInfo && instrumentInfo.loop_count > 0) {
returnedValue.hasLoop = true; 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); returnedValue.loopEnd = min(returnedValue.end, instrumentInfo.loops[0].end - 1);
} }
} else { } else {
@ -297,7 +297,7 @@ bool sfz::FilePool::preloadFile(const FileId& fileId, uint32_t maxOffset) noexce
const auto factor = static_cast<double>(oversamplingFactor); const auto factor = static_cast<double>(oversamplingFactor);
fileInformation->sampleRate = factor * static_cast<double>(reader->sampleRate()); fileInformation->sampleRate = factor * static_cast<double>(reader->sampleRate());
fileInformation->end = static_cast<uint32_t>(factor * fileInformation->end); fileInformation->end = static_cast<uint32_t>(factor * fileInformation->end);
fileInformation->loopBegin = static_cast<uint32_t>(factor * fileInformation->loopBegin); fileInformation->loopStart = static_cast<uint32_t>(factor * fileInformation->loopStart);
fileInformation->loopEnd = static_cast<uint32_t>(factor * fileInformation->loopEnd); fileInformation->loopEnd = static_cast<uint32_t>(factor * fileInformation->loopEnd);
auto insertedPair = preloadedFiles.insert_or_assign(fileId, { auto insertedPair = preloadedFiles.insert_or_assign(fileId, {
readFromFile(*reader, framesToLoad, oversamplingFactor), readFromFile(*reader, framesToLoad, oversamplingFactor),
@ -329,7 +329,7 @@ sfz::FileDataHolder sfz::FilePool::loadFile(const FileId& fileId) noexcept
const auto factor = static_cast<double>(oversamplingFactor); const auto factor = static_cast<double>(oversamplingFactor);
fileInformation->sampleRate = factor * static_cast<double>(reader->sampleRate()); fileInformation->sampleRate = factor * static_cast<double>(reader->sampleRate());
fileInformation->end = static_cast<uint32_t>(factor * fileInformation->end); fileInformation->end = static_cast<uint32_t>(factor * fileInformation->end);
fileInformation->loopBegin = static_cast<uint32_t>(factor * fileInformation->loopBegin); fileInformation->loopStart = static_cast<uint32_t>(factor * fileInformation->loopStart);
fileInformation->loopEnd = static_cast<uint32_t>(factor * fileInformation->loopEnd); fileInformation->loopEnd = static_cast<uint32_t>(factor * fileInformation->loopEnd);
auto insertedPair = preloadedFiles.insert_or_assign(fileId, { auto insertedPair = preloadedFiles.insert_or_assign(fileId, {
readFromFile(*reader, frames, oversamplingFactor), readFromFile(*reader, frames, oversamplingFactor),
@ -461,7 +461,7 @@ void sfz::FilePool::setOversamplingFactor(sfz::Oversampling factor) noexcept
FileInformation& information = preloadedFile.second.information; FileInformation& information = preloadedFile.second.information;
information.sampleRate *= samplerateChange; information.sampleRate *= samplerateChange;
information.end = static_cast<uint32_t>(samplerateChange * information.end); information.end = static_cast<uint32_t>(samplerateChange * information.end);
information.loopBegin = static_cast<uint32_t>(samplerateChange * information.loopBegin); information.loopStart = static_cast<uint32_t>(samplerateChange * information.loopStart);
information.loopEnd = static_cast<uint32_t>(samplerateChange * information.loopEnd); information.loopEnd = static_cast<uint32_t>(samplerateChange * information.loopEnd);
if (preloadedFile.second.status == FileData::Status::Done) { if (preloadedFile.second.status == FileData::Status::Done) {

View file

@ -51,10 +51,10 @@ using FileAudioBuffer = AudioBuffer<float, 2, config::defaultAlignment,
using FileAudioBufferPtr = std::shared_ptr<FileAudioBuffer>; using FileAudioBufferPtr = std::shared_ptr<FileAudioBuffer>;
struct FileInformation { struct FileInformation {
uint32_t end { Default::sampleEnd.value }; uint32_t end { Default::sampleEnd };
uint32_t maxOffset { 0 }; uint32_t maxOffset { 0 };
uint32_t loopBegin { Default::loopRange.bounds.getStart() }; uint32_t loopStart { Default::loopStart };
uint32_t loopEnd { Default::loopRange.bounds.getEnd() }; uint32_t loopEnd { Default::loopEnd };
bool hasLoop { false }; bool hasLoop { false };
double sampleRate { config::defaultSampleRate }; double sampleRate { config::defaultSampleRate };
int numChannels { 0 }; int numChannels { 0 };

View file

@ -14,13 +14,13 @@ namespace sfz
{ {
struct FilterDescription struct FilterDescription
{ {
float cutoff { Default::filterCutoff.value }; float cutoff { Default::filterCutoff };
float resonance { Default::filterCutoff.value }; float resonance { Default::filterCutoff };
float gain { Default::filterGain.value }; float gain { Default::filterGain };
int keytrack { Default::filterKeytrack.value }; int keytrack { Default::filterKeytrack };
uint8_t keycenter { Default::key.value }; uint8_t keycenter { Default::key };
int veltrack { Default::filterVeltrack.value }; int veltrack { Default::filterVeltrack };
float random { Default::filterRandom.value }; float random { Default::filterRandom };
FilterType type { FilterType::kFilterLpf2p }; FilterType type { FilterType::kFilterLpf2p };
}; };
} }

View file

@ -22,7 +22,7 @@ public:
* @param noteNumber the triggering note number * @param noteNumber the triggering note number
* @param velocity the triggering note velocity/value * @param velocity the triggering note velocity/value
*/ */
void setup(const Region& region, unsigned filterId, int noteNumber = static_cast<int>(Default::key.value), float velocity = 0); void setup(const Region& region, unsigned filterId, int noteNumber = static_cast<int>(Default::key), float velocity = 0);
/** /**
* @brief Process a block of stereo inputs * @brief Process a block of stereo inputs
* *
@ -45,9 +45,9 @@ private:
Resources& resources; Resources& resources;
const FilterDescription* description; const FilterDescription* description;
std::unique_ptr<Filter> filter; std::unique_ptr<Filter> filter;
float baseCutoff { Default::filterCutoff.value }; float baseCutoff { Default::filterCutoff };
float baseResonance { Default::filterResonance.value }; float baseResonance { Default::filterResonance };
float baseGain { Default::filterGain.value }; float baseGain { Default::filterGain };
ModMatrix::TargetId gainTarget; ModMatrix::TargetId gainTarget;
ModMatrix::TargetId cutoffTarget; ModMatrix::TargetId cutoffTarget;
ModMatrix::TargetId resonanceTarget; ModMatrix::TargetId resonanceTarget;

View file

@ -18,24 +18,24 @@ namespace FlexEGs {
}; };
struct FlexEGPoint { struct FlexEGPoint {
float time { Default::flexEGPointTime.value }; // duration until next step (s) float time { Default::flexEGPointTime }; // duration until next step (s)
float level { Default::flexEGPointLevel.value }; // normalized amplitude float level { Default::flexEGPointLevel }; // normalized amplitude
void setShape(float shape); void setShape(float shape);
float shape() const noexcept { return shape_; } float shape() const noexcept { return shape_; }
const Curve& curve() const; const Curve& curve() const;
private: 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<Curve> shapeCurve_; std::shared_ptr<Curve> shapeCurve_;
}; };
struct FlexEGDescription { struct FlexEGDescription {
int dynamic { Default::flexEGDynamic.value }; // whether parameters can be modulated while EG runs int dynamic { Default::flexEGDynamic }; // whether parameters can be modulated while EG runs
int sustain { Default::flexEGSustain.value }; // index of the sustain point (default to 0 in ARIA) int sustain { Default::flexEGSustain }; // index of the sustain point (default to 0 in ARIA)
std::vector<FlexEGPoint> points; std::vector<FlexEGPoint> points;
// ARIA // 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 } // namespace sfz

View file

@ -11,34 +11,21 @@
namespace sfz { namespace sfz {
enum class LFOWave : int {
Triangle,
Sine,
Pulse75,
Square,
Pulse25,
Pulse12_5,
Ramp,
Saw,
// ARIA extra
RandomSH = 12,
};
struct LFODescription { struct LFODescription {
LFODescription(); LFODescription();
~LFODescription(); ~LFODescription();
static const LFODescription& getDefault(); static const LFODescription& getDefault();
float freq { Default::lfoFreq.value }; // lfoN_freq float freq { Default::lfoFreq }; // lfoN_freq
float beats { Default::lfoBeats.value }; // lfoN_beats float beats { Default::lfoBeats }; // lfoN_beats
float phase0 { Default::lfoPhase.value }; // lfoN_phase float phase0 { Default::lfoPhase }; // lfoN_phase
float delay { Default::lfoDelay.value }; // lfoN_delay float delay { Default::lfoDelay }; // lfoN_delay
float fade { Default::lfoFade.value }; // lfoN_fade float fade { Default::lfoFade }; // lfoN_fade
unsigned count { Default::lfoCount.value }; // lfoN_count unsigned count { Default::lfoCount }; // lfoN_count
struct Sub { struct Sub {
LFOWave wave { static_cast<LFOWave>(Default::lfoWave.value) }; // lfoN_wave[X] LFOWave wave { Default::lfoWave }; // lfoN_wave[X]
float offset { Default::lfoOffset.value }; // lfoN_offset[X] float offset { Default::lfoOffset }; // lfoN_offset[X]
float ratio { Default::lfoRatio.value }; // lfoN_ratio[X] float ratio { Default::lfoRatio }; // lfoN_ratio[X]
float scale { Default::lfoScale.value }; // lfoN_scale[X] float scale { Default::lfoScale }; // lfoN_scale[X]
}; };
struct StepSequence { struct StepSequence {
std::vector<float> steps {}; // lfoN_stepX - normalized to unity std::vector<float> steps {}; // lfoN_stepX - normalized to unity

View file

@ -5,6 +5,7 @@
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "Opcode.h" #include "Opcode.h"
#include "LFODescription.h"
#include "StringViewHelpers.h" #include "StringViewHelpers.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/match.h" #include "absl/strings/match.h"
@ -141,30 +142,22 @@ absl::optional<T> readInt_(OpcodeSpec<T> spec, absl::string_view v)
if (spec.flags & kEnforceUpperBound) if (spec.flags & kEnforceUpperBound)
return spec.bounds.getEnd(); return spec.bounds.getEnd();
if (spec.flags & kIgnoreOOB) return {};
return {}; } else if (returnedValue < static_cast<int64_t>(spec.bounds.getStart())) {
}
if (returnedValue < static_cast<int64_t>(spec.bounds.getStart())) {
if (spec.flags & kEnforceLowerBound) if (spec.flags & kEnforceLowerBound)
return spec.bounds.getStart(); return spec.bounds.getStart();
if (spec.flags & kIgnoreOOB) return {};
return {};
} }
T castValue = static_cast<T>(returnedValue); return returnedValue;
if ((castValue != returnedValue) & kIgnoreOOB)
return {};
return castValue;
} }
#define INSTANTIATE_FOR_INTEGRAL(T) \ #define INSTANTIATE_FOR_INTEGRAL(T) \
template <> \ template <> \
absl::optional<T> Opcode::read(OpcodeSpec<T> spec) const \ T Opcode::read(OpcodeSpec<T> spec) const \
{ \ { \
return readInt_<T>(spec, value); \ return readInt_<T>(spec, value).value_or(spec.defaultValue); \
} }
INSTANTIATE_FOR_INTEGRAL(uint8_t) INSTANTIATE_FOR_INTEGRAL(uint8_t)
@ -198,30 +191,37 @@ absl::optional<T> readFloat_(OpcodeSpec<T> spec, absl::string_view v)
if (!absl::SimpleAtof(v, &returnedValue)) if (!absl::SimpleAtof(v, &returnedValue))
return absl::nullopt; return absl::nullopt;
if (returnedValue > static_cast<int64_t>(spec.bounds.getEnd())) { if (spec.flags & kWrapPhase)
returnedValue = wrapPhase(returnedValue);
else if (returnedValue > static_cast<int64_t>(spec.bounds.getEnd())) {
if (spec.flags & kEnforceUpperBound) if (spec.flags & kEnforceUpperBound)
return spec.bounds.getEnd(); return spec.bounds.getEnd();
if (spec.flags & kIgnoreOOB) return {};
return {}; } else if (returnedValue < static_cast<int64_t>(spec.bounds.getStart())) {
}
if (returnedValue < static_cast<int64_t>(spec.bounds.getStart())) {
if (spec.flags & kEnforceLowerBound) if (spec.flags & kEnforceLowerBound)
return spec.bounds.getStart(); 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; return returnedValue;
} }
#define INSTANTIATE_FOR_FLOATING_POINT(T) \ #define INSTANTIATE_FOR_FLOATING_POINT(T) \
template <> \ template <> \
absl::optional<T> Opcode::read(OpcodeSpec<T> spec) const \ T Opcode::read(OpcodeSpec<T> spec) const \
{ \ { \
return readFloat_<T>(spec, value); \ return readFloat_<T>(spec, value).value_or(spec.defaultValue); \
} }
INSTANTIATE_FOR_FLOATING_POINT(float) INSTANTIATE_FOR_FLOATING_POINT(float)
@ -288,24 +288,21 @@ absl::optional<bool> readBooleanFromOpcode(const Opcode& opcode)
// ARIA-style booleans? (seen in egN_dynamic=1 for example) // ARIA-style booleans? (seen in egN_dynamic=1 for example)
// TODO check this // TODO check this
const OpcodeSpec<int64_t> fullInt64 { 0, Range<int64_t>::wholeRange(), 0 }; const OpcodeSpec<int64_t> fullInt64 { 0, Range<int64_t>::wholeRange(), 0 };
if (auto value = opcode.read(fullInt64)) return opcode.read(fullInt64);
return *value != 0;
return absl::nullopt;
} }
template <> template <>
absl::optional<OscillatorEnabled> Opcode::read(OpcodeSpec<OscillatorEnabled>) const OscillatorEnabled Opcode::read(OpcodeSpec<OscillatorEnabled> spec) const
{ {
auto v = readBooleanFromOpcode(*this); auto v = readBooleanFromOpcode(*this);
if (!v) if (!v)
return absl::nullopt; return spec.defaultValue;
return *v ? OscillatorEnabled::On : OscillatorEnabled::Off; return *v ? OscillatorEnabled::On : OscillatorEnabled::Off;
} }
template <> template <>
absl::optional<Trigger> Opcode::read(OpcodeSpec<Trigger>) const Trigger Opcode::read(OpcodeSpec<Trigger> spec) const
{ {
switch (hash(value)) { switch (hash(value)) {
case hash("attack"): return Trigger::attack; case hash("attack"): return Trigger::attack;
@ -316,11 +313,11 @@ absl::optional<Trigger> Opcode::read(OpcodeSpec<Trigger>) const
} }
DBG("Unknown trigger value: " << value); DBG("Unknown trigger value: " << value);
return absl::nullopt; return spec.defaultValue;
} }
template <> template <>
absl::optional<CrossfadeCurve> Opcode::read(OpcodeSpec<CrossfadeCurve>) const CrossfadeCurve Opcode::read(OpcodeSpec<CrossfadeCurve> spec) const
{ {
switch (hash(value)) { switch (hash(value)) {
case hash("power"): return CrossfadeCurve::power; case hash("power"): return CrossfadeCurve::power;
@ -328,11 +325,11 @@ absl::optional<CrossfadeCurve> Opcode::read(OpcodeSpec<CrossfadeCurve>) const
} }
DBG("Unknown crossfade power curve: " << value); DBG("Unknown crossfade power curve: " << value);
return absl::nullopt; return spec.defaultValue;
} }
template <> template <>
absl::optional<OffMode> Opcode::read(OpcodeSpec<OffMode>) const OffMode Opcode::read(OpcodeSpec<OffMode> spec) const
{ {
switch (hash(value)) { switch (hash(value)) {
case hash("fast"): return OffMode::fast; case hash("fast"): return OffMode::fast;
@ -341,11 +338,11 @@ absl::optional<OffMode> Opcode::read(OpcodeSpec<OffMode>) const
} }
DBG("Unknown off mode: " << value); DBG("Unknown off mode: " << value);
return absl::nullopt; return spec.defaultValue;
} }
template <> template <>
absl::optional<FilterType> Opcode::read(OpcodeSpec<FilterType>) const FilterType Opcode::read(OpcodeSpec<FilterType> spec) const
{ {
switch (hash(value)) { switch (hash(value)) {
case hash("lpf_1p"): return kFilterLpf1p; case hash("lpf_1p"): return kFilterLpf1p;
@ -374,11 +371,11 @@ absl::optional<FilterType> Opcode::read(OpcodeSpec<FilterType>) const
} }
DBG("Unknown filter type: " << value); DBG("Unknown filter type: " << value);
return kFilterNone; return spec.defaultValue;
} }
template <> template <>
absl::optional<EqType> Opcode::read(OpcodeSpec<EqType>) const EqType Opcode::read(OpcodeSpec<EqType> spec) const
{ {
switch (hash(value)) { switch (hash(value)) {
case hash("peak"): return kEqPeak; case hash("peak"): return kEqPeak;
@ -387,11 +384,11 @@ absl::optional<EqType> Opcode::read(OpcodeSpec<EqType>) const
} }
DBG("Unknown EQ type: " << value); DBG("Unknown EQ type: " << value);
return kEqNone; return spec.defaultValue;
} }
template <> template <>
absl::optional<VelocityOverride> Opcode::read(OpcodeSpec<VelocityOverride>) const VelocityOverride Opcode::read(OpcodeSpec<VelocityOverride> spec) const
{ {
switch (hash(value)) { switch (hash(value)) {
case hash("current"): return VelocityOverride::current; case hash("current"): return VelocityOverride::current;
@ -399,11 +396,11 @@ absl::optional<VelocityOverride> Opcode::read(OpcodeSpec<VelocityOverride>) cons
} }
DBG("Unknown velocity override: " << value); DBG("Unknown velocity override: " << value);
return absl::nullopt; return spec.defaultValue;
} }
template <> template <>
absl::optional<SelfMask> Opcode::read(OpcodeSpec<SelfMask>) const SelfMask Opcode::read(OpcodeSpec<SelfMask> spec) const
{ {
switch (hash(value)) { switch (hash(value)) {
case hash("on"): case hash("on"):
@ -412,13 +409,25 @@ absl::optional<SelfMask> Opcode::read(OpcodeSpec<SelfMask>) const
} }
DBG("Unknown velocity override: " << value); DBG("Unknown velocity override: " << value);
return absl::nullopt; return spec.defaultValue;
} }
template <> template <>
absl::optional<bool> Opcode::read(OpcodeSpec<bool>) const bool Opcode::read(OpcodeSpec<bool> spec) const
{ {
return readBooleanFromOpcode(*this); return readBooleanFromOpcode(*this).value_or(spec.defaultValue);
}
template <>
LFOWave Opcode::read(OpcodeSpec<LFOWave> spec) const
{
const OpcodeSpec<int> intSpec {
static_cast<int>(spec.defaultValue),
Range<int>(static_cast<int>(spec.bounds.getStart()), static_cast<int>(spec.bounds.getEnd())),
0
};
int value = read(intSpec);
return static_cast<LFOWave>(value);
} }
} // namespace sfz } // namespace sfz

View file

@ -102,7 +102,7 @@ struct Opcode {
} }
template <class T> template <class T>
absl::optional<T> read(OpcodeSpec<T> spec) const; T read(OpcodeSpec<T> spec) const;
private: private:
static OpcodeCategory identifyCategory(absl::string_view name); static OpcodeCategory identifyCategory(absl::string_view name);

File diff suppressed because it is too large Load diff

View file

@ -319,44 +319,44 @@ struct Region {
// Sound source: sample playback // Sound source: sample playback
std::shared_ptr<FileId> sampleId { new FileId }; // Sample std::shared_ptr<FileId> sampleId { new FileId }; // Sample
absl::optional<int> sampleQuality {}; absl::optional<int> sampleQuality {};
float delay { Default::delay.value }; // delay float delay { Default::delay }; // delay
float delayRandom { Default::delayRandom.value }; // delay_random float delayRandom { Default::delayRandom }; // delay_random
int64_t offset { Default::offset.value }; // offset int64_t offset { Default::offset }; // offset
int64_t offsetRandom { Default::offsetRandom.value }; // offset_random int64_t offsetRandom { Default::offsetRandom }; // offset_random
CCMap<int64_t> offsetCC { Default::offsetMod.value }; CCMap<int64_t> offsetCC { Default::offsetMod };
uint32_t sampleEnd { Default::sampleEnd.value }; // end uint32_t sampleEnd { Default::sampleEnd }; // end
absl::optional<uint32_t> sampleCount {}; // count uint32_t sampleCount { Default::sampleCount }; // count
absl::optional<LoopMode> loopMode {}; // loopmode absl::optional<LoopMode> loopMode {}; // loopmode
Range<uint32_t> loopRange { Default::loopRange.bounds }; //loopstart and loopend Range<uint32_t> loopRange { Default::loopStart, Default::loopEnd }; //loopstart and loopend
float loopCrossfade { Default::loopCrossfade.value }; // loop_crossfade float loopCrossfade { Default::loopCrossfade }; // loop_crossfade
// Wavetable oscillator // Wavetable oscillator
float oscillatorPhase { Default::oscillatorPhase.value }; float oscillatorPhase { Default::oscillatorPhase };
OscillatorEnabled oscillatorEnabled { Default::oscillator.value }; // oscillator OscillatorEnabled oscillatorEnabled { Default::oscillator }; // oscillator
bool hasWavetableSample { false }; // (set according to sample file) bool hasWavetableSample { false }; // (set according to sample file)
int oscillatorMode { Default::oscillatorMode.value }; int oscillatorMode { Default::oscillatorMode };
int oscillatorMulti { Default::oscillatorMulti.value }; int oscillatorMulti { Default::oscillatorMulti };
float oscillatorDetune { Default::oscillatorDetune.value }; float oscillatorDetune { Default::oscillatorDetune };
float oscillatorModDepth { Default::oscillatorModDepth.value }; float oscillatorModDepth { Default::oscillatorModDepth };
absl::optional<int> oscillatorQuality; absl::optional<int> oscillatorQuality;
// Instrument settings: voice lifecycle // Instrument settings: voice lifecycle
uint32_t group { Default::group.value }; // group uint32_t group { Default::group }; // group
absl::optional<uint32_t> offBy {}; // off_by absl::optional<uint32_t> offBy {}; // off_by
OffMode offMode { Default::offMode.value }; // off_mode OffMode offMode { Default::offMode }; // off_mode
float offTime { Default::offTime.value }; // off_mode float offTime { Default::offTime }; // off_mode
absl::optional<uint32_t> notePolyphony {}; // note_polyphony absl::optional<uint32_t> notePolyphony {}; // note_polyphony
uint32_t polyphony { config::maxVoices }; // polyphony uint32_t polyphony { config::maxVoices }; // polyphony
SelfMask selfMask { Default::selfMask.value }; SelfMask selfMask { Default::selfMask };
bool rtDead { Default::rtDead.value }; bool rtDead { Default::rtDead };
// Region logic: key mapping // Region logic: key mapping
Range<uint8_t> keyRange { Default::key.bounds }; //lokey, hikey and key Range<uint8_t> keyRange { Default::loKey, Default::hiKey }; //lokey, hikey and key
Range<float> velocityRange { Default::normalized.bounds }; // hivel and lovel Range<float> velocityRange { Default::loVel, Default::hiVel }; // hivel and lovel
// Region logic: MIDI conditions // Region logic: MIDI conditions
Range<float> bendRange { Default::bipolar.bounds }; // hibend and lobend Range<float> bendRange { Default::loBend, Default::hiBend }; // hibend and lobend
CCMap<Range<float>> ccConditions { Default::normalized.bounds }; CCMap<Range<float>> ccConditions {{ Default::loCC, Default::hiCC }};
absl::optional<uint8_t> lastKeyswitch {}; // sw_last absl::optional<uint8_t> lastKeyswitch {}; // sw_last
absl::optional<Range<uint8_t>> lastKeyswitchRange {}; // sw_last absl::optional<Range<uint8_t>> lastKeyswitchRange {}; // sw_last
absl::optional<std::string> keyswitchLabel {}; absl::optional<std::string> keyswitchLabel {};
@ -364,45 +364,45 @@ struct Region {
absl::optional<uint8_t> downKeyswitch {}; // sw_down absl::optional<uint8_t> downKeyswitch {}; // sw_down
absl::optional<uint8_t> previousKeyswitch {}; // sw_previous absl::optional<uint8_t> previousKeyswitch {}; // sw_previous
absl::optional<uint8_t> defaultSwitch {}; absl::optional<uint8_t> defaultSwitch {};
VelocityOverride velocityOverride { Default::velocityOverride.value }; // sw_vel VelocityOverride velocityOverride { Default::velocityOverride }; // sw_vel
bool checkSustain { Default::checkSustain.value }; // sustain_sw bool checkSustain { Default::checkSustain }; // sustain_sw
bool checkSostenuto { Default::checkSostenuto.value }; // sostenuto_sw bool checkSostenuto { Default::checkSostenuto }; // sostenuto_sw
uint16_t sustainCC { Default::sustainCC.value }; // sustain_cc uint16_t sustainCC { Default::sustainCC }; // sustain_cc
float sustainThreshold { Default::sustainThreshold.value }; // sustain_cc float sustainThreshold { Default::sustainThreshold }; // sustain_cc
// Region logic: internal conditions // Region logic: internal conditions
Range<uint8_t> aftertouchRange { Default::midi7.bounds }; // hichanaft and lochanaft Range<uint8_t> aftertouchRange { Default::loChannelAftertouch, Default::hiChannelAftertouch }; // hichanaft and lochanaft
Range<float> bpmRange { Default::bpm.bounds }; // hibpm and lobpm Range<float> bpmRange { Default::loBPM, Default::hiBPM }; // hibpm and lobpm
Range<float> randRange { Default::normalized.bounds }; // hirand and lorand Range<float> randRange { Default::loNormalized, Default::hiNormalized }; // hirand and lorand
uint8_t sequenceLength { Default::sequence.value }; // seq_length uint8_t sequenceLength { Default::sequence }; // seq_length
uint8_t sequencePosition { Default::sequence.value }; // seq_position uint8_t sequencePosition { Default::sequence }; // seq_position
// Region logic: triggers // Region logic: triggers
Trigger trigger { Default::trigger.value }; // trigger Trigger trigger { Default::trigger }; // trigger
CCMap<Range<float>> ccTriggers { Default::normalized.bounds }; // on_loccN on_hiccN CCMap<Range<float>> ccTriggers {{ Default::loCC, Default::hiCC }}; // on_loccN on_hiccN
// Performance parameters: amplifier // Performance parameters: amplifier
float volume { Default::volume.value }; // volume float volume { Default::volume }; // volume
float amplitude { normalizePercents(Default::amplitude.value) }; // amplitude float amplitude { normalizePercents(Default::amplitude) }; // amplitude
float pan { normalizePercents(Default::pan.value) }; // pan float pan { normalizePercents(Default::pan) }; // pan
float width { normalizePercents(Default::width.value) }; // width float width { normalizePercents(Default::width) }; // width
float position { normalizePercents(Default::position.value) }; // position float position { normalizePercents(Default::position) }; // position
uint8_t ampKeycenter { Default::key.value }; // amp_keycenter uint8_t ampKeycenter { Default::key }; // amp_keycenter
float ampKeytrack { Default::ampKeytrack.value }; // amp_keytrack float ampKeytrack { Default::ampKeytrack }; // amp_keytrack
float ampVeltrack { normalizePercents(Default::ampVeltrack.value) }; // amp_veltrack float ampVeltrack { normalizePercents(Default::ampVeltrack) }; // amp_veltrack
std::vector<std::pair<uint8_t, float>> velocityPoints; // amp_velcurve_N std::vector<std::pair<uint8_t, float>> velocityPoints; // amp_velcurve_N
absl::optional<Curve> velCurve {}; absl::optional<Curve> velCurve {};
float ampRandom { Default::ampRandom.value }; // amp_random float ampRandom { Default::ampRandom }; // amp_random
Range<uint8_t> crossfadeKeyInRange { Default::crossfadeKeyInRange }; Range<uint8_t> crossfadeKeyInRange { Default::crossfadeKeyInRange };
Range<uint8_t> crossfadeKeyOutRange { Default::crossfadeKeyOutRange }; Range<uint8_t> crossfadeKeyOutRange { Default::crossfadeKeyOutRange };
Range<float> crossfadeVelInRange { Default::crossfadeVelInRange }; Range<float> crossfadeVelInRange { Default::crossfadeVelInRange };
Range<float> crossfadeVelOutRange { Default::crossfadeVelOutRange }; Range<float> crossfadeVelOutRange { Default::crossfadeVelOutRange };
CrossfadeCurve crossfadeKeyCurve { Default::crossfadeCurve.value }; CrossfadeCurve crossfadeKeyCurve { Default::crossfadeCurve };
CrossfadeCurve crossfadeVelCurve { Default::crossfadeCurve.value }; CrossfadeCurve crossfadeVelCurve { Default::crossfadeCurve };
CrossfadeCurve crossfadeCCCurve { Default::crossfadeCurve.value }; CrossfadeCurve crossfadeCCCurve { Default::crossfadeCurve };
CCMap<Range<float>> crossfadeCCInRange { Default::crossfadeCCInRange }; // xfin_loccN xfin_hiccN CCMap<Range<float>> crossfadeCCInRange { Default::crossfadeCCInRange }; // xfin_loccN xfin_hiccN
CCMap<Range<float>> crossfadeCCOutRange { Default::crossfadeCCOutRange }; // xfout_loccN xfout_hiccN CCMap<Range<float>> 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 globalAmplitude { 1.0 }; // global_amplitude
float masterAmplitude { 1.0 }; // master_amplitude float masterAmplitude { 1.0 }; // master_amplitude
@ -416,17 +416,17 @@ struct Region {
std::vector<FilterDescription> filters; std::vector<FilterDescription> filters;
// Performance parameters: pitch // Performance parameters: pitch
uint8_t pitchKeycenter { Default::key.value }; // pitch_keycenter uint8_t pitchKeycenter { Default::key }; // pitch_keycenter
bool pitchKeycenterFromSample { false }; bool pitchKeycenterFromSample { false };
int pitchKeytrack { Default::pitchKeytrack.value }; // pitch_keytrack int pitchKeytrack { Default::pitchKeytrack }; // pitch_keytrack
float pitchRandom { Default::pitchRandom.value }; // pitch_random float pitchRandom { Default::pitchRandom }; // pitch_random
int pitchVeltrack { Default::pitchVeltrack.value }; // pitch_veltrack int pitchVeltrack { Default::pitchVeltrack }; // pitch_veltrack
int transpose { Default::transpose.value }; // transpose int transpose { Default::transpose }; // transpose
float pitch { Default::pitch.value }; // tune float pitch { Default::pitch }; // tune
float bendUp { Default::bendUp.value }; float bendUp { Default::bendUp };
float bendDown { Default::bendDown.value }; float bendDown { Default::bendDown };
float bendStep { Default::bendStep.value }; float bendStep { Default::bendStep };
uint8_t bendSmooth { Default::smoothCC.value }; uint8_t bendSmooth { Default::smoothCC };
// Envelopes // Envelopes
EGDescription amplitudeEG; EGDescription amplitudeEG;

View file

@ -191,7 +191,7 @@ void Synth::Impl::buildRegion(const std::vector<Opcode>& regionOpcodes)
currentSwitch_ = *lastRegion->defaultSwitch; currentSwitch_ = *lastRegion->defaultSwitch;
// There was a combination of group= and polyphony= on a region, so set the group polyphony // 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); voiceManager_.setGroupPolyphony(lastRegion->group, lastRegion->polyphony);
} else { } else {
// Just check that there are enough polyphony groups // Just check that there are enough polyphony groups
@ -276,12 +276,10 @@ void Synth::Impl::handleMasterOpcodes(const std::vector<Opcode>& members)
switch (member.lettersOnlyHash) { switch (member.lettersOnlyHash) {
case hash("polyphony"): case hash("polyphony"):
ASSERT(currentSet_ != nullptr); ASSERT(currentSet_ != nullptr);
if (auto value = member.read(Default::polyphony)) currentSet_->setPolyphonyLimit(member.read(Default::polyphony));
currentSet_->setPolyphonyLimit(*value);
break; break;
case hash("sw_default"): case hash("sw_default"):
if (auto value = member.read(Default::key)) currentSwitch_ = member.read(Default::key);
currentSwitch_ = *value;
break; break;
} }
} }
@ -295,12 +293,10 @@ void Synth::Impl::handleGlobalOpcodes(const std::vector<Opcode>& members)
switch (member.lettersOnlyHash) { switch (member.lettersOnlyHash) {
case hash("polyphony"): case hash("polyphony"):
ASSERT(currentSet_ != nullptr); ASSERT(currentSet_ != nullptr);
if (auto value = member.read(Default::polyphony)) currentSet_->setPolyphonyLimit(member.read(Default::polyphony));
currentSet_->setPolyphonyLimit(*value);
break; break;
case hash("sw_default"): case hash("sw_default"):
if (auto value = member.read(Default::key)) currentSwitch_ = member.read(Default::key);
currentSwitch_ = *value;
break; break;
case hash("volume"): case hash("volume"):
// FIXME : Probably best not to mess with this and let the host control the 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<Opcode>& members, const s
switch (member.lettersOnlyHash) { switch (member.lettersOnlyHash) {
case hash("group"): case hash("group"):
if (auto value = member.read(Default::group)) groupIdx = member.read(Default::group);
groupIdx = *value;
break; break;
case hash("polyphony"): case hash("polyphony"):
if (auto value = member.read(Default::polyphony)) maxPolyphony = member.read(Default::polyphony);
maxPolyphony = *value;
break; break;
case hash("sw_default"): case hash("sw_default"):
if (auto value = member.read(Default::key)) currentSwitch_ = member.read(Default::key);
currentSwitch_ = *value;
break; break;
} }
}; };
@ -358,16 +351,12 @@ void Synth::Impl::handleControlOpcodes(const std::vector<Opcode>& members)
switch (member.lettersOnlyHash) { switch (member.lettersOnlyHash) {
case hash("set_cc&"): case hash("set_cc&"):
if (Default::ccNumber.bounds.containsWithEnd(member.parameters.back())) { if (Default::ccNumber.bounds.containsWithEnd(member.parameters.back())) {
const auto ccValue = member.read(Default::midi7); setDefaultHdcc(member.parameters.back(), member.read(Default::loCC));
if (ccValue)
setDefaultHdcc(member.parameters.back(), normalizeCC(*ccValue));
} }
break; break;
case hash("set_hdcc&"): case hash("set_hdcc&"):
if (Default::ccNumber.bounds.containsWithEnd(member.parameters.back())) { if (Default::ccNumber.bounds.containsWithEnd(member.parameters.back())) {
const auto ccValue = member.read(Default::normalized); setDefaultHdcc(member.parameters.back(), member.read(Default::loNormalized));
if (ccValue)
setDefaultHdcc(member.parameters.back(), *ccValue);
} }
break; break;
case hash("label_cc&"): case hash("label_cc&"):
@ -385,10 +374,10 @@ void Synth::Impl::handleControlOpcodes(const std::vector<Opcode>& members)
DBG("Changing default sample path to " << defaultPath_); DBG("Changing default sample path to " << defaultPath_);
break; break;
case hash("note_offset"): case hash("note_offset"):
noteOffset_ = member.read(Default::noteOffset).value_or(noteOffset_); noteOffset_ = member.read(Default::noteOffset);
break; break;
case hash("octave_offset"): case hash("octave_offset"):
octaveOffset_ = member.read(Default::octaveOffset).value_or(octaveOffset_); octaveOffset_ = member.read(Default::octaveOffset);
break; break;
case hash("hint_ram_based"): case hash("hint_ram_based"):
if (member.value == "1") if (member.value == "1")
@ -451,22 +440,19 @@ void Synth::Impl::handleEffectOpcodes(const std::vector<Opcode>& rawMembers)
// note(jpc): gain opcodes are linear volumes in % units // note(jpc): gain opcodes are linear volumes in % units
case hash("directtomain"): case hash("directtomain"):
if (auto valueOpt = opcode.read(Default::effect)) getOrCreateBus(0).setGainToMain(opcode.read(Default::effect));
getOrCreateBus(0).setGainToMain(*valueOpt / 100);
break; break;
case hash("fx&tomain"): // fx&tomain case hash("fx&tomain"): // fx&tomain
if (opcode.parameters.front() < 1 || opcode.parameters.front() > config::maxEffectBuses) if (opcode.parameters.front() < 1 || opcode.parameters.front() > config::maxEffectBuses)
break; break;
if (auto valueOpt = opcode.read(Default::effect)) getOrCreateBus(opcode.parameters.front()).setGainToMain(opcode.read(Default::effect));
getOrCreateBus(opcode.parameters.front()).setGainToMain(*valueOpt / 100);
break; break;
case hash("fx&tomix"): // fx&tomix case hash("fx&tomix"): // fx&tomix
if (opcode.parameters.front() < 1 || opcode.parameters.front() > config::maxEffectBuses) if (opcode.parameters.front() < 1 || opcode.parameters.front() > config::maxEffectBuses)
break; break;
if (auto valueOpt = opcode.read(Default::effect)) getOrCreateBus(opcode.parameters.front()).setGainToMix(opcode.read(Default::effect));
getOrCreateBus(opcode.parameters.front()).setGainToMix(*valueOpt / 100);
break; break;
} }
} }
@ -589,10 +575,10 @@ void Synth::Impl::finalizeSfzLoad()
region->sampleEnd = std::min(region->sampleEnd, fileInformation->end); region->sampleEnd = std::min(region->sampleEnd, fileInformation->end);
if (fileInformation->hasLoop) { if (fileInformation->hasLoop) {
if (region->loopRange.getStart() == Default::loopRange.bounds.getStart()) if (region->loopRange.getStart() == Default::loopStart)
region->loopRange.setStart(fileInformation->loopBegin); region->loopRange.setStart(fileInformation->loopStart);
if (region->loopRange.getEnd() == Default::loopRange.bounds.getEnd()) if (region->loopRange.getEnd() == Default::loopEnd)
region->loopRange.setEnd(fileInformation->loopEnd); region->loopRange.setEnd(fileInformation->loopEnd);
if (!region->loopMode) if (!region->loopMode)
@ -602,7 +588,7 @@ void Synth::Impl::finalizeSfzLoad()
if (region->isRelease() && !region->loopMode) if (region->isRelease() && !region->loopMode)
region->loopMode = LoopMode::one_shot; region->loopMode = LoopMode::one_shot;
if (region->loopRange.getEnd() == Default::loopRange.bounds.getEnd()) if (region->loopRange.getEnd() == Default::loopEnd)
region->loopRange.setEnd(region->sampleEnd); region->loopRange.setEnd(region->sampleEnd);
if (fileInformation->numChannels == 2) if (fileInformation->numChannels == 2)
@ -668,13 +654,13 @@ void Synth::Impl::finalizeSfzLoad()
// Set the default frequencies on equalizers if needed // Set the default frequencies on equalizers if needed
if (region->equalizers.size() > 0 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]; region->equalizers[0].frequency = Default::defaultEQFreq[0];
if (region->equalizers.size() > 1 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]; region->equalizers[1].frequency = Default::defaultEQFreq[1];
if (region->equalizers.size() > 2 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]; region->equalizers[2].frequency = Default::defaultEQFreq[2];
} }
} }

View file

@ -13,7 +13,7 @@ struct SynthConfig
{ {
bool freeWheeling { false }; bool freeWheeling { false };
int liveSampleQuality { Default::sampleQuality.value }; int liveSampleQuality { Default::sampleQuality };
int freeWheelingSampleQuality { Default::freewheelingQuality }; int freeWheelingSampleQuality { Default::freewheelingQuality };
int currentSampleQuality() const noexcept int currentSampleQuality() const noexcept

View file

@ -144,11 +144,7 @@ void sfz::Synth::dispatchMessage(Client& client, int delay, const char* path, co
MATCH("/region&/count", "") { MATCH("/region&/count", "") {
GET_REGION_OR_BREAK(indices[0]) GET_REGION_OR_BREAK(indices[0])
if (!region.sampleCount) { client.receive<'h'>(delay, path, region.sampleCount);
client.receive<'N'>(delay, path, {});
} else {
client.receive<'h'>(delay, path, *region.sampleCount);
}
} break; } break;
MATCH("/region&/loop_range", "") { MATCH("/region&/loop_range", "") {

View file

@ -257,8 +257,8 @@ struct Synth::Impl final: public Parser::Listener {
// Control opcodes // Control opcodes
std::string defaultPath_ { "" }; std::string defaultPath_ { "" };
int noteOffset_ { Default::noteOffset.value }; int noteOffset_ { Default::noteOffset };
int octaveOffset_ { Default::octaveOffset.value }; int octaveOffset_ { Default::octaveOffset };
// Modulation source generators // Modulation source generators
std::unique_ptr<ControllerSource> genController_; std::unique_ptr<ControllerSource> genController_;

View file

@ -371,7 +371,7 @@ void Voice::startVoice(Region* region, int delay, const TriggerEvent& event) noe
} }
const float phase = region->getPhase(); const float phase = region->getPhase();
const int quality = const int quality =
region->oscillatorQuality.value_or(Default::oscillatorQuality.value); region->oscillatorQuality.value_or(Default::oscillatorQuality);
for (WavetableOscillator& osc : impl.waveOscillators_) { for (WavetableOscillator& osc : impl.waveOscillators_) {
osc.setWavetable(wave); osc.setWavetable(wave);
osc.setPhase(phase); osc.setPhase(phase);
@ -465,7 +465,7 @@ void Voice::off(int delay, bool fast) noexcept
Impl& impl = *impl_; Impl& impl = *impl_;
if (!impl.region_->flexAmpEG) { if (!impl.region_->flexAmpEG) {
if (impl.region_->offMode == OffMode::fast || fast) { 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) { } else if (impl.region_->offMode == OffMode::time) {
impl.egAmplitude_.setReleaseTime(impl.region_->offTime); impl.egAmplitude_.setReleaseTime(impl.region_->offTime);
} }

View file

@ -81,28 +81,22 @@ namespace fx {
for (const Opcode& opc : members) { for (const Opcode& opc : members) {
switch (opc.lettersOnlyHash) { switch (opc.lettersOnlyHash) {
case hash("apan_waveform"): case hash("apan_waveform"):
if (auto value = opc.read(Default::apanWaveform)) apan->_lfoWave = opc.read(Default::apanWaveform);
apan->_lfoWave = *value;
break; break;
case hash("apan_freq"): case hash("apan_freq"):
if (auto value = opc.read(Default::apanFrequency)) apan->_lfoFrequency = opc.read(Default::apanFrequency);
apan->_lfoFrequency = *value;
break; break;
case hash("apan_phase"): case hash("apan_phase"):
if (auto value = opc.read(Default::apanPhase)) apan->_lfoPhaseOffset = opc.read(Default::apanPhase);
apan->_lfoPhaseOffset = wrapPhase(*value);
break; break;
case hash("apan_dry"): case hash("apan_dry"):
if (auto value = opc.read(Default::apanLevel)) apan->_dry = opc.read(Default::apanLevel);
apan->_dry = *value / 100.0f;
break; break;
case hash("apan_wet"): case hash("apan_wet"):
if (auto value = opc.read(Default::apanLevel)) apan->_wet = opc.read(Default::apanLevel);
apan->_wet = *value / 100.0f;
break; break;
case hash("apan_depth"): case hash("apan_depth"):
if (auto value = opc.read(Default::apanLevel)) apan->_depth = opc.read(Default::apanLevel);
apan->_depth = *value / 100.0f;
break; break;
} }
} }

View file

@ -52,12 +52,12 @@ namespace fx {
sfz::Buffer<float> _lfoOutRight { config::defaultSamplesPerBlock }; sfz::Buffer<float> _lfoOutRight { config::defaultSamplesPerBlock };
// Controls // Controls
float _dry { Default::apanLevel.value }; float _dry { Default::apanLevel };
float _wet { Default::apanLevel.value }; float _wet { Default::apanLevel };
float _depth { Default::apanLevel.value }; float _depth { Default::apanLevel };
int _lfoWave { Default::apanWaveform.value }; int _lfoWave { Default::apanWaveform };
float _lfoFrequency { Default::apanFrequency.value }; float _lfoFrequency { Default::apanFrequency };
float _lfoPhaseOffset { Default::apanPhase.value }; float _lfoPhaseOffset { Default::apanPhase };
// State // State
float _lfoPhase { 0.0f }; float _lfoPhase { 0.0f };

View file

@ -31,8 +31,8 @@ namespace fx {
struct Compressor::Impl { struct Compressor::Impl {
faustCompressor _compressor[2]; faustCompressor _compressor[2];
bool _stlink { Default::compSTLink.value }; bool _stlink { Default::compSTLink };
float _inputGain { Default::compGain.value }; float _inputGain { Default::compGain };
AudioBuffer<float, 2> _tempBuffer2x { 2, _oversampling * config::defaultSamplesPerBlock }; AudioBuffer<float, 2> _tempBuffer2x { 2, _oversampling * config::defaultSamplesPerBlock };
AudioBuffer<float, 2> _gain2x { 2, _oversampling * config::defaultSamplesPerBlock }; AudioBuffer<float, 2> _gain2x { 2, _oversampling * config::defaultSamplesPerBlock };
hiir::Downsampler2xFpu<12> _downsampler2x[EffectChannels]; hiir::Downsampler2xFpu<12> _downsampler2x[EffectChannels];
@ -163,35 +163,38 @@ namespace fx {
for (const Opcode& opc : members) { for (const Opcode& opc : members) {
switch (opc.lettersOnlyHash) { switch (opc.lettersOnlyHash) {
case hash("comp_attack"): 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) for (size_t c = 0; c < 2; ++c)
impl.set_Attack(c, *value); impl.set_Attack(c, value);
} }
break; break;
case hash("comp_release"): 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) for (size_t c = 0; c < 2; ++c)
impl.set_Release(c, *value); impl.set_Release(c, value);
} }
break; break;
case hash("comp_threshold"): 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) for (size_t c = 0; c < 2; ++c)
impl.set_Threshold(c, *value); impl.set_Threshold(c, value);
} }
break; break;
case hash("comp_ratio"): 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) for (size_t c = 0; c < 2; ++c)
impl.set_Ratio(c, *value); impl.set_Ratio(c, value);
} }
break; break;
case hash("comp_gain"): case hash("comp_gain"):
if (auto value = opc.read(Default::compGain)) impl._inputGain = opc.read(Default::compGain);
impl._inputGain = db2mag(*value);
break; break;
case hash("comp_stlink"): case hash("comp_stlink"):
impl._stlink = opc.read(Default::compSTLink).value_or(impl._stlink); impl._stlink = opc.read(Default::compSTLink);
break; break;
} }
} }

View file

@ -38,11 +38,11 @@ struct Disto::Impl {
enum { maxStages = 4 }; enum { maxStages = 4 };
float _samplePeriod { 1.0f / config::defaultSampleRate }; float _samplePeriod { 1.0f / config::defaultSampleRate };
float _tone { Default::distoTone.value }; float _tone { Default::distoTone };
float _depth { Default::distoDepth.value }; float _depth { Default::distoDepth };
float _dry { Default::effect.value }; float _dry { Default::effect };
float _wet { Default::effect.value }; float _wet { Default::effect };
unsigned _numStages = { Default::distoStages.value }; unsigned _numStages = { Default::distoStages };
float _toneLpfMem[EffectChannels] = {}; float _toneLpfMem[EffectChannels] = {};
faustDisto _stages[EffectChannels][Default::maxDistoStages]; faustDisto _stages[EffectChannels][Default::maxDistoStages];
@ -205,24 +205,19 @@ std::unique_ptr<Effect> Disto::makeInstance(absl::Span<const Opcode> members)
for (const Opcode& opc : members) { for (const Opcode& opc : members) {
switch (opc.lettersOnlyHash) { switch (opc.lettersOnlyHash) {
case hash("disto_tone"): case hash("disto_tone"):
if (auto value = opc.read(Default::distoTone)) impl._tone = opc.read(Default::distoTone);
impl._tone = *value;
break; break;
case hash("disto_depth"): case hash("disto_depth"):
if (auto value = opc.read(Default::distoDepth)) impl._depth = opc.read(Default::distoDepth);
impl._depth = *value;
break; break;
case hash("disto_stages"): case hash("disto_stages"):
if (auto value = opc.read(Default::distoStages)) impl._numStages = opc.read(Default::distoStages);
impl._numStages = *value;
break; break;
case hash("disto_dry"): case hash("disto_dry"):
if (auto value = opc.read(Default::effect)) impl._dry = opc.read(Default::effect);
impl._dry = *value * 0.01f;
break; break;
case hash("disto_wet"): case hash("disto_wet"):
if (auto value = opc.read(Default::effect)) impl._wet = opc.read(Default::effect);
impl._wet = *value * 0.01f;
break; break;
} }
} }

View file

@ -70,22 +70,17 @@ namespace fx {
for (const Opcode& opc : members) { for (const Opcode& opc : members) {
switch (opc.lettersOnlyHash) { switch (opc.lettersOnlyHash) {
case hash("eq_freq"): case hash("eq_freq"):
if (auto value = opc.read(Default::eqFrequency)) desc.frequency = opc.read(Default::eqFrequency);
desc.frequency = *value;
break; break;
case hash("eq_bw"): case hash("eq_bw"):
if (auto value = opc.read(Default::eqBandwidth)) desc.bandwidth = opc.read(Default::eqBandwidth);
desc.bandwidth = *value;
break; break;
case hash("eq_gain"): case hash("eq_gain"):
if (auto value = opc.read(Default::eqGain)) desc.gain = opc.read(Default::eqGain);
desc.gain = *value;
break; break;
case hash("eq_type"): case hash("eq_type"):
{ desc.type = opc.read(Default::eq);
desc.type = opc.read(Default::eq).value_or(desc.type); break;
break;
}
} }
} }

View file

@ -72,22 +72,17 @@ namespace fx {
for (const Opcode& opc : members) { for (const Opcode& opc : members) {
switch (opc.lettersOnlyHash) { switch (opc.lettersOnlyHash) {
case hash("filter_cutoff"): case hash("filter_cutoff"):
if (auto value = opc.read(Default::filterCutoff)) desc.cutoff = opc.read(Default::filterCutoff);
desc.cutoff = *value;
break; break;
case hash("filter_resonance"): case hash("filter_resonance"):
if (auto value = opc.read(Default::filterResonance)) desc.resonance = opc.read(Default::filterResonance);
desc.resonance = *value;
break; break;
case hash("filter_type"): case hash("filter_type"):
{ desc.type = opc.read(Default::filter);
desc.type = opc.read(Default::filter).value_or(desc.type); break;
break;
}
// extension // extension
case hash("sfizz:filter_gain"): case hash("sfizz:filter_gain"):
if (auto value = opc.read(Default::filterGain)) desc.gain = opc.read(Default::filterGain);
desc.gain = *value;
break; break;
} }
} }

View file

@ -180,13 +180,13 @@ namespace fx {
std::unique_ptr<Effect> fx { reverb }; std::unique_ptr<Effect> fx { reverb };
const Impl::Profile* profile = &Impl::largeHall; const Impl::Profile* profile = &Impl::largeHall;
float dry { Default::effect.value }; float dry { Default::effect };
float wet { Default::effect.value }; float wet { Default::effect };
float input { Default::effect.value }; float input { Default::effect };
float size { Default::fverbSize.value }; float size { Default::fverbSize };
float predelay { Default::fverbPredelay.value }; float predelay { Default::fverbPredelay };
float tone { Default::fverbTone.value }; float tone { Default::fverbTone };
float damp { Default::fverbDamp.value }; float damp { Default::fverbDamp };
for (const Opcode& opc : members) { for (const Opcode& opc : members) {
switch (opc.lettersOnlyHash) { switch (opc.lettersOnlyHash) {
@ -212,25 +212,25 @@ namespace fx {
break; break;
case hash("reverb_dry"): case hash("reverb_dry"):
dry = opc.read(Default::effect).value_or(dry); dry = opc.read(Default::effect);
break; break;
case hash("reverb_wet"): case hash("reverb_wet"):
wet = opc.read(Default::effect).value_or(wet); wet = opc.read(Default::effect);
break; break;
case hash("reverb_input"): case hash("reverb_input"):
input = opc.read(Default::effect).value_or(input); input = opc.read(Default::effect);
break; break;
case hash("reverb_size"): case hash("reverb_size"):
size = opc.read(Default::fverbSize).value_or(size); size = opc.read(Default::fverbSize);
break; break;
case hash("reverb_predelay"): case hash("reverb_predelay"):
predelay = opc.read(Default::fverbPredelay).value_or(predelay); predelay = opc.read(Default::fverbPredelay);
break; break;
case hash("reverb_tone"): case hash("reverb_tone"):
tone = opc.read(Default::fverbTone).value_or(tone); tone = opc.read(Default::fverbTone);
break; break;
case hash("reverb_damp"): case hash("reverb_damp"):
damp = opc.read(Default::fverbDamp).value_or(damp); damp = opc.read(Default::fverbDamp);
break; break;
} }
} }

View file

@ -62,8 +62,7 @@ namespace fx {
for (const Opcode& opc : members) { for (const Opcode& opc : members) {
switch (opc.lettersOnlyHash) { switch (opc.lettersOnlyHash) {
case hash("gain"): case hash("gain"):
if (auto value = opc.read(Default::volume)) gain->_gain = opc.read(Default::volume);
gain->_gain = *value;
break; break;
} }
} }

View file

@ -34,7 +34,7 @@ namespace fx {
struct Gate::Impl { struct Gate::Impl {
faustGate _gate[2]; faustGate _gate[2];
bool _stlink { Default::gateSTLink.value }; bool _stlink { Default::gateSTLink };
float _inputGain = 1.0; float _inputGain = 1.0;
AudioBuffer<float, 2> _tempBuffer2x { 2, _oversampling * config::defaultSamplesPerBlock }; AudioBuffer<float, 2> _tempBuffer2x { 2, _oversampling * config::defaultSamplesPerBlock };
AudioBuffer<float, 2> _gain2x { 2, _oversampling * config::defaultSamplesPerBlock }; AudioBuffer<float, 2> _gain2x { 2, _oversampling * config::defaultSamplesPerBlock };
@ -166,31 +166,35 @@ namespace fx {
for (const Opcode& opc : members) { for (const Opcode& opc : members) {
switch (opc.lettersOnlyHash) { switch (opc.lettersOnlyHash) {
case hash("gate_attack"): 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) for (size_t c = 0; c < 2; ++c)
impl.set_Attack(c, *value); impl.set_Attack(c, value);
} }
break; break;
case hash("gate_hold"): 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) for (size_t c = 0; c < 2; ++c)
impl.set_Hold(c, *value); impl.set_Hold(c, value);
} }
break; break;
case hash("gate_release"): 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) for (size_t c = 0; c < 2; ++c)
impl.set_Release(c, *value); impl.set_Release(c, value);
} }
break; break;
case hash("gate_threshold"): 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) for (size_t c = 0; c < 2; ++c)
impl.set_Threshold(c, *value); impl.set_Threshold(c, value);
} }
break; break;
case hash("gate_stlink"): case hash("gate_stlink"):
impl._stlink = opc.read(Default::gateSTLink).value_or(impl._stlink); impl._stlink = opc.read(Default::gateSTLink);
} }
} }

View file

@ -85,12 +85,10 @@ namespace fx {
for (const Opcode& opcode : members) { for (const Opcode& opcode : members) {
switch (opcode.lettersOnlyHash) { switch (opcode.lettersOnlyHash) {
case hash("bitred"): case hash("bitred"):
if (auto value = opcode.read(Default::lofiBitred)) lofi->_bitred_depth = opcode.read(Default::lofiBitred);
lofi->_bitred_depth = *value;
break; break;
case hash("decim"): case hash("decim"):
if (auto value = opcode.read(Default::lofiDecim)) lofi->_decim_depth = opcode.read(Default::lofiDecim);
lofi->_decim_depth = *value;
break; break;
} }
} }

View file

@ -95,8 +95,7 @@ namespace fx {
rectify->_full = false; rectify->_full = false;
break; break;
case hash("rectify"): case hash("rectify"):
if (auto value = opc.read(Default::rectify)) rectify->_amount = opc.read(Default::rectify);
rectify->_amount = *value;
break; break;
} }
} }

View file

@ -132,12 +132,10 @@ namespace fx {
for (const Opcode& opc : members) { for (const Opcode& opc : members) {
switch (opc.lettersOnlyHash) { switch (opc.lettersOnlyHash) {
case hash("strings_number"): case hash("strings_number"):
if (auto value = opc.read(Default::stringsNumber)) strings->_numStrings = opc.read(Default::stringsNumber);
strings->_numStrings = *value;
break; break;
case hash("strings_wet"): case hash("strings_wet"):
if (auto value = opc.read(Default::effect)) strings->_wet = opc.read(Default::effect);
strings->_wet = *value;
break; break;
} }
} }

View file

@ -52,7 +52,7 @@ namespace fx {
enum { MaximumNumStrings = 88 }; enum { MaximumNumStrings = 88 };
unsigned _numStrings { Default::maxStrings }; unsigned _numStrings { Default::maxStrings };
float _wet { Default::effect.value }; float _wet { Default::effect };
std::unique_ptr<ResonantArray> _stringsArray; std::unique_ptr<ResonantArray> _stringsArray;

View file

@ -69,8 +69,7 @@ namespace fx {
for (const Opcode& opc : members) { for (const Opcode& opc : members) {
switch (opc.lettersOnlyHash) { switch (opc.lettersOnlyHash) {
case hash("width"): case hash("width"):
if (auto value = opc.read(Default::width)) width->_width = opc.read(Default::width);
width->_width = *value;
break; break;
} }
} }

View file

@ -317,8 +317,8 @@ TEST_CASE("[Opcode] opcode read (uint8_t)")
SECTION("Ignore") SECTION("Ignore")
{ {
Opcode opcode { "", "110" }; Opcode opcode { "", "110" };
OpcodeSpec<uint8_t> spec { 0, Range<uint8_t>(0, 100), kIgnoreOOB }; OpcodeSpec<uint8_t> spec { 0, Range<uint8_t>(0, 100), 0 };
REQUIRE( !opcode.read(spec) ); REQUIRE( opcode.read(spec) == spec.defaultValue );
} }
SECTION("Clamp upper") SECTION("Clamp upper")
@ -345,21 +345,21 @@ TEST_CASE("[Opcode] opcode read (uint8_t)")
SECTION("Text after") SECTION("Text after")
{ {
Opcode opcode { "", "10garbage" }; Opcode opcode { "", "10garbage" };
OpcodeSpec<uint8_t> spec { 0, Range<uint8_t>(20, 100), kEnforceLowerBound }; OpcodeSpec<uint8_t> spec { 0, Range<uint8_t>(0, 100), 0 };
REQUIRE( opcode.read(spec) == 20 ); REQUIRE( opcode.read(spec) == 10 );
} }
SECTION("Text before") SECTION("Text before")
{ {
Opcode opcode { "", "garbage10" }; Opcode opcode { "", "garbage10" };
OpcodeSpec<uint8_t> spec { 0, Range<uint8_t>(20, 100), 0 }; OpcodeSpec<uint8_t> spec { 0, Range<uint8_t>(0, 100), 0 };
REQUIRE( !opcode.read(spec) ); REQUIRE( opcode.read(spec) == spec.defaultValue );
} }
SECTION("Can be note") SECTION("Can be note")
{ {
Opcode opcode { "", "c4" }; Opcode opcode { "", "c4" };
OpcodeSpec<uint8_t> spec { 0, Range<uint8_t>(20, 100), kCanBeNote }; OpcodeSpec<uint8_t> spec { 0, Range<uint8_t>(0, 100), kCanBeNote };
REQUIRE( opcode.read(spec) == 60 ); REQUIRE( opcode.read(spec) == 60 );
} }
} }
@ -387,13 +387,6 @@ TEST_CASE("[Opcode] opcode read (int)")
REQUIRE( opcode.read(spec) == -16); REQUIRE( opcode.read(spec) == -16);
} }
SECTION("Ignore")
{
Opcode opcode { "", "110" };
OpcodeSpec<int> spec { 0, Range<int>(-100, 100), kIgnoreOOB };
REQUIRE( !opcode.read(spec) );
}
SECTION("Clamp upper") SECTION("Clamp upper")
{ {
Opcode opcode { "", "110" }; Opcode opcode { "", "110" };
@ -418,7 +411,7 @@ TEST_CASE("[Opcode] opcode read (int)")
SECTION("Text after") SECTION("Text after")
{ {
Opcode opcode { "", "10garbage" }; Opcode opcode { "", "10garbage" };
OpcodeSpec<int> spec { 0, Range<int>(20, 100), kEnforceLowerBound }; OpcodeSpec<int> spec { 0, Range<int>(20, 100), 0 };
REQUIRE( opcode.read(spec) == 20 ); REQUIRE( opcode.read(spec) == 20 );
} }
@ -464,8 +457,8 @@ TEST_CASE("[Opcode] opcode read (float)")
SECTION("Ignore") SECTION("Ignore")
{ {
Opcode opcode { "", "110" }; Opcode opcode { "", "110" };
OpcodeSpec<float> spec { 0.0f, Range<float>(-100.0f, 100.0f), kIgnoreOOB }; OpcodeSpec<float> spec { 0.0f, Range<float>(-100.0f, 100.0f), 0 };
REQUIRE( !opcode.read(spec) ); REQUIRE( opcode.read(spec) == spec.defaultValue );
} }
SECTION("Clamp upper") SECTION("Clamp upper")

View file

@ -299,15 +299,15 @@ TEST_CASE("[Region] rt_decay")
region.parseOpcode({ "rt_decay", "10" }); region.parseOpcode({ "rt_decay", "10" });
midiState.noteOnEvent(0, 64, 64_norm); midiState.noteOnEvent(0, 64, 64_norm);
midiState.advanceTime(100); 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" }); region.parseOpcode({ "rt_decay", "20" });
midiState.noteOnEvent(0, 64, 64_norm); midiState.noteOnEvent(0, 64, 64_norm);
midiState.advanceTime(100); 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" }); region.parseOpcode({ "trigger", "attack" });
midiState.noteOnEvent(0, 64, 64_norm); midiState.noteOnEvent(0, 64, 64_norm);
midiState.advanceTime(100); 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") TEST_CASE("[Region] Base delay")

View file

@ -248,9 +248,9 @@ TEST_CASE("[Values] Count")
synth.dispatchMessage(client, 0, "/region1/count", "", nullptr); synth.dispatchMessage(client, 0, "/region1/count", "", nullptr);
synth.dispatchMessage(client, 0, "/region2/count", "", nullptr); synth.dispatchMessage(client, 0, "/region2/count", "", nullptr);
std::vector<std::string> expected { std::vector<std::string> expected {
"/region0/count,N : { }", "/region0/count,h : { 1 }",
"/region1/count,h : { 2 }", "/region1/count,h : { 2 }",
"/region2/count,N : { }", "/region2/count,h : { 1 }",
}; };
REQUIRE(messageList == expected); REQUIRE(messageList == expected);
} }
@ -453,7 +453,7 @@ TEST_CASE("[Values] Off time")
std::vector<std::string> expected { std::vector<std::string> expected {
"/region0/off_time,f : { 0.006 }", "/region0/off_time,f : { 0.006 }",
"/region1/off_time,f : { 0.1 }", "/region1/off_time,f : { 0.1 }",
"/region2/off_time,f : { 0 }", "/region2/off_time,f : { 0.006 }",
}; };
REQUIRE(messageList == expected); REQUIRE(messageList == expected);
} }
@ -747,7 +747,7 @@ TEST_CASE("[Values] Upswitch")
"/region2/sw_up,N : { }", "/region2/sw_up,N : { }",
"/region3/sw_up,N : { }", "/region3/sw_up,N : { }",
"/region4/sw_up,i : { 60 }", "/region4/sw_up,i : { 60 }",
"/region5/sw_up,i : { 64 }", "/region5/sw_up,i : { 60 }",
}; };
REQUIRE(messageList == expected); REQUIRE(messageList == expected);
} }
@ -778,7 +778,7 @@ TEST_CASE("[Values] Downswitch")
"/region2/sw_down,N : { }", "/region2/sw_down,N : { }",
"/region3/sw_down,N : { }", "/region3/sw_down,N : { }",
"/region4/sw_down,i : { 60 }", "/region4/sw_down,i : { 60 }",
"/region5/sw_down,i : { 64 }", "/region5/sw_down,i : { 60 }",
}; };
REQUIRE(messageList == expected); REQUIRE(messageList == expected);
} }

View file

@ -572,7 +572,7 @@ TEST_CASE("[Synth] sample quality")
// default sample quality // default sample quality
synth.noteOn(0, 60, 100); synth.noteOn(0, 60, 100);
REQUIRE(synth.getNumActiveVoices() == 1); REQUIRE(synth.getNumActiveVoices() == 1);
REQUIRE(synth.getVoiceView(0)->getCurrentSampleQuality() == sfz::Default::sampleQuality.value); REQUIRE(synth.getVoiceView(0)->getCurrentSampleQuality() == sfz::Default::sampleQuality);
synth.allSoundOff(); synth.allSoundOff();
// default sample quality, freewheeling // default sample quality, freewheeling