From 59a57d6fd293f9ff9bfe86cf2da90a890495c16b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Tue, 20 Sep 2005 08:12:38 +0000 Subject: added more objects by fz svn path=/trunk/externals/iem/iemmatrix/; revision=3600 --- src/mtx_decay.c | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 src/mtx_decay.c (limited to 'src/mtx_decay.c') diff --git a/src/mtx_decay.c b/src/mtx_decay.c new file mode 100644 index 0000000..9170d43 --- /dev/null +++ b/src/mtx_decay.c @@ -0,0 +1,251 @@ +/* + * iemmatrix + * + * objects for manipulating simple matrices + * mostly refering to matlab/octave matrix functions + * + * Copyright (c) 2005, Franz Zotter + * IEM, Graz, Austria + * + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. + * + */ + +#include "iemmatrix.h" + +static t_class *mtx_decay_class; + +typedef struct _MTXDecay_ MTXDecay; +struct _MTXDecay_ +{ + t_object x_obj; + int rows; + int columns; + int size; + int decay_dimension; + int decay_direction; + t_float decay_parameter; + + t_outlet *list_outlet; + + t_atom *list_out; + t_atom *list_in; + t_float *x; + t_float *y; +}; + +static void deleteMTXDecay (MTXDecay *mtx_decay_obj) +{ + if (mtx_decay_obj->list_out) + freebytes (mtx_decay_obj->list_out, sizeof(t_atom)*(mtx_decay_obj->size+2)); + if (mtx_decay_obj->x) + freebytes (mtx_decay_obj->x, sizeof(t_float)*(mtx_decay_obj->size)); + if (mtx_decay_obj->y) + freebytes (mtx_decay_obj->y, sizeof(t_float)*(mtx_decay_obj->size)); +} + +static void mTXSetDecayParameter (MTXDecay *mtx_decay_obj, t_float d_param) +{ + d_param = (d_param > 0.0f)?d_param:0.0f; + d_param = (d_param < 1.0f)?d_param:1.0f; + mtx_decay_obj->decay_parameter = d_param; +} +static void mTXSetDecayDirection (MTXDecay *mtx_decay_obj, t_float c_dir) +{ + int direction = (int) c_dir; + mtx_decay_obj->decay_direction = (direction==-1)?direction:1; +} +static void mTXSetDecayDimension (MTXDecay *mtx_decay_obj, t_float c_dim) +{ + int dimension = (int) c_dim; + mtx_decay_obj->decay_dimension = (dimension==2)?dimension:1; +} + +static void *newMTXDecay (t_symbol *s, int argc, t_atom *argv) +{ + MTXDecay *mtx_decay_obj = (MTXDecay *) pd_new (mtx_decay_class); + int c_dir = 1; + int c_dim = 1; + t_float c_par = 0.9f; + + mtx_decay_obj->decay_dimension = c_dim; + switch ((argc>3)?3:argc) { + case 3: + c_dir = atom_getint(argv+2); + case 2: + c_dim = atom_getint(argv+1); + case 1: + c_par = atom_getfloat(argv); + } + mTXSetDecayParameter (mtx_decay_obj, c_par); + mTXSetDecayDirection (mtx_decay_obj, (t_float) c_dir); + mTXSetDecayDimension (mtx_decay_obj, (t_float) c_dim); + + mtx_decay_obj->list_outlet = outlet_new (&mtx_decay_obj->x_obj, gensym("matrix")); + return ((void *) mtx_decay_obj); +} + +static void mTXDecayBang (MTXDecay *mtx_decay_obj) +{ + if (mtx_decay_obj->list_out) + outlet_anything(mtx_decay_obj->list_outlet, gensym("matrix"), + mtx_decay_obj->size+2, mtx_decay_obj->list_out); +} + +static void writeFloatIntoList (int n, t_atom *l, t_float *f) +{ + for (;n--;f++, l++) + SETFLOAT (l, *f); +} +static void readFloatFromList (int n, t_atom *l, t_float *f) +{ + while (n--) + *f++ = atom_getfloat (l++); +} +static void readFloatFromListModulo (int n, int m, t_atom *l, t_float *f) +{ + t_atom *ptr = l; + int count1, count2; + n /= m; + count1 = m; + while (count1--) + for (count2 = n, ptr = l++; count2--; ptr += m, f++) + *f = atom_getfloat (ptr); +} +static void writeFloatIntoListModulo (int n, int m, t_atom *l, t_float *f) +{ + t_atom *ptr = l; + int count1, count2; + n /= m; + count1 = m; + while (count1--) + for (count2 = n, ptr = l++; count2--; ptr += m, f++) + SETFLOAT(ptr,*f); +} + +static void deCay (int n, t_float *x, t_float *y, t_float alpha) +{ + t_float decay = *x; + t_float oneminusalpha = 1.0f-alpha; + for (;n--; x++, y++) { + decay = alpha * decay + oneminusalpha * *x; + *y = decay = (decay < *x)? *x : decay; + } +} +static void deCayReverse (int n, t_float *x, t_float *y, t_float alpha) +{ + t_float decay = *x; + t_float oneminusalpha = 1.0f-alpha; + for (;n--; x--, y--) { + decay = alpha * decay + oneminusalpha * *x; + *y = decay = (decay < *x)? *x : decay; + } +} + +static void mTXDecayMatrix (MTXDecay *mtx_decay_obj, t_symbol *s, + int argc, t_atom *argv) +{ + int rows = atom_getint (argv++); + int columns = atom_getint (argv++); + int size = rows * columns; + int list_size = argc - 2; + t_atom *list_ptr = argv; + t_atom *list_out = mtx_decay_obj->list_out; + t_float *x = mtx_decay_obj->x; + t_float *y = mtx_decay_obj->y; + int count; + + // size check + if (!size) { + post("mtx_decay: invalid dimensions"); + return; + } + else if (list_sizesize) { + x = (t_float *) resizebytes (x, + sizeof (t_float) * (mtx_decay_obj->size), + sizeof (t_float) * (size)); + y = (t_float *) resizebytes (y, + sizeof (t_float) * (mtx_decay_obj->size), + sizeof (t_float) * (size)); + list_out = (t_atom *) resizebytes (list_out, + sizeof (t_atom) * (mtx_decay_obj->size+2), + sizeof (t_atom) * (size + 2)); + } + mtx_decay_obj->size = size; + mtx_decay_obj->rows = rows; + mtx_decay_obj->columns = columns; + mtx_decay_obj->list_out = list_out; + mtx_decay_obj->x = x; + mtx_decay_obj->y = y; + + // main part + // reading matrix from inlet + if (mtx_decay_obj->decay_dimension == 2) { + readFloatFromListModulo (size, columns, list_ptr, x); + columns = mtx_decay_obj->rows; + rows = mtx_decay_obj->columns; + } + else + readFloatFromList (size, list_ptr, x); + + // calculating decay + if (mtx_decay_obj->decay_direction == -1) { + x += columns-1; + y += columns-1; + for (count = rows; count--; x += columns, y += columns) + deCayReverse (columns,x,y,mtx_decay_obj->decay_parameter); + } + else + for (count = rows; count--; x += columns, y += columns) + deCay (columns,x,y,mtx_decay_obj->decay_parameter); + x = mtx_decay_obj->x; + y = mtx_decay_obj->y; + + // writing matrix to outlet + if (mtx_decay_obj->decay_dimension == 2) { + columns = mtx_decay_obj->columns; + rows = mtx_decay_obj->rows; + writeFloatIntoListModulo (size, columns, list_out+2, y); + } + else + writeFloatIntoList (size, list_out+2, y); + + SETSYMBOL(list_out, gensym("matrix")); + SETFLOAT(list_out, rows); + SETFLOAT(&list_out[1], columns); + outlet_anything(mtx_decay_obj->list_outlet, gensym("matrix"), + mtx_decay_obj->size+2, list_out); +} + +void mtx_decay_setup (void) +{ + mtx_decay_class = class_new + (gensym("mtx_decay"), + (t_newmethod) newMTXDecay, + (t_method) deleteMTXDecay, + sizeof (MTXDecay), + CLASS_DEFAULT, A_GIMME, 0); + class_addbang (mtx_decay_class, (t_method) mTXDecayBang); + class_addmethod (mtx_decay_class, (t_method) mTXDecayMatrix, gensym("matrix"), A_GIMME,0); + class_addmethod (mtx_decay_class, (t_method) mTXSetDecayParameter, gensym("alpha"), A_DEFFLOAT,0); + class_addmethod (mtx_decay_class, (t_method) mTXSetDecayDimension, gensym("dimension"), A_DEFFLOAT,0); + class_addmethod (mtx_decay_class, (t_method) mTXSetDecayDirection, gensym("direction"), A_DEFFLOAT,0); + class_sethelpsymbol (mtx_decay_class, gensym("iemmatrix/mtx_decay")); +} + +void iemtx_decay_setup(void){ + mtx_decay_setup(); +} -- cgit v1.2.1