Be explicit in the filter/EQ processes

This commit is contained in:
Paul Ferrand 2020-03-30 20:07:54 +02:00
parent 0da5c43bb5
commit 1f7786cc74
3 changed files with 46 additions and 47 deletions

View file

@ -28,12 +28,20 @@ void sfz::EQHolder::setup(const EQDescription& description, unsigned numChannels
baseGain = description.gain + velocity * description.vel2gain;
// Setup the modulated values
lastFrequency = baseFrequency + midiState.fastAdditiveModifiers(description.frequencyCC);
lastFrequency = baseFrequency;
for (auto& mod : description.frequencyCC)
lastFrequency += midiState.getCCValue(mod.cc) * mod.value;
lastFrequency = Default::eqFrequencyRange.clamp(lastFrequency);
lastBandwidth = baseBandwidth + midiState.fastAdditiveModifiers(description.bandwidthCC);
lastBandwidth = baseBandwidth;
for (auto& mod : description.bandwidthCC)
lastBandwidth += midiState.getCCValue(mod.cc) * mod.value;
lastBandwidth = Default::eqBandwidthRange.clamp(lastBandwidth);
lastGain = baseGain + midiState.fastAdditiveModifiers(description.gainCC);
lastGain = Default::eqGainRange.clamp(lastGain);
lastGain = baseGain;
for (auto& mod : description.gainCC)
lastGain += midiState.getCCValue(mod.cc) * mod.value;
lastGain = Default::filterGainRange.clamp(lastGain);
// Initialize the EQ
eq.prepare(lastFrequency, lastBandwidth, lastGain);
@ -53,12 +61,20 @@ void sfz::EQHolder::process(const float** inputs, float** outputs, unsigned numF
// TODO: Once the midistate envelopes are done, add modulation in there!
// For now we take the last value
lastFrequency = baseFrequency + midiState.fastAdditiveModifiers(description->frequencyCC);
lastFrequency = baseFrequency;
for (auto& mod : description->frequencyCC)
lastFrequency += midiState.getCCValue(mod.cc) * mod.value;
lastFrequency = Default::eqFrequencyRange.clamp(lastFrequency);
lastBandwidth = baseBandwidth + midiState.fastAdditiveModifiers(description->bandwidthCC);
lastBandwidth = baseBandwidth;
for (auto& mod : description->bandwidthCC)
lastBandwidth += midiState.getCCValue(mod.cc) * mod.value;
lastBandwidth = Default::eqBandwidthRange.clamp(lastBandwidth);
lastGain = baseGain + midiState.fastAdditiveModifiers(description->gainCC);
lastGain = Default::eqGainRange.clamp(lastGain);
lastGain = baseGain;
for (auto& mod : description->gainCC)
lastGain += midiState.getCCValue(mod.cc) * mod.value;
lastGain = Default::filterGainRange.clamp(lastGain);
if (lastGain == 0.0f) {
justCopy();

View file

@ -40,11 +40,19 @@ void sfz::FilterHolder::setup(const FilterDescription& description, unsigned num
baseResonance = description.resonance;
// Setup the modulated values
lastCutoff = baseCutoff * midiState.fastMultiplicativeModifiers(description.cutoffCC, multiplyByCentsModifier);
lastCutoff = baseCutoff;
for (auto& mod : description.cutoffCC)
lastCutoff *= centsFactor(midiState.getCCValue(mod.cc) * mod.value);
lastCutoff = Default::filterCutoffRange.clamp(lastCutoff);
lastResonance = baseResonance + midiState.fastAdditiveModifiers(description.resonanceCC);
lastResonance = baseResonance;
for (auto& mod : description.resonanceCC)
lastResonance += midiState.getCCValue(mod.cc) * mod.value;
lastResonance = Default::filterResonanceRange.clamp(lastResonance);
lastGain = baseGain + midiState.fastAdditiveModifiers(description.gainCC);
lastGain = baseGain;
for (auto& mod : description.gainCC)
lastGain += midiState.getCCValue(mod.cc) * mod.value;
lastGain = Default::filterGainRange.clamp(lastGain);
// Initialize the filter
@ -62,13 +70,19 @@ void sfz::FilterHolder::process(const float** inputs, float** outputs, unsigned
// TODO: Once the midistate envelopes are done, add modulation in there!
// For now we take the last value
// TODO: the template deduction could be automatic here?
lastCutoff = baseCutoff * midiState.fastMultiplicativeModifiers(description->cutoffCC, [](const int& modifier, float value) -> float {
return value * centsFactor(modifier);
});
lastCutoff = baseCutoff;
for (auto& mod : description->cutoffCC)
lastCutoff *= centsFactor(midiState.getCCValue(mod.cc) * mod.value);
lastCutoff = Default::filterCutoffRange.clamp(lastCutoff);
lastResonance = baseResonance + midiState.fastAdditiveModifiers(description->resonanceCC);
lastResonance = baseResonance;
for (auto& mod : description->resonanceCC)
lastResonance += midiState.getCCValue(mod.cc) * mod.value;
lastResonance = Default::filterResonanceRange.clamp(lastResonance);
lastGain = baseGain + midiState.fastAdditiveModifiers(description->gainCC);
lastGain = baseGain;
for (auto& mod : description->gainCC)
lastGain += midiState.getCCValue(mod.cc) * mod.value;
lastGain = Default::filterGainRange.clamp(lastGain);
filter.process(inputs, outputs, lastCutoff, lastResonance, lastGain, numFrames);

View file

@ -123,37 +123,6 @@ public:
*/
void resetAllControllers(int delay) noexcept;
/**
* @brief Modulate a value using the last entered CCs in the midiState
*
* @tparam T
* @tparam U
* @param value the base value
* @param modifiers the list of CC modifiers
* @param validRange a range to clamp the output
* @param lambda the function to apply for each modifier
* @return T
*/
template<class T, class F = decltype(gainModifier<T>)>
float fastAdditiveModifiers(const CCMap<T>& modifiers, F&& lambda = gainModifier<T>) const noexcept
{
float returnedValue { 0.0f };
for (auto& mod: modifiers) {
returnedValue += lambda(getCCValue(mod.cc), mod.value);
}
return returnedValue;
}
template<class T, class F = decltype(gainModifier<T>)>
float fastMultiplicativeModifiers(const CCMap<T>& modifiers, F&& lambda = gainModifier<T>) const noexcept
{
float returnedValue { 1.0f };
for (auto& mod: modifiers) {
returnedValue *= lambda(getCCValue(mod.cc), mod.value);
}
return returnedValue;
}
const EventVector& getEvents(int ccIdx) const noexcept;
template<class T, class F>