[PD-cvs] externals/iem/iemmatrix/src mtx_decay.c, NONE, 1.1 mtx_rowrfft.c, NONE, 1.1 mtx_rowrifft.c, NONE, 1.1 mtx_slice.c, NONE, 1.1

IOhannes m zmölnig zmoelnig at users.sourceforge.net
Tue Sep 20 10:12:40 CEST 2005


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();
}





More information about the Pd-cvs mailing list