aboutsummaryrefslogtreecommitdiff
path: root/filters
diff options
context:
space:
mode:
authorGuenter Geiger <ggeiger@users.sourceforge.net>2002-06-17 10:13:57 +0000
committerGuenter Geiger <ggeiger@users.sourceforge.net>2002-06-17 10:13:57 +0000
commitfc3d3c0a4f110a23335398c327ac0a4fc949d5cb (patch)
tree1849d6afbe34cee9cec97bdb2295401f5126870b /filters
This commit was generated by cvs2svn to compensate for changes in r12,svn2git-root
which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/ggee/; revision=13
Diffstat (limited to 'filters')
-rwxr-xr-xfilters/Makefile50
-rwxr-xr-xfilters/bandpass.c86
-rwxr-xr-xfilters/bandpass.pd38
-rwxr-xr-xfilters/equalizer.c89
-rwxr-xr-xfilters/equalizer.pd39
-rwxr-xr-xfilters/filters.h74
-rwxr-xr-xfilters/filtgain.pd74
-rwxr-xr-xfilters/highpass.c87
-rwxr-xr-xfilters/highpass.pd35
-rwxr-xr-xfilters/highshelf.c90
-rwxr-xr-xfilters/highshelf.pd39
-rwxr-xr-xfilters/hlshelf.c226
-rwxr-xr-xfilters/hlshelf.pd34
-rwxr-xr-xfilters/lowpass.c89
-rwxr-xr-xfilters/lowpass.pd35
-rwxr-xr-xfilters/lowshelf.c91
-rwxr-xr-xfilters/lowshelf.pd39
-rwxr-xr-xfilters/moog~.c182
-rwxr-xr-xfilters/moog~.pd39
-rwxr-xr-xfilters/notch.c89
-rwxr-xr-xfilters/notch.pd35
21 files changed, 1560 insertions, 0 deletions
diff --git a/filters/Makefile b/filters/Makefile
new file mode 100755
index 0000000..f002498
--- /dev/null
+++ b/filters/Makefile
@@ -0,0 +1,50 @@
+current: nt
+
+
+# TARGETS += stk
+
+VERSION = \"0.24\"
+
+.SUFFIXES: .dll .obj
+# ----------------------- NT ----------------------------
+
+NTOBJECTS = *.obj
+NTDLLS = *.dll
+
+PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
+
+PDNTINCLUDE = /I. /I..\..\pd\src
+ProgramFiles = C:\Program Files
+PDNTLDIR = "$(ProgramFiles)\Microsoft Visual Studio\Vc98\lib"
+#PDNTLDIR = "C:\Programme\Msdev\Vc98\lib"
+
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\wsock32.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ $(PDNTLDIR)\uuid.lib \
+ ..\..\pd\bin\pd.lib
+
+nt: $(NTOBJECTS)
+ -link /dll $(PDNTLIB) bandpass.obj /export:bandpass_setup
+ -link /dll $(PDNTLIB) highpass.obj /export:highpass_setup
+ -link /dll $(PDNTLIB) highshelf.obj /export:highshelf_setup
+ -link /dll $(PDNTLIB) hlshelf.obj /export:hlshelf_setup
+ -link /dll $(PDNTLIB) lowpass.obj /export:lowpass_setup
+ -link /dll $(PDNTLIB) notch.obj /export:notch_setup
+ -link /dll $(PDNTLIB) equalizer.obj /export:equalizer_setup
+
+
+clean:
+ del *.obj
+ del *.dll
+
+
+.c.obj:
+ -cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+
+.obj.dll:
+
+
+
+
diff --git a/filters/bandpass.c b/filters/bandpass.c
new file mode 100755
index 0000000..c4c2e13
--- /dev/null
+++ b/filters/bandpass.c
@@ -0,0 +1,86 @@
+
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+/* ------------------- bandpass ----------------------------*/
+
+static t_class *bandpass_class;
+
+void bandpass_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float alpha = e_alpha(x->x_bw* 0.01,omega);
+ t_float b1 = 0.;
+ t_float b0 = alpha;
+ t_float b2 = -alpha;
+ t_float a0 = 1 + alpha;
+ t_float a1 = -2.*cos(omega);
+ t_float a2 = 1 - alpha;
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("bandpass: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void bandpass_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ bandpass_bang(x);
+}
+
+
+static void *bandpass_new(t_floatarg f,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(bandpass_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+/* floatinlet_new(&x->x_obj, &x->x_gain); */
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ return (x);
+}
+
+
+void bandpass_setup(void)
+{
+ bandpass_class = class_new(gensym("bandpass"), (t_newmethod)bandpass_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(bandpass_class,bandpass_bang);
+ class_addfloat(bandpass_class,bandpass_float);
+}
+
+
+
diff --git a/filters/bandpass.pd b/filters/bandpass.pd
new file mode 100755
index 0000000..73cace4
--- /dev/null
+++ b/filters/bandpass.pd
@@ -0,0 +1,38 @@
+#N canvas 295 68 622 469 10;
+#X obj 77 199 print;
+#X floatatom 77 114 0 0 0;
+#X floatatom 139 114 0 0 0;
+#X msg 360 109 \; paint 0;
+#X obj 164 196 filtgain;
+#X msg 91 138 bang;
+#X text 139 93 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which
+is expressed in octaves. A bandwidth of 100 is equivalent to one octave.
+;
+#X text 358 25 click first;
+#X text 186 159 click on filtgain to view frequency plot;
+#X text 76 12 Bandpass coefficients for biquad~;
+#X text 70 26 ===================================;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients
+for biquad~;
+#X obj 77 160 bandpass 4000 33;
+#X obj 33 114 r doit;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X connect 1 0 24 0;
+#X connect 2 0 24 1;
+#X connect 2 0 5 0;
+#X connect 5 0 24 0;
+#X connect 24 0 0 0;
+#X connect 24 0 4 0;
+#X connect 25 0 5 0;
diff --git a/filters/equalizer.c b/filters/equalizer.c
new file mode 100755
index 0000000..80d8410
--- /dev/null
+++ b/filters/equalizer.c
@@ -0,0 +1,89 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+
+/* ------------------- equ ----------------------------*/
+static t_class *equ_class;
+
+void equ_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float alpha = e_alpha(x->x_bw*0.01,omega);
+ t_float b0 = 1 + alpha*e_A(x->x_gain);
+ t_float b1 = -2.*cos(omega);
+ t_float b2 = 1;
+ t_float a0 = 1 + alpha;
+ t_float a1 = -2.*cos(omega);
+ t_float a2 = 1 - alpha;
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("equ: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void equ_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ equ_bang(x);
+}
+
+
+static void *equ_new(t_floatarg f,t_floatarg g,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(equ_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+ floatinlet_new(&x->x_obj, &x->x_gain);
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ if (g != 0.) x->x_gain = g;
+ return (x);
+}
+
+
+void equalizer_setup(void)
+{
+ equ_class = class_new(gensym("equalizer"), (t_newmethod)equ_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(equ_class,equ_bang);
+ class_addfloat(equ_class,equ_float);
+}
+
+
+
+
+
diff --git a/filters/equalizer.pd b/filters/equalizer.pd
new file mode 100755
index 0000000..05f7c56
--- /dev/null
+++ b/filters/equalizer.pd
@@ -0,0 +1,39 @@
+#N canvas 561 126 620 459 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 186 112;
+#X msg 360 117 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 186 91 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 200 158 click on filtgain to view frequency plot;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X floatatom 129 113;
+#X text 138 92 gain;
+#X text 71 26 ==============================================;
+#X text 76 12 Parametric Equalizer coefficients for biquad~;
+#X obj 77 160 equalizer 5000 70 8;
+#X obj 31 114 r doit;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X connect 1 0 26 0;
+#X connect 2 0 5 0;
+#X connect 2 0 26 2;
+#X connect 5 0 26 0;
+#X connect 22 0 5 0;
+#X connect 22 0 26 1;
+#X connect 26 0 0 0;
+#X connect 26 0 4 0;
+#X connect 27 0 26 0;
diff --git a/filters/filters.h b/filters/filters.h
new file mode 100755
index 0000000..6ff7962
--- /dev/null
+++ b/filters/filters.h
@@ -0,0 +1,74 @@
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+
+#ifndef __GGEE_FILTERS_H__
+#define __GGEE_FILTERS_H__
+
+
+
+#ifndef M_PI
+#define M_PI 3.141593f
+#endif
+
+
+#include <math.h>
+#define LN2 0.69314718
+#define e_A(g) (pow(10,(g/40.)))
+#define e_omega(f,r) (2.0*M_PI*f/r)
+#define e_alpha(bw,omega) (sin(omega)*sinh(LN2/2. * bw * omega/sin(omega)))
+#define e_beta(a,S) (sqrt((a*a + 1)/(S) - (a-1)*(a-1)))
+
+
+
+
+typedef struct _rbjfilter
+{
+ t_object x_obj;
+ t_float x_rate;
+ t_float x_freq;
+ t_float x_gain;
+ t_float x_bw;
+} t_rbjfilter;
+
+
+static int check_stability(t_float fb1,
+ t_float fb2,
+ t_float ff1,
+ t_float ff2,
+ t_float ff3)
+{
+ float discriminant = fb1 * fb1 + 4 * fb2;
+
+ if (discriminant < 0) /* imaginary roots -- resonant filter */
+ {
+ /* they're conjugates so we just check that the product
+ is less than one */
+ if (fb2 >= -1.0f) goto stable;
+ }
+ else /* real roots */
+ {
+ /* check that the parabola 1 - fb1 x - fb2 x^2 has a
+ vertex between -1 and 1, and that it's nonnegative
+ at both ends, which implies both roots are in [1-,1]. */
+ if (fb1 <= 2.0f && fb1 >= -2.0f &&
+ 1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0)
+ goto stable;
+ }
+ return 0;
+stable:
+ return 1;
+}
+
+
+
+
+
+
+#endif
diff --git a/filters/filtgain.pd b/filters/filtgain.pd
new file mode 100755
index 0000000..b276a52
--- /dev/null
+++ b/filters/filtgain.pd
@@ -0,0 +1,74 @@
+#N canvas 178 144 702 459 10;
+#X obj 38 342 biquad~;
+#X obj 38 316 osc~ 220;
+#X obj 118 340 env~;
+#X floatatom 38 297;
+#X obj 38 419 dac~;
+#X obj 193 428 tabwrite array1;
+#X obj 325 400 int;
+#X obj 350 401 + 1;
+#X msg 296 399 0;
+#X obj 193 410 float;
+#X obj 218 372 t b f;
+#X obj 38 398 *~;
+#X obj 61 399 dbtorms;
+#X floatatom 368 359;
+#X obj 296 418 sel 500;
+#X obj 38 277 * 40;
+#X obj 325 380 metro 10;
+#X obj 325 359 r paint;
+#X obj 61 381 r volume;
+#X obj 38 7 inlet;
+#X floatatom 194 368;
+#X floatatom 279 360;
+#X obj 118 360 - 100;
+#X obj 118 382 * 0.01;
+#X graph graph2 0 -1 500 1 148 253 648 113;
+#X array array1 500 float;
+#X pop;
+#X msg 273 272 5000;
+#X msg 273 82 5000;
+#X msg 398 82 10000;
+#X msg 398 272 10000;
+#X msg 173 83 1000;
+#X msg 173 271 1000;
+#X text 105 6 subpatch used in filter externals see;
+#X obj 347 12 bandpass;
+#X obj 414 13 notch;
+#X obj 470 14 lowpass;
+#X obj 522 13 highpass;
+#X obj 522 35 equalizer;
+#X obj 347 34 highshelf;
+#X obj 414 34 lowshelf;
+#X obj 470 34 hlshelf;
+#X connect 0 0 2 0;
+#X connect 0 0 11 0;
+#X connect 1 0 0 0;
+#X connect 2 0 22 0;
+#X connect 3 0 1 0;
+#X connect 6 0 7 0;
+#X connect 6 0 10 0;
+#X connect 6 0 14 0;
+#X connect 6 0 15 0;
+#X connect 7 0 6 1;
+#X connect 8 0 6 0;
+#X connect 9 0 5 0;
+#X connect 10 0 9 0;
+#X connect 10 1 5 1;
+#X connect 11 0 4 0;
+#X connect 11 0 4 1;
+#X connect 12 0 11 1;
+#X connect 13 0 16 1;
+#X connect 14 0 8 0;
+#X connect 15 0 3 0;
+#X connect 16 0 6 0;
+#X connect 17 0 16 0;
+#X connect 18 0 12 0;
+#X connect 19 0 0 0;
+#X connect 20 0 5 0;
+#X connect 21 0 5 1;
+#X connect 22 0 23 0;
+#X connect 23 0 9 1;
+#X connect 26 0 25 0;
+#X connect 27 0 28 0;
+#X connect 29 0 30 0;
diff --git a/filters/highpass.c b/filters/highpass.c
new file mode 100755
index 0000000..e7e0443
--- /dev/null
+++ b/filters/highpass.c
@@ -0,0 +1,87 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+/* ------------------- highpass ----------------------------*/
+
+static t_class *highpass_class;
+
+void highpass_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float alpha = e_alpha(x->x_bw* 0.01,omega);
+ t_float b1 = -(1 + cos(omega));
+ t_float b0 = -b1/2.;
+ t_float b2 = b0;
+ t_float a0 = 1 + alpha;
+ t_float a1 = -2.*cos(omega);
+ t_float a2 = 1 - alpha;
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("highpass: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void highpass_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ highpass_bang(x);
+}
+
+
+static void *highpass_new(t_floatarg f,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(highpass_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+/* floatinlet_new(&x->x_obj, &x->x_gain); */
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ return (x);
+}
+
+
+void highpass_setup(void)
+{
+ highpass_class = class_new(gensym("highpass"), (t_newmethod)highpass_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(highpass_class,highpass_bang);
+ class_addfloat(highpass_class,highpass_float);
+}
+
+
+
+
diff --git a/filters/highpass.pd b/filters/highpass.pd
new file mode 100755
index 0000000..e953888
--- /dev/null
+++ b/filters/highpass.pd
@@ -0,0 +1,35 @@
+#N canvas 365 183 620 463 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 168 115;
+#X msg 360 109 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 168 94 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 182 148 click on filtgain to view frequency plot;
+#X text 70 26 ===================================;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X text 76 12 Highpass coefficients for biquad~;
+#X obj 77 160 highpass 4000 33;
+#X obj 34 113 r doit;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X connect 1 0 24 0;
+#X connect 2 0 5 0;
+#X connect 2 0 24 1;
+#X connect 5 0 24 0;
+#X connect 24 0 0 0;
+#X connect 24 0 4 0;
+#X connect 25 0 24 0;
diff --git a/filters/highshelf.c b/filters/highshelf.c
new file mode 100755
index 0000000..ee6006c
--- /dev/null
+++ b/filters/highshelf.c
@@ -0,0 +1,90 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+/* ------------------- highshelf ----------------------------*/
+
+static t_class *highshelf_class;
+
+void highshelf_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float A = e_A(x->x_gain);
+ t_float cs = cos(omega);
+ t_float sn = sin(omega);
+ t_float beta = e_beta(A,x->x_bw* 0.01);
+
+ t_float b0 = A*((A+1) + (A-1)*cs + beta*sn);
+ t_float b1 =-2.*A*((A-1) + (A+1)*cs);
+ t_float b2 = A*((A+1) + (A-1)*cs - beta*sn);
+ t_float a0 = ((A+1) - (A-1)*cs + beta*sn);
+ t_float a1 = 2.*((A-1) - (A+1)*cs);
+ t_float a2 = ((A+1) - (A-1)*cs - beta*sn);
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("highshelf: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void highshelf_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ highshelf_bang(x);
+}
+
+
+static void *highshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(highshelf_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+ floatinlet_new(&x->x_obj, &x->x_gain);
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ if (g != 0.) x->x_gain = g;
+ return (x);
+}
+
+
+void highshelf_setup(void)
+{
+ highshelf_class = class_new(gensym("highshelf"), (t_newmethod)highshelf_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(highshelf_class,highshelf_bang);
+ class_addfloat(highshelf_class,highshelf_float);
+}
+
+
diff --git a/filters/highshelf.pd b/filters/highshelf.pd
new file mode 100755
index 0000000..be2a577
--- /dev/null
+++ b/filters/highshelf.pd
@@ -0,0 +1,39 @@
+#N canvas 310 193 620 455 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 186 112;
+#X msg 360 117 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 208 159 click on filtgain to view frequency plot;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X floatatom 129 113;
+#X text 138 92 gain;
+#X text 71 26 ==============================================;
+#X text 186 91 slope (0 - 100);
+#X text 76 12 Highshelf coefficients for biquad~;
+#X obj 77 160 highshelf 5000 70 100;
+#X obj 30 113 r doit;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X connect 1 0 26 0;
+#X connect 2 0 5 0;
+#X connect 2 0 26 2;
+#X connect 5 0 26 0;
+#X connect 21 0 5 0;
+#X connect 21 0 26 1;
+#X connect 26 0 0 0;
+#X connect 26 0 4 0;
+#X connect 27 0 26 0;
diff --git a/filters/hlshelf.c b/filters/hlshelf.c
new file mode 100755
index 0000000..a2189d7
--- /dev/null
+++ b/filters/hlshelf.c
@@ -0,0 +1,226 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include <math.h>
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ hlshelf ----------------------------- */
+
+
+#ifndef M_PI
+#define M_PI 3.141593f
+#endif
+
+#define SRATE 44100.0
+#define MAX_GAIN 120.0f
+
+static t_class *hlshelf_class;
+
+
+typedef struct _hlshelf
+{
+ t_object x_obj;
+ float s_rate;
+ float s_gain0;
+ float s_gain1;
+ float s_gain2;
+ float s_ltransfq;
+ float s_htransfq;
+ float s_lradians;
+ float s_hradians;
+} t_hlshelf;
+
+
+int hlshelf_check_stability(t_float fb1,
+ t_float fb2,
+ t_float ff1,
+ t_float ff2,
+ t_float ff3)
+{
+ float discriminant = fb1 * fb1 + 4 * fb2;
+
+ if (discriminant < 0) /* imaginary roots -- resonant filter */
+ {
+ /* they're conjugates so we just check that the product
+ is less than one */
+ if (fb2 >= -1.0f) goto stable;
+ }
+ else /* real roots */
+ {
+ /* check that the parabola 1 - fb1 x - fb2 x^2 has a
+ vertex between -1 and 1, and that it's nonnegative
+ at both ends, which implies both roots are in [1-,1]. */
+ if (fb1 <= 2.0f && fb1 >= -2.0f &&
+ 1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0)
+ goto stable;
+ }
+ return 0;
+stable:
+ return 1;
+}
+
+
+void hlshelf_check(t_hlshelf *x)
+{
+
+ if(x->s_gain0 - x->s_gain1 > MAX_GAIN) {
+ x->s_gain0 = x->s_gain1 + MAX_GAIN;
+ post("setting gain0 to %f",x->s_gain0);
+ }
+
+
+ if(x->s_gain1 > MAX_GAIN) {
+ x->s_gain1 = MAX_GAIN;
+ post("setting gain1 to %f",x->s_gain1);
+ }
+
+ if(x->s_gain2 - x->s_gain1 > MAX_GAIN) {
+ x->s_gain2 = x->s_gain1 + MAX_GAIN;
+ post("setting gain2 to %f",x->s_gain2);
+ }
+
+ /* constrain: 0 <= x->s_ltransfq < x->s_htransfq. */
+ x->s_ltransfq = (x->s_ltransfq < x->s_htransfq) ? x->s_ltransfq : x->s_htransfq - 0.5f;
+
+ if (x->s_ltransfq < 0) x->s_ltransfq = 0.0f;
+
+ x->s_lradians = M_PI * x->s_ltransfq / x->s_rate;
+ x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate));
+
+}
+
+
+void hlshelf_bang(t_hlshelf *x)
+{
+ t_atom at[6];
+ float c0, c1, c2, d0, d1, d2; /* output coefs */
+ float a1, a2, b1, b2, g1, g2; /* temp coefs */
+ double xf;
+
+ hlshelf_check(x);
+
+ /* low shelf */
+ xf = 0.5 * 0.115129255 * (double)(x->s_gain0 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */
+ if(xf < -200.) /* exp(x) -> 0 */
+ {
+ a1 = 1.0f;
+ b1 = -1.0f;
+ g1 = 0.0f;
+ }
+ else
+ {
+ double t = tan(x->s_lradians);
+ double e = exp(xf);
+ double r = t / e;
+ double kr = t * e;
+
+ a1 = (r - 1) / (r + 1);
+ b1 = (kr - 1) / (kr + 1);
+ g1 = (kr + 1) / (r + 1);
+ }
+
+ /* high shelf */
+ xf = 0.5 * 0.115129255 * (double)(x->s_gain2 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */
+ if(xf < -200.) /* exp(x) -> 0 */
+ {
+ a2 = -1.0f;
+ b2 = 1.0f;
+ g2 = 0.0f;
+ }
+ else
+ {
+ double t = tan(x->s_hradians);
+ double e = exp(xf);
+ double r = t / e;
+ double kr = t * e;
+
+ a2 = (1 - r) / (1 + r);
+ b2 = (1 - kr) / (1 + kr);
+ g2 = (1 + kr) / (1 + r);
+ }
+
+ /* form product */
+ c0 = g1 * g2 * (float)(exp((double)(x->s_gain1) * 0.05f * 2.302585093f)); ;
+ c1 = a1 + a2;
+ c2 = a1 * a2;
+ d0 = 1.0f;
+ d1 = b1 + b2;
+ d2 = b1 * b2;
+
+ if (!hlshelf_check_stability(-c1/d0,-c2/d0,d0/d0,d1/d0,d2/d0)) {
+ post("hlshelf: filter unstable -> resetting");
+ c0=1.;c1=0.;c2=0.;
+ d0=1.;d1=0.;d2=0.;
+ }
+
+ SETFLOAT(at,-c1/d0);
+ SETFLOAT(at+1,-c2/d0);
+ SETFLOAT(at+2,d0/d0);
+ SETFLOAT(at+3,d1/d0);
+ SETFLOAT(at+4,d2/d0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+void hlshelf_float(t_hlshelf *x,t_floatarg f)
+{
+ x->s_gain0 = f;
+ hlshelf_bang(x);
+}
+
+
+static void *hlshelf_new(t_symbol* s,t_int argc, t_atom* at)
+{
+ t_hlshelf *x = (t_hlshelf *)pd_new(hlshelf_class);
+ t_float k0 = atom_getfloat(at);
+ t_float k1 = atom_getfloat(at+1);
+ t_float k2 = atom_getfloat(at+2);
+ t_float f1 = atom_getfloat(at+3);
+ t_float f2 = atom_getfloat(at+4);
+
+
+ f1 = atom_getfloat(at);
+ f2 = atom_getfloat(at);
+
+ if ((f1 == 0.0f && f2 == 0.0f) || f1 > f2){ /* all gains = 0db */
+ f1 = 150.0f;
+ f2 = 5000.0f;
+ }
+
+ if (f1 < 0) f1 = 0.0f;
+ if (f2 > SRATE) f2 = .5f*SRATE;
+
+ x->s_rate = SRATE; /* srate default */
+ x->s_gain0 = k0;
+ x->s_gain1 = k1;
+ x->s_gain2 = k2;
+
+ x->s_ltransfq = 0.0f;
+ x->s_htransfq = SRATE/2;
+
+ x->s_lradians = M_PI * x->s_ltransfq / x->s_rate;
+ x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate));
+
+ floatinlet_new(&x->x_obj, &x->s_gain1);
+ floatinlet_new(&x->x_obj, &x->s_gain2);
+ floatinlet_new(&x->x_obj, &x->s_ltransfq);
+ floatinlet_new(&x->x_obj, &x->s_htransfq);
+ outlet_new(&x->x_obj, &s_list);
+
+ return (x);
+}
+
+void hlshelf_setup(void)
+{
+ hlshelf_class = class_new(gensym("hlshelf"), (t_newmethod)hlshelf_new, 0,
+ sizeof(t_hlshelf), 0, A_GIMME, 0);
+ class_addbang(hlshelf_class,hlshelf_bang);
+ class_addfloat(hlshelf_class,hlshelf_float);
+}
+
+
diff --git a/filters/hlshelf.pd b/filters/hlshelf.pd
new file mode 100755
index 0000000..0e5251d
--- /dev/null
+++ b/filters/hlshelf.pd
@@ -0,0 +1,34 @@
+#N canvas 365 183 620 471 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 139 114;
+#X msg 360 109 \; paint 0;
+#X obj 159 175 filtgain;
+#X text 139 93 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 158 159 click on filtgain to view frequency plot;
+#X text 76 12 Bandpass coefficients for biquad~;
+#X text 70 26 ===================================;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X obj 77 61 r freq;
+#X obj 139 61 r bw;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; freq 4000 \; bw 33;
+#X obj 77 160 hlshelf;
+#X connect 1 0 26 0;
+#X connect 2 0 26 1;
+#X connect 23 0 1 0;
+#X connect 24 0 2 0;
+#X connect 26 0 0 0;
+#X connect 26 0 4 0;
diff --git a/filters/lowpass.c b/filters/lowpass.c
new file mode 100755
index 0000000..4e1b2b9
--- /dev/null
+++ b/filters/lowpass.c
@@ -0,0 +1,89 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+
+/* ------------------- lowpass ----------------------------*/
+
+static t_class *lowpass_class;
+
+void lowpass_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float alpha = e_alpha(x->x_bw*0.01,omega);
+ t_float b1 = 1 - cos(omega);
+ t_float b0 = b1/2.;
+ t_float b2 = b0;
+ t_float a0 = 1 + alpha;
+ t_float a1 = -2.*cos(omega);
+ t_float a2 = 1 - alpha;
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("lowpass: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void lowpass_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ lowpass_bang(x);
+}
+
+
+static void *lowpass_new(t_floatarg f,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(lowpass_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+/* floatinlet_new(&x->x_obj, &x->x_gain); */
+ floatinlet_new(&x->x_obj, &x->x_bw);
+
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ return (x);
+}
+
+
+void lowpass_setup(void)
+{
+ lowpass_class = class_new(gensym("lowpass"), (t_newmethod)lowpass_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(lowpass_class,lowpass_bang);
+ class_addfloat(lowpass_class,lowpass_float);
+}
+
+
+
+
diff --git a/filters/lowpass.pd b/filters/lowpass.pd
new file mode 100755
index 0000000..9d15c16
--- /dev/null
+++ b/filters/lowpass.pd
@@ -0,0 +1,35 @@
+#N canvas 365 183 620 467 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 162 114;
+#X msg 360 109 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 139 93 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 175 159 click on filtgain to view frequency plot;
+#X text 70 26 ===================================;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X text 71 12 Lowpass coefficients for biquad~;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X obj 32 114 r doit;
+#X obj 77 160 lowpass 4000 33;
+#X connect 1 0 26 0;
+#X connect 2 0 5 0;
+#X connect 2 0 26 1;
+#X connect 5 0 26 0;
+#X connect 25 0 26 0;
+#X connect 26 0 0 0;
+#X connect 26 0 4 0;
diff --git a/filters/lowshelf.c b/filters/lowshelf.c
new file mode 100755
index 0000000..dd925dc
--- /dev/null
+++ b/filters/lowshelf.c
@@ -0,0 +1,91 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+
+/* ------------------- lowshelf ----------------------------*/
+
+static t_class *lowshelf_class;
+
+void lowshelf_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float A = e_A(x->x_gain);
+ t_float cs = cos(omega);
+ t_float sn = sin(omega);
+ t_float beta = e_beta(A,x->x_bw*0.01);
+
+ t_float b0 = A*((A+1) - (A-1)*cs + beta*sn);
+ t_float b1 = 2.*A*((A-1) - (A+1)*cs);
+ t_float b2 = A*((A+1) - (A-1)*cs - beta*sn);
+ t_float a0 = ((A+1) + (A-1)*cs + beta*sn);
+ t_float a1 = -2.*((A-1) + (A+1)*cs);
+ t_float a2 = ((A+1) + (A-1)*cs - beta*sn);
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("lowshelf: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void lowshelf_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ lowshelf_bang(x);
+}
+
+
+static void *lowshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(lowshelf_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+ floatinlet_new(&x->x_obj, &x->x_gain);
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ if (g != 0.) x->x_gain = g;
+ return (x);
+}
+
+
+void lowshelf_setup(void)
+{
+ lowshelf_class = class_new(gensym("lowshelf"), (t_newmethod)lowshelf_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(lowshelf_class,lowshelf_bang);
+ class_addfloat(lowshelf_class,lowshelf_float);
+}
+
+
diff --git a/filters/lowshelf.pd b/filters/lowshelf.pd
new file mode 100755
index 0000000..140c754
--- /dev/null
+++ b/filters/lowshelf.pd
@@ -0,0 +1,39 @@
+#N canvas 365 183 620 459 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 192 113;
+#X msg 360 117 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 211 159 click on filtgain to view frequency plot;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X floatatom 129 113;
+#X text 138 92 gain;
+#X text 71 26 ==============================================;
+#X text 192 92 slope (0 - 100);
+#X text 76 12 Lowshelf coefficients for biquad~;
+#X obj 31 113 r doit;
+#X msg 360 45 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X obj 77 160 lowshelf 4000 50 100;
+#X connect 1 0 28 0;
+#X connect 2 0 5 0;
+#X connect 2 0 28 2;
+#X connect 5 0 28 0;
+#X connect 21 0 5 0;
+#X connect 21 0 28 1;
+#X connect 26 0 28 0;
+#X connect 28 0 0 0;
+#X connect 28 0 4 0;
diff --git a/filters/moog~.c b/filters/moog~.c
new file mode 100755
index 0000000..924ff31
--- /dev/null
+++ b/filters/moog~.c
@@ -0,0 +1,182 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include "math.h"
+#include <m_pd.h>
+
+/* ----------------------------- moog ----------------------------- */
+static t_class *moog_class;
+
+
+typedef struct _moog
+{
+ t_object x_obj;
+ t_pd in2;
+ t_float x_1,x_2,x_3,x_4;
+ t_float y_1,y_2,y_3,y_4;
+} t_moog;
+
+static void moog_reset(t_moog *x)
+{
+ x->x_1 = x->x_2 = x->x_3 = x->x_4 = 0.0;
+ x->y_1 = x->y_2 = x->y_3 = x->y_4 = 0.0;
+
+}
+
+
+
+static void *moog_new(t_symbol *s, int argc, t_atom *argv)
+{
+ if (argc > 1) post("moog~: extra arguments ignored");
+ {
+ t_moog *x = (t_moog *)pd_new(moog_class);
+ outlet_new(&x->x_obj, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->in2, &s_signal, &s_signal);
+ moog_reset(x);
+ return (x);
+ }
+
+
+}
+
+
+
+static t_float calc_k(t_float f,t_float k) {
+ if (k>4.) k =4.;
+ if (k < 0.) k = 0.;
+ if (f <= 3800) return k;
+ k = k - 0.5*((f-3800)/4300);
+ return k;
+}
+
+t_int *moog_perform(t_int *w)
+{
+ t_moog* x = (t_moog*) (w[1]);
+ t_float *in1 = (t_float *)(w[2]);
+ t_float *p = (t_float *)(w[3]);
+ t_float *k = (t_float *)(w[4]);
+
+ t_float *out = (t_float *)(w[5]);
+ int n = (int)(w[6]);
+ float in;
+ float pt,pt1;
+
+ float x1 = x->x_1;
+ float x2 = x->x_2;
+ float x3 = x->x_3;
+ float x4 = x->x_4;
+ float y1 = x->y_1;
+ float y2 = x->y_2;
+ float y3 = x->y_3;
+ float y4 = x->y_4;
+
+
+ while (n--) {
+ if (*p > 8140) *p = 8140.;
+ *k = calc_k(*p,*k);
+ pt =*p;
+ pt1=(pt+1)*0.76923077;
+ in = *in1++ - *k*y4;
+ y1 = (pt1)*in + 0.3*x1 - pt*y1;
+ x1 = in;
+ y2 = (pt1)*y1 + 0.3*x2 - pt*y2;
+ x2 = y1;
+ y3 = (pt1)*y2 + 0.3 *x3 - pt*y3;
+ x3 = y2;
+ y4 = (pt1)*y3 + 0.3*x4 - pt*y4;
+ x4 = y3;
+ *out++ = y4;
+ }
+
+
+ x->y_1 = y1;
+ x->y_2 = y2;
+ x->y_3 = y3;
+ x->y_4 = y4;
+ x->x_1 = x1;
+ x->x_2 = x2;
+ x->x_3 = x3;
+ x->x_4 = x4;
+
+ return (w+7);
+}
+
+
+#define CLIP(x) x = ((x) > 1.0 ? (1.0) : (x))
+
+t_int *moog_perf8(t_int *w)
+{
+ t_moog* x = (t_moog*) (w[1]);
+ t_float *in1 = (t_float *)(w[2]);
+ t_float *p = (t_float *)(w[3]);
+ t_float *k = (t_float *)(w[4]);
+ t_float *out = (t_float *)(w[5]);
+ int n = (int)(w[6]);
+
+ t_float x1 = x->x_1;
+ t_float x2 = x->x_2;
+ t_float x3 = x->x_3;
+ t_float x4 = x->x_4;
+ t_float y1 = x->y_1;
+ t_float y2 = x->y_2;
+ t_float y3 = x->y_3;
+ t_float y4 = x->y_4;
+ t_float temp,temp2;
+ t_float pt,pt1;
+ t_float in;
+
+ while (n--) {
+ if (*p > 8140.) *p = 8140.;
+ *k = calc_k(*p,*k);
+
+ pt =*p* 0.01*0.0140845 - 0.9999999f;
+ pt1=(pt+1.0)*0.76923077;
+ in = *in1++ - *k*y4;
+ y1 = pt1*(in + 0.3*x1) - pt*y1;
+ x1 = in;
+ y2 = pt1*(y1 + 0.3*x2) - pt*y2;
+ x2 = y1;
+ y3 = pt1*(y2 + 0.3*x3) - pt*y3;
+ x3 = y2;
+ y4 = pt1*(y3 + 0.3*x4) - pt*y4;
+ x4 = y3;
+ *out++ = y4;
+
+ p++;k++;
+ }
+
+ x->y_1 = y1;
+ x->y_2 = y2;
+ x->y_3 = y3;
+ x->y_4 = y4;
+ x->x_1 = x1;
+ x->x_2 = x2;
+ x->x_3 = x3;
+ x->x_4 = x4;
+
+ return (w+7);
+}
+
+void dsp_add_moog(t_moog *x, t_sample *in1, t_sample *in2, t_sample *in3, t_sample *out, int n)
+{
+ if (n&7)
+ dsp_add(moog_perform, 6,(t_int)x, in1,in2,in3, out, n);
+ else
+ dsp_add(moog_perf8, 6,(t_int) x, in1, in2, in3, out, n);
+}
+
+static void moog_dsp(t_moog *x, t_signal **sp)
+{
+ dsp_add_moog(x,sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,sp[0]->s_n);
+}
+
+
+void moog_tilde_setup(void)
+{
+ moog_class = class_new(gensym("moog~"), (t_newmethod)moog_new, 0,
+ sizeof(t_moog), 0, A_GIMME, 0);
+ class_addmethod(moog_class, nullfn, gensym("signal"), 0);
+ class_addmethod(moog_class, (t_method)moog_reset, gensym("reset"), 0);
+ class_addmethod(moog_class, (t_method)moog_dsp, gensym("dsp"), A_NULL);
+}
diff --git a/filters/moog~.pd b/filters/moog~.pd
new file mode 100755
index 0000000..7e0139b
--- /dev/null
+++ b/filters/moog~.pd
@@ -0,0 +1,39 @@
+#N canvas 225 113 568 397 10;
+#X obj 186 210 moog~;
+#X obj 178 288 dac~;
+#X floatatom 226 163 5 0 0;
+#X floatatom 183 104 5 0 0;
+#X floatatom 25 113 5 0 0;
+#X obj 238 237 env~;
+#X floatatom 238 257 5 0 0;
+#X obj 186 257 *~ 0.1;
+#X msg 182 163 reset;
+#X obj 116 105 +~ 1;
+#X floatatom 116 63 5 0 0;
+#X floatatom 180 128 5 0 0;
+#X obj 116 146 +~ 100;
+#X obj 116 84 osc~ 0.25;
+#X obj 116 125 *~ 2000;
+#X obj 226 182 sig~ 3;
+#X obj 25 139 phasor~ 110;
+#X msg 249 52 \; pd dsp 1 \;;
+#X text 17 7 A signal controlled "moog" resonant lowpass;
+#X text 272 163 Q (1-4);
+#X text 61 46 resonance freq modulation;
+#X connect 0 0 5 0;
+#X connect 0 0 7 0;
+#X connect 2 0 15 0;
+#X connect 3 0 14 1;
+#X connect 4 0 16 0;
+#X connect 5 0 6 0;
+#X connect 7 0 1 0;
+#X connect 7 0 1 1;
+#X connect 8 0 0 0;
+#X connect 9 0 14 0;
+#X connect 10 0 13 0;
+#X connect 11 0 12 1;
+#X connect 12 0 0 1;
+#X connect 13 0 9 0;
+#X connect 14 0 12 0;
+#X connect 15 0 0 2;
+#X connect 16 0 0 0;
diff --git a/filters/notch.c b/filters/notch.c
new file mode 100755
index 0000000..ab11a7a
--- /dev/null
+++ b/filters/notch.c
@@ -0,0 +1,89 @@
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+/*
+
+ These filter coefficients computations are taken from
+ http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
+
+ written by Robert Bristow-Johnson
+
+*/
+
+#include <m_pd.h>
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+#include <math.h>
+#include "filters.h"
+
+
+
+/* ------------------- notch ----------------------------*/
+
+static t_class *notch_class;
+
+void notch_bang(t_rbjfilter *x)
+{
+ t_atom at[5];
+ t_float omega = e_omega(x->x_freq,x->x_rate);
+ t_float alpha = e_alpha(x->x_bw* 0.01,omega);
+ t_float b1 = -2.*cos(omega);
+ t_float b0 = 1;
+ t_float b2 = b0;
+ t_float a0 = 1 + alpha;
+ t_float a1 = -2.*cos(omega);
+ t_float a2 = 1 - alpha;
+
+/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
+
+ if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
+ post("notch: filter unstable -> resetting");
+ a0=1.;a1=0.;a2=0.;
+ b0=1.;b1=0.;b2=0.;
+ }
+
+ SETFLOAT(at,-a1/a0);
+ SETFLOAT(at+1,-a2/a0);
+ SETFLOAT(at+2,b0/a0);
+ SETFLOAT(at+3,b1/a0);
+ SETFLOAT(at+4,b2/a0);
+
+ outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
+}
+
+
+void notch_float(t_rbjfilter *x,t_floatarg f)
+{
+ x->x_freq = f;
+ notch_bang(x);
+}
+
+
+static void *notch_new(t_floatarg f,t_floatarg bw)
+{
+ t_rbjfilter *x = (t_rbjfilter *)pd_new(notch_class);
+
+ x->x_rate = 44100.0;
+ outlet_new(&x->x_obj,&s_float);
+/* floatinlet_new(&x->x_obj, &x->x_gain); */
+ floatinlet_new(&x->x_obj, &x->x_bw);
+ if (f > 0.) x->x_freq = f;
+ if (bw > 0.) x->x_bw = bw;
+ return (x);
+}
+
+
+void notch_setup(void)
+{
+ notch_class = class_new(gensym("notch"), (t_newmethod)notch_new, 0,
+ sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addbang(notch_class,notch_bang);
+ class_addfloat(notch_class,notch_float);
+}
+
+
+
+
+
diff --git a/filters/notch.pd b/filters/notch.pd
new file mode 100755
index 0000000..a65d9c4
--- /dev/null
+++ b/filters/notch.pd
@@ -0,0 +1,35 @@
+#N canvas 363 47 620 467 10;
+#X obj 77 182 print;
+#X floatatom 77 114;
+#X floatatom 150 114;
+#X msg 360 109 \; paint 0;
+#X obj 159 175 filtgain;
+#X msg 91 138 bang;
+#X text 150 93 bandwidth (0 - 100);
+#X text 6 334 See also:;
+#X obj 72 335 bandpass;
+#X obj 139 336 notch;
+#X obj 195 337 lowpass;
+#X obj 247 336 highpass;
+#X obj 247 358 equalizer;
+#X obj 72 357 highshelf;
+#X obj 139 357 lowshelf;
+#X obj 195 357 hlshelf;
+#X text 75 226 These filters are all controlled by a bandwidth which is expressed in octaves. A bandwidth of 100 is equivalent to one octave.;
+#X text 358 25 click first;
+#X text 165 159 click on filtgain to view frequency plot;
+#X text 70 26 ===================================;
+#X text 6 393 (C) Guenter Geiger 2000;
+#X text 75 92 frequency;
+#X text 75 268 Attention \, only the left inlet triggers new coefficients for biquad~;
+#X text 72 13 Notch coefficients for biquad~;
+#X msg 360 46 \; pd dsp 1 \; paint 1 \; doit bang \;;
+#X obj 35 114 r doit;
+#X obj 77 160 notch 4000 33;
+#X connect 1 0 26 0;
+#X connect 2 0 5 0;
+#X connect 2 0 26 1;
+#X connect 5 0 26 0;
+#X connect 25 0 26 0;
+#X connect 26 0 0 0;
+#X connect 26 0 4 0;