[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