[PD-cvs] SF.net SVN: pure-data: [9768] trunk/externals/iem/iemmatrix/src

fzotter at users.sourceforge.net fzotter at users.sourceforge.net
Wed May 7 07:42:26 CEST 2008


Revision: 9768
          http://pure-data.svn.sourceforge.net/pure-data/?rev=9768&view=rev
Author:   fzotter
Date:     2008-05-06 22:42:25 -0700 (Tue, 06 May 2008)

Log Message:
-----------
added complex valued matrix fft routines

Added Paths:
-----------
    trunk/externals/iem/iemmatrix/src/mtx_fft.c
    trunk/externals/iem/iemmatrix/src/mtx_ifft.c

Added: trunk/externals/iem/iemmatrix/src/mtx_fft.c
===================================================================
--- trunk/externals/iem/iemmatrix/src/mtx_fft.c	                        (rev 0)
+++ trunk/externals/iem/iemmatrix/src/mtx_fft.c	2008-05-07 05:42:25 UTC (rev 9768)
@@ -0,0 +1,208 @@
+/*
+ *  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 <stdlib.h>
+
+static t_class *mtx_fft_class;
+
+typedef struct _MtxFFT_ MtxFFT;
+struct _MtxFFT_
+{
+  t_object x_obj;
+  int size;
+
+  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 deleteMtxFFT (MtxFFT *x) 
+{
+  if (x->f_re)
+     free (x->f_re);
+  if (x->f_im) 
+     free (x->f_im);
+  if (x->list_re)
+     free (x->list_re);
+  if (x->list_im)
+     free (x->list_im);
+}
+
+static void *newMtxFFT (t_symbol *s, int argc, t_atom *argv)
+{
+  MtxFFT *x = (MtxFFT *) pd_new (mtx_fft_class);
+  inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("matrix"),gensym(""));
+  x->list_re_out = outlet_new (&x->x_obj, gensym("matrix"));
+  x->list_im_out = outlet_new (&x->x_obj, gensym("matrix"));
+
+  x->size=0;
+  x->f_re=x->f_im=0;
+  x->list_re=x->list_im=0;
+  
+  return ((void *) x);
+} 
+
+static void mtxFFTBang (MtxFFT *x)
+{
+  if (x->list_im) {
+    outlet_anything(x->list_im_out, gensym("matrix"), x->size, x->list_im);
+    outlet_anything(x->list_re_out, gensym("matrix"), x->size, x->list_re);
+  }
+}
+
+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 mtxFFTMatrixCold (MtxFFT *x, t_symbol *s, 
+			      int argc, t_atom *argv)
+{
+  int rows = atom_getint (argv++);
+  int columns = atom_getint (argv++);
+  int size = rows * columns;
+  int in_size = argc-2;
+  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_fft: invalid dimensions");
+  else if (in_size<size)
+    post("mtx_fft: sparse matrix not yet supported: use \"mtx_check\"");
+  else if (columns < 4){
+    post("mtx_fft: matrix must have at least 4 columns");
+  }
+  else if (columns == (1 << ilog2(columns))) {
+    /* ok, prepare real-part of FFT! */
+
+    /* memory things */
+    f_re=(t_float*)realloc(f_re, sizeof(t_float)*size);
+    f_im=(t_float*)realloc(f_im, sizeof(t_float)*size);
+    list_re=(t_atom*)realloc(list_re, sizeof(t_atom)*(size+2));
+    list_im=(t_atom*)realloc(list_im, sizeof(t_atom)*(size+2));
+
+    x->size = size;
+    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_im);
+
+  }
+  else
+    post("mtx_rowfft: rowvector size no power of 2!");
+
+}
+
+
+static void mtxFFTMatrixHot (MtxFFT *x, t_symbol *s, 
+			      int argc, t_atom *argv)
+{
+  int rows = atom_getint (argv++);
+  int columns = atom_getint (argv++);
+  int size = rows * columns;
+  int in_size = argc-2;
+  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_fft: invalid dimensions");
+  else if (in_size<size)
+    post("mtx_fft: sparse matrix not yet supported: use \"mtx_check\"");
+  else if (size != x->size)
+     post("mtx_fft: left matrix has other dimensions than right matrix");
+  else if (columns < 4){
+    post("mtx_fft: matrix must have at least 4 columns");
+  }
+  else if (columns == (1 << ilog2(columns))) {
+    /* ok, do the FFT! */
+    
+    /* main part */
+    readFloatFromList (size, argv, f_re);
+
+    fft_count = rows;
+    list_re += 2;
+    list_im += 2;
+    while (fft_count--){ 
+      mayer_fft (columns, f_re, f_im);
+      writeFloatIntoList (columns, list_re, f_re);
+      writeFloatIntoList (columns, list_im, f_im);
+      f_im += columns;
+      f_re += columns;
+      list_re += columns;
+      list_im += columns;
+    }
+
+    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);
+    SETFLOAT(list_im+1, columns);
+    outlet_anything(x->list_im_out, gensym("matrix"), 
+		    x->size+2, list_im);
+    outlet_anything(x->list_re_out, gensym("matrix"), 
+		    x->size+2, list_re);
+  }
+  else
+    post("mtx_rowfft: rowvector size no power of 2!");
+
+}
+
+void mtx_fft_setup (void)
+{
+  mtx_fft_class = class_new 
+    (gensym("mtx_fft"),
+     (t_newmethod) newMtxFFT,
+     (t_method) deleteMtxFFT,
+     sizeof (MtxFFT),
+     CLASS_DEFAULT, A_GIMME, 0);
+  class_addbang (mtx_fft_class, (t_method) mtxFFTBang);
+  class_addmethod (mtx_fft_class, (t_method) mtxFFTMatrixHot, gensym("matrix"), A_GIMME,0);
+  class_addmethod (mtx_fft_class, (t_method) mtxFFTMatrixCold, gensym(""), A_GIMME,0);
+}
+
+void iemtx_fft_setup(void){
+  mtx_fft_setup();
+}

