Update of /cvsroot/pure-data/externals/pmpd/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7863
Modified Files: masse.c masse2D.c masse3D.c pmpd.c Added Files: pmpd~.c Log Message: pmpd version 0.06 test version!
Index: masse3D.c =================================================================== RCS file: /cvsroot/pure-data/externals/pmpd/src/masse3D.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** masse3D.c 9 Apr 2004 16:55:37 -0000 1.1.1.1 --- masse3D.c 28 Oct 2004 17:45:36 -0000 1.2 *************** *** 4,11 **** static t_class *masse3D_class;
- extern t_float max(t_float, t_float); - extern t_float min(t_float, t_float); - - typedef struct _masse3D { t_object x_obj; --- 4,7 ---- *************** *** 21,24 **** --- 17,45 ---- } t_masse3D;
+ static int makeseed3D(void) + { + static unsigned int random_nextseed = 1489853723; + random_nextseed = random_nextseed * 435898247 + 938284287; + return (random_nextseed & 0x7fffffff); + } + + static float random_bang3D(t_masse3D *x) + { + int nval; + int range = 2000000; + float rnd; + unsigned int randval = x->x_state; + x->x_state = randval = randval * 472940017 + 832416023; + nval = ((double)range) * ((double)randval) + * (1./4294967296.); + if (nval >= range) nval = range-1; + + rnd=nval; + + rnd-=1000000; + rnd=rnd/1000000.; //pour mettre entre -1 et 1; + return (rnd); + } + void masse3D_on(t_masse3D *x) { *************** *** 143,149 **** void masse3D_force(t_masse3D *x, t_floatarg f1, t_floatarg f2, t_floatarg f3) { ! x->forceX = x->forceX+f1; ! x->forceY = x->forceY+f2; ! x->forceZ = x->forceZ+f3; }
--- 164,170 ---- void masse3D_force(t_masse3D *x, t_floatarg f1, t_floatarg f2, t_floatarg f3) { ! x->forceX += f1; ! x->forceY += f2; ! x->forceZ += f3; }
*************** *** 289,295 **** SETFLOAT(&(x->force[3]), sqrt( (x->forceX * x->forceX) + (x->forceY * x->forceY) + (x->forceZ * x->forceZ) ));
! x->forceX=0; ! x->forceY=0; ! x->forceZ=0;
x->dX=0; --- 310,321 ---- SETFLOAT(&(x->force[3]), sqrt( (x->forceX * x->forceX) + (x->forceY * x->forceY) + (x->forceZ * x->forceZ) ));
! // x->forceX=0; ! // x->forceY=0; ! // x->forceZ=0; ! ! x->forceX = random_bang3D(x)*1e-25; ! x->forceY = random_bang3D(x)*1e-25; // avoiding denormal problem by adding low amplitude noise ! x->forceZ = random_bang3D(x)*1e-25; !
x->dX=0; *************** *** 371,400 **** }
- static int makeseed3D(void) - { - static unsigned int random_nextseed = 1489853723; - random_nextseed = random_nextseed * 435898247 + 938284287; - return (random_nextseed & 0x7fffffff); - } - - static float random_bang3D(t_masse3D *x) - { - int nval; - int range = 2000000; - float rnd; - unsigned int randval = x->x_state; - x->x_state = randval = randval * 472940017 + 832416023; - nval = ((double)range) * ((double)randval) - * (1./4294967296.); - if (nval >= range) nval = range-1; - - rnd=nval; - - rnd-=1000000; - rnd=rnd/1000000.; //pour mettre entre -1 et 1; - return (rnd); - } - - void masse3D_inter_ambient(t_masse3D *x, t_symbol *s, int argc, t_atom *argv) { --- 397,400 ----
Index: masse.c =================================================================== RCS file: /cvsroot/pure-data/externals/pmpd/src/masse.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** masse.c 9 Apr 2004 16:55:37 -0000 1.1.1.1 --- masse.c 28 Oct 2004 17:45:36 -0000 1.2 *************** *** 10,19 **** t_float minX, maxX; t_outlet *position_new, *vitesse_out, *force_out; ! t_symbol *x_sym; // receive ! } t_masse;
! extern t_float max(t_float, t_float); ! extern t_float min(t_float, t_float);
void masse_minX(t_masse *x, t_floatarg f1) --- 10,43 ---- t_float minX, maxX; t_outlet *position_new, *vitesse_out, *force_out; ! t_symbol *x_sym; // receive ! unsigned int x_state; // random ! t_float x_f; // random
! } t_masse; ! ! static int makeseed(void) ! { ! static unsigned int random_nextseed = 1489853723; ! random_nextseed = random_nextseed * 435898247 + 938284287; ! return (random_nextseed & 0x7fffffff); ! } ! ! static float random_bang(t_masse *x) ! { ! int nval; ! int range = 2000000; ! float rnd; ! unsigned int randval = x->x_state; ! x->x_state = randval = randval * 472940017 + 832416023; ! nval = ((double)range) * ((double)randval) ! * (1./4294967296.); ! if (nval >= range) nval = range-1; ! ! rnd=nval;
+ rnd-=1000000; + rnd=rnd/1000000.; //pour mettre entre -1 et 1; + return (rnd); + }
void masse_minX(t_masse *x, t_floatarg f1) *************** *** 53,57 **** x->pos_old_1 = pos_new;
! x->force = 0; x->dX = 0;
--- 77,84 ---- x->pos_old_1 = pos_new;
! // x->force = 0; ! ! x->force = random_bang(x)*1e-25; // avoiding denormal problem by adding low amplitude noise ! x->dX = 0;
*************** *** 71,74 **** --- 98,102 ---- { x->force=0; + }
*************** *** 80,84 **** void masse_setX(t_masse *x, t_float posX) { ! x->pos_old_2 = posX; // clear hystory for stability (instability) problem x->pos_old_1 = posX;
--- 108,112 ---- void masse_setX(t_masse *x, t_float posX) { ! x->pos_old_2 = posX; // clear history for stability (instability) problem x->pos_old_1 = posX;
*************** *** 125,129 **** x->maxX = 100000;
! if (x->masse<=0) x->masse=1;
return (void *)x; --- 153,159 ---- x->maxX = 100000;
! if (x->masse<=0) x->masse=1; ! ! makeseed();
return (void *)x;
Index: pmpd.c =================================================================== RCS file: /cvsroot/pure-data/externals/pmpd/src/pmpd.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** pmpd.c 9 Apr 2004 16:55:37 -0000 1.1.1.1 --- pmpd.c 28 Oct 2004 17:45:36 -0000 1.2 *************** *** 1,5 **** /* -------------------------- pmpd ---------------------------------------- ! pmpd = physical modeling for pure data Written by Cyrille Henry (cyrille.henry@la-kitchen.fr) --- 1,6 ---- /* -------------------------- pmpd ---------------------------------------- ! ! pmpd = physical modeling for pure data Written by Cyrille Henry (cyrille.henry@la-kitchen.fr) *************** *** 28,32 ****
#ifndef VERSION ! #define VERSION "0.05" #endif
--- 29,33 ----
#ifndef VERSION ! #define VERSION "0.06" #endif
*************** *** 37,40 **** --- 38,51 ---- #endif
+ #define nb_max_link 2000 + #define nb_max_mass 2000 + #define nb_max_out 200 + #define nb_max_in 200 + #define nb_max_outlet 20 + #define nb_max_inlet 20 // hard-coded on the methods definition + + #define max(a,b) ( ((a) > (b)) ? (a) : (b) ) + #define min(a,b) ( ((a) < (b)) ? (a) : (b) ) + #include "masse.c" #include "lia.c" *************** *** 69,101 **** #include "tLia3D.c"
static t_class *pmpd_class;
typedef struct _pmpd { ! t_object x_obj; } t_pmpd;
! t_float max(t_float x, t_float y) { ! if (x >= y) ! { ! return x; ! } ! return y; }
! t_float min(t_float x, t_float y) { ! if (x <= y) ! { ! return x; ! } ! return y; }
! void *pmpd_new(void) ! { ! t_pmpd *x = (t_pmpd *)pd_new(pmpd_class); ! return (void *)x; }
--- 80,297 ---- #include "tLia3D.c"
+ #include "pmpd~.c" + static t_class *pmpd_class;
typedef struct _pmpd { ! t_object x_obj; ! struct _link link[nb_max_link]; ! struct _mass mass[nb_max_mass]; ! struct _out out[nb_max_out]; ! struct _in in[nb_max_in]; ! t_float outlet[nb_max_outlet]; ! t_outlet *taboutlet[nb_max_outlet]; ! t_float inlet[nb_max_inlet]; ! int nb_link, nb_mass, nb_outlet, nb_inlet, nb_in, nb_out; } t_pmpd;
! #define max(a,b) ( ((a) > (b)) ? (a) : (b) ) ! #define min(a,b) ( ((a) < (b)) ? (a) : (b) ) ! ! void pmpd_bang(t_pmpd *x) ! /////////////////////////////////////////////////////////////////////////////////// ! // this part is doing all the job! { ! t_float F; ! t_int i; ! struct _mass mass_1, mass_2; ! ! for (i=0; i<x->nb_in; i++) ! // compute input ! { ! x->in[i].mass1->forceX += x->in[i].influence * x->inlet[x->in[i].nbr_inlet]; ! } ! ! for (i=0; i<x->nb_inlet; i++) ! // clear inlet[i] ! { ! x->inlet[i]=0; ! } ! ! for (i=0; i<x->nb_link; i++) ! // comput link forces ! { ! F = x->link[i].K1 * ( x->link[i].mass1->posX - x->link[i].mass2->posX ) ; ! F += x->link[i].D1 * ( x->link[i].mass1->speedX - x->link[i].mass2->speedX) ; ! x->link[i].mass1->forceX -= F; ! x->link[i].mass2->forceX += F; ! } ! ! for (i=1; i<x->nb_mass; i++) ! // compute new masses position ! if (x->mass[i].Id >0) // only if Id >0 ! { ! x->mass[i].speedX += x->mass[i].forceX * x->mass[i].invM; ! x->mass[i].forceX = 0; ! x->mass[i].posX += x->mass[i].speedX ; ! } ! ! for (i=0; i<x->nb_out; i++) ! // compute output point ! { ! x->outlet[x->out[i].nbr_outlet] += x->out[i].mass1->posX * x->out[i].influence ; ! } ! ! // for (i=0; i<x->nb_outlet; i++) ! for (i=x->nb_outlet-1; i>=0; i--) ! // output everything on the corresponding outlet ! { ! outlet_float(x->taboutlet[i], x->outlet[i]); ! x->outlet[i] = 0; ! } }
! void pmpd_forceX(t_pmpd *x, t_float nbr_mass, t_float force) { ! // add a force to a specific mass ! nbr_mass = max(0, min( x->nb_mass, (int)nbr_mass)); ! x->mass[(int)nbr_mass].forceX += force; }
! void pmpd_posX(t_pmpd *x, t_float nbr_mass, t_float posX) ! { ! // displace a mass to a certain position ! nbr_mass = max(0, min( x->nb_mass, (int)nbr_mass)); ! x->mass[(int)nbr_mass].posX = posX; ! } ! ! void pmpd_mass(t_pmpd *x, t_float Id, t_float M, t_float posX) ! // add a mass ! // Id, invM speedX posX forceX ! { ! if (M==0) M=1; ! x->mass[x->nb_mass].Id = (int)Id; ! x->mass[x->nb_mass].invM = 1/M; ! x->mass[x->nb_mass].speedX = 0; ! x->mass[x->nb_mass].posX = posX; ! x->mass[x->nb_mass].forceX = 0; ! ! x->nb_mass++ ; ! x->nb_mass = min ( nb_max_mass -1, x->nb_mass ); ! } ! ! void pmpd_link(t_pmpd *x, t_float Id, t_float mass_1, t_float mass_2, t_float K1, t_float D1) ! // add a link ! // Id, *mass1, *mass2, Ke, K1, D1, K2, D2; ! { ! ! x->link[x->nb_link].Id = (int)Id; ! x->link[x->nb_link].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))]; ! x->link[x->nb_link].mass2 = &x->mass[max(0, min ( x->nb_mass, (int)mass_2))]; ! x->link[x->nb_link].K1 = K1; ! x->link[x->nb_link].D1 = D1; ! ! x->nb_link++ ; ! x->nb_link = min ( nb_max_link -1, x->nb_link ); ! } ! ! void pmpd_out(t_pmpd *x, t_float Id, t_float nb_outlet, t_float mass_1, t_float influence) ! // add an output point ! // Id, nbr_outlet, *mass1, influence; ! { ! x->out[x->nb_out].Id = (int)Id; ! x->out[x->nb_out].nbr_outlet = max(0, min( x->nb_outlet,(int)nb_outlet)); ! x->out[x->nb_out].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))]; ! x->out[x->nb_out].influence = influence; ! ! x->nb_out++ ; ! x->nb_out = min ( nb_max_out - 1, x->nb_out ); ! } ! ! void pmpd_in(t_pmpd *x, t_float Id, t_float nb_inlet, t_float mass_1, t_float influence) ! //add an input point ! // Id, nbr_inlet, *mass1, influence; ! { ! x->in[x->nb_in].Id = (int)Id; ! x->in[x->nb_in].nbr_inlet = max(0, min( x->nb_inlet,(int)nb_inlet)); ! x->in[x->nb_in].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))]; ! x->in[x->nb_in].influence = influence; ! ! x->nb_in++; ! x->nb_in = min ( nb_max_in - 1, x->nb_in ); ! } ! ! void pmpd_forceX_1(t_pmpd *x, t_float force) ! { x->inlet[0] += force; } ! void pmpd_forceX_2(t_pmpd *x, t_float force) ! { x->inlet[1] += force; } ! void pmpd_forceX_3(t_pmpd *x, t_float force) ! { x->inlet[2] += force; } ! void pmpd_forceX_4(t_pmpd *x, t_float force) ! { x->inlet[3] += force; } ! void pmpd_forceX_5(t_pmpd *x, t_float force) ! { x->inlet[4] += force; } ! void pmpd_forceX_6(t_pmpd *x, t_float force) ! { x->inlet[5] += force; } ! void pmpd_forceX_7(t_pmpd *x, t_float force) ! { x->inlet[6] += force; } ! void pmpd_forceX_8(t_pmpd *x, t_float force) ! { x->inlet[7] += force; } ! void pmpd_forceX_9(t_pmpd *x, t_float force) ! { x->inlet[8] += force; } ! void pmpd_forceX_10(t_pmpd *x, t_float force) ! { x->inlet[9] += force; } ! void pmpd_forceX_11(t_pmpd *x, t_float force) ! { x->inlet[10]+= force; } ! void pmpd_forceX_12(t_pmpd *x, t_float force) ! { x->inlet[11]+= force; } ! void pmpd_forceX_13(t_pmpd *x, t_float force) ! { x->inlet[12]+= force; } ! void pmpd_forceX_14(t_pmpd *x, t_float force) ! { x->inlet[13]+= force; } ! void pmpd_forceX_15(t_pmpd *x, t_float force) ! { x->inlet[14]+= force; } ! void pmpd_forceX_16(t_pmpd *x, t_float force) ! { x->inlet[15]+= force; } ! void pmpd_forceX_17(t_pmpd *x, t_float force) ! { x->inlet[16]+= force; } ! void pmpd_forceX_18(t_pmpd *x, t_float force) ! { x->inlet[17]+= force; } ! void pmpd_forceX_19(t_pmpd *x, t_float force) ! { x->inlet[18]+= force; } ! void pmpd_forceX_20(t_pmpd *x, t_float force) ! { x->inlet[19]+= force; } ! ! void pmpd_reset(t_pmpd *x) ! { ! x->nb_link = 0; ! x->nb_mass = 1; ! x->nb_out= 0; ! x->nb_in= 0; ! } ! ! void *pmpd_new(t_symbol *s, int argc, t_atom *argv) ! { ! int i; ! char buffer[10]; ! ! t_pmpd *x = (t_pmpd *)pd_new(pmpd_class); ! ! pmpd_reset(x); ! ! x->nb_outlet= (int)atom_getfloatarg(1, argc, argv); ! x->nb_outlet= max(0, min(nb_max_outlet, x->nb_outlet) ); ! for(i=0; i<x->nb_outlet; i++) ! x->taboutlet[i]=outlet_new(&x->x_obj, 0); ! ! x->nb_inlet = (int)atom_getfloatarg(0, argc, argv); ! x->nb_inlet= max(0, min(nb_max_inlet, x->nb_inlet) ); ! for(i=0; i<x->nb_inlet; i++) ! { ! sprintf (buffer, "forceX_%i", i+1); ! inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("forceX"), gensym(buffer)); ! } ! return (void *)x; }
*************** *** 104,108 **** pmpd_class = class_new(gensym("pmpd"), (t_newmethod)pmpd_new, ! 0, sizeof(t_pmpd),0,0);
post(""); --- 300,334 ---- pmpd_class = class_new(gensym("pmpd"), (t_newmethod)pmpd_new, ! 0, sizeof(t_pmpd),CLASS_DEFAULT, A_GIMME, 0); ! ! class_addbang(pmpd_class, pmpd_bang); ! class_addmethod(pmpd_class, (t_method)pmpd_mass, gensym("mass"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_link, gensym("link"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_out, gensym("out"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_in, gensym("in"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_posX, gensym("posX"), A_DEFFLOAT, A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX, gensym("forceX"), A_DEFFLOAT, A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_1, gensym("forceX_1"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_2, gensym("forceX_2"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_3, gensym("forceX_3"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_4, gensym("forceX_4"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_5, gensym("forceX_5"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_6, gensym("forceX_6"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_7, gensym("forceX_7"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_8, gensym("forceX_8"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_9, gensym("forceX_9"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_10, gensym("forceX_10"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_11, gensym("forceX_11"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_12, gensym("forceX_12"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_13, gensym("forceX_13"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_14, gensym("forceX_14"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_15, gensym("forceX_15"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_16, gensym("forceX_16"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_17, gensym("forceX_17"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_18, gensym("forceX_18"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_19, gensym("forceX_19"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_forceX_20, gensym("forceX_20"), A_DEFFLOAT, 0); ! class_addmethod(pmpd_class, (t_method)pmpd_reset, gensym("reset"), 0); !
post(""); *************** *** 144,146 **** tCircle3D_setup();
! } --- 370,375 ---- tCircle3D_setup();
! pmpd_tilde_setup(); ! ! } !
Index: masse2D.c =================================================================== RCS file: /cvsroot/pure-data/externals/pmpd/src/masse2D.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** masse2D.c 9 Apr 2004 16:55:36 -0000 1.1.1.1 --- masse2D.c 28 Oct 2004 17:45:36 -0000 1.2 *************** *** 17,25 **** } t_masse2D;
! extern t_float max(t_float, t_float); ! extern t_float min(t_float, t_float); ! ! ! static int makeseed(void) { static unsigned int random_nextseed = 1489853723; --- 17,21 ---- } t_masse2D;
! static int makeseed2D(void) { static unsigned int random_nextseed = 1489853723; *************** *** 28,32 **** }
! static float random_bang(t_masse2D *x) { int nval; --- 24,28 ---- }
! static float random_bang2D(t_masse2D *x) { int nval; *************** *** 144,148 **** x->forceY += x->damp * ((x->posY_old_2)-(x->posY_old_1)); // damping
- if (x->masse2D != 0) { --- 140,143 ---- *************** *** 183,189 **** SETFLOAT(&(x->force[2]), sqrt( (x->forceX * x->forceX) + (x->forceY * x->forceY) ));
! x->forceX=0; ! x->forceY=0; ! x->dX=0; x->dY=0; --- 178,188 ---- SETFLOAT(&(x->force[2]), sqrt( (x->forceX * x->forceX) + (x->forceY * x->forceY) ));
! // x->forceX=0; ! // x->forceY=0; ! ! x->forceX = random_bang2D(x)*1e-25; ! x->forceY = random_bang2D(x)*1e-25; // avoiding denormal problem by adding low amplitude noise ! ! x->dX=0; x->dY=0; *************** *** 323,328 **** x->forceY += atom_getfloatarg(1, argc, argv); // constant
! x->forceX += random_bang(x)*atom_getfloatarg(2, argc, argv); ! x->forceY += random_bang(x)*atom_getfloatarg(3, argc, argv); // random x->forceX += atom_getfloatarg(4, argc, argv) * ((x->posX_old_2)-(x->posX_old_1)); --- 322,327 ---- x->forceY += atom_getfloatarg(1, argc, argv); // constant
! x->forceX += random_bang2D(x)*atom_getfloatarg(2, argc, argv); ! x->forceY += random_bang2D(x)*atom_getfloatarg(3, argc, argv); // random x->forceX += atom_getfloatarg(4, argc, argv) * ((x->posX_old_2)-(x->posX_old_1)); *************** *** 689,693 ****
x->x_sym = atom_getsymbolarg(0, argc, argv); ! x->x_state = makeseed();
pd_bind(&x->x_obj.ob_pd, atom_getsymbolarg(0, argc, argv)); --- 688,692 ----
x->x_sym = atom_getsymbolarg(0, argc, argv); ! x->x_state = makeseed2D();
pd_bind(&x->x_obj.ob_pd, atom_getsymbolarg(0, argc, argv));
--- NEW FILE: pmpd~.c --- ////////////////////////////////////////////////////////////////////// // this is the standard blablabla // made for pd // Gnu Public Licence // cyrille.henry@la-kitchen.fr // // pmpd~ // The same than pmpd, but with audio data for input and output // It can be used for particular physical modeling and for modal sound synthesis //////////////////////////////////////////////////////////////////////
#include "m_pd.h" #include "stdio.h"
#define max(a,b) ( ((a) > (b)) ? (a) : (b) ) #define min(a,b) ( ((a) < (b)) ? (a) : (b) )
static t_class *pmpd_tilde_class;
typedef struct _mass { t_int Id; t_float invM; t_float speedX; t_float posX; t_float forceX; } foo;
typedef struct _link { t_int Id; struct _mass *mass1; struct _mass *mass2; t_float Ke, K1, D1, K2, D2; } foo1;
typedef struct _out { // TODO ajouter un type pour diferencier les outlets en forces et celles en position t_int Id; t_int nbr_outlet; struct _mass *mass1; t_float influence; } foo2;
typedef struct _in { // TODO ajouter un type pour diferencier les inlets en forces et celles en position t_int Id; t_int nbr_inlet; struct _mass *mass1; t_float influence; } foo3;
typedef struct _pmpd_tilde { t_object x_obj; struct _link link[nb_max_link]; struct _mass mass[nb_max_mass]; struct _out out[nb_max_out]; struct _in in[nb_max_in]; t_float outlet[nb_max_outlet]; t_sample *outlet_vector[nb_max_outlet]; t_sample *inlet_vector[nb_max_inlet]; int nb_link, nb_mass, nb_inlet, nb_outlet, nb_in, nb_out; t_sample f; // used for signal inlet t_int loop, nb_loop; // to be able not to compute everything a each iteration unsigned int x_state; // random t_float x_f; // random } t_pmpd_tilde;
static int makeseed_pmpd_tilde(void) { static unsigned int random_nextseed = 1489853723; random_nextseed = random_nextseed * 435898247 + 938284287; return (random_nextseed & 0x7fffffff); }
static float random_bang_pmpd_tilde(t_pmpd_tilde *x) { int nval; int range = 2000000; float rnd; unsigned int randval = x->x_state; x->x_state = randval = randval * 472940017 + 832416023; nval = ((double)range) * ((double)randval) * (1./4294967296.); if (nval >= range) nval = range-1;
rnd=nval;
rnd-=1000000; rnd=rnd/1000000.; //pour mettre entre -1 et 1; return (rnd); }
t_int *pmpd_tilde_perform(t_int *w) /////////////////////////////////////////////////////////////////////////////////// { t_pmpd_tilde *x = (t_pmpd_tilde *)(w[1]); int n = (int)(w[2]);
t_float F; t_int i; struct _mass mass_1, mass_2;
t_sample *out[nb_max_outlet]; t_sample *in[nb_max_inlet];
for (i=0; i<x->nb_inlet; i++) // TODO : ameliorer la copie du tableau a l'initialisation in[i]= x->inlet_vector[i];
for (i=0; i<x->nb_outlet; i++) // TODO : ameliorer la copie du tableau out[i]= x->outlet_vector[i];
while (n--) { if (++x->loop == x->nb_loop) { x->loop = 0;
for (i=0; i<x->nb_in; i++) if ( x->in[i].influence == 0) // get inlet value and make it a position to the specified mass x->in[i].mass1->posX = *in[x->in[i].nbr_inlet]; else // get inlet value and make it a force to the specified mass x->in[i].mass1->forceX += x->in[i].influence * *in[x->in[i].nbr_inlet];
for (i=0; i<x->nb_link; i++) // compute forces generated by links (spring / dashpot) { F = x->link[i].K1 * ( x->link[i].mass1->posX - x->link[i].mass2->posX ) ; // spring
F += x->link[i].D1 * ( x->link[i].mass1->speedX - x->link[i].mass2->speedX) ; // dashpot x->link[i].mass1->forceX -= F; x->link[i].mass2->forceX += F; }
for (i=1; i<x->nb_mass; i++) // compute new masses position if (x->mass[i].Id >0) // only if Id >0 { x->mass[i].speedX += x->mass[i].forceX * x->mass[i].invM; x->mass[i].forceX = random_bang_pmpd_tilde(x) * 1e-25; x->mass[i].posX += x->mass[i].speedX ; } }
for (i=0; i<x->nb_inlet; i++) // increase pointer to inlet vectors value in[i]++;
for (i=0; i<x->nb_out; i++) x->outlet[x->out[i].nbr_outlet] += x->out[i].mass1->posX * x->out[i].influence; // compute output vector value
for (i=0; i<x->nb_outlet; i++) // send vector value to the vector pointer { *out[i]++ = x->outlet[i]; x->outlet[i] = 0; } } return(w+3); }
void pmpd_tilde_dsp(t_pmpd_tilde *x, t_signal **sp) { int i;
for (i=0; i<x->nb_inlet; i++) x->inlet_vector[i] = sp[i]->s_vec;
for (i=0; i<x->nb_outlet; i++) x->outlet_vector[i] = sp[i+x->nb_inlet]->s_vec;
dsp_add(pmpd_tilde_perform, 2, x, sp[0]->s_n); // post("%p, %p, %p", sp, sp2[2], sp[2]->s_vec); }
void pmpd_tilde_bang(t_pmpd_tilde *x) { // add a unity force to all masses int i; for (i=0;i < x->nb_mass; i++) x->mass[i].forceX += 1; }
void pmpd_tilde_float(t_pmpd_tilde *x, t_float force) { // add a unity force to all masses int i; for (i=0;i < x->nb_mass; i++) x->mass[i].forceX += force; }
void pmpd_tilde_forceX(t_pmpd_tilde *x, t_float nbr_mass, t_float force) { // add a force to a specific mass nbr_mass = max(0, min( x->nb_mass, (int)nbr_mass)); x->mass[(int)nbr_mass].forceX += force; }
void pmpd_tilde_posX(t_pmpd_tilde *x, t_float nbr_mass, t_float posX) { // displace a mass to a certain position nbr_mass = max(0, min( x->nb_mass, (int)nbr_mass)); x->mass[(int)nbr_mass].posX = posX; }
void pmpd_tilde_mass(t_pmpd_tilde *x, t_float Id, t_float M, t_float posX) // add a mass // Id, invM speedX posX forceX { if (M==0) M=1; x->mass[x->nb_mass].Id = (int)Id; x->mass[x->nb_mass].invM = 1/M; x->mass[x->nb_mass].speedX = 0; x->mass[x->nb_mass].posX = posX; x->mass[x->nb_mass].forceX = 0;
x->nb_mass++ ; x->nb_mass = min ( nb_max_mass -1, x->nb_mass ); }
void pmpd_tilde_link(t_pmpd_tilde *x, t_float Id, t_float mass_1, t_float mass_2, t_float K1, t_float D1) // add a link // Id, *mass1, *mass2, Ke, K1, D1, K2, D2; {
x->link[x->nb_link].Id = (int)Id; x->link[x->nb_link].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))]; x->link[x->nb_link].mass2 = &x->mass[max(0, min ( x->nb_mass, (int)mass_2))]; x->link[x->nb_link].K1 = K1; x->link[x->nb_link].D1 = D1;
x->nb_link++ ; x->nb_link = min ( nb_max_link -1, x->nb_link ); }
void pmpd_tilde_out(t_pmpd_tilde *x, t_float Id, t_float nb_outlet, t_float mass_1, t_float influence) // add an output point // Id, nbr_outlet, *mass1, influence; { x->out[x->nb_out].Id = (int)Id; x->out[x->nb_out].nbr_outlet = max(0, min( x->nb_outlet,(int)nb_outlet)); x->out[x->nb_out].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))]; x->out[x->nb_out].influence = influence;
x->nb_out++ ; x->nb_out = min ( nb_max_out - 1, x->nb_out ); }
void pmpd_tilde_in(t_pmpd_tilde *x, t_float Id, t_float nb_inlet, t_float mass_1, t_float influence) //add an input point // Id, nbr_inlet, *mass1, influence; { x->in[x->nb_in].Id = (int)Id; x->in[x->nb_in].nbr_inlet = max(0, min( x->nb_inlet,(int)nb_inlet)); x->in[x->nb_in].mass1 = &x->mass[max(0, min ( x->nb_mass, (int)mass_1))]; x->in[x->nb_in].influence = influence;
x->nb_in++; x->nb_in = min ( nb_max_in - 1, x->nb_in ); }
void pmpd_tilde_reset(t_pmpd_tilde *x) { x->nb_link = 0; x->nb_mass = 1; x->nb_out= 0; x->nb_in= 0; x->mass[x->nb_mass].posX = 1; // ajouter le reset des paramettress de la masse }
void *pmpd_tilde_new(t_symbol *s, int argc, t_atom *argv) { int i;
t_pmpd_tilde *x = (t_pmpd_tilde *)pd_new(pmpd_tilde_class);
pmpd_tilde_reset(x); makeseed_pmpd_tilde(); x->nb_outlet= (int)atom_getfloatarg(1, argc, argv); x->nb_outlet= max(1, min(nb_max_outlet, x->nb_outlet) ); for(i=0; i<x->nb_outlet; i++) outlet_new(&x->x_obj, &s_signal);
x->nb_inlet = (int)atom_getfloatarg(0, argc, argv); x->nb_inlet= max(1, min(nb_max_inlet, x->nb_inlet) ); for(i=0; i<x->nb_inlet-1; i++) inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
x->nb_loop = max (1, (int)atom_getfloatarg(2, argc, argv) ); x->loop = 0 ;
return (void *)x; }
void pmpd_tilde_setup(void) { pmpd_tilde_class = class_new(gensym("pmpd~"), (t_newmethod)pmpd_tilde_new, 0, sizeof(t_pmpd_tilde), CLASS_DEFAULT, A_GIMME, 0);
CLASS_MAINSIGNALIN(pmpd_tilde_class, t_pmpd_tilde, f);
class_addbang(pmpd_tilde_class, pmpd_tilde_bang); class_addfloat(pmpd_tilde_class, (t_method)pmpd_tilde_float); class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_mass, gensym("mass"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_link, gensym("link"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_out, gensym("out"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_in, gensym("in"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_posX, gensym("posX"), A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_forceX, gensym("forceX"), A_DEFFLOAT, A_DEFFLOAT, 0);
class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_reset, gensym("reset"), 0); class_addmethod(pmpd_tilde_class, (t_method)pmpd_tilde_dsp, gensym("dsp"), 0); }