aboutsummaryrefslogtreecommitdiff
path: root/pd/src/d_filter.c
diff options
context:
space:
mode:
authorMiller Puckette <millerpuckette@users.sourceforge.net>2004-09-06 20:20:36 +0000
committerMiller Puckette <millerpuckette@users.sourceforge.net>2004-09-06 20:20:36 +0000
commited932acb5860bf8b9296169676499562a55d139e (patch)
treedc6a40dba908deb07c175cd40ee19c197318f72d /pd/src/d_filter.c
parentdad636821f6e7d3ead02c157f308c0ceeba9af3d (diff)
checking in version 0.38test5.
Oops, I realize I forgot some more nice files, will add them and re-commit. svn path=/trunk/; revision=2010
Diffstat (limited to 'pd/src/d_filter.c')
-rw-r--r--pd/src/d_filter.c646
1 files changed, 567 insertions, 79 deletions
diff --git a/pd/src/d_filter.c b/pd/src/d_filter.c
index 732bd3d6..7a5649ee 100644
--- a/pd/src/d_filter.c
+++ b/pd/src/d_filter.c
@@ -32,7 +32,7 @@ static void *sighip_new(t_floatarg f)
{
t_sighip *x = (t_sighip *)pd_new(sighip_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
- outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, &s_signal);
x->x_sr = 44100;
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x = 0;
@@ -47,9 +47,9 @@ static void sighip_ft1(t_sighip *x, t_floatarg f)
x->x_hz = f;
x->x_ctl->c_coef = 1 - f * (2 * 3.14159) / x->x_sr;
if (x->x_ctl->c_coef < 0)
- x->x_ctl->c_coef = 0;
+ x->x_ctl->c_coef = 0;
else if (x->x_ctl->c_coef > 1)
- x->x_ctl->c_coef = 1;
+ x->x_ctl->c_coef = 1;
}
static t_int *sighip_perform(t_int *w)
@@ -63,21 +63,21 @@ static t_int *sighip_perform(t_int *w)
float coef = c->c_coef;
if (coef < 1)
{
- for (i = 0; i < n; i++)
- {
- float new = *in++ + coef * last;
- *out++ = new - last;
- last = new;
- }
- if (PD_BADFLOAT(last))
- last = 0;
- c->c_x = last;
+ for (i = 0; i < n; i++)
+ {
+ float new = *in++ + coef * last;
+ *out++ = new - last;
+ last = new;
+ }
+ if (PD_BIGORSMALL(last))
+ last = 0;
+ c->c_x = last;
}
else
{
- for (i = 0; i < n; i++)
- *out++ = *in++;
- c->c_x = 0;
+ for (i = 0; i < n; i++)
+ *out++ = *in++;
+ c->c_x = 0;
}
return (w+5);
}
@@ -87,8 +87,8 @@ static void sighip_dsp(t_sighip *x, t_signal **sp)
x->x_sr = sp[0]->s_sr;
sighip_ft1(x, x->x_hz);
dsp_add(sighip_perform, 4,
- sp[0]->s_vec, sp[1]->s_vec,
- x->x_ctl, sp[0]->s_n);
+ sp[0]->s_vec, sp[1]->s_vec,
+ x->x_ctl, sp[0]->s_n);
}
@@ -100,11 +100,11 @@ static void sighip_clear(t_sighip *x, t_floatarg q)
void sighip_setup(void)
{
sighip_class = class_new(gensym("hip~"), (t_newmethod)sighip_new, 0,
- sizeof(t_sighip), 0, A_DEFFLOAT, 0);
+ sizeof(t_sighip), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sighip_class, t_sighip, x_f);
class_addmethod(sighip_class, (t_method)sighip_dsp, gensym("dsp"), 0);
class_addmethod(sighip_class, (t_method)sighip_ft1,
- gensym("ft1"), A_FLOAT, 0);
+ gensym("ft1"), A_FLOAT, 0);
class_addmethod(sighip_class, (t_method)sighip_clear, gensym("clear"), 0);
}
@@ -134,7 +134,7 @@ static void *siglop_new(t_floatarg f)
{
t_siglop *x = (t_siglop *)pd_new(siglop_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
- outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, &s_signal);
x->x_sr = 44100;
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x = 0;
@@ -149,9 +149,9 @@ static void siglop_ft1(t_siglop *x, t_floatarg f)
x->x_hz = f;
x->x_ctl->c_coef = f * (2 * 3.14159) / x->x_sr;
if (x->x_ctl->c_coef > 1)
- x->x_ctl->c_coef = 1;
+ x->x_ctl->c_coef = 1;
else if (x->x_ctl->c_coef < 0)
- x->x_ctl->c_coef = 0;
+ x->x_ctl->c_coef = 0;
}
static void siglop_clear(t_siglop *x, t_floatarg q)
@@ -170,9 +170,9 @@ static t_int *siglop_perform(t_int *w)
float coef = c->c_coef;
float feedback = 1 - coef;
for (i = 0; i < n; i++)
- last = *out++ = coef * *in++ + feedback * last;
- if (PD_BADFLOAT(last))
- last = 0;
+ last = *out++ = coef * *in++ + feedback * last;
+ if (PD_BIGORSMALL(last))
+ last = 0;
c->c_x = last;
return (w+5);
}
@@ -182,19 +182,19 @@ static void siglop_dsp(t_siglop *x, t_signal **sp)
x->x_sr = sp[0]->s_sr;
siglop_ft1(x, x->x_hz);
dsp_add(siglop_perform, 4,
- sp[0]->s_vec, sp[1]->s_vec,
- x->x_ctl, sp[0]->s_n);
+ sp[0]->s_vec, sp[1]->s_vec,
+ x->x_ctl, sp[0]->s_n);
}
void siglop_setup(void)
{
siglop_class = class_new(gensym("lop~"), (t_newmethod)siglop_new, 0,
- sizeof(t_siglop), 0, A_DEFFLOAT, 0);
+ sizeof(t_siglop), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(siglop_class, t_siglop, x_f);
class_addmethod(siglop_class, (t_method)siglop_dsp, gensym("dsp"), 0);
class_addmethod(siglop_class, (t_method)siglop_ft1,
- gensym("ft1"), A_FLOAT, 0);
+ gensym("ft1"), A_FLOAT, 0);
class_addmethod(siglop_class, (t_method)siglop_clear, gensym("clear"), 0);
}
@@ -229,7 +229,7 @@ static void *sigbp_new(t_floatarg f, t_floatarg q)
t_sigbp *x = (t_sigbp *)pd_new(sigbp_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft2"));
- outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, &s_signal);
x->x_sr = 44100;
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x1 = 0;
@@ -243,8 +243,8 @@ static float sigbp_qcos(float f)
{
if (f >= -(0.5f*3.14159f) && f <= 0.5f*3.14159f)
{
- float g = f*f;
- return (((g*g*g * (-1.0f/720.0f) + g*g*(1.0f/24.0f)) - g*0.5) + 1);
+ float g = f*f;
+ return (((g*g*g * (-1.0f/720.0f) + g*g*(1.0f/24.0f)) - g*0.5) + 1);
}
else return (0);
}
@@ -265,7 +265,7 @@ static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q)
x->x_ctl->c_coef2 = - r * r;
x->x_ctl->c_gain = 2 * oneminusr * (oneminusr + r * omega);
/* post("r %f, omega %f, coef1 %f, coef2 %f",
- r, omega, x->x_ctl->c_coef1, x->x_ctl->c_coef2); */
+ r, omega, x->x_ctl->c_coef1, x->x_ctl->c_coef2); */
}
static void sigbp_ft1(t_sigbp *x, t_floatarg f)
@@ -297,15 +297,15 @@ static t_int *sigbp_perform(t_int *w)
float gain = c->c_gain;
for (i = 0; i < n; i++)
{
- float output = *in++ + coef1 * last + coef2 * prev;
- *out++ = gain * output;
- prev = last;
- last = output;
+ float output = *in++ + coef1 * last + coef2 * prev;
+ *out++ = gain * output;
+ prev = last;
+ last = output;
}
- if (PD_BADFLOAT(last))
- last = 0;
- if (PD_BADFLOAT(prev))
- prev = 0;
+ if (PD_BIGORSMALL(last))
+ last = 0;
+ if (PD_BIGORSMALL(prev))
+ prev = 0;
c->c_x1 = last;
c->c_x2 = prev;
return (w+5);
@@ -316,21 +316,21 @@ static void sigbp_dsp(t_sigbp *x, t_signal **sp)
x->x_sr = sp[0]->s_sr;
sigbp_docoef(x, x->x_freq, x->x_q);
dsp_add(sigbp_perform, 4,
- sp[0]->s_vec, sp[1]->s_vec,
- x->x_ctl, sp[0]->s_n);
+ sp[0]->s_vec, sp[1]->s_vec,
+ x->x_ctl, sp[0]->s_n);
}
void sigbp_setup(void)
{
sigbp_class = class_new(gensym("bp~"), (t_newmethod)sigbp_new, 0,
- sizeof(t_sigbp), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ sizeof(t_sigbp), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigbp_class, t_sigbp, x_f);
class_addmethod(sigbp_class, (t_method)sigbp_dsp, gensym("dsp"), 0);
class_addmethod(sigbp_class, (t_method)sigbp_ft1,
- gensym("ft1"), A_FLOAT, 0);
+ gensym("ft1"), A_FLOAT, 0);
class_addmethod(sigbp_class, (t_method)sigbp_ft2,
- gensym("ft2"), A_FLOAT, 0);
+ gensym("ft2"), A_FLOAT, 0);
class_addmethod(sigbp_class, (t_method)sigbp_clear, gensym("clear"), 0);
}
@@ -362,7 +362,7 @@ static void sigbiquad_list(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv);
static void *sigbiquad_new(t_symbol *s, int argc, t_atom *argv)
{
t_sigbiquad *x = (t_sigbiquad *)pd_new(sigbiquad_class);
- outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, &s_signal);
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x1 = x->x_cspace.c_x2 = 0;
sigbiquad_list(x, s, argc, argv);
@@ -386,12 +386,12 @@ static t_int *sigbiquad_perform(t_int *w)
float ff3 = c->c_ff3;
for (i = 0; i < n; i++)
{
- float output = *in++ + fb1 * last + fb2 * prev;
- if (PD_BADFLOAT(output))
- output = 0;
- *out++ = ff1 * output + ff2 * last + ff3 * prev;
- prev = last;
- last = output;
+ float output = *in++ + fb1 * last + fb2 * prev;
+ if (PD_BIGORSMALL(output))
+ output = 0;
+ *out++ = ff1 * output + ff2 * last + ff3 * prev;
+ prev = last;
+ last = output;
}
c->c_x1 = last;
c->c_x2 = prev;
@@ -409,20 +409,20 @@ static void sigbiquad_list(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv)
t_biquadctl *c = x->x_ctl;
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;
+ /* 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;
+ /* 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;
}
- /* if unstable, just bash to zero */
+ /* if unstable, just bash to zero */
fb1 = fb2 = ff1 = ff2 = ff3 = 0;
stable:
c->c_fb1 = fb1;
@@ -442,22 +442,22 @@ static void sigbiquad_set(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv)
static void sigbiquad_dsp(t_sigbiquad *x, t_signal **sp)
{
dsp_add(sigbiquad_perform, 4,
- sp[0]->s_vec, sp[1]->s_vec,
- x->x_ctl, sp[0]->s_n);
+ sp[0]->s_vec, sp[1]->s_vec,
+ x->x_ctl, sp[0]->s_n);
}
void sigbiquad_setup(void)
{
sigbiquad_class = class_new(gensym("biquad~"), (t_newmethod)sigbiquad_new,
- 0, sizeof(t_sigbiquad), 0, A_GIMME, 0);
+ 0, sizeof(t_sigbiquad), 0, A_GIMME, 0);
CLASS_MAINSIGNALIN(sigbiquad_class, t_sigbiquad, x_f);
class_addmethod(sigbiquad_class, (t_method)sigbiquad_dsp, gensym("dsp"), 0);
class_addlist(sigbiquad_class, sigbiquad_list);
class_addmethod(sigbiquad_class, (t_method)sigbiquad_set, gensym("set"),
- A_GIMME, 0);
+ A_GIMME, 0);
class_addmethod(sigbiquad_class, (t_method)sigbiquad_set, gensym("clear"),
- A_GIMME, 0);
+ A_GIMME, 0);
}
/* ---------------- samphold~ - sample and hold ----------------- */
@@ -476,7 +476,7 @@ static void *sigsamphold_new(void)
{
t_sigsamphold *x = (t_sigsamphold *)pd_new(sigsamphold_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
- outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, &s_signal);
x->x_lastin = 0;
x->x_lastout = 0;
x->x_f = 0;
@@ -495,10 +495,10 @@ static t_int *sigsamphold_perform(t_int *w)
float lastout = x->x_lastout;
for (i = 0; i < n; i++, *in1++)
{
- float next = *in2++;
- if (next < lastin) lastout = *in1;
- *out++ = lastout;
- lastin = next;
+ float next = *in2++;
+ if (next < lastin) lastout = *in1;
+ *out++ = lastout;
+ lastin = next;
}
x->x_lastin = lastin;
x->x_lastout = lastout;
@@ -508,8 +508,8 @@ static t_int *sigsamphold_perform(t_int *w)
static void sigsamphold_dsp(t_sigsamphold *x, t_signal **sp)
{
dsp_add(sigsamphold_perform, 5,
- sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec,
- x, sp[0]->s_n);
+ sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec,
+ x, sp[0]->s_n);
}
static void sigsamphold_reset(t_sigsamphold *x)
@@ -525,14 +525,496 @@ static void sigsamphold_set(t_sigsamphold *x, t_float f)
void sigsamphold_setup(void)
{
sigsamphold_class = class_new(gensym("samphold~"),
- (t_newmethod)sigsamphold_new, 0, sizeof(t_sigsamphold), 0, 0);
+ (t_newmethod)sigsamphold_new, 0, sizeof(t_sigsamphold), 0, 0);
CLASS_MAINSIGNALIN(sigsamphold_class, t_sigsamphold, x_f);
class_addmethod(sigsamphold_class, (t_method)sigsamphold_set,
- gensym("set"), A_FLOAT, 0);
+ gensym("set"), A_DEFFLOAT, 0);
class_addmethod(sigsamphold_class, (t_method)sigsamphold_reset,
- gensym("reset"), 0);
+ gensym("reset"), 0);
class_addmethod(sigsamphold_class, (t_method)sigsamphold_dsp,
- gensym("dsp"), 0);
+ gensym("dsp"), 0);
+}
+
+/* ---------------- rpole~ - real one-pole filter (raw) ----------------- */
+
+typedef struct sigrpole
+{
+ t_object x_obj;
+ float x_f;
+ float x_last;
+} t_sigrpole;
+
+t_class *sigrpole_class;
+
+static void *sigrpole_new(t_float f)
+{
+ t_sigrpole *x = (t_sigrpole *)pd_new(sigrpole_class);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_last = 0;
+ x->x_f = f;
+ return (x);
+}
+
+static t_int *sigrpole_perform(t_int *w)
+{
+ float *in1 = (float *)(w[1]);
+ float *in2 = (float *)(w[2]);
+ float *out = (float *)(w[3]);
+ t_sigrpole *x = (t_sigrpole *)(w[4]);
+ int n = (t_int)(w[5]);
+ int i;
+ float last = x->x_last;
+ for (i = 0; i < n; i++)
+ {
+ float next = *in1++;
+ float coef = *in2++;
+ *out++ = last = coef * last + next;
+ }
+ x->x_last = last;
+ return (w+6);
+}
+
+static void sigrpole_dsp(t_sigrpole *x, t_signal **sp)
+{
+ dsp_add(sigrpole_perform, 5,
+ sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec,
+ x, sp[0]->s_n);
+}
+
+static void sigrpole_clear(t_sigrpole *x)
+{
+ x->x_last = 0;
+}
+
+static void sigrpole_set(t_sigrpole *x, t_float f)
+{
+ x->x_last = f;
+}
+
+void sigrpole_setup(void)
+{
+ sigrpole_class = class_new(gensym("rpole~"),
+ (t_newmethod)sigrpole_new, 0, sizeof(t_sigrpole), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigrpole_class, t_sigrpole, x_f);
+ class_addmethod(sigrpole_class, (t_method)sigrpole_set,
+ gensym("set"), A_DEFFLOAT, 0);
+ class_addmethod(sigrpole_class, (t_method)sigrpole_clear,
+ gensym("clear"), 0);
+ class_addmethod(sigrpole_class, (t_method)sigrpole_dsp,
+ gensym("dsp"), 0);
+}
+
+/* ---------------- rzero~ - real one-zero filter (raw) ----------------- */
+
+typedef struct sigrzero
+{
+ t_object x_obj;
+ float x_f;
+ float x_last;
+} t_sigrzero;
+
+t_class *sigrzero_class;
+
+static void *sigrzero_new(t_float f)
+{
+ t_sigrzero *x = (t_sigrzero *)pd_new(sigrzero_class);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_last = 0;
+ x->x_f = f;
+ return (x);
+}
+
+static t_int *sigrzero_perform(t_int *w)
+{
+ float *in1 = (float *)(w[1]);
+ float *in2 = (float *)(w[2]);
+ float *out = (float *)(w[3]);
+ t_sigrzero *x = (t_sigrzero *)(w[4]);
+ int n = (t_int)(w[5]);
+ int i;
+ float last = x->x_last;
+ for (i = 0; i < n; i++)
+ {
+ float next = *in1++;
+ float coef = *in2++;
+ *out++ = next - coef * last;
+ last = next;
+ }
+ x->x_last = last;
+ return (w+6);
+}
+
+static void sigrzero_dsp(t_sigrzero *x, t_signal **sp)
+{
+ dsp_add(sigrzero_perform, 5,
+ sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec,
+ x, sp[0]->s_n);
+}
+
+static void sigrzero_clear(t_sigrzero *x)
+{
+ x->x_last = 0;
+}
+
+static void sigrzero_set(t_sigrzero *x, t_float f)
+{
+ x->x_last = f;
+}
+
+void sigrzero_setup(void)
+{
+ sigrzero_class = class_new(gensym("rzero~"),
+ (t_newmethod)sigrzero_new, 0, sizeof(t_sigrzero), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigrzero_class, t_sigrzero, x_f);
+ class_addmethod(sigrzero_class, (t_method)sigrzero_set,
+ gensym("set"), A_DEFFLOAT, 0);
+ class_addmethod(sigrzero_class, (t_method)sigrzero_clear,
+ gensym("clear"), 0);
+ class_addmethod(sigrzero_class, (t_method)sigrzero_dsp,
+ gensym("dsp"), 0);
+}
+
+/* ---------- rzero_rev~ - real, reverse one-zero filter (raw) ------------ */
+
+typedef struct sigrzero_rev
+{
+ t_object x_obj;
+ float x_f;
+ float x_last;
+} t_sigrzero_rev;
+
+t_class *sigrzero_rev_class;
+
+static void *sigrzero_rev_new(t_float f)
+{
+ t_sigrzero_rev *x = (t_sigrzero_rev *)pd_new(sigrzero_rev_class);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_last = 0;
+ x->x_f = f;
+ return (x);
+}
+
+static t_int *sigrzero_rev_perform(t_int *w)
+{
+ float *in1 = (float *)(w[1]);
+ float *in2 = (float *)(w[2]);
+ float *out = (float *)(w[3]);
+ t_sigrzero_rev *x = (t_sigrzero_rev *)(w[4]);
+ int n = (t_int)(w[5]);
+ int i;
+ float last = x->x_last;
+ for (i = 0; i < n; i++)
+ {
+ float next = *in1++;
+ float coef = *in2++;
+ *out++ = last - coef * next;
+ last = next;
+ }
+ x->x_last = last;
+ return (w+6);
+}
+
+static void sigrzero_rev_dsp(t_sigrzero_rev *x, t_signal **sp)
+{
+ dsp_add(sigrzero_rev_perform, 5,
+ sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec,
+ x, sp[0]->s_n);
+}
+
+static void sigrzero_rev_clear(t_sigrzero_rev *x)
+{
+ x->x_last = 0;
+}
+
+static void sigrzero_rev_set(t_sigrzero_rev *x, t_float f)
+{
+ x->x_last = f;
+}
+
+void sigrzero_rev_setup(void)
+{
+ sigrzero_rev_class = class_new(gensym("rzero_rev~"),
+ (t_newmethod)sigrzero_rev_new, 0, sizeof(t_sigrzero_rev),
+ 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigrzero_rev_class, t_sigrzero_rev, x_f);
+ class_addmethod(sigrzero_rev_class, (t_method)sigrzero_rev_set,
+ gensym("set"), A_DEFFLOAT, 0);
+ class_addmethod(sigrzero_rev_class, (t_method)sigrzero_rev_clear,
+ gensym("clear"), 0);
+ class_addmethod(sigrzero_rev_class, (t_method)sigrzero_rev_dsp,
+ gensym("dsp"), 0);
+}
+
+/* -------------- cpole~ - complex one-pole filter (raw) --------------- */
+
+typedef struct sigcpole
+{
+ t_object x_obj;
+ float x_f;
+ float x_lastre;
+ float x_lastim;
+} t_sigcpole;
+
+t_class *sigcpole_class;
+
+static void *sigcpole_new(t_float re, t_float im)
+{
+ t_sigcpole *x = (t_sigcpole *)pd_new(sigcpole_class);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ pd_float(
+ (t_pd *)inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal),
+ re);
+ pd_float(
+ (t_pd *)inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal),
+ im);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_lastre = x->x_lastim = 0;
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *sigcpole_perform(t_int *w)
+{
+ float *inre1 = (float *)(w[1]);
+ float *inim1 = (float *)(w[2]);
+ float *inre2 = (float *)(w[3]);
+ float *inim2 = (float *)(w[4]);
+ float *outre = (float *)(w[5]);
+ float *outim = (float *)(w[6]);
+ t_sigcpole *x = (t_sigcpole *)(w[7]);
+ int n = (t_int)(w[8]);
+ int i;
+ float lastre = x->x_lastre;
+ float lastim = x->x_lastim;
+ for (i = 0; i < n; i++)
+ {
+ float nextre = *inre1++;
+ float nextim = *inim1++;
+ float coefre = *inre2++;
+ float coefim = *inim2++;
+ float tempre = *outre++ = nextre + lastre * coefre - lastim * coefim;
+ lastim = *outim++ = nextim + lastre * coefim + lastim * coefre;
+ lastre = tempre;
+ }
+ x->x_lastre = lastre;
+ x->x_lastim = lastim;
+ return (w+9);
+}
+
+static void sigcpole_dsp(t_sigcpole *x, t_signal **sp)
+{
+ dsp_add(sigcpole_perform, 8,
+ sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,
+ sp[4]->s_vec, sp[5]->s_vec, x, sp[0]->s_n);
+}
+
+static void sigcpole_clear(t_sigcpole *x)
+{
+ x->x_lastre = x->x_lastim = 0;
+}
+
+static void sigcpole_set(t_sigcpole *x, t_float re, t_float im)
+{
+ x->x_lastre = re;
+ x->x_lastim = im;
+}
+
+void sigcpole_setup(void)
+{
+ sigcpole_class = class_new(gensym("cpole~"),
+ (t_newmethod)sigcpole_new, 0, sizeof(t_sigcpole), 0,
+ A_DEFFLOAT, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigcpole_class, t_sigcpole, x_f);
+ class_addmethod(sigcpole_class, (t_method)sigcpole_set,
+ gensym("set"), A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(sigcpole_class, (t_method)sigcpole_clear,
+ gensym("clear"), 0);
+ class_addmethod(sigcpole_class, (t_method)sigcpole_dsp,
+ gensym("dsp"), 0);
+}
+
+/* -------------- czero~ - complex one-pole filter (raw) --------------- */
+
+typedef struct sigczero
+{
+ t_object x_obj;
+ float x_f;
+ float x_lastre;
+ float x_lastim;
+} t_sigczero;
+
+t_class *sigczero_class;
+
+static void *sigczero_new(t_float re, t_float im)
+{
+ t_sigczero *x = (t_sigczero *)pd_new(sigczero_class);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ pd_float(
+ (t_pd *)inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal),
+ re);
+ pd_float(
+ (t_pd *)inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal),
+ im);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_lastre = x->x_lastim = 0;
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *sigczero_perform(t_int *w)
+{
+ float *inre1 = (float *)(w[1]);
+ float *inim1 = (float *)(w[2]);
+ float *inre2 = (float *)(w[3]);
+ float *inim2 = (float *)(w[4]);
+ float *outre = (float *)(w[5]);
+ float *outim = (float *)(w[6]);
+ t_sigczero *x = (t_sigczero *)(w[7]);
+ int n = (t_int)(w[8]);
+ int i;
+ float lastre = x->x_lastre;
+ float lastim = x->x_lastim;
+ for (i = 0; i < n; i++)
+ {
+ float nextre = *inre1++;
+ float nextim = *inim1++;
+ float coefre = *inre2++;
+ float coefim = *inim2++;
+ *outre++ = nextre - lastre * coefre + lastim * coefim;
+ *outim++ = nextim - lastre * coefim - lastim * coefre;
+ lastre = nextre;
+ lastim = nextim;
+ }
+ x->x_lastre = lastre;
+ x->x_lastim = lastim;
+ return (w+9);
+}
+
+static void sigczero_dsp(t_sigczero *x, t_signal **sp)
+{
+ dsp_add(sigczero_perform, 8,
+ sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,
+ sp[4]->s_vec, sp[5]->s_vec, x, sp[0]->s_n);
+}
+
+static void sigczero_clear(t_sigczero *x)
+{
+ x->x_lastre = x->x_lastim = 0;
+}
+
+static void sigczero_set(t_sigczero *x, t_float re, t_float im)
+{
+ x->x_lastre = re;
+ x->x_lastim = im;
+}
+
+void sigczero_setup(void)
+{
+ sigczero_class = class_new(gensym("czero~"),
+ (t_newmethod)sigczero_new, 0, sizeof(t_sigczero), 0,
+ A_DEFFLOAT, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigczero_class, t_sigczero, x_f);
+ class_addmethod(sigczero_class, (t_method)sigczero_set,
+ gensym("set"), A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(sigczero_class, (t_method)sigczero_clear,
+ gensym("clear"), 0);
+ class_addmethod(sigczero_class, (t_method)sigczero_dsp,
+ gensym("dsp"), 0);
+}
+
+/* -------------- czero_rev~ - complex one-pole filter (raw) --------------- */
+
+typedef struct sigczero_rev
+{
+ t_object x_obj;
+ float x_f;
+ float x_lastre;
+ float x_lastim;
+} t_sigczero_rev;
+
+t_class *sigczero_rev_class;
+
+static void *sigczero_rev_new(t_float re, t_float im)
+{
+ t_sigczero_rev *x = (t_sigczero_rev *)pd_new(sigczero_rev_class);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ pd_float(
+ (t_pd *)inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal),
+ re);
+ pd_float(
+ (t_pd *)inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal),
+ im);
+ outlet_new(&x->x_obj, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_lastre = x->x_lastim = 0;
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *sigczero_rev_perform(t_int *w)
+{
+ float *inre1 = (float *)(w[1]);
+ float *inim1 = (float *)(w[2]);
+ float *inre2 = (float *)(w[3]);
+ float *inim2 = (float *)(w[4]);
+ float *outre = (float *)(w[5]);
+ float *outim = (float *)(w[6]);
+ t_sigczero_rev *x = (t_sigczero_rev *)(w[7]);
+ int n = (t_int)(w[8]);
+ int i;
+ float lastre = x->x_lastre;
+ float lastim = x->x_lastim;
+ for (i = 0; i < n; i++)
+ {
+ float nextre = *inre1++;
+ float nextim = *inim1++;
+ float coefre = *inre2++;
+ float coefim = *inim2++;
+ *outre++ = lastre - nextre * coefre + nextim * coefim;
+ *outim++ = lastim - nextre * coefim - nextim * coefre;
+ lastre = nextre;
+ lastim = nextim;
+ }
+ x->x_lastre = lastre;
+ x->x_lastim = lastim;
+ return (w+9);
+}
+
+static void sigczero_rev_dsp(t_sigczero_rev *x, t_signal **sp)
+{
+ dsp_add(sigczero_rev_perform, 8,
+ sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,
+ sp[4]->s_vec, sp[5]->s_vec, x, sp[0]->s_n);
+}
+
+static void sigczero_rev_clear(t_sigczero_rev *x)
+{
+ x->x_lastre = x->x_lastim = 0;
+}
+
+static void sigczero_rev_set(t_sigczero_rev *x, t_float re, t_float im)
+{
+ x->x_lastre = re;
+ x->x_lastim = im;
+}
+
+void sigczero_rev_setup(void)
+{
+ sigczero_rev_class = class_new(gensym("czero_rev~"),
+ (t_newmethod)sigczero_rev_new, 0, sizeof(t_sigczero_rev), 0,
+ A_DEFFLOAT, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigczero_rev_class, t_sigczero_rev, x_f);
+ class_addmethod(sigczero_rev_class, (t_method)sigczero_rev_set,
+ gensym("set"), A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(sigczero_rev_class, (t_method)sigczero_rev_clear,
+ gensym("clear"), 0);
+ class_addmethod(sigczero_rev_class, (t_method)sigczero_rev_dsp,
+ gensym("dsp"), 0);
}
/* ------------------------ setup routine ------------------------- */
@@ -544,4 +1026,10 @@ void d_filter_setup(void)
sigbp_setup();
sigbiquad_setup();
sigsamphold_setup();
+ sigrpole_setup();
+ sigrzero_setup();
+ sigrzero_rev_setup();
+ sigcpole_setup();
+ sigczero_setup();
+ sigczero_rev_setup();
}