/* * 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"); if (argc<4) { post("mtx_slice: invalid index vector: "); 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_indexslice_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_size0"); return; } if ((stopcol > columns) || (stoprow > rows)) { post("mtx_slice: slice index exceeds matrix dimensions"); return; } if ((stoprowslice_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); } void iemtx_slice_setup(void){ mtx_slice_setup(); }