aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mtx_decay.c251
-rw-r--r--src/mtx_rowrfft.c205
-rw-r--r--src/mtx_rowrifft.c238
-rw-r--r--src/mtx_slice.c215
4 files changed, 909 insertions, 0 deletions
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_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();
+}
diff --git a/src/mtx_rowrfft.c b/src/mtx_rowrfft.c
new file mode 100644
index 0000000..e7f0551
--- /dev/null
+++ b/src/mtx_rowrfft.c
@@ -0,0 +1,205 @@
+/*
+ * 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();
+}
diff --git a/src/mtx_rowrifft.c b/src/mtx_rowrifft.c
new file mode 100644
index 0000000..9eaba9c
--- /dev/null
+++ b/src/mtx_rowrifft.c
@@ -0,0 +1,238 @@
+/*
+ * 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();
+}
diff --git a/src/mtx_slice.c b/src/mtx_slice.c
new file mode 100644
index 0000000..7dc1042
--- /dev/null
+++ b/src/mtx_slice.c
@@ -0,0 +1,215 @@
+/*
+ * 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();
+}