Prepare filters on first call

This commit is contained in:
Paul Ferrand 2020-09-16 15:33:26 +02:00
parent 9aceecaa54
commit fd3a08b7a4
4 changed files with 20 additions and 38 deletions

View file

@ -14,6 +14,7 @@ sfz::EQHolder::EQHolder(Resources& resources)
void sfz::EQHolder::reset() void sfz::EQHolder::reset()
{ {
eq->clear(); eq->clear();
prepared = false;
} }
void sfz::EQHolder::setup(const Region& region, unsigned eqId, float velocity) void sfz::EQHolder::setup(const Region& region, unsigned eqId, float velocity)
@ -30,29 +31,12 @@ void sfz::EQHolder::setup(const Region& region, unsigned eqId, float velocity)
baseBandwidth = description->bandwidth; baseBandwidth = description->bandwidth;
baseGain = description->gain + velocity * description->vel2gain; baseGain = description->gain + velocity * description->vel2gain;
// Setup the modulated values
float lastFrequency = baseFrequency;
for (const auto& mod : description->frequencyCC)
lastFrequency += resources.midiState.getCCValue(mod.cc) * mod.data;
lastFrequency = Default::eqFrequencyRange.clamp(lastFrequency);
float lastBandwidth = baseBandwidth;
for (const auto& mod : description->bandwidthCC)
lastBandwidth += resources.midiState.getCCValue(mod.cc) * mod.data;
lastBandwidth = Default::eqBandwidthRange.clamp(lastBandwidth);
float lastGain = baseGain;
for (const auto& mod : description->gainCC)
lastGain += resources.midiState.getCCValue(mod.cc) * mod.data;
lastGain = Default::filterGainRange.clamp(lastGain);
gainTarget = resources.modMatrix.findTarget(ModKey::createNXYZ(ModId::EqGain, region.id, eqId)); gainTarget = resources.modMatrix.findTarget(ModKey::createNXYZ(ModId::EqGain, region.id, eqId));
bandwidthTarget = resources.modMatrix.findTarget(ModKey::createNXYZ(ModId::EqBandwidth, region.id, eqId)); bandwidthTarget = resources.modMatrix.findTarget(ModKey::createNXYZ(ModId::EqBandwidth, region.id, eqId));
frequencyTarget = resources.modMatrix.findTarget(ModKey::createNXYZ(ModId::EqFrequency, region.id, eqId)); frequencyTarget = resources.modMatrix.findTarget(ModKey::createNXYZ(ModId::EqFrequency, region.id, eqId));
// Initialize the EQ // Disables smoothing of the parameters on the first call
DBG(baseFrequency << " " << baseBandwidth << " " << baseGain); prepared = false;
eq->prepare(lastFrequency, lastBandwidth, lastGain);
} }
void sfz::EQHolder::process(const float** inputs, float** outputs, unsigned numFrames) void sfz::EQHolder::process(const float** inputs, float** outputs, unsigned numFrames)
@ -83,7 +67,10 @@ void sfz::EQHolder::process(const float** inputs, float** outputs, unsigned numF
if (float* mod = mm.getModulation(gainTarget)) if (float* mod = mm.getModulation(gainTarget))
add<float>(absl::Span<float>(mod, numFrames), *gainSpan); add<float>(absl::Span<float>(mod, numFrames), *gainSpan);
DBG(frequencySpan->back() << " " << bandwidthSpan->back() << " " << gainSpan->back()); if (!prepared) {
eq->prepare(frequencySpan->front(), bandwidthSpan->front(), gainSpan->front());
prepared = true;
}
eq->processModulated( eq->processModulated(
inputs, inputs,

View file

@ -48,6 +48,7 @@ private:
float baseBandwidth { Default::eqBandwidth }; float baseBandwidth { Default::eqBandwidth };
float baseFrequency { Default::eqFrequency1 }; float baseFrequency { Default::eqFrequency1 };
float baseGain { Default::eqGain }; float baseGain { Default::eqGain };
bool prepared { false };
ModMatrix::TargetId gainTarget; ModMatrix::TargetId gainTarget;
ModMatrix::TargetId frequencyTarget; ModMatrix::TargetId frequencyTarget;
ModMatrix::TargetId bandwidthTarget; ModMatrix::TargetId bandwidthTarget;

View file

@ -15,6 +15,7 @@ sfz::FilterHolder::FilterHolder(Resources& resources)
void sfz::FilterHolder::reset() void sfz::FilterHolder::reset()
{ {
filter->clear(); filter->clear();
prepared = false;
} }
void sfz::FilterHolder::setup(const Region& region, unsigned filterId, int noteNumber, float velocity) void sfz::FilterHolder::setup(const Region& region, unsigned filterId, int noteNumber, float velocity)
@ -41,33 +42,20 @@ void sfz::FilterHolder::setup(const Region& region, unsigned filterId, int noteN
baseGain = description->gain; baseGain = description->gain;
baseResonance = description->resonance; baseResonance = description->resonance;
// Setup the modulated values
float lastCutoff = baseCutoff;
for (const auto& mod : description->cutoffCC)
lastCutoff *= centsFactor(resources.midiState.getCCValue(mod.cc) * mod.data);
lastCutoff = Default::filterCutoffRange.clamp(lastCutoff);
float lastResonance = baseResonance;
for (const auto& mod : description->resonanceCC)
lastResonance += resources.midiState.getCCValue(mod.cc) * mod.data;
lastResonance = Default::filterResonanceRange.clamp(lastResonance);
float lastGain = baseGain;
for (const auto& mod : description->gainCC)
lastGain += resources.midiState.getCCValue(mod.cc) * mod.data;
lastGain = Default::filterGainRange.clamp(lastGain);
ModMatrix& mm = resources.modMatrix; ModMatrix& mm = resources.modMatrix;
gainTarget = mm.findTarget(ModKey::createNXYZ(ModId::FilGain, region.id, filterId)); gainTarget = mm.findTarget(ModKey::createNXYZ(ModId::FilGain, region.id, filterId));
cutoffTarget = mm.findTarget(ModKey::createNXYZ(ModId::FilCutoff, region.id, filterId)); cutoffTarget = mm.findTarget(ModKey::createNXYZ(ModId::FilCutoff, region.id, filterId));
resonanceTarget = mm.findTarget(ModKey::createNXYZ(ModId::FilResonance, region.id, filterId)); resonanceTarget = mm.findTarget(ModKey::createNXYZ(ModId::FilResonance, region.id, filterId));
// Initialize the filter // Disable smoothing of the parameters on the first call
filter->prepare(lastCutoff, lastResonance, lastGain); prepared = false;
} }
void sfz::FilterHolder::process(const float** inputs, float** outputs, unsigned numFrames) void sfz::FilterHolder::process(const float** inputs, float** outputs, unsigned numFrames)
{ {
if (numFrames == 0)
return;
if (description == nullptr) { if (description == nullptr) {
for (unsigned channelIdx = 0; channelIdx < filter->channels(); channelIdx++) for (unsigned channelIdx = 0; channelIdx < filter->channels(); channelIdx++)
copy<float>({ inputs[channelIdx], numFrames }, { outputs[channelIdx], numFrames }); copy<float>({ inputs[channelIdx], numFrames }, { outputs[channelIdx], numFrames });
@ -96,6 +84,11 @@ void sfz::FilterHolder::process(const float** inputs, float** outputs, unsigned
if (float* mod = mm.getModulation(gainTarget)) if (float* mod = mm.getModulation(gainTarget))
add<float>(absl::Span<float>(mod, numFrames), *gainSpan); add<float>(absl::Span<float>(mod, numFrames), *gainSpan);
if (!prepared) {
filter->prepare(cutoffSpan->front(), resonanceSpan->front(), gainSpan->front());
prepared = true;
}
filter->processModulated( filter->processModulated(
inputs, inputs,
outputs, outputs,

View file

@ -53,6 +53,7 @@ private:
ModMatrix::TargetId gainTarget; ModMatrix::TargetId gainTarget;
ModMatrix::TargetId cutoffTarget; ModMatrix::TargetId cutoffTarget;
ModMatrix::TargetId resonanceTarget; ModMatrix::TargetId resonanceTarget;
bool prepared { false };
using filterRandomDist = std::uniform_int_distribution<int>; using filterRandomDist = std::uniform_int_distribution<int>;
filterRandomDist dist { 0, sfz::Default::filterRandom }; filterRandomDist dist { 0, sfz::Default::filterRandom };
}; };