Make all phase opcodes normalized

This commit is contained in:
Jean Pierre Cimalando 2020-10-15 13:14:17 +02:00
parent c69c054f44
commit e258ad254f
7 changed files with 34 additions and 30 deletions

View file

@ -65,7 +65,7 @@ namespace Default
// Wavetable oscillator // Wavetable oscillator
constexpr float oscillatorPhase { 0.0 }; constexpr float oscillatorPhase { 0.0 };
constexpr Range<float> oscillatorPhaseRange { -1.0, 360.0 }; constexpr Range<float> oscillatorPhaseRange { -1.0, 1.0 };
constexpr int oscillatorMode { 0 }; constexpr int oscillatorMode { 0 };
constexpr int oscillatorMulti { 1 }; constexpr int oscillatorMulti { 1 };
constexpr Range<int> oscillatorModeRange { 0, 2 }; constexpr Range<int> oscillatorModeRange { 0, 2 };
@ -222,7 +222,7 @@ namespace Default
constexpr int numLFOSubs { 2 }; constexpr int numLFOSubs { 2 };
constexpr int numLFOSteps { 8 }; constexpr int numLFOSteps { 8 };
constexpr Range<float> lfoFreqRange { 0.0, 100.0 }; constexpr Range<float> lfoFreqRange { 0.0, 100.0 };
constexpr Range<float> lfoPhaseRange { 0.0, 360.0 }; constexpr Range<float> lfoPhaseRange { 0.0, 1.0 };
constexpr Range<float> lfoDelayRange { 0.0, 30.0 }; constexpr Range<float> lfoDelayRange { 0.0, 30.0 };
constexpr Range<float> lfoFadeRange { 0.0, 30.0 }; constexpr Range<float> lfoFadeRange { 0.0, 30.0 };
constexpr Range<unsigned> lfoCountRange { 0, 1000 }; constexpr Range<unsigned> lfoCountRange { 0, 1000 };
@ -281,7 +281,7 @@ namespace Default
constexpr Range<int> apanWaveformRange { 0, std::numeric_limits<int>::max() }; constexpr Range<int> apanWaveformRange { 0, std::numeric_limits<int>::max() };
constexpr Range<float> apanFrequencyRange { 0, std::numeric_limits<float>::max() }; constexpr Range<float> apanFrequencyRange { 0, std::numeric_limits<float>::max() };
constexpr Range<float> apanPhaseRange { 0.0, 360.0 }; constexpr Range<float> apanPhaseRange { 0.0, 1.0 };
constexpr Range<float> apanLevelRange { 0.0, 100.0 }; constexpr Range<float> apanLevelRange { 0.0, 100.0 };
} }
} }

View file

@ -288,6 +288,17 @@ constexpr long int lroundPositive(T value)
return static_cast<int>(0.5f + value); // NOLINT return static_cast<int>(0.5f + value); // NOLINT
} }
/**
@brief Wrap a normalized phase into the domain [0;1[
*/
template <class T>
static T wrapPhase(T phase)
{
T wrapped = phase - static_cast<int>(phase);
wrapped += wrapped < 0;
return wrapped;
}
/** /**
@brief A fraction which is parameterized by integer type @brief A fraction which is parameterized by integer type
*/ */

View file

