diff options
Diffstat (limited to 'nusmuk-utils/mtx_preset.c')
-rw-r--r-- | nusmuk-utils/mtx_preset.c | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/nusmuk-utils/mtx_preset.c b/nusmuk-utils/mtx_preset.c new file mode 100644 index 0000000..afd681c --- /dev/null +++ b/nusmuk-utils/mtx_preset.c @@ -0,0 +1,303 @@ +/* +mtx_preset : store and interpol presets that are in a matrix form +Copyright (C) 2014 Cyrile Henry + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + + +#include "m_pd.h" +#include "math.h" + +#define sizemaxX 1000 +#define sizemaxY 1000 + +static t_class *mtx_preset_class; + +typedef struct _mtx_preset { + t_object x_obj; + t_outlet *main_outlet; + t_int sizeX; + t_int sizeY; + t_float matrix[sizemaxX][sizemaxY+1]; +} t_mtx_preset; + +t_float mix(t_float X, t_float Y, t_float mix) +{ + return (1-mix)*X + mix*Y ; +} + +#define min(X, Y) (((X) < (Y)) ? (X) : (Y)) +#define max(X, Y) (((X) > (Y)) ? (X) : (Y)) + +void *mtx_preset_new(t_symbol *s, int argc, t_atom *argv) +{ + int i, j; + t_mtx_preset *x = (t_mtx_preset *)pd_new(mtx_preset_class); + + x->sizeX = 2; + if ((argc>0) && (argv[0].a_type == A_FLOAT)) + x->sizeX = atom_getfloatarg(0, argc, argv); + if (x->sizeX > sizemaxX) + x->sizeX = sizemaxX; + if (x->sizeX < 1) + x->sizeX = 1; + + x->sizeY = 2; + if ((argc>1) && (argv[1].a_type == A_FLOAT)) + x->sizeY = atom_getfloatarg(1, argc, argv); + if (x->sizeY > sizemaxX) + x->sizeY = sizemaxX; + if (x->sizeY < 1) + x->sizeY = 1; + + for (i=0; i < sizemaxX; i++) + for (j=0; j < sizemaxY; j++) + x->matrix[i][j] = 0; + + x->main_outlet = outlet_new(&x->x_obj, 0); + return (void *)x; +} + + void mtx_preset_resize(t_mtx_preset *x, t_float sizeX, t_float sizeY) +{ + x->sizeX = sizeX; + x->sizeY = sizeY; + + if (x->sizeX > sizemaxX) + x->sizeX = sizemaxX; + if (x->sizeX < 1) + x->sizeX = 1; + + if (x->sizeY > sizemaxX) + x->sizeY = sizemaxX; + if (x->sizeY < 1) + x->sizeY = 1; +} + + +void mtx_preset_matrix(t_mtx_preset *x, t_symbol *s, int argc, t_atom *argv) +{ + int X,Y, mtxX, mtxY, i, j,k; + + if ((argc > 3) && (argv[0].a_type == A_FLOAT) && (argv[1].a_type == A_FLOAT) && (argv[2].a_type == A_FLOAT)) { + // reception de matrix X Y values + // copy data, carfull if matrix and mtx_interpol have different size + mtxX = atom_getfloatarg(0,argc,argv); + mtxY = atom_getfloatarg(1,argc,argv); + + X = min(x->sizeX, mtxX); + Y = min(x->sizeY, mtxY); + + for (i=0; i < X; i++) { + for (j=0; j < Y; j++) { + k= j*mtxX + i + 2; + if ((argc > k) && (argv[k].a_type == A_FLOAT)) + x->matrix[i][j] = atom_getfloatarg(k,argc,argv); + } + } + } + else if ((argc > 1) && (argv[1].a_type == A_FLOAT)) { + // reception de matrix value + for (i=0; i < x->sizeX; i++) { + for (j=0; j < x->sizeY; j++) { + x->matrix[i][j] = atom_getfloatarg(0,argc,argv); + } + } + } + else { + error("bad matrix"); + return; + } +} + +void mtx_preset_row(t_mtx_preset *x, t_symbol *s, int argc, t_atom *argv) +{ +// reception de row Y values... + int row, i; + + if ((argc > 0) && (argv[0].a_type == A_FLOAT)) + row = atom_getfloatarg(0,argc,argv); + else { + error("bad row"); + return; + } + row = min(x->sizeY, row); + for (i=0; i < x->sizeX; i++) + if ((argc > i+1) && (argv[i+1].a_type == A_FLOAT)) + x->matrix[i][row] = atom_getfloatarg(i+1,argc,argv); +} + +void mtx_preset_col(t_mtx_preset *x, t_symbol *s, int argc, t_atom *argv) +{ +// reception de col X values... + int col, i; + + if ((argc > 0) && (argv[0].a_type == A_FLOAT)) + col = atom_getfloatarg(0,argc,argv); + else { + error("bad col"); + return; + } + col = min(x->sizeX, col); + for (i=0; i < x->sizeY; i++) + if ((argc > i+1) && (argv[i+1].a_type == A_FLOAT)) + x->matrix[col][i] = atom_getfloatarg(i+1,argc,argv); +} + +void mtx_preset_setrow(t_mtx_preset *x, t_symbol *s, int argc, t_atom *argv) +{ +// reception de row Y values... +// TODO : optimized + int row, i; + + if ((argc > 0) && (argv[0].a_type == A_FLOAT)) + row = atom_getfloatarg(0,argc,argv); + else { + error("bad row"); + return; + } + row = min(x->sizeY, row); + for (i=0; i < x->sizeX; i++) + if ((argc > 1) && (argv[1].a_type == A_FLOAT)) + x->matrix[i][row] = atom_getfloatarg(1,argc,argv); +} + +void mtx_preset_setcol(t_mtx_preset *x, t_symbol *s, int argc, t_atom *argv) +{ +// reception de col X values... +// TODO : optimized + int col, i; + + if ((argc > 0) && (argv[0].a_type == A_FLOAT)) + col = atom_getfloatarg(0,argc,argv); + else { + error("bad col"); + return; + } + col = min(x->sizeX, col); + for (i=0; i < x->sizeY; i++) + if ((argc > 1) && (argv[1].a_type == A_FLOAT)) + x->matrix[col][i] = atom_getfloatarg(1,argc,argv); +} + +void mtx_preset_element(t_mtx_preset *x, t_float posX, t_float posY, t_float value) +{ +// reception de element X Y value + if ((posX < x->sizeX) && (posX < x->sizeX)) { + x->matrix[(int)posX][(int)posY] = value; + } +} + +void mtx_preset_getMatrix(t_mtx_preset *x) +{ + int i, j; +// dump matrix tailleX tailleY datas... + t_atom std_out[x->sizeX*x->sizeY+2]; + SETFLOAT(&(std_out[0]),x->sizeX); + SETFLOAT(&(std_out[1]),x->sizeY); + for (i=0; i < x->sizeX; i++) + for (j=0; j < x->sizeY; j++) + SETFLOAT(&(std_out[i+x->sizeX*j+2]),x->matrix[i][j]); + + outlet_anything(x->main_outlet, gensym("matrix"),x->sizeX*x->sizeY+2,std_out); +} + +void mtx_preset_getRow(t_mtx_preset *x, t_symbol *s, int argc, t_atom *argv) +{ + int i,j, a,b; + t_float c; + t_atom std_out[x->sizeX+1]; + + if (argc == 0) + for (i=0; i< x->sizeY; i++) { + SETFLOAT(&(std_out[0]),i); + for (j=0; j < x->sizeX; j++) { + SETFLOAT(&(std_out[j+1]),x->matrix[j][i]); + } + outlet_anything(x->main_outlet, gensym("row"),x->sizeX+1,std_out); + } + else if ((argc > 0) && (argv[0].a_type == A_FLOAT)) { + a = floor(atom_getfloatarg(0,argc,argv)); + b = a+1; + c = atom_getfloatarg(0,argc,argv)-a; + + for (i=0; i < x->sizeX; i++) { + SETFLOAT(&(std_out[i]),mix(x->matrix[i][a], x->matrix[i][b], c)); + } + outlet_list(x->main_outlet, gensym("list"), x->sizeX, std_out); + } +} + +void mtx_preset_getElement(t_mtx_preset *x, t_float posX, t_float posY) +{ + int a,b; + + a = min(posX, x->sizeX); + a = max(a,0); + b = min(posY, x->sizeY); + b = max(b,0); + + outlet_float(x->main_outlet, x->matrix[a][b]); +} + +void mtx_preset_mixRow(t_mtx_preset *x, t_symbol *s, int argc, t_atom *argv) +{ + int i, j; + t_atom std_out[x->sizeX]; + t_float row[x->sizeX]; + + for (i=0; i < x->sizeX; i++) + row[i] = 0; + + + for (j=0; j<min(argc, x->sizeY); j++) + for (i=0; i < x->sizeX; i++) + row[i] += x->matrix[i][j] * atom_getfloatarg(j, argc, argv); + + for (i=0; i < x->sizeX; i++) + SETFLOAT(&(std_out[i]),row[i]); + outlet_list(x->main_outlet, gensym("list"), x->sizeX, std_out); +} + +void mtx_preset_setup(void) { + mtx_preset_class = class_new(gensym("mtx_preset"), + (t_newmethod)mtx_preset_new, + 0, sizeof(t_mtx_preset), + CLASS_DEFAULT, A_GIMME, 0); + class_addmethod(mtx_preset_class, (t_method)mtx_preset_matrix, gensym("matrix"),A_GIMME, 0); // put Matrix + // matrix value -> all matrix will be at the float value + // matrix sizeX sizeY values ... -> put the matrix in 0 0 + class_addmethod(mtx_preset_class, (t_method)mtx_preset_row, gensym("row"),A_GIMME, 0); // put Row + // row float float ... -> put all value to a row + class_addmethod(mtx_preset_class, (t_method)mtx_preset_col, gensym("col"),A_GIMME, 0); // put Col + // coll float float ... -> put all value to a col + class_addmethod(mtx_preset_class, (t_method)mtx_preset_setrow, gensym("setRow"),A_GIMME, 0); // set Row + // row float float -> put value to a row + class_addmethod(mtx_preset_class, (t_method)mtx_preset_setcol, gensym("setCol"),A_GIMME, 0); // set Col + // coll float float -> put value to a col + class_addmethod(mtx_preset_class, (t_method)mtx_preset_element, gensym("element"),A_FLOAT, A_FLOAT, A_FLOAT, 0); // put 1 element + // element posX posY value + class_addmethod(mtx_preset_class, (t_method)mtx_preset_getMatrix, gensym("getMatrix"), 0); // get matrix (matrix sizeX sizeY value) + class_addmethod(mtx_preset_class, (t_method)mtx_preset_getRow, gensym("getRow"), A_GIMME, 0); // get row + // getRow -> dump all row (row now_number row values) + // getRow row_number -> dump 1 row (values) + // row_number can be float : row will be interpolated + class_addmethod(mtx_preset_class, (t_method)mtx_preset_getElement,gensym("getElement"),A_FLOAT, A_FLOAT, 0); // get 1 element + // get posX posY -> dump 1 element + // posX and posY can be float : value will be interpolated in X and Y + class_addmethod(mtx_preset_class, (t_method)mtx_preset_mixRow, gensym("mixRow"), A_GIMME, 0); // interpol between all row + // mixRow value0 value1 value2 : (value0*row0 + value1*row1 + value2*row2) + class_addmethod(mtx_preset_class, (t_method)mtx_preset_resize, gensym("resize"),A_FLOAT, A_FLOAT, 0); // resize matrix +} |