#include "../src/m_pd.h" #include "../src/m_fixed.h" #include "cos_table.h" /* ---------------- vcf~ - 2-pole bandpass filter. ----------------- */ /* GG: complex resonator with signal frequency control this time using the bigger cos_table without interpolation really have to switch to a separate fixpoint format sometime */ typedef struct vcfctl { t_sample c_re; t_sample c_im; t_sample c_q; t_sample c_isr; } t_vcfctl; typedef struct sigvcf { t_object x_obj; t_vcfctl x_cspace; t_vcfctl *x_ctl; float x_f; } t_sigvcf; t_class *sigvcf_class; static void *sigvcf_new(t_floatarg q) { t_sigvcf *x = (t_sigvcf *)pd_new(sigvcf_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, gensym("float"), gensym("ft1")); outlet_new(&x->x_obj, gensym("signal")); outlet_new(&x->x_obj, gensym("signal")); x->x_ctl = &x->x_cspace; x->x_cspace.c_re = 0; x->x_cspace.c_im = 0; x->x_cspace.c_q = ftofix(q); x->x_cspace.c_isr = 0; x->x_f = 0; return (x); } static void sigvcf_ft1(t_sigvcf *x, t_floatarg f) { x->x_ctl->c_q = (f > 0 ? ftofix(f) : 0); } static t_int *sigvcf_perform(t_int *w) { t_sample *in1 = (t_sample *)(w[1]); t_sample *in2 = (t_sample *)(w[2]); t_sample *out1 = (t_sample *)(w[3]); t_sample *out2 = (t_sample *)(w[4]); t_vcfctl *c = (t_vcfctl *)(w[5]); int n = (t_int)(w[6]); int i; t_sample re = c->c_re, re2; t_sample im = c->c_im; t_sample q = c->c_q; t_sample qinv = (q > 0 ? idiv(ftofix(1.0),q) : 0); t_sample ampcorrect = ftofix(2.0f) - idiv(ftofix(2.0f) , (q + ftofix(2.0f))); t_sample isr = c->c_isr; t_sample coefr, coefi; t_sample *tab = cos_table; t_sample oneminusr,cfindx,cf,r; for (i = 0; i < n; i++) { cf = mult(*in2++,isr); if (cf < 0) cf = 0; cfindx = mult(cf,ftofix(0.15915494))>>(fix1-ILOGCOSTABSIZE); /* 1/2*PI */ r = (qinv > 0 ? ftofix(1.01) - mult(cf,qinv) : 0); if (r < 0) r = 0; oneminusr = ftofix(1.02f) - r; /* hand adapted */ /* r*cos(cf) */ coefr = mult(r,tab[cfindx]); /* r*sin(cf) */ cfindx-=(ICOSTABSIZE>>2); cfindx += cfindx < 0 ? ICOSTABSIZE:0; coefi = mult(r,tab[cfindx]); re2 = re; *out1++ = re = mult(ampcorrect,mult(oneminusr,*in1++)) + mult(coefr,re2) - mult(coefi, im); *out2++ = im = mult(coefi,re2) + mult(coefr,im); } c->c_re = re; c->c_im = im; return (w+7); } static void sigvcf_dsp(t_sigvcf *x, t_signal **sp) { /* TODO sr is hardcoded */ x->x_ctl->c_isr = ftofix(0.0001424758); // idiv(ftofix(6.28318),ftofix(sp[0]->s_sr)); post("%f",fixtof(x->x_ctl->c_isr)); dsp_add(sigvcf_perform, 6, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, x->x_ctl, sp[0]->s_n); } void vcf_tilde_setup(void) { sigvcf_class = class_new(gensym("vcf~"), (t_newmethod)sigvcf_new, 0, sizeof(t_sigvcf), 0, A_DEFFLOAT, 0); CLASS_MAINSIGNALIN(sigvcf_class, t_sigvcf, x_f); class_addmethod(sigvcf_class, (t_method)sigvcf_dsp, gensym("dsp"), 0); class_addmethod(sigvcf_class, (t_method)sigvcf_ft1, gensym("ft1"), A_FLOAT, 0); class_sethelpsymbol(sigvcf_class, gensym("lop~-help.pd")); }