From aac2fa3f2d131ebca1378d93445bd1090b16c84c Mon Sep 17 00:00:00 2001 From: Martin Peach Date: Tue, 23 Mar 2010 21:11:28 +0000 Subject: signal/float operators like [>=~] from zexy but operator can be reconfigured on the fly. svn path=/trunk/externals/mrpeach/; revision=13248 --- op~/op~.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 op~/op~.c (limited to 'op~/op~.c') diff --git a/op~/op~.c b/op~/op~.c new file mode 100644 index 0000000..8a15bc3 --- /dev/null +++ b/op~/op~.c @@ -0,0 +1,238 @@ +/* op~ by Martin Peach 201003123, based on the zexy binop externals: */ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +/* ----------------------------- op_tilde ----------------------------- */ +#include "m_pd.h" + +static t_class *op_tilde_class; + +static char *operator_names[] = {"<=", ">=", "!=", "==", "<", ">", "le", "ge", "ne", "eq", "lt", "gt", "nop"}; +static int n_opnames = 13; + +typedef enum +{ + le = 0, + ge, + ne, + eq, + lt, + gt, + nop, + none +} op_op; + +typedef struct _op_tilde +{ + t_object x_obj; + t_float x_f; + t_float x_g; /* inlet value */ + op_op x_operator; +} t_op_tilde; + + +static void *op_tilde_new(t_symbol *s, int argc, t_atom *argv); +static t_int *op_tilde_perform(t_int *w); +static void op_tilde_help(t_op_tilde *x); +static void op_tilde_op(t_op_tilde *x, t_symbol *op); +static void op_tilde_dsp(t_op_tilde *x, t_signal **sp); +void op_tilde_setup(void); + +static void *op_tilde_new(t_symbol *s, int argc, t_atom *argv) +{ + t_symbol *argsym; + + if (argc > 1) post("op~: extra arguments ignored"); + if (argc == 0) post("op~: need to specify operator"); + argsym = atom_getsymbolarg(0, argc, argv); +// post ("op~: %s", argsym->s_name); + + t_op_tilde *x = (t_op_tilde *)pd_new(op_tilde_class); + + x->x_operator = none; + + switch (argsym->s_name[0]) + { + case '<': + if (argsym->s_name[1] == 0) x->x_operator = lt; + else if (argsym->s_name[1] == '=') x->x_operator = le; + break; + case '>': + if (argsym->s_name[1] == 0) x->x_operator = gt; + else if (argsym->s_name[1] == '=') x->x_operator = ge; + break; + case '=': + if (argsym->s_name[1] == '=') x->x_operator = eq; + break; + case '!': + if (argsym->s_name[1] == '=') x->x_operator = ne; + break; + case 'n': + if + ( + (argsym->s_name[1] == 'o') + && (argsym->s_name[2] == 'p') + && (argsym->s_name[3] == '\0') + ) + x->x_operator = nop; + break; + } + if (x->x_operator == none) + { + post("op~: unknown operator"); + x->x_operator = nop; + } + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, &s_signal); + x->x_f = 0; + x->x_g = 0; + return (x); +} + +static t_int *op_tilde_perform(t_int *w) +{ + t_op_tilde *x = (t_op_tilde *)(w[1]); + t_sample *in1 = (t_sample *)(w[2]); + t_sample *in2 = (t_sample *)(w[3]); + t_sample *out = (t_sample *)(w[4]); + int n = (int)(w[5]); + + switch (x->x_operator) + { + case le: + while (n--) *out++ = *in1++ <= *in2++; + break; + case ge: + while (n--) *out++ = *in1++ >= *in2++; + break; + case ne: + while (n--) *out++ = *in1++ != *in2++; + break; + case eq: + while (n--) *out++ = *in1++ == *in2++; + break; + case lt: + while (n--) *out++ = *in1++ < *in2++; + break; + case gt: + while (n--) *out++ = *in1++ > *in2++; + break; + case nop: + default: + while (n--) *out++ = 0; + break; + } + return (w+6); +} + +static void op_tilde_help(t_op_tilde *x) +{ + int i; + + post("op~: available operators:"); + for (i = 0; i < n_opnames; ++i) + { + post ("%s", operator_names[i]); + } +} + +static void op_tilde_op(t_op_tilde *x, t_symbol *op) +{ + int i, j = 0; + + while ((op->s_name[j] != '\0') && (j < 3)) ++j; + if ((j < 1) || (j > 3)) + { + post("op~: %s is not a valid operator (length %d)", op->s_name, j); + return; + } + for (i = 0; i < n_opnames; ++i) + { + if (operator_names[i][0] != op->s_name[0]) continue; + if ((j == 2) && (operator_names[i][1] != op->s_name[1])) continue; + if ((j == 3) && (operator_names[i][2] != op->s_name[2])) continue; + if ((j == 1) && (operator_names[i][1] != '\0')) continue; + break; + } + if (i == n_opnames) + { + post("op~: %s is not a valid operator (match)", op->s_name); + return; + } +switch(i) + { + /*"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"*/ + /*"<=", ">=", "!=", "==", "<", ">", "le", "ge", "ne", "eq", "lt", "gt", "nop"*/ + case 0: + case 6: + /* "<=" "le" */ + x->x_operator = 0; + break; + case 1: + case 7: + /* ">=" "ge" */ + x->x_operator = 1; + break; + case 2: + case 8: + /* "!=" "ne" */ + x->x_operator = 2; + break; + case 3: + case 9: + /* "==" "eq" */ + x->x_operator = 3; + break; + case 4: + case 10: + /* "<" "lt" */ + x->x_operator = 4; + break; + case 5: + case 11: + /* ">" "gt" */ + x->x_operator = 5; + break; + default: + /* "nop" */ + x->x_operator = 6; + break; + } +// post("op~: operator %s", operator_names[i]); +} + +static void op_tilde_dsp(t_op_tilde *x, t_signal **sp) +{ + t_sample *in1 = sp[0]->s_vec; + t_sample *in2 = sp[1]->s_vec; + t_sample *out = sp[2]->s_vec; + int n = sp[0]->s_n; + + dsp_add(op_tilde_perform, 5, x, in1, in2, out, n); +} + +void op_tilde_setup(void) +{ + op_tilde_class = class_new(gensym("op~"), (t_newmethod)op_tilde_new, 0, + sizeof(t_op_tilde), 0, A_GIMME, 0); + class_addmethod(op_tilde_class, (t_method)op_tilde_dsp, gensym("dsp"), 0); + class_addmethod(op_tilde_class, (t_method)op_tilde_help, gensym("help"), 0); + class_addmethod(op_tilde_class, (t_method)op_tilde_op, gensym("op"), A_DEFSYMBOL, 0); + CLASS_MAINSIGNALIN(op_tilde_class, t_op_tilde, x_f); +} + +/* fin op~.c */ + -- cgit v1.2.1