aboutsummaryrefslogtreecommitdiff
path: root/modules/cheby.c
diff options
context:
space:
mode:
authorTom Schouten <doelie@users.sourceforge.net>2003-01-21 10:18:19 +0000
committerTom Schouten <doelie@users.sourceforge.net>2003-01-21 10:18:19 +0000
commitcdf8ded57019d5c905f16422d40be7b1a18ab3bc (patch)
tree92623f40f305b1e2f51198d5c16893c7ca70a2c6 /modules/cheby.c
This commit was generated by cvs2svn to compensate for changes in r350,svn2git-root
which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/creb/; revision=351
Diffstat (limited to 'modules/cheby.c')
-rw-r--r--modules/cheby.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/modules/cheby.c b/modules/cheby.c
new file mode 100644
index 0000000..2c32d68
--- /dev/null
+++ b/modules/cheby.c
@@ -0,0 +1,138 @@
+/*
+ * cheby.c - chebychev polynomial evaluation
+ * Copyright (c) 2000-2003 by Tom Schouten
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "m_pd.h"
+#include <math.h>
+
+
+#define MAX_ORDER 1024
+#define DEFAULT_ORDER 4
+
+typedef struct chebyctl
+{
+ t_float c_gain[MAX_ORDER];
+ t_int c_order;
+} t_chebyctl;
+
+typedef struct cheby
+{
+ t_object x_obj;
+ t_float x_f;
+ t_chebyctl x_ctl;
+} t_cheby;
+
+static void cheby_bang(t_cheby *x)
+{
+
+}
+
+static void cheby_coef(t_cheby *x, t_floatarg coef, t_floatarg f)
+{
+ int i = (int)coef;
+ if ((i > 0) && (i < x->x_ctl.c_order + 1)){
+ x->x_ctl.c_gain[i-1] = f;
+ /* post("cheby: harmonic %d set to %f", i, f); */
+ }
+}
+
+
+static t_int *cheby_perform(t_int *w)
+{
+
+
+ t_float *in = (float *)(w[3]);
+ t_float *out = (float *)(w[4]);
+ t_chebyctl *ctl = (t_chebyctl *)(w[1]);
+ t_float *gain = ctl->c_gain;
+ t_int i;
+ t_int n = (t_int)(w[2]), k;
+ t_float x,y,t1,t2,t,acc;
+
+
+ for (i = 0; i < n; i++)
+ {
+ x = *in++;
+
+ gain = ctl->c_gain;
+ t2 = 1; /* T_0 */
+ t1 = x; /* T_1 */
+
+ acc = *gain++ * x; /* a_1 T_1 */
+ for (k=2; k<=ctl->c_order; k++){
+ t = 2*x*t1 - t2; /* T_k = 2 x T_{k-1} - T_{k-2} */
+ acc += *gain++ * t; /* a_k T_k */
+ t2 = t1;
+ t1 = t;
+ }
+
+ *out++ = acc;
+
+ }
+
+
+ return (w+5);
+}
+
+static void cheby_dsp(t_cheby *x, t_signal **sp)
+{
+ dsp_add(cheby_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec);
+
+}
+static void cheby_free(void)
+{
+
+}
+
+t_class *cheby_class;
+
+static void *cheby_new(t_floatarg order_f)
+{
+ int i;
+ int order = (int)order_f;
+
+ t_cheby *x = (t_cheby *)pd_new(cheby_class);
+ outlet_new(&x->x_obj, gensym("signal"));
+
+ if (order < 1) order = DEFAULT_ORDER; /* default */
+ if (order > MAX_ORDER) order = MAX_ORDER; /* maximum */
+
+
+ //post("cheby: order = %d", order);
+
+ x->x_ctl.c_order = order;
+ cheby_coef(x, 1, 1);
+ for (i=2; i<order+1; i++){
+ cheby_coef(x, 0, i);
+ }
+
+ return (void *)x;
+}
+
+void cheby_tilde_setup(void)
+{
+ //post("cheby~ v0.1");
+ cheby_class = class_new(gensym("cheby~"), (t_newmethod)cheby_new,
+ (t_method)cheby_free, sizeof(t_cheby), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(cheby_class, t_cheby, x_f);
+ class_addmethod(cheby_class, (t_method)cheby_bang, gensym("bang"), 0);
+ class_addmethod(cheby_class, (t_method)cheby_dsp, gensym("dsp"), 0);
+ class_addmethod(cheby_class, (t_method)cheby_coef, gensym("coef"), A_DEFFLOAT, A_DEFFLOAT, 0);
+
+}
+