@ -144,7 +144,8 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
// Wavetable oscillator // Wavetable oscillator
case hash("oscillator_phase"): case hash("oscillator_phase"):
setValueFromOpcode(opcode, oscillatorPhase, Default::oscillatorPhaseRange); if (auto value = readOpcode(opcode.value, Default::oscillatorPhaseRange))
oscillatorPhase = (*value >= 0) ? wrapPhase(*value) : -1.0f;
break; break;
case hash("oscillator"): case hash("oscillator"):
if (auto value = readBooleanFromOpcode(opcode)) if (auto value = readBooleanFromOpcode(opcode))
@ -851,12 +852,8 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
return false; return false;
if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs)) if (!extendIfNecessary(lfos, lfoNumber, Default::numLFOs))
return false; return false;
if (auto value = readOpcode(opcode.value, Default::lfoPhaseRange)) { if (auto value = readOpcode(opcode.value, Default::lfoPhaseRange))
float normalPhase = *value * (1.0 / 360.0); lfos[lfoNumber - 1].phase0 = wrapPhase(*value);
normalPhase -= int(normalPhase);
normalPhase += (normalPhase < 0) ? 1 : 0;
lfos[lfoNumber - 1].phase0 = normalPhase;
}
} }
break; break;
case hash("lfo&_delay"): case hash("lfo&_delay"):
@ -1762,10 +1759,9 @@ float sfz::Region::getBaseGain() const noexcept
float sfz::Region::getPhase() const noexcept float sfz::Region::getPhase() const noexcept
{ {
float phase; float phase;
if (oscillatorPhase >= 0) { if (oscillatorPhase >= 0)
phase = oscillatorPhase * (1.0f / 360.0f); phase = oscillatorPhase;
phase -= static_cast<float>(static_cast<int>(phase)); else {
} else {
fast_real_distribution<float> phaseDist { 0.0001f, 0.9999f }; fast_real_distribution<float> phaseDist { 0.0001f, 0.9999f };
phase = phaseDist(Random::randomGenerator); phase = phaseDist(Random::randomGenerator);
} }

View file

@ -89,11 +89,8 @@ namespace fx {
apan->_lfoFrequency = *value; apan->_lfoFrequency = *value;
break; break;
case hash("apan_phase"): case hash("apan_phase"):
if (auto value = readOpcode(opc.value, Default::apanPhaseRange)) { if (auto value = readOpcode(opc.value, Default::apanPhaseRange))
float phase = *value / 360.0f; apan->_lfoPhaseOffset = wrapPhase(*value);
phase -= static_cast<int>(phase);
apan->_lfoPhaseOffset = phase;
}
break; break;
case hash("apan_dry"): case hash("apan_dry"):
if (auto value = readOpcode(opc.value, Default::apanLevelRange)) if (auto value = readOpcode(opc.value, Default::apanLevelRange))

View file

@ -1595,14 +1595,14 @@ TEST_CASE("[Region] Parsing opcodes")
SECTION("Wavetable phase") SECTION("Wavetable phase")
{ {
REQUIRE(region.oscillatorPhase == 0.0f); REQUIRE(region.oscillatorPhase == 0.0f);
region.parseOpcode({ "oscillator_phase", "45" }); region.parseOpcode({ "oscillator_phase", "0.25" });
REQUIRE(region.oscillatorPhase == 45.0f); REQUIRE(region.oscillatorPhase == 0.25f);
region.parseOpcode({ "oscillator_phase", "45.32" }); region.parseOpcode({ "oscillator_phase", "0.3" });
REQUIRE(region.oscillatorPhase == 45.32_a); REQUIRE(region.oscillatorPhase == 0.3_a);
region.parseOpcode({ "oscillator_phase", "-1" }); region.parseOpcode({ "oscillator_phase", "-1" });
REQUIRE(region.oscillatorPhase == -1.0f); REQUIRE(region.oscillatorPhase == -1.0f);
region.parseOpcode({ "oscillator_phase", "361" }); region.parseOpcode({ "oscillator_phase", "1.1" });
REQUIRE(region.oscillatorPhase == 360.0f); REQUIRE(region.oscillatorPhase == 0.0f);
} }
SECTION("Note polyphony") SECTION("Note polyphony")

View file

@ -7,23 +7,23 @@ fil_type=brf_2p
lfo1_cutoff=1200.0 lfo1_cutoff=1200.0
// //
lfo1_freq=1 lfo1_freq=1
lfo1_phase=180 lfo1_phase=0.5
lfo1_wave=3 lfo1_wave=3
// //
lfo2_freq=1 lfo2_freq=1
lfo2_phase=180 lfo2_phase=0.5
lfo2_wave=3 lfo2_wave=3
lfo2_wave2=1 lfo2_wave2=1
// //
lfo3_freq=1 lfo3_freq=1
lfo3_phase=180 lfo3_phase=0.5
lfo3_wave=3 lfo3_wave=3
lfo3_wave2=1 lfo3_wave2=1
lfo3_ratio2=2 lfo3_ratio2=2
// //
lfo4_freq=1 lfo4_freq=1
lfo4_phase=180 lfo4_phase=0.5
lfo4_wave=3 lfo4_wave=3
lfo4_wave2=1 lfo4_wave2=1
lfo4_ratio2=2 lfo4_ratio2=2

View file

@ -18,6 +18,6 @@ lfo6_wave=5
lfo6_freq=2.0 lfo6_freq=2.0
lfo7_wave=6 lfo7_wave=6
lfo7_freq=1.0 lfo7_freq=1.0
lfo7_phase=180 lfo7_phase=0.5
lfo8_wave=7 lfo8_wave=7
lfo8_freq=2.0 lfo8_freq=2.0