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> #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();

View file

@ -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

View file

@ -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

View file

@ -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;
} }
} }