Update of /cvsroot/pure-data/externals/iem/iemmatrix/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19370
Added Files: mtx_decay.c mtx_rowrfft.c mtx_rowrifft.c mtx_slice.c Log Message: added more objects by fz
--- NEW FILE: mtx_slice.c --- /* * 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_slice_class;
typedef struct _MTXslice_ MTXslice; struct _MTXslice_ { t_object x_obj; int slice_size; int slice_startcol; int slice_startrow; int slice_stopcol; int slice_stoprow;
t_outlet *list_outlet;
t_atom *list_out; };
static void deleteMTXSlice (MTXslice *mtx_slice_obj) { if (mtx_slice_obj->list_out) freebytes (mtx_slice_obj->list_out, sizeof(t_atom)*(mtx_slice_obj->slice_size+2)); }
static void mTXSliceIndexList (MTXslice *mtx_slice_obj, t_symbol *s, int argc, t_atom *argv) { int startcol; int startrow; int stopcol; int stoprow; t_symbol *endsym = gensym("end"); t_atom *list_out = mtx_slice_obj->list_out;
if (argc<4) { post("mtx_slice: invalid index vector: <startrow><startcol><stoprow><stopcol>"); return; } startrow = atom_getint(&argv[0]); startcol = atom_getint(&argv[1]); stoprow = atom_getint(&argv[2]); stopcol = atom_getint(&argv[3]); if (atom_getsymbol(&argv[0])==endsym) { startrow = -1; } if (atom_getsymbol(&argv[1])==endsym) { startcol = -1; } if (atom_getsymbol(&argv[2])==endsym) { stoprow = -1; } if (atom_getsymbol(&argv[3])==endsym) { stopcol = -1; }
if (((startrow<1) && (atom_getsymbol(&argv[0])!=endsym)) || ((startcol<1) && (atom_getsymbol(&argv[1])!=endsym))) { post("mtx_slice: row and column indices must be >0, or misused "end" keyword"); return; }
if (((startrow>stoprow) && (atom_getsymbol(&argv[2])!=endsym)) || ((startcol>stopcol) && (atom_getsymbol (&argv[3])!=endsym))) { post("mtx_slice: start_index<stop_index for rows and columns, or misused "end" keyword"); return; }
mtx_slice_obj->slice_startrow = startrow; mtx_slice_obj->slice_startcol = startcol; mtx_slice_obj->slice_stoprow = stoprow; mtx_slice_obj->slice_stopcol = stopcol; }
static void *newMTXSlice (t_symbol *s, int argc, t_atom *argv) { MTXslice *mtx_slice_obj = (MTXslice *) pd_new (mtx_slice_class); if (argc==4) mTXSliceIndexList (mtx_slice_obj, gensym("list"),argc,argv); else { mtx_slice_obj->slice_startrow = 1; mtx_slice_obj->slice_startcol = 1; mtx_slice_obj->slice_stopcol = -1; mtx_slice_obj->slice_stoprow = -1; } mtx_slice_obj->list_outlet = outlet_new (&mtx_slice_obj->x_obj, gensym("matrix")); inlet_new(&mtx_slice_obj->x_obj, &mtx_slice_obj->x_obj.ob_pd, gensym("list"),gensym("")); return ((void *) mtx_slice_obj); }
static void mTXSliceBang (MTXslice *mtx_slice_obj) { if (mtx_slice_obj->list_out) outlet_anything(mtx_slice_obj->list_outlet, gensym("matrix"), mtx_slice_obj->slice_size+2, mtx_slice_obj->list_out); } /* static void copyList (int size, t_atom *x, t_atom *y) { while(size--) *y++=*x++; } */
static void writeVectorIntoList (int n, t_atom *x, t_atom *y) { for (;n--;x++,y++) *y = *x; }
static void writeSliceIntoList (int slicerows, const int slicecols, int columns, t_atom *x, t_atom *y) { for (;slicerows--;x+=columns,y+=slicecols) writeVectorIntoList(slicecols, x, y); }
static void mTXSliceMatrix (MTXslice *mtx_slice_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_in = argv; t_atom *list_out = mtx_slice_obj->list_out; int stopcol = mtx_slice_obj->slice_stopcol; int stoprow = mtx_slice_obj->slice_stoprow; int startrow = mtx_slice_obj->slice_startrow; int startcol = mtx_slice_obj->slice_startcol; int slicecols, slicerows, slicesize;
// size check if (!size) { post("mtx_slice: invalid dimensions"); return; } else if (list_size<size) { post("mtx_slice: sparse matrix not yet supported: use "mtx_check""); return; } startrow = (startrow==-1)?rows:startrow; startcol = (startcol==-1)?columns:startcol; stoprow = (stoprow==-1)?rows:stoprow; stopcol = (stopcol==-1)?columns:stopcol; if ((!startrow)||(!startcol)) { post("mtx_slice: indices must be >0"); return; } if ((stopcol > columns) || (stoprow > rows)) { post("mtx_slice: slice index exceeds matrix dimensions"); return; } if ((stoprow<startrow) || (stopcol<startcol)) { post("mtx_slice: start_index<stop_index for rows and columns, or misused "end" keyword"); return; } slicerows = stoprow-startrow+1; slicecols = stopcol-startcol+1; slicesize = slicerows*slicecols;
// main part if (slicesize != mtx_slice_obj->slice_size) { if (!list_out) list_out = (t_atom *) getbytes (sizeof (t_atom) * (slicesize + 2)); else list_out = (t_atom *) resizebytes (list_out, sizeof (t_atom) * (mtx_slice_obj->slice_size+2), sizeof (t_atom) * (slicesize + 2)); mtx_slice_obj->slice_size = slicesize; mtx_slice_obj->list_out = list_out; } list_out += 2; list_in += columns * (startrow-1) + startcol-1; writeSliceIntoList (slicerows, slicecols, columns, list_in,list_out); list_out = mtx_slice_obj->list_out; SETSYMBOL(list_out, gensym("matrix")); SETFLOAT(list_out, slicerows); SETFLOAT(&list_out[1], slicecols); outlet_anything(mtx_slice_obj->list_outlet, gensym("matrix"), slicesize+2, list_out); }
void mtx_slice_setup (void) { mtx_slice_class = class_new (gensym("mtx_slice"), (t_newmethod) newMTXSlice, (t_method) deleteMTXSlice, sizeof (MTXslice), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_slice_class, (t_method) mTXSliceBang); class_addmethod (mtx_slice_class, (t_method) mTXSliceMatrix, gensym("matrix"), A_GIMME,0); class_addmethod (mtx_slice_class, (t_method) mTXSliceIndexList, gensym(""), A_GIMME,0); class_sethelpsymbol (mtx_slice_class, gensym("iemmatrix/mtx_slice")); }
void iemtx_slice_setup(void){ mtx_slice_setup(); }
--- NEW FILE: mtx_rowrifft.c --- /* * 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_rowrifft_class;
typedef struct _MTXRowrifft_ { t_object x_obj; int rows; int columns; int columns_re; int size; int size2; t_float renorm_fac;
t_float *f_re; t_float *f_im;
t_outlet *list_re_out; t_outlet *list_im_out;
t_atom *list_re; t_atom *list_im; } MTXRowrifft;
// helper functions: these should really go into a separate file!
static void zeroFloatArray (int n, t_float *f) { while (n--) *f++ = 0.0f; }
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++); }
//--------------inverse real fft
static void multiplyVector (int n, t_float *f, t_float fac) { while (n--) *f++ *= fac; }
static void ifftPrepareReal (int n, t_float *re, t_float *im) { n >>= 1; re += n; im += n;
while (--n) *++re = -*--im; }
static void *newMTXRowrifft (t_symbol *s, int argc, t_atom *argv) { MTXRowrifft *mtx_rowrifft_obj = (MTXRowrifft *) pd_new (mtx_rowrifft_class); inlet_new(&mtx_rowrifft_obj->x_obj, &mtx_rowrifft_obj->x_obj.ob_pd, gensym("matrix"),gensym("")); mtx_rowrifft_obj->list_re_out = outlet_new (&mtx_rowrifft_obj->x_obj, gensym("matrix")); return ((void *) mtx_rowrifft_obj); }
static void mTXrowrifftMatrixCold (MTXRowrifft *mtx_rowrifft_obj, t_symbol *s, int argc, t_atom *argv) { //mTXrowrifftList (mtx_rowrifft_obj, s, argc-2, argv+2); int rows = atom_getint (argv++); int columns_re = atom_getint (argv++); int in_size = argc-2; int columns = (columns_re-1)<<1; int size2 = columns_re * rows; int size = rows * columns; int ifft_count; t_atom *ptr_re = mtx_rowrifft_obj->list_re; t_float *f_re = mtx_rowrifft_obj->f_re; t_float *f_im = mtx_rowrifft_obj->f_im;
// ifftsize check if (!size) post("mtx_rowrifft: invalid dimensions"); else if (in_size < size2) post("mtx_rowrifft: sparse matrix not yet supported: use "mtx_check""); else if (columns == (1 << ilog2(columns))) { // memory things if (f_re) { if (size != mtx_rowrifft_obj->size) { f_re = (t_float *) resizebytes (f_re, sizeof (t_float) * mtx_rowrifft_obj->size, sizeof (t_float) * size); f_im = (t_float *) resizebytes (f_im, sizeof (t_float) * mtx_rowrifft_obj->size, sizeof (t_float) * size); ptr_re = (t_atom *) resizebytes (ptr_re, sizeof (t_atom) * (mtx_rowrifft_obj->size + 2), sizeof (t_atom) * (size + 2)); } } else { f_re = (t_float *) getbytes (sizeof (t_float) * size); f_im = (t_float *) getbytes (sizeof (t_float) * size); ptr_re = (t_atom *) getbytes (sizeof (t_atom) * (size + 2)); } mtx_rowrifft_obj->size = size; mtx_rowrifft_obj->size2 = size2; mtx_rowrifft_obj->rows = rows; mtx_rowrifft_obj->columns = columns; mtx_rowrifft_obj->columns_re = columns_re; mtx_rowrifft_obj->list_re = ptr_re; mtx_rowrifft_obj->f_re = f_re; mtx_rowrifft_obj->f_im = f_im;
// main part: reading imaginary part ifft_count = rows; mtx_rowrifft_obj->renorm_fac = 1.0f / columns; while (ifft_count--) { readFloatFromList (columns_re, argv, f_im); argv += columns_re; f_im += columns; } // do nothing else! } else post("mtx_rowrifft: rowvector size no power of 2!"); }
static void mTXrowrifftMatrixHot (MTXRowrifft *mtx_rowrifft_obj, t_symbol *s, int argc, t_atom *argv) { //mTXrowrifftList (mtx_rowrifft_obj, s, argc-2, argv+2); int rows = atom_getint (argv++); int columns_re = atom_getint (argv++); int columns = mtx_rowrifft_obj->columns; int size = mtx_rowrifft_obj->size; int in_size = argc-2; int size2 = mtx_rowrifft_obj->size2; int ifft_count; t_atom *ptr_re = mtx_rowrifft_obj->list_re; t_float *f_re = mtx_rowrifft_obj->f_re; t_float *f_im = mtx_rowrifft_obj->f_im; t_float renorm_fac;
// ifftsize check if ((rows != mtx_rowrifft_obj->rows) || (columns_re != mtx_rowrifft_obj->columns_re)) post("mtx_rowrifft: matrix dimensions do not match"); else if (in_size<size2) post("mtx_rowrifft: sparse matrix not yet supported: use "mtx_check""); else if (!mtx_rowrifft_obj->size2) post("mtx_rowrifft: invalid right side matrix"); else { // main part ifft_count = rows; ptr_re += 2; renorm_fac = mtx_rowrifft_obj->renorm_fac; while (ifft_count--){ readFloatFromList (columns_re, argv, f_re); ifftPrepareReal (columns, f_re, f_im); mayer_realifft (columns, f_re); multiplyVector (columns, f_re, renorm_fac); f_im += columns; f_re += columns; ptr_re += columns; argv += columns_re; } ptr_re = mtx_rowrifft_obj->list_re; f_re = mtx_rowrifft_obj->f_re; size2 = mtx_rowrifft_obj->size2;
SETSYMBOL(ptr_re, gensym("matrix")); SETFLOAT(ptr_re, rows); SETFLOAT(&ptr_re[1], mtx_rowrifft_obj->columns); writeFloatIntoList (size, ptr_re+2, f_re); outlet_anything(mtx_rowrifft_obj->list_re_out, gensym("matrix"), size+2, ptr_re); } }
static void mTXrowrifftBang (MTXRowrifft *mtx_rowrifft_obj) { if (mtx_rowrifft_obj->list_re) outlet_anything(mtx_rowrifft_obj->list_re_out, gensym("matrix"), mtx_rowrifft_obj->size+2, mtx_rowrifft_obj->list_re); }
static void deleteMTXRowrifft (MTXRowrifft *mtx_rowrfft_obj) { if (mtx_rowrfft_obj->f_re) freebytes (mtx_rowrfft_obj->f_re, sizeof(t_float)*mtx_rowrfft_obj->size); if (mtx_rowrfft_obj->f_im) freebytes (mtx_rowrfft_obj->f_im, sizeof(t_float)*mtx_rowrfft_obj->size); if (mtx_rowrfft_obj->list_re) freebytes (mtx_rowrfft_obj->list_re, sizeof(t_atom)*(mtx_rowrfft_obj->size2+2)); if (mtx_rowrfft_obj->list_im) freebytes (mtx_rowrfft_obj->list_im, sizeof(t_atom)*(mtx_rowrfft_obj->size2+2)); }
static void mtx_rowrifft_setup (void) { mtx_rowrifft_class = class_new (gensym("mtx_rowrifft"), (t_newmethod) newMTXRowrifft, (t_method) deleteMTXRowrifft, sizeof (MTXRowrifft), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_rowrifft_class, (t_method) mTXrowrifftBang); class_addmethod (mtx_rowrifft_class, (t_method) mTXrowrifftMatrixHot, gensym("matrix"), A_GIMME,0); class_addmethod (mtx_rowrifft_class, (t_method) mTXrowrifftMatrixCold, gensym(""), A_GIMME,0); class_sethelpsymbol (mtx_rowrifft_class, gensym("iemmatrix/mtx_rowrfft")); }
void iemtx_rowrifft_setup(void){ mtx_rowrifft_setup(); }
--- NEW FILE: mtx_decay.c --- /* * 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_size<size) { post("mtx_decay: sparse matrix not yet supported: use "mtx_check""); return; } else if ((!x)||(!list_out)||(!y)) { if (!x) x = (t_float *) getbytes (sizeof (t_float) * (size)); if (!y) y = (t_float *) getbytes (sizeof (t_float) * (size)); if (!list_out) list_out = (t_atom *) getbytes (sizeof (t_atom) * (size+2)); } else if (size != mtx_decay_obj->size) { 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(); }
--- NEW FILE: mtx_rowrfft.c --- /* * 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_rowrfft_class;
typedef struct _MTXRowrfft_ MTXRowrfft; struct _MTXRowrfft_ { t_object x_obj; int rows; int columns; int columns_re; int size; int size2; t_float renorm_fac;
t_float *f_re; t_float *f_im;
t_outlet *list_re_out; t_outlet *list_im_out;
t_atom *list_re; t_atom *list_im; };
static void deleteMTXRowrfft (MTXRowrfft *mtx_rowrfft_obj) { if (mtx_rowrfft_obj->f_re) freebytes (mtx_rowrfft_obj->f_re, sizeof(t_float)*mtx_rowrfft_obj->size); if (mtx_rowrfft_obj->f_im) freebytes (mtx_rowrfft_obj->f_im, sizeof(t_float)*mtx_rowrfft_obj->size); if (mtx_rowrfft_obj->list_re) freebytes (mtx_rowrfft_obj->list_re, sizeof(t_atom)*(mtx_rowrfft_obj->size2+2)); if (mtx_rowrfft_obj->list_im) freebytes (mtx_rowrfft_obj->list_im, sizeof(t_atom)*(mtx_rowrfft_obj->size2+2)); }
static void *newMTXRowrfft (t_symbol *s, int argc, t_atom *argv) { MTXRowrfft *mtx_rowrfft_obj = (MTXRowrfft *) pd_new (mtx_rowrfft_class); mtx_rowrfft_obj->list_re_out = outlet_new (&mtx_rowrfft_obj->x_obj, gensym("matrix")); mtx_rowrfft_obj->list_im_out = outlet_new (&mtx_rowrfft_obj->x_obj, gensym("matrix")); return ((void *) mtx_rowrfft_obj); }
static void mTXrowrfftBang (MTXRowrfft *mtx_rowrfft_obj) { if (mtx_rowrfft_obj->list_im) { outlet_anything(mtx_rowrfft_obj->list_im_out, gensym("matrix"), mtx_rowrfft_obj->size2+2, mtx_rowrfft_obj->list_im); outlet_anything(mtx_rowrfft_obj->list_re_out, gensym("matrix"), mtx_rowrfft_obj->size2+2, mtx_rowrfft_obj->list_re); } }
static void fftRestoreImag (int n, t_float *re, t_float *im) { t_float *im2; n >>= 1; *im=0; re += n; im += n; im2 = im; *im=0; while (--n) { *--im = -*++re; *++im2 = 0; *re = 0; } }
static void zeroFloatArray (int n, t_float *f) { while (n--) *f++ = 0.0f; }
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 mTXrowrfftMatrix (MTXRowrfft *mtx_rowrfft_obj, t_symbol *s, int argc, t_atom *argv) { //mTXrowrfftList (mtx_rowrfft_obj, s, argc-2, argv+2); int rows = atom_getint (argv++); int columns = atom_getint (argv++); int columns_re = (columns>>1)+1; int size = rows * columns; int in_size = argc-2; int size2 = columns_re * rows; int fft_count; t_atom *ptr_re = mtx_rowrfft_obj->list_re; t_atom *ptr_im = mtx_rowrfft_obj->list_im; t_float *f_re = mtx_rowrfft_obj->f_re; t_float *f_im = mtx_rowrfft_obj->f_im;
// fftsize check if (!size) post("mtx_rowrfft: invalid dimensions"); else if (in_size<size) post("mtx_rowrfft: sparse matrix not yet supported: use "mtx_check""); else if (columns == (1 << ilog2(columns))) { // memory things if (f_re) { if (size != mtx_rowrfft_obj->size) { f_re = (t_float *) resizebytes (f_re, sizeof (t_float) * mtx_rowrfft_obj->size, sizeof (t_float) * size); f_im = (t_float *) resizebytes (f_im, sizeof (t_float) * mtx_rowrfft_obj->size, sizeof (t_float) * size); ptr_re = (t_atom *) resizebytes (ptr_re, sizeof (t_atom) * (mtx_rowrfft_obj->size2+2), sizeof (t_atom) * (size2 + 2)); ptr_im = (t_atom *) resizebytes (ptr_im, sizeof (t_atom) * (mtx_rowrfft_obj->size2+2), sizeof (t_atom) * (size2 + 2)); } } else { f_re = (t_float *) getbytes (sizeof (t_float) * size); f_im = (t_float *) getbytes (sizeof (t_float) * size); ptr_re = (t_atom *) getbytes (sizeof (t_atom) * (size2+2)); ptr_im = (t_atom *) getbytes (sizeof (t_atom) * (size2+2)); } mtx_rowrfft_obj->size = size; mtx_rowrfft_obj->size2 = size2; mtx_rowrfft_obj->rows = rows; mtx_rowrfft_obj->columns = columns; mtx_rowrfft_obj->columns_re = columns_re; mtx_rowrfft_obj->list_im = ptr_im; mtx_rowrfft_obj->list_re = ptr_re; mtx_rowrfft_obj->f_re = f_re; mtx_rowrfft_obj->f_im = f_im;
// main part readFloatFromList (size, argv, f_re);
fft_count = rows; ptr_re += 2; ptr_im += 2; while (fft_count--){ mayer_realfft (columns, f_re); fftRestoreImag (columns, f_re, f_im); writeFloatIntoList (columns_re, ptr_re, f_re); writeFloatIntoList (columns_re, ptr_im, f_im); f_im += columns; f_re += columns; ptr_re += columns_re; ptr_im += columns_re; } ptr_re = mtx_rowrfft_obj->list_re; ptr_im = mtx_rowrfft_obj->list_im;
SETSYMBOL(ptr_re, gensym("matrix")); SETSYMBOL(ptr_im, gensym("matrix")); SETFLOAT(ptr_re, rows); SETFLOAT(ptr_im, rows); SETFLOAT(&ptr_re[1], columns_re); SETFLOAT(&ptr_im[1], columns_re); outlet_anything(mtx_rowrfft_obj->list_im_out, gensym("matrix"), mtx_rowrfft_obj->size2+2, ptr_im); outlet_anything(mtx_rowrfft_obj->list_re_out, gensym("matrix"), mtx_rowrfft_obj->size2+2, ptr_re); } else post("mtx_rowfft: rowvector size no power of 2!"); }
void mtx_rowrfft_setup (void) { mtx_rowrfft_class = class_new (gensym("mtx_rowrfft"), (t_newmethod) newMTXRowrfft, (t_method) deleteMTXRowrfft, sizeof (MTXRowrfft), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_rowrfft_class, (t_method) mTXrowrfftBang); class_addmethod (mtx_rowrfft_class, (t_method) mTXrowrfftMatrix, gensym("matrix"), A_GIMME,0); class_sethelpsymbol (mtx_rowrfft_class, gensym("iemmatrix/mtx_rowrfft")); }
void iemtx_rowrfft_setup(void){ mtx_rowrfft_setup(); }