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
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 oscillatorMulti { 1 };
constexpr Range<int> oscillatorModeRange { 0, 2 };
@ -222,7 +222,7 @@ namespace Default
constexpr int numLFOSubs { 2 };
constexpr int numLFOSteps { 8 };
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> lfoFadeRange { 0.0, 30.0 };
constexpr Range<unsigned> lfoCountRange { 0, 1000 };
@ -281,7 +281,7 @@ namespace Default
constexpr Range<int> apanWaveformRange { 0, std::numeric_limits<int>::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 };
}
}

View file

@ -288,6 +288,17 @@ constexpr long int lroundPositive(T value)
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
*/

View file

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

View file

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

View file

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

View file

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

View file

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