/* * 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" #include static t_class *mtx_rowrfft_class; typedef struct _MTXRowrfft_ MTXRowrfft; struct _MTXRowrfft_ { t_object x_obj; int size; int size2; 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 *x) { free (x->f_re); free (x->f_im); free (x->list_re); free (x->list_im); } static void *newMTXRowrfft (t_symbol *s, int argc, t_atom *argv) { MTXRowrfft *x = (MTXRowrfft *) pd_new (mtx_rowrfft_class); x->list_re_out = outlet_new (&x->x_obj, gensym("matrix")); x->list_im_out = outlet_new (&x->x_obj, gensym("matrix")); x->size=x->size2=0; x->f_re=x->f_im=0; x->list_re=x->list_im=0; return ((void *) x); } static void mTXrowrfftBang (MTXRowrfft *x) { if (x->list_im) { outlet_anything(x->list_im_out, gensym("matrix"), x->size2, x->list_im); outlet_anything(x->list_re_out, gensym("matrix"), x->size2, x->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 *x, t_symbol *s, int argc, t_atom *argv) { //mTXrowrfftList (x, s, argc-2, argv+2); int rows = atom_getint (argv++); int columns = atom_getint (argv++); int columns_re = (columns>>1); int size = rows * columns; int in_size = argc-2; int size2 = columns_re * rows + 2; /* +2 since the list also contains matrix row+col */ int fft_count; t_atom *list_re = x->list_re; t_atom *list_im = x->list_im; t_float *f_re = x->f_re; t_float *f_im = x->f_im; // fftsize check if (!size) post("mtx_rowrfft: invalid dimensions"); else if (in_sizesize = size; x->size2 = size2; x->list_im = list_im; x->list_re = list_re; x->f_re = f_re; x->f_im = f_im; // main part readFloatFromList (size, argv, f_re); fft_count = rows; list_re += 2; list_im += 2; while (fft_count--){ mayer_realfft (columns, f_re); fftRestoreImag (columns, f_re, f_im); writeFloatIntoList (columns_re, list_re, f_re); writeFloatIntoList (columns_re, list_im, f_im); f_im += columns; f_re += columns; list_re += columns_re; list_im += columns_re; } list_re = x->list_re; list_im = x->list_im; SETSYMBOL(list_re, gensym("matrix")); SETSYMBOL(list_im, gensym("matrix")); SETFLOAT(list_re, rows); SETFLOAT(list_im, rows); SETFLOAT(list_re+1, columns_re); SETFLOAT(list_im+1, columns_re); outlet_anything(x->list_im_out, gensym("matrix"), x->size2, list_im); outlet_anything(x->list_re_out, gensym("matrix"), x->size2, list_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(); }