Added: trunk/externals/iem/iemmatrix/src/mtx_ifft.c
===================================================================
--- trunk/externals/iem/iemmatrix/src/mtx_ifft.c	                        (rev 0)
+++ trunk/externals/iem/iemmatrix/src/mtx_ifft.c	2008-05-07 05:42:25 UTC (rev 9768)
@@ -0,0 +1,219 @@
+/*
+ *  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 <stdlib.h>
+
+static t_class *mtx_ifft_class;
+
+typedef struct _MtxIFFT_ MtxIFFT;
+struct _MtxIFFT_
+{
+  t_object x_obj;
+  int size;
+  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 deleteMtxIFFT (MtxIFFT *x) 
+{
+  if (x->f_re)
+     free (x->f_re);
+  if (x->f_im) 
+     free (x->f_im);
+  if (x->list_re)
+     free (x->list_re);
+  if (x->list_im)
+     free (x->list_im);
+}
+
+static void *newMtxIFFT (t_symbol *s, int argc, t_atom *argv)
+{
+  MtxIFFT *x = (MtxIFFT *) pd_new (mtx_ifft_class);
+  inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("matrix"),gensym(""));
+  x->list_re_out = outlet_new (&x->x_obj, gensym("matrix"));
+  x->list_im_out = outlet_new (&x->x_obj, gensym("matrix"));
+
+  x->size=0;
+  x->f_re=x->f_im=0;
+  x->list_re=x->list_im=0;
+  
+  return ((void *) x);
+} 
+
+static void mtxIFFTBang (MtxIFFT *x)
+{
+  if (x->list_im) {
+    outlet_anything(x->list_im_out, gensym("matrix"), x->size, x->list_im);
+    outlet_anything(x->list_re_out, gensym("matrix"), x->size, x->list_re);
+  }
+}
+
+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 multiplyVector (int n, t_float *f, t_float fac)
+{
+  while (n--)
+    *f++ *= fac;
+}
+
+static void mtxIFFTMatrixCold (MtxIFFT *x, t_symbol *s, 
+			      int argc, t_atom *argv)
+{
+  int rows = atom_getint (argv++);
+  int columns = atom_getint (argv++);
+  int size = rows * columns;
+  int in_size = argc-2;
+  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_ifft: invalid dimensions");
+  else if (in_size<size)
+    post("mtx_ifft: sparse matrix not yet supported: use \"mtx_check\"");
+  else if (columns < 4){
+    post("mtx_ifft: matrix must have at least 4 columns");
+  }
+  else if (columns == (1 << ilog2(columns))) {
+    /* ok, prepare real-part of FFT! */
+    
+     x->renorm_fac = 1.0f / columns;
+
+    /* memory things */
+    f_re=(t_float*)realloc(f_re, sizeof(t_float)*size);
+    f_im=(t_float*)realloc(f_im, sizeof(t_float)*size);
+    list_re=(t_atom*)realloc(list_re, sizeof(t_atom)*(size+2));
+    list_im=(t_atom*)realloc(list_im, sizeof(t_atom)*(size+2));
+
+    x->size = size;
+    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_im);
+
+  }
+  else
+    post("mtx_rowfft: rowvector size no power of 2!");
+
+}
+
+
+static void mtxIFFTMatrixHot (MtxIFFT *x, t_symbol *s, 
+			      int argc, t_atom *argv)
+{
+  int rows = atom_getint (argv++);
+  int columns = atom_getint (argv++);
+  int size = rows * columns;
+  int in_size = argc-2;
+  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_ifft: invalid dimensions");
+  else if (in_size<size)
+    post("mtx_ifft: sparse matrix not yet supported: use \"mtx_check\"");
+  else if (size != x->size)
+     post("mtx_ifft: left matrix has other dimensions than right matrix");
+  else if (columns < 4){
+    post("mtx_ifft: matrix must have at least 4 columns");
+  }
+  else if (columns == (1 << ilog2(columns))) {
+    /* ok, do the FFT! */
+
+    /* main part */
+    readFloatFromList (size, argv, f_re);
+
+    fft_count = rows;
+    list_re += 2;
+    list_im += 2;
+    while (fft_count--){ 
+      mayer_ifft (columns, f_re, f_im);
+      multiplyVector (columns, f_re, x->renorm_fac);
+      multiplyVector (columns, f_im, x->renorm_fac);
+      writeFloatIntoList (columns, list_re, f_re);
+      writeFloatIntoList (columns, list_im, f_im);
+      f_im += columns;
+      f_re += columns;
+      list_re += columns;
+      list_im += columns;
+    }
+
+    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);
+    SETFLOAT(list_im+1, columns);
+    outlet_anything(x->list_im_out, gensym("matrix"), 
+		    x->size+2, list_im);
+    outlet_anything(x->list_re_out, gensym("matrix"), 
+		    x->size+2, list_re);
+  }
+  else
+    post("mtx_rowfft: rowvector size no power of 2!");
+
+}
+
+void mtx_ifft_setup (void)
+{
+  mtx_ifft_class = class_new 
+    (gensym("mtx_ifft"),
+     (t_newmethod) newMtxIFFT,
+     (t_method) deleteMtxIFFT,
+     sizeof (MtxIFFT),
+     CLASS_DEFAULT, A_GIMME, 0);
+  class_addbang (mtx_ifft_class, (t_method) mtxIFFTBang);
+  class_addmethod (mtx_ifft_class, (t_method) mtxIFFTMatrixHot, gensym("matrix"), A_GIMME,0);
+  class_addmethod (mtx_ifft_class, (t_method) mtxIFFTMatrixCold, gensym(""), A_GIMME,0);
+}
+
+void iemtx_ifft_setup(void){
+  mtx_ifft_setup();
+}


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Pd-cvs mailing list