From 97234177a120c4fe5b64e885e8c72f46bc487509 Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Sun, 29 Mar 2020 19:22:19 +0200 Subject: [PATCH] Use modifiers for panning/width --- src/sfizz/Defaults.h | 3 ++- src/sfizz/Region.cpp | 24 +++++++++++++++------ src/sfizz/Region.h | 8 +++---- src/sfizz/Voice.cpp | 50 ++++++++++++-------------------------------- src/sfizz/Voice.h | 3 --- 5 files changed, 37 insertions(+), 51 deletions(-) diff --git a/src/sfizz/Defaults.h b/src/sfizz/Defaults.h index 5ceaa784..e76a6805 100644 --- a/src/sfizz/Defaults.h +++ b/src/sfizz/Defaults.h @@ -54,9 +54,10 @@ namespace Default constexpr SfzLoopMode loopMode { SfzLoopMode::no_loop }; constexpr Range loopRange { 0, std::numeric_limits::max() }; - // Global ranges + // common defaults constexpr Range midi7Range { 0, 127 }; constexpr Range normalizedRange { 0.0f, 1.0f }; + constexpr float zeroModifier { 0.0f }; // Wavetable oscillator constexpr float oscillatorPhase { 0.0 }; diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 10b7b7ec..cd78075a 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -305,22 +305,34 @@ bool sfz::Region::parseOpcode(const Opcode& opcode) amplitudeCC[opcode.parameters.back()] = normalizePercents(*value); break; case hash("pan"): - setValueFromOpcode(opcode, pan, Default::panRange); + if (auto value = readOpcode(opcode.value, Default::panRange)) + pan = normalizePercents(*value); break; case hash("pan_oncc&"): - setCCPairFromOpcode(opcode, panCC, Default::panCCRange); + if (opcode.parameters.back() > config::numCCs) + return false; + if (auto value = readOpcode(opcode.value, Default::panCCRange)) + panCC[opcode.parameters.back()] = normalizePercents(*value); break; case hash("position"): - setValueFromOpcode(opcode, position, Default::positionRange); + if (auto value = readOpcode(opcode.value, Default::positionRange)) + position = normalizePercents(*value); break; case hash("position_oncc&"): - setCCPairFromOpcode(opcode, positionCC, Default::positionCCRange); + if (opcode.parameters.back() > config::numCCs) + return false; + if (auto value = readOpcode(opcode.value, Default::positionCCRange)) + positionCC[opcode.parameters.back()] = normalizePercents(*value); break; case hash("width"): - setValueFromOpcode(opcode, width, Default::widthRange); + if (auto value = readOpcode(opcode.value, Default::widthRange)) + width = normalizePercents(*value); break; case hash("width_oncc&"): - setCCPairFromOpcode(opcode, widthCC, Default::widthCCRange); + if (opcode.parameters.back() > config::numCCs) + return false; + if (auto value = readOpcode(opcode.value, Default::widthCCRange)) + widthCC[opcode.parameters.back()] = normalizePercents(*value); break; case hash("amp_keycenter"): setValueFromOpcode(opcode, ampKeycenter, Default::keyRange); diff --git a/src/sfizz/Region.h b/src/sfizz/Region.h index 19b7f35d..f9c560cd 100644 --- a/src/sfizz/Region.h +++ b/src/sfizz/Region.h @@ -277,10 +277,10 @@ struct Region { float width { Default::width }; // width float position { Default::position }; // position absl::optional> volumeCC; // volume_oncc - CCMap amplitudeCC { Default::amplitude }; // amplitude_oncc - absl::optional> panCC; // pan_oncc - absl::optional> widthCC; // width_oncc - absl::optional> positionCC; // position_oncc + CCMap amplitudeCC { Default::zeroModifier }; // amplitude_oncc + CCMap panCC { Default::zeroModifier }; // pan_oncc + CCMap widthCC { Default::zeroModifier }; // width_oncc + CCMap positionCC { Default::zeroModifier }; // position_oncc uint8_t ampKeycenter { Default::ampKeycenter }; // amp_keycenter float ampKeytrack { Default::ampKeytrack }; // amp_keytrack float ampVeltrack { Default::ampVeltrack }; // amp_keytrack diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index ee93a3d3..596250a8 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -85,24 +85,6 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value, if (triggerType != TriggerType::CC) baseGain *= region->getNoteGain(number, value); - basePan = normalizePercents(region->pan); - auto pan = basePan; - if (region->panCC) - pan += resources.midiState.getCCValue(region->panCC->cc) * normalizePercents(region->panCC->value); - panEnvelope.reset(Default::symmetricNormalizedRange.clamp(pan)); - - basePosition = normalizePercents(region->position); - auto position = basePosition; - if (region->positionCC) - position += resources.midiState.getCCValue(region->positionCC->cc) * normalizePercents(region->positionCC->value); - positionEnvelope.reset(Default::symmetricNormalizedRange.clamp(position)); - - baseWidth = normalizePercents(region->width); - auto width = baseWidth; - if (region->widthCC) - width += resources.midiState.getCCValue(region->widthCC->cc) * normalizePercents(region->widthCC->value); - widthEnvelope.reset(Default::symmetricNormalizedRange.clamp(width)); - pitchBendEnvelope.setFunction([region](float pitchValue){ const auto normalizedBend = normalizeBend(pitchValue); const auto bendInCents = normalizedBend > 0.0f ? normalizedBend * static_cast(region->bendUp) : -normalizedBend * static_cast(region->bendDown); @@ -199,21 +181,6 @@ void sfz::Voice::registerCC(int delay, int ccNumber, float ccValue) noexcept const float newVolumedB { baseVolumedB + ccValue * region->volumeCC->value }; volumeEnvelope.registerEvent(delay, db2mag(Default::volumeRange.clamp(newVolumedB))); } - - if (region->panCC && ccNumber == region->panCC->cc) { - const float newPan { basePan + ccValue * normalizePercents(region->panCC->value) }; - panEnvelope.registerEvent(delay, Default::symmetricNormalizedRange.clamp(newPan)); - } - - if (region->positionCC && ccNumber == region->positionCC->cc) { - const float newPosition { basePosition + ccValue * normalizePercents(region->positionCC->value) }; - positionEnvelope.registerEvent(delay, Default::symmetricNormalizedRange.clamp(newPosition)); - } - - if (region->widthCC && ccNumber == region->widthCC->cc) { - const float newWidth { baseWidth + ccValue * normalizePercents(region->widthCC->value) }; - widthEnvelope.registerEvent(delay, Default::symmetricNormalizedRange.clamp(newWidth)); - } } void sfz::Voice::registerPitchWheel(int delay, int pitch) noexcept @@ -378,7 +345,9 @@ void sfz::Voice::processMono(AudioSpan buffer) noexcept copy(leftBuffer, rightBuffer); // Apply panning - panEnvelope.getBlock(modulationSpan); + fill(modulationSpan, 0.0f); + getLinearEnvelope(region->panCC, resources.midiState, modulationSpan, [](float modifier, float value) { return value * modifier; }); + add(region->pan, modulationSpan); pan(modulationSpan, leftBuffer, rightBuffer); } } @@ -431,13 +400,20 @@ void sfz::Voice::processStereo(AudioSpan buffer) noexcept ScopedTiming logger { panningDuration }; // Apply panning - panEnvelope.getBlock(modulationSpan); + fill(modulationSpan, 0.0f); + getLinearEnvelope(region->panCC, resources.midiState, modulationSpan, [](float modifier, float value) { return value * modifier; }); + add(region->pan, modulationSpan); pan(modulationSpan, leftBuffer, rightBuffer); // Apply the width/position process - widthEnvelope.getBlock(modulationSpan); + fill(modulationSpan, 0.0f); + getLinearEnvelope(region->widthCC, resources.midiState, modulationSpan, [](float modifier, float value) { return value * modifier; }); + add(region->width, modulationSpan); width(modulationSpan, leftBuffer, rightBuffer); - positionEnvelope.getBlock(modulationSpan); + + fill(modulationSpan, 0.0f); + getLinearEnvelope(region->positionCC, resources.midiState, modulationSpan, [](float modifier, float value) { return value * modifier; }); + add(region->position, modulationSpan); pan(modulationSpan, leftBuffer, rightBuffer); } diff --git a/src/sfizz/Voice.h b/src/sfizz/Voice.h index 7e8a9a97..0d51cb3e 100644 --- a/src/sfizz/Voice.h +++ b/src/sfizz/Voice.h @@ -268,9 +268,6 @@ private: float pitchRatio { 1.0 }; float baseVolumedB{ 0.0 }; float baseGain { 1.0 }; - float basePan { 0.0 }; - float basePosition { 0.0 }; - float baseWidth { 0.0 }; float baseFrequency { 440.0 }; float phase { 0.0f };