/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ #include "m_pd.h" #include "iemlib.h" /* ---------- FIR~ - FIR-filter with table-coef ----------- */ typedef struct _FIR_tilde { t_object x_obj; t_float *x_coef_beg; t_float *x_history_beg; int x_rw_index; int x_fir_order; t_symbol *x_table_name; t_float x_msi; } t_FIR_tilde; t_class *FIR_tilde_class; static t_int *FIR_tilde_perform(t_int *w) { t_float *in = (t_float *)(w[1]); t_float *out = (t_float *)(w[2]); t_FIR_tilde *x = (t_FIR_tilde *)(w[3]); int n = (t_int)(w[4]); int rw_index = x->x_rw_index; int i, j; int order = x->x_fir_order; int ord16 = order / 16; t_float sum=0.0f; t_float *coef = x->x_coef_beg; t_float *write_hist1=x->x_history_beg; t_float *write_hist2; t_float *read_hist; t_float *coef_vec; t_float *hist_vec; if(!coef) goto FIR_tildeperfzero; write_hist1 = x->x_history_beg; write_hist2 = write_hist1 + order; read_hist = write_hist2; for(i=0; i= order) rw_index -= order; } x->x_rw_index = rw_index; return(w+5); FIR_tildeperfzero: while(n--) *out++ = 0.0f; return(w+5); } void FIR_tilde_set(t_FIR_tilde *x, t_symbol *table_name, t_floatarg forder) { t_garray *ga; int table_size; int order = (int)forder; x->x_table_name = table_name; if(!(ga = (t_garray *)pd_findbyclass(x->x_table_name, garray_class))) { if(*table_name->s_name) error("FIR~: %s: no such table~", x->x_table_name->s_name); x->x_coef_beg = 0; } else if(!garray_getfloatarray(ga, &table_size, &x->x_coef_beg)) { error("%s: bad template for FIR~", x->x_table_name->s_name); x->x_coef_beg = 0; } else if(table_size < order) { error("FIR~: tablesize %d < order %d !!!!", table_size, order); x->x_coef_beg = 0; } else garray_usedindsp(ga); x->x_rw_index = 0; if(order > x->x_fir_order)/* resize */ x->x_history_beg = (t_float *)resizebytes(x->x_history_beg, 2*x->x_fir_order*sizeof(t_float), 2*order*sizeof(float)); x->x_fir_order = order; } static void FIR_tilde_dsp(t_FIR_tilde *x, t_signal **sp) { FIR_tilde_set(x, x->x_table_name, x->x_fir_order); dsp_add(FIR_tilde_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n); } static void *FIR_tilde_new(t_symbol *ref, t_floatarg np) { t_FIR_tilde *x = (t_FIR_tilde *)pd_new(FIR_tilde_class); outlet_new(&x->x_obj, &s_signal); x->x_msi = 0; x->x_table_name = ref; x->x_coef_beg = 0; if((int)np < 1) np = 1.0; x->x_fir_order = (int)np; x->x_history_beg = (t_float *)getbytes((2*x->x_fir_order)*sizeof(t_float)); x->x_rw_index = 0; return(x); } static void FIR_tilde_free(t_FIR_tilde *x) { if(x->x_history_beg) freebytes(x->x_history_beg, (2*x->x_fir_order)*sizeof(t_float)); } void FIR_tilde_setup(void) { FIR_tilde_class = class_new(gensym("FIR~"), (t_newmethod)FIR_tilde_new, (t_method)FIR_tilde_free, sizeof(t_FIR_tilde), 0, A_DEFSYM, A_DEFFLOAT, 0); CLASS_MAINSIGNALIN(FIR_tilde_class, t_FIR_tilde, x_msi); class_addmethod(FIR_tilde_class, (t_method)FIR_tilde_dsp, gensym("dsp"), 0); class_addmethod(FIR_tilde_class, (t_method)FIR_tilde_set, gensym("set"), A_SYMBOL, A_FLOAT, 0); class_sethelpsymbol(FIR_tilde_class, gensym("iemhelp/help-FIR~")); }