aboutsummaryrefslogtreecommitdiff
path: root/iemlib1/src/FIR~.c
diff options
context:
space:
mode:
authormusil <tmusil@users.sourceforge.net>2006-12-09 02:00:52 +0000
committermusil <tmusil@users.sourceforge.net>2006-12-09 02:00:52 +0000
commitd6b088044e161a27d49df537bbb6d998a8d0e50d (patch)
tree1a1b3a30e994767f4ef97b90194782258f2baa8a /iemlib1/src/FIR~.c
parent32dc0c0deb13ce57f099f616ddc427296970d8a5 (diff)
// class_sethelpsymbol();
changed help-*.pd to *-help.pd chanded file structure to standard 1st step remove old svn path=/trunk/externals/iemlib/; revision=6756
Diffstat (limited to 'iemlib1/src/FIR~.c')
-rw-r--r--iemlib1/src/FIR~.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/iemlib1/src/FIR~.c b/iemlib1/src/FIR~.c
new file mode 100644
index 0000000..05bf267
--- /dev/null
+++ b/iemlib1/src/FIR~.c
@@ -0,0 +1,169 @@
+/* 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 - 2006 */
+
+
+#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<n; i++)
+ {
+ write_hist1[rw_index] = in[i];
+ write_hist2[rw_index] = in[i];
+
+ sum = 0.0f;
+ coef_vec = coef;
+ hist_vec = &read_hist[rw_index];
+ for(j=0; j<ord16; j++)
+ {
+ sum += coef_vec[0] * hist_vec[0];
+ sum += coef_vec[1] * hist_vec[-1];
+ sum += coef_vec[2] * hist_vec[-2];
+ sum += coef_vec[3] * hist_vec[-3];
+ sum += coef_vec[4] * hist_vec[-4];
+ sum += coef_vec[5] * hist_vec[-5];
+ sum += coef_vec[6] * hist_vec[-6];
+ sum += coef_vec[7] * hist_vec[-7];
+ sum += coef_vec[8] * hist_vec[-8];
+ sum += coef_vec[9] * hist_vec[-9];
+ sum += coef_vec[10] * hist_vec[-10];
+ sum += coef_vec[11] * hist_vec[-11];
+ sum += coef_vec[12] * hist_vec[-12];
+ sum += coef_vec[13] * hist_vec[-13];
+ sum += coef_vec[14] * hist_vec[-14];
+ sum += coef_vec[15] * hist_vec[-15];
+ coef_vec += 16;
+ hist_vec -= 16;
+ }
+ for(j=ord16*16; j<order; j++)
+ {
+ sum += coef[j] * read_hist[rw_index-j];
+ }
+ out[i] = sum;
+
+ rw_index++;
+ if(rw_index >= 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~"));
+}