diff options
author | Cyrille Henry <nusmuk@users.sourceforge.net> | 2008-06-23 09:10:14 +0000 |
---|---|---|
committer | Cyrille Henry <nusmuk@users.sourceforge.net> | 2008-06-23 09:10:14 +0000 |
commit | 87fd5886f1c162922a9d86ec56faa9e1f7f44b67 (patch) | |
tree | 2388309968ab7e140904ff1441f9db8563ca4a36 /biquad/bq~.c | |
parent | 2bb6afaa53a3e0d1f8b47b075ec77e88f5eac941 (diff) |
add a biquad with audio inlet for coefficients.
add abstraction to compute a set of standard filter :
low pass / high pass / band pass / band cut / low shelf and high shelf
svn path=/trunk/externals/nusmuk/; revision=10069
Diffstat (limited to 'biquad/bq~.c')
-rw-r--r-- | biquad/bq~.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/biquad/bq~.c b/biquad/bq~.c new file mode 100644 index 0000000..d8a70b4 --- /dev/null +++ b/biquad/bq~.c @@ -0,0 +1,112 @@ +/* Copyright (c) 1997-1999 Miller Puckette. +* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +// modification of this code by cyrille henry in order to change the biquad topology and add audio inlet for filter coefs + +#include "m_pd.h" +#include <math.h> + +/* ---------------- bq~ - raw bq filter ----------------- */ + +typedef struct bqctl +{ + t_sample c_x1; + t_sample c_x2; + t_sample c_y1; + t_sample c_y2; +} t_bqctl; + +typedef struct bq_tilde +{ + t_object x_obj; + t_float x_f; + t_bqctl x_cspace; + t_bqctl *x_ctl; +} t_bq_tilde; + +t_class *bq_tilde_class; + +static void *bq_tilde_new(t_symbol *s, int argc, t_atom *argv) +{ + t_bq_tilde *x = (t_bq_tilde *)pd_new(bq_tilde_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_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; + x->x_cspace.c_y1 = x->x_cspace.c_y2 = 0; + x->x_f = 0; + return (x); +} + +static t_int *bq_tilde_perform(t_int *w) +{ + t_sample *in = (t_sample *)(w[1]); + t_sample *ina1 = (t_sample *)(w[2]); + t_sample *ina2 = (t_sample *)(w[3]); + t_sample *inb1 = (t_sample *)(w[4]); + t_sample *inb2 = (t_sample *)(w[5]); + t_sample *inb3 = (t_sample *)(w[6]); + t_sample *out = (t_sample *)(w[7]); + t_bqctl *c = (t_bqctl *)(w[8]); + int n = (t_int)(w[9]); + int i; + t_sample last_in = c->c_x1; + t_sample prev_in = c->c_x2; + t_sample last_out = c->c_y1; + t_sample prev_out = c->c_y2; + + for (i = 0; i < n; i++) + { + t_sample output = *inb1++ * *in + *inb2++ * last_in + *inb3++ * prev_in - *ina1++ * last_out - *ina2++ * prev_out; +// if (PD_BIGORSMALL(output)) +// output = 0; i don't understnd why it did not compile with this 2 lines. +// should be fixed latter if denormal is a problem + *out++ = output; + prev_in = last_in; + prev_out = last_out; + last_out = output; + last_in = *in++; + } + c->c_x1 = last_in; + c->c_x2 = prev_in; + c->c_y1 = last_out; + c->c_y2 = prev_out; + + return (w+10); +} + +static void bq_tilde_set(t_bq_tilde *x, t_symbol *s, int argc, t_atom *argv) +{ + t_bqctl *c = x->x_ctl; + c->c_x1 = atom_getfloatarg(0, argc, argv); + c->c_x2 = atom_getfloatarg(1, argc, argv); + c->c_y1 = atom_getfloatarg(2, argc, argv); + c->c_y2 = atom_getfloatarg(3, argc, argv); +} + +static void bq_tilde_dsp(t_bq_tilde *x, t_signal **sp) +{ + dsp_add(bq_tilde_perform, 9, + sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, + sp[5]->s_vec, sp[6]->s_vec, x->x_ctl, sp[0]->s_n); + +} + +void bq_tilde_setup(void) +{ + bq_tilde_class = class_new(gensym("bq~"), (t_newmethod)bq_tilde_new, + 0, sizeof(t_bq_tilde), 0, A_GIMME, 0); + CLASS_MAINSIGNALIN(bq_tilde_class, t_bq_tilde, x_f); + class_addmethod(bq_tilde_class, (t_method)bq_tilde_dsp, gensym("dsp"), 0); + class_addmethod(bq_tilde_class, (t_method)bq_tilde_set, gensym("set"), + A_GIMME, 0); + class_addmethod(bq_tilde_class, (t_method)bq_tilde_set, gensym("clear"), + A_GIMME, 0); +} + + |