Compare commits

...
Sign in to create a new pull request.

1 commit

4 changed files with 70 additions and 22 deletions

View file

@ -2,33 +2,49 @@
#include <cmath>
Filter::Filter(float initCutOff, float initSampleRate)
: cutOff_(initCutOff), feedback_(0.0f), alpha_(0.0f),
sampleRate_(initSampleRate), zL_(0.0f), zR_(0.0f) {
: cutOff_(initCutOff), feedback_(0.0f), resonance_(0.1f), a1_(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();
};
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,
float *outLeft, float *outRight, uint32_t frames) {
filter(inLeft, outLeft, frames, &zL_);
filter(inRight, outRight, frames, &zR_);
filter(inLeft, outLeft, frames, &s1L_, &s2L_, &outZL_);
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) {
float feedbackInput = in[i] + (feedback_ * (*z));
*z = *z + alpha_ * (feedbackInput - *z);
out[i] = *z;
float x = in[i] + (feedback_ * (*outZ));
float v3 = x - *s2;
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() {
float fc = std::fmax(cutOff_, 1.0f);
float rc = 1.0f / (2.0f * M_PI * fc);
float val = 1.0f - std::exp(-1.0f / (rc * sampleRate_));
alpha_ = std::fmin(val, 0.999f);
float sr = std::fmax(sampleRate_, 1.0f);
float fc = std::fmin(std::fmax(cutOff_, 1.0f), 0.45f * sr);
g_ = std::tan(static_cast<float>(M_PI) * (fc / sr));
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) {
@ -38,10 +54,16 @@ void Filter::setCutOff(float newCutOff) {
float Filter::getCutOff() const { return cutOff_; }
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_; }
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) {
sampleRate_ = newSampleRate;
recompute();

View file

@ -17,17 +17,29 @@ public:
float getCutOff() const;
void setFeedback(float newFeedback);
float getFeedback() const;
void setResonance(float newResonance);
float getResonance() const;
void setSampleRate(float newSampleRate);
float getSampleRate() const;
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 feedback_;
float alpha_;
float resonance_;
float a1_;
float a2_;
float a3_;
float g_;
float k_;
float sampleRate_;
float zL_;
float zR_;
float s1L_;
float s2L_;
float s1R_;
float s2R_;
float outZL_;
float outZR_;
};
#endif // FILTER_HPP_INCLUDED

View file

@ -9,7 +9,7 @@
#define DISTRHO_PLUGIN_NUM_INPUTS 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_STATE 0

View file

@ -30,6 +30,7 @@ public:
kParamFilter,
kParamFilterFeedback,
kParamMixVolume,
kParamResonance,
kParameterCount // must be last
};
SquidgeDistortion()
@ -83,11 +84,11 @@ protected:
parameter.hints = kParameterIsAutomatable;
break;
case kParamFilterFeedback:
parameter.name = "Filter Feedback";
parameter.name = "Feedback";
parameter.symbol = "filterfeedback";
parameter.ranges.min = 0.0f;
parameter.ranges.def = .1f;
parameter.ranges.max = 0.99f;
parameter.ranges.def = 0.0f;
parameter.ranges.max = 0.95f;
parameter.hints = kParameterIsAutomatable;
break;
case kParamMixVolume:
@ -98,6 +99,14 @@ protected:
parameter.ranges.max = 1.0f;
parameter.hints = kParameterIsAutomatable;
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();
case kParamMixVolume:
return mixer_.getInputGain(kChannelWet);
case kParamResonance:
return (float)filter_.getResonance();
}
return 0.0f;
}
@ -137,6 +148,9 @@ protected:
mixer_.setInputGain(kChannelWet, value);
mixer_.setInputGain(kChannelDry, 1.0f - value);
break;
case kParamResonance:
filter_.setResonance(value);
break;
}
}