aboutsummaryrefslogtreecommitdiffstats
path: root/ofxMaxim
diff options
context:
space:
mode:
authorChris Kiefer <chrisk13fer@gmail.com>2013-07-05 11:06:14 +0100
committerChris Kiefer <chrisk13fer@gmail.com>2013-07-05 11:06:14 +0100
commit8338a16fd441ab1b5497afb68566fb61cbe486e2 (patch)
treef6e60830d8ad245584a64cc91ae346c83a0193c4 /ofxMaxim
parent7f4c6ff482637ea9be4fe69448099fc3cebe73fd (diff)
state variable filter
Diffstat (limited to 'ofxMaxim')
-rwxr-xr-xofxMaxim/ofxMaxim/libs/maximilian.h68
1 files changed, 68 insertions, 0 deletions
diff --git a/ofxMaxim/ofxMaxim/libs/maximilian.h b/ofxMaxim/ofxMaxim/libs/maximilian.h
index f46a2e3..8d36c91 100755
--- a/ofxMaxim/ofxMaxim/libs/maximilian.h
+++ b/ofxMaxim/ofxMaxim/libs/maximilian.h
@@ -551,5 +551,73 @@ public:
}
};
+/*
+ State Variable Filter
+
+ algorithm from http://www.cytomic.com/files/dsp/SvfLinearTrapOptimised.pdf
+ usage:
+ either set the parameters separately as required (to save CPU)
+
+ filter.setCutoff(param1);
+ filter.setResonance(param2);
+
+ w = filter.play(w, 0.0, 1.0, 0.0, 0.0);
+
+ or set everything together at once
+
+ w = filter.setCutoff(param1).setResonance(param2).play(w, 0.0, 1.0, 0.0, 0.0);
+
+ */
+class maxiSVF {
+public:
+ maxiSVF() : v0z(0), v1(0), v2(0) { setParams(1000, 1);}
+
+ //20 < cutoff < 20000
+ inline maxiSVF& setCutoff(double cutoff) {
+ setParams(cutoff, res);
+ return *this;
+ }
+
+ //from 0 upwards, starts to ring from 2-3ish, cracks a bit around 10
+ inline maxiSVF& setResonance(double q) {
+ setParams(freq, q);
+ return *this;
+ }
+
+ //run the filter, and get a mixture of lowpass, bandpass, highpass and notch outputs
+ inline double play(double w, double lpmix, double bpmix, double hpmix, double notchmix) {
+ double low, band, high, notch;
+ double v1z = v1;
+ double v2z = v2;
+ double v3 = w + v0z - 2.0 * v2z;
+ v1 += g1*v3-g2*v1z;
+ v2 += g3*v3+g4*v1z;
+ v0z = w;
+ low = v2;
+ band = v1;
+ high = w-k*v1-v2;
+ notch = w-k*v1;
+ return (low * lpmix) + (band * bpmix) + (high * hpmix) + (notch * notchmix);
+ }
+
+private:
+ inline void setParams(double _freq, double _res) {
+ freq = _freq;
+ res = _res;
+ g = tan(PI * freq / maxiSettings::sampleRate);
+ damping = 1.0 / res;
+ k = damping;
+ ginv = g / (1.0 + g * (g + k));
+ g1 = ginv;
+ g2 = 2.0 * (g + k) * ginv;
+ g3 = g * ginv;
+ g4 = 2.0 * ginv;
+ }
+
+ double v0z, v1, v2, g, damping, k, ginv, g1, g2, g3 ,g4;
+ double freq, res;
+
+};
+
#endif