feat: add resonance parameter to filter and update plugin info
This commit is contained in:
parent
970cb6049d
commit
467142603d
4 changed files with 70 additions and 22 deletions
|
|
@ -2,33 +2,49 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
Filter::Filter(float initCutOff, float initSampleRate)
|
Filter::Filter(float initCutOff, float initSampleRate)
|
||||||
: cutOff_(initCutOff), feedback_(0.0f), alpha_(0.0f),
|
: cutOff_(initCutOff), feedback_(0.0f), resonance_(0.1f), a1_(0.0f),
|
||||||
sampleRate_(initSampleRate), zL_(0.0f), zR_(0.0f) {
|
a2_(0.0f), a3_(0.0f), g_(0.0f), k_(2.0f), sampleRate_(initSampleRate),
|
||||||
|
s1L_(0.0f), s2L_(0.0f), s1R_(0.0f), s2R_(0.0f), outZL_(0.0f),
|
||||||
|
outZR_(0.0f) {
|
||||||
recompute();
|
recompute();
|
||||||
};
|
};
|
||||||
|
|
||||||
void Filter::process(const float *in, float *out, uint32_t frames) {
|
void Filter::process(const float *in, float *out, uint32_t frames) {
|
||||||
filter(in, out, frames, &zL_);
|
filter(in, out, frames, &s1L_, &s2L_, &outZL_);
|
||||||
};
|
};
|
||||||
void Filter::processStereo(const float *inLeft, const float *inRight,
|
void Filter::processStereo(const float *inLeft, const float *inRight,
|
||||||
float *outLeft, float *outRight, uint32_t frames) {
|
float *outLeft, float *outRight, uint32_t frames) {
|
||||||
filter(inLeft, outLeft, frames, &zL_);
|
filter(inLeft, outLeft, frames, &s1L_, &s2L_, &outZL_);
|
||||||
filter(inRight, outRight, frames, &zR_);
|
filter(inRight, outRight, frames, &s1R_, &s2R_, &outZR_);
|
||||||
};
|
};
|
||||||
|
|
||||||
void Filter::filter(const float *in, float *out, uint32_t frames, float *z) {
|
void Filter::filter(const float *in, float *out, uint32_t frames, float *s1,
|
||||||
|
float *s2, float *outZ) {
|
||||||
for (uint32_t i = 0; i < frames; ++i) {
|
for (uint32_t i = 0; i < frames; ++i) {
|
||||||
float feedbackInput = in[i] + (feedback_ * (*z));
|
float x = in[i] + (feedback_ * (*outZ));
|
||||||
*z = *z + alpha_ * (feedbackInput - *z);
|
float v3 = x - *s2;
|
||||||
out[i] = *z;
|
if (resonance_ > 0.995f && std::fabs(v3) < 1.0e-9f) {
|
||||||
|
v3 = 1.0e-6f;
|
||||||
|
}
|
||||||
|
float v1 = (a1_ * (*s1)) + (a2_ * v3);
|
||||||
|
float v2 = (*s2) + (a2_ * (*s1)) + (a3_ * v3);
|
||||||
|
*s1 = (2.0f * v1) - *s1;
|
||||||
|
*s2 = (2.0f * v2) - *s2;
|
||||||
|
out[i] = v2;
|
||||||
|
*outZ = v2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filter::recompute() {
|
void Filter::recompute() {
|
||||||
float fc = std::fmax(cutOff_, 1.0f);
|
float sr = std::fmax(sampleRate_, 1.0f);
|
||||||
float rc = 1.0f / (2.0f * M_PI * fc);
|
float fc = std::fmin(std::fmax(cutOff_, 1.0f), 0.45f * sr);
|
||||||
float val = 1.0f - std::exp(-1.0f / (rc * sampleRate_));
|
g_ = std::tan(static_cast<float>(M_PI) * (fc / sr));
|
||||||
alpha_ = std::fmin(val, 0.999f);
|
k_ = 2.0f * (1.0f - std::fmin(std::fmax(resonance_, 0.0f), 1.0f));
|
||||||
|
|
||||||
|
float denom = 1.0f + (g_ * (g_ + k_));
|
||||||
|
a1_ = 1.0f / denom;
|
||||||
|
a2_ = g_ * a1_;
|
||||||
|
a3_ = g_ * a2_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Filter::setCutOff(float newCutOff) {
|
void Filter::setCutOff(float newCutOff) {
|
||||||
|
|
@ -38,10 +54,16 @@ void Filter::setCutOff(float newCutOff) {
|
||||||
float Filter::getCutOff() const { return cutOff_; }
|
float Filter::getCutOff() const { return cutOff_; }
|
||||||
|
|
||||||
void Filter::setFeedback(float newFeedback) {
|
void Filter::setFeedback(float newFeedback) {
|
||||||
feedback_ = std::fmin(std::fmax(newFeedback, 0.0f), 0.99f);
|
feedback_ = std::fmin(std::fmax(newFeedback, 0.0f), 0.95f);
|
||||||
}
|
}
|
||||||
float Filter::getFeedback() const { return feedback_; }
|
float Filter::getFeedback() const { return feedback_; }
|
||||||
|
|
||||||
|
void Filter::setResonance(float newResonance) {
|
||||||
|
resonance_ = std::fmin(std::fmax(newResonance, 0.0f), 1.0f);
|
||||||
|
recompute();
|
||||||
|
}
|
||||||
|
float Filter::getResonance() const { return resonance_; }
|
||||||
|
|
||||||
void Filter::setSampleRate(float newSampleRate) {
|
void Filter::setSampleRate(float newSampleRate) {
|
||||||
sampleRate_ = newSampleRate;
|
sampleRate_ = newSampleRate;
|
||||||
recompute();
|
recompute();
|
||||||
|
|
|
||||||
|
|
@ -17,17 +17,29 @@ public:
|
||||||
float getCutOff() const;
|
float getCutOff() const;
|
||||||
void setFeedback(float newFeedback);
|
void setFeedback(float newFeedback);
|
||||||
float getFeedback() const;
|
float getFeedback() const;
|
||||||
|
void setResonance(float newResonance);
|
||||||
|
float getResonance() const;
|
||||||
void setSampleRate(float newSampleRate);
|
void setSampleRate(float newSampleRate);
|
||||||
float getSampleRate() const;
|
float getSampleRate() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void filter(const float *in, float *out, uint32_t frames, float *z);
|
void filter(const float *in, float *out, uint32_t frames, float *s1,
|
||||||
|
float *s2, float *outZ);
|
||||||
float cutOff_;
|
float cutOff_;
|
||||||
float feedback_;
|
float feedback_;
|
||||||
float alpha_;
|
float resonance_;
|
||||||
|
float a1_;
|
||||||
|
float a2_;
|
||||||
|
float a3_;
|
||||||
|
float g_;
|
||||||
|
float k_;
|
||||||
float sampleRate_;
|
float sampleRate_;
|
||||||
float zL_;
|
float s1L_;
|
||||||
float zR_;
|
float s2L_;
|
||||||
|
float s1R_;
|
||||||
|
float s2R_;
|
||||||
|
float outZL_;
|
||||||
|
float outZR_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FILTER_HPP_INCLUDED
|
#endif // FILTER_HPP_INCLUDED
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
#define DISTRHO_PLUGIN_NUM_INPUTS 2
|
#define DISTRHO_PLUGIN_NUM_INPUTS 2
|
||||||
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
|
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
|
||||||
|
|
||||||
#define DISTRHO_PLUGIN_NUM_PARAMETERS 5
|
#define DISTRHO_PLUGIN_NUM_PARAMETERS 6
|
||||||
|
|
||||||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 0
|
#define DISTRHO_PLUGIN_WANT_PROGRAMS 0
|
||||||
#define DISTRHO_PLUGIN_WANT_STATE 0
|
#define DISTRHO_PLUGIN_WANT_STATE 0
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ public:
|
||||||
kParamFilter,
|
kParamFilter,
|
||||||
kParamFilterFeedback,
|
kParamFilterFeedback,
|
||||||
kParamMixVolume,
|
kParamMixVolume,
|
||||||
|
kParamResonance,
|
||||||
kParameterCount // must be last
|
kParameterCount // must be last
|
||||||
};
|
};
|
||||||
SquidgeDistortion()
|
SquidgeDistortion()
|
||||||
|
|
@ -83,11 +84,11 @@ protected:
|
||||||
parameter.hints = kParameterIsAutomatable;
|
parameter.hints = kParameterIsAutomatable;
|
||||||
break;
|
break;
|
||||||
case kParamFilterFeedback:
|
case kParamFilterFeedback:
|
||||||
parameter.name = "Filter Feedback";
|
parameter.name = "Feedback";
|
||||||
parameter.symbol = "filterfeedback";
|
parameter.symbol = "filterfeedback";
|
||||||
parameter.ranges.min = 0.0f;
|
parameter.ranges.min = 0.0f;
|
||||||
parameter.ranges.def = .1f;
|
parameter.ranges.def = 0.0f;
|
||||||
parameter.ranges.max = 0.99f;
|
parameter.ranges.max = 0.95f;
|
||||||
parameter.hints = kParameterIsAutomatable;
|
parameter.hints = kParameterIsAutomatable;
|
||||||
break;
|
break;
|
||||||
case kParamMixVolume:
|
case kParamMixVolume:
|
||||||
|
|
@ -98,6 +99,14 @@ protected:
|
||||||
parameter.ranges.max = 1.0f;
|
parameter.ranges.max = 1.0f;
|
||||||
parameter.hints = kParameterIsAutomatable;
|
parameter.hints = kParameterIsAutomatable;
|
||||||
break;
|
break;
|
||||||
|
case kParamResonance:
|
||||||
|
parameter.name = "Resonance";
|
||||||
|
parameter.symbol = "resonance";
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.def = 0.1f;
|
||||||
|
parameter.ranges.max = 1.0f;
|
||||||
|
parameter.hints = kParameterIsAutomatable;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,6 +122,8 @@ protected:
|
||||||
return (float)filter_.getFeedback();
|
return (float)filter_.getFeedback();
|
||||||
case kParamMixVolume:
|
case kParamMixVolume:
|
||||||
return mixer_.getInputGain(kChannelWet);
|
return mixer_.getInputGain(kChannelWet);
|
||||||
|
case kParamResonance:
|
||||||
|
return (float)filter_.getResonance();
|
||||||
}
|
}
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
@ -137,6 +148,9 @@ protected:
|
||||||
mixer_.setInputGain(kChannelWet, value);
|
mixer_.setInputGain(kChannelWet, value);
|
||||||
mixer_.setInputGain(kChannelDry, 1.0f - value);
|
mixer_.setInputGain(kChannelDry, 1.0f - value);
|
||||||
break;
|
break;
|
||||||
|
case kParamResonance:
|
||||||
|
filter_.setResonance(value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue