From bd6957bd624da4ee9d99da0cced28d144da67f6f Mon Sep 17 00:00:00 2001 From: Thomas O Fredericks Date: Wed, 30 Sep 2009 18:38:08 +0000 Subject: Added put~ and get~, a buffered send/throw receive/catch system loosers svn path=/trunk/externals/tof/; revision=12499 --- test/Makefile | 1 + test/get~.c | 93 ++++++++++++++++++++++++ test/pak.c | 218 +++++++++++++++++++++++++++++++-------------------------- test/putget~.h | 133 +++++++++++++++++++++++++++++++++++ test/put~.c | 89 +++++++++++++++++++++++ 5 files changed, 436 insertions(+), 98 deletions(-) create mode 100644 test/get~.c create mode 100644 test/putget~.h create mode 100644 test/put~.c (limited to 'test') diff --git a/test/Makefile b/test/Makefile index 8d83e14..b064d5d 100644 --- a/test/Makefile +++ b/test/Makefile @@ -31,3 +31,4 @@ LINUXINCLUDE = -I$(PDPATH)/src ld --export-dynamic -shared -o $*.pd_linux $*.o -lc -lm strip --strip-unneeded $*.pd_linux rm $*.o + mv $*.pd_linux ~/pd-externals/tof diff --git a/test/get~.c b/test/get~.c new file mode 100644 index 0000000..4d6356d --- /dev/null +++ b/test/get~.c @@ -0,0 +1,93 @@ +#include "putget~.h" + +static t_class *get_tilde_class; + +typedef struct _get_tilde { + t_object x_obj; + t_sample f_put; + struct putget* pg; + t_sample f; +} t_get_tilde; + +t_int *get_tilde_perform(t_int *w) +{ + t_get_tilde *x = (t_get_tilde *)(w[1]); + t_sample *out = (t_sample *)(w[2]); + int n = (int)(w[3]); + + if ( x->pg) { + + putget_arm( x->pg); + + + t_sample *samples = x->pg->r; + + while (n--) { + *out++ = *samples++; + } + } else { + while (n--) { + *out++ = 0; + } + } + + return (w+4); +} + +static void get_tilde_set(t_get_tilde *x, t_symbol* s) { + + if (gensym("") != s ) { + if ( x->pg ) { + if ( x->pg->name != s) { + putget_unregister(x->pg,0); + x->pg = putget_register(s,0); + } + } else { + x->pg = putget_register(s,0); + } + } + +} + +void get_tilde_dsp(t_get_tilde *x, t_signal **sp) +{ + + if ( sp[0]->s_n == 64 ) { + dsp_add(get_tilde_perform, 3, x,sp[0]->s_vec, sp[0]->s_n); + } else { + pd_error(x,"get~ only works with a block size of 64"); + } +} + +static void get_tilde_free( t_get_tilde *x) { + + if (x->pg) putget_unregister(x->pg,0); +} + + +void *get_tilde_new(t_symbol* s) +{ + t_get_tilde *x = (t_get_tilde *)pd_new(get_tilde_class); + + + if (gensym("") != s ) x->pg = putget_register(s,0); + + outlet_new(&x->x_obj, &s_signal); + + return (void *)x; +} + +void get_tilde_setup(void) { + get_tilde_class = class_new(gensym("get~"), + (t_newmethod)get_tilde_new, + (t_method)get_tilde_free, sizeof(t_get_tilde), + CLASS_DEFAULT, + A_DEFSYMBOL, 0); + + class_addmethod(get_tilde_class, + (t_method)get_tilde_set, gensym("set"), A_SYMBOL, 0); + + class_addmethod(get_tilde_class, + (t_method)get_tilde_dsp, gensym("dsp"), 0); + //CLASS_MAINSIGNALIN(get_tilde_class, t_get_tilde, f); +} diff --git a/test/pak.c b/test/pak.c index 8d004c1..ad1cf73 100644 --- a/test/pak.c +++ b/test/pak.c @@ -1,87 +1,34 @@ - static t_class *pak_class; static t_class *pak_inlet_class; -struct _param_inlet2; - -#define PAK_MAX_INLETS 100 typedef struct _pak { - t_object x_obj; - struct _pak_inlet inlets[PAK_MAX_INLETS]; - int number; + t_object x_obj; + t_int x_n; // number of args + t_atom *x_vec; // input values + t_int x_nptr; // number of pointers + t_gpointer *x_gpointer; // the pointers + t_atom *x_outvec; // space for output values + int count; + struct _pak_inlet **proxy; + t_inlet **in; } t_pak; -typedef struct _pak_inlet -{ - t_object x_obj; - t_pak *p_owner; -} t_pak_inlet; - - - - - -// CONSTRUCTOR -static void *param_new(t_symbol *s, int ac, t_atom *av) -{ - t_param *x = (t_param *)pd_new(param_class); - t_param_inlet2 *p = (t_param_inlet2 *)pd_new(param_inlet2_class); - - // Stuff - x->s_set = gensym("set"); - x->s_PARAM = gensym("PARAM"); - - // Set up second inlet proxy - x->x_param_inlet2 = p; - p->p_owner = x; - - - - - return (x); -} -void pak_setup(void) +typedef struct _pak_inlet { - pak_class = class_new(gensym("pak"), - (t_newmethod)pak_new, (t_method)pak_free, - sizeof(t_param), 0, A_GIMME, 0); - - - //class_addanything(param_class, param_anything); - //class_addbang(param_class, param_bang); - - //class_addmethod(param_class, (t_method)param_loadbang, gensym("loadbang"), 0); - - pak_inlet_class = class_new(gensym("_pak_inlet"), - 0, 0, sizeof(t_pak_inlet), CLASS_PD | CLASS_NOINLET, 0); - - //class_addanything(pak_inlet_class, pak_inlet_anything); - -} - - -///////////////// PACK /////////////// + t_pd p_pd; + t_pack *master; + int id; + t_symbol* type; +} t_pak_inlet; -/* -static t_class *pack_class; -typedef struct _pack +static void *pak_new(t_symbol *s, int argc, t_atom *argv) { - t_object x_obj; - t_int x_n; // number of args - t_atom *x_vec; // input values - t_int x_nptr; // number of pointers - t_gpointer *x_gpointer; // the pointers - t_atom *x_outvec; // space for output values -} t_pack; - -static void *pack_new(t_symbol *s, int argc, t_atom *argv) -{ - t_pack *x = (t_pack *)pd_new(pack_class); - t_atom defarg[2], *ap, *vec, *vp; + t_pak *x = (t_pak *)pd_new(pak_class); + t_atom defarg[2], *vap, *vec, *vp; t_gpointer *gp; int nptr = 0; int i; @@ -104,12 +51,40 @@ static void *pack_new(t_symbol *s, int argc, t_atom *argv) gp = x->x_gpointer = (t_gpointer *)t_getbytes(nptr * sizeof (*gp)); x->x_nptr = nptr; + + // Create inlet proxys + x->count = argc - 1; + if (x->count < 0) x->count = 0; + x->in = (t_inlet **)getbytes(x->count * sizeof(t_inlet *)); + x->proxy = (t_pak_inlet**)getbytes(x->count * sizeof(t_pak_inlet*)); + // + + /* + + for (n = 0; n < x->count; n++) { + x->proxy[n]=(t_pak_inlet*)pd_new(pak_inlet_class); + x->proxy[n]->master = x; + x->proxy[n]->id=n; + x->in[n] = inlet_new ((t_object*)x, (t_pd*)x->proxy[n], 0,0); + } + + */ + + int n; for (i = 0, vp = x->x_vec, ap = argv; i < argc; i++, ap++, vp++) { + n = i-1; if (ap->a_type == A_FLOAT) { *vp = *ap; - if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float); + if (i) { + //floatinlet_new(&x->x_obj, &vp->a_w.w_float); + x->proxy[n]=(t_pak_inlet*)pd_new(pak_inlet_class); + x->proxy[n]->master = x; + x->proxy[n]->id=n; + x->proxy[n]->typr = &s_float; + x->in[n] = inlet_new ((t_object*)x, (t_pd*)x->proxy[n], 0,0); + } } else if (ap->a_type == A_SYMBOL) { @@ -129,18 +104,25 @@ static void *pack_new(t_symbol *s, int argc, t_atom *argv) } else { - if (c != 'f') pd_error(x, "pack: %s: bad type", + if (c != 'f') pd_error(x, "pak: %s: bad type", ap->a_w.w_symbol->s_name); SETFLOAT(vp, 0); if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float); } } } + + + + + + + outlet_new(&x->x_obj, &s_list); return (x); } -static void pack_bang(t_pack *x) +static void pak_bang(t_pak *x) { int i, reentered = 0, size = x->x_n * sizeof (t_atom); t_gpointer *gp; @@ -148,7 +130,7 @@ static void pack_bang(t_pack *x) for (i = x->x_nptr, gp = x->x_gpointer; i--; gp++) if (!gpointer_check(gp, 1)) { - pd_error(x, "pack: stale pointer"); + pd_error(x, "pak: stale pointer"); return; } // reentrancy protection. The first time through use the pre-allocated @@ -157,7 +139,7 @@ static void pack_bang(t_pack *x) { // LATER figure out how to deal with reentrancy and pointers... if (x->x_nptr) - post("pack_bang: warning: reentry with pointers unprotected"); + post("pak_bang: warning: reentry with pointers unprotected"); outvec = t_getbytes(size); reentered = 1; } @@ -173,44 +155,44 @@ static void pack_bang(t_pack *x) else x->x_outvec = outvec; } -static void pack_pointer(t_pack *x, t_gpointer *gp) +static void pak_pointer(t_pak *x, t_gpointer *gp) { if (x->x_vec->a_type == A_POINTER) { gpointer_unset(x->x_gpointer); *x->x_gpointer = *gp; if (gp->gp_stub) gp->gp_stub->gs_refcount++; - pack_bang(x); + pak_bang(x); } - else pd_error(x, "pack_pointer: wrong type"); + else pd_error(x, "pak_pointer: wrong type"); } -static void pack_float(t_pack *x, t_float f) +static void pak_float(t_pak *x, t_float f) { if (x->x_vec->a_type == A_FLOAT) { x->x_vec->a_w.w_float = f; - pack_bang(x); + pak_bang(x); } - else pd_error(x, "pack_float: wrong type"); + else pd_error(x, "pak_float: wrong type"); } -static void pack_symbol(t_pack *x, t_symbol *s) +static void pak_symbol(t_pak *x, t_symbol *s) { if (x->x_vec->a_type == A_SYMBOL) { x->x_vec->a_w.w_symbol = s; - pack_bang(x); + pak_bang(x); } - else pd_error(x, "pack_symbol: wrong type"); + else pd_error(x, "pak_symbol: wrong type"); } -static void pack_list(t_pack *x, t_symbol *s, int ac, t_atom *av) +static void pak_list(t_pak *x, t_symbol *s, int ac, t_atom *av) { obj_list(&x->x_obj, 0, ac, av); } -static void pack_anything(t_pack *x, t_symbol *s, int ac, t_atom *av) +static void pak_anything(t_pak *x, t_symbol *s, int ac, t_atom *av) { t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom)); int i; @@ -221,7 +203,16 @@ static void pack_anything(t_pack *x, t_symbol *s, int ac, t_atom *av) freebytes(av2, (ac + 1) * sizeof(t_atom)); } -static void pack_free(t_pack *x) + +static void pak_inlet(t_pak *y, t_symbol *s, int argc, t_atom *argv) +{ + t_mux*x=y->p_master; + if(y->id==x->i_selected) + outlet_anything(x->x_obj.ob_outlet, s, argc, argv); +} + + +static void pak_free(t_pak *x) { t_gpointer *gp; int i; @@ -230,20 +221,51 @@ static void pack_free(t_pack *x) freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec)); freebytes(x->x_outvec, x->x_n * sizeof(*x->x_outvec)); freebytes(x->x_gpointer, x->x_nptr * sizeof(*x->x_gpointer)); + + // Free proxys + const int count = x->count; + + if(x->in && x->proxy){ + int n=0; + for(n=0; nin[n]){ + inlet_free(x->in[n]); + } + x->in[n]=0; + if(x->proxy[n]){ + t_pak_inlet *y=x->proxy[n]; + y->master=0; + y->id=0; + pd_free(&y->p_pd); + } + x->proxy[n]=0; + } + freebytes(x->in, x->count * sizeof(t_inlet *)); + freebytes(x->proxy, x->count * sizeof(t_pak_inlet*)); + } + + } -static void pack_setup(void) +static void pak_setup(void) { - pack_class = class_new(gensym("pack"), (t_newmethod)pack_new, - (t_method)pack_free, sizeof(t_pack), 0, A_GIMME, 0); - class_addbang(pack_class, pack_bang); - class_addpointer(pack_class, pack_pointer); - class_addfloat(pack_class, pack_float); - class_addsymbol(pack_class, pack_symbol); - class_addlist(pack_class, pack_list); - class_addanything(pack_class, pack_anything); + pak_class = class_new(gensym("pak"), (t_newmethod)pak_new, + (t_method)pak_free, sizeof(t_pak), 0, A_GIMME, 0); + class_addbang(pak_class, pak_bang); + class_addpointer(pak_class, pak_pointer); + class_addfloat(pak_class, pak_float); + class_addsymbol(pak_class, pak_symbol); + class_addlist(pak_class, pak_list); + class_addanything(pak_class, pak_anything); + + // Setup proxies + + pak_inlet_class = class_new(0, 0, 0, sizeof(t_pak_inlet),CLASS_PD | CLASS_NOINLET, 0); + class_addanything(pak_inlet_class, pak_inlet); + } -*/ + + //////////////// MULTIPLEX ////////////// diff --git a/test/putget~.h b/test/putget~.h new file mode 100644 index 0000000..e585791 --- /dev/null +++ b/test/putget~.h @@ -0,0 +1,133 @@ +#include "m_pd.h" + +/* + typedef struct _param_inlet2 +{ + t_object x_obj; + t_param *p_owner; +} t_param_inlet2; + +*/ + +struct putget { + t_symbol* name; + t_sample a[64]; + t_sample b[64]; + t_sample* w; + t_sample* r; + int writers; + //int written; + int users; + struct putget* next; + struct putget* previous; + t_clock* clock; + int armed; +}; + + +struct putget* PUTGETS; + +// This should be triggered by the clock +static void putget_swap(struct putget* pg) { + //post("clock"); + + t_sample* temp = pg->r; + pg->r = pg->w; + pg->w = temp; + + int i; + t_sample* samples = pg->w; + for (i=0;i<64;i++) { + *samples++ = 0; + + } + + pg->armed = 0; + + //if (pg == NULL) post("ouc"); + //pg->written = 0; + +} + +static struct putget* putget_register(t_symbol* name, int is_writer) { + + struct putget* new_putget; + + is_writer = is_writer ? 1 : 0; + + struct putget* pg = PUTGETS; + + if ( pg != NULL) { + + // Search for previous putget + while( pg ) { + if ( pg->name == name) { + //#ifdef PARAMDEBUG + // post("Found put/get with same name"); + //#endif + pg->writers = pg->writers + is_writer; + pg->users = pg->users + 1; + return pg; + } + if ( pg->next == NULL ) break; + pg = pg->next; + } + } + + + //post("Appending new put/get"); + // Append new putget + new_putget = getbytes(sizeof(*new_putget)); + new_putget->name = name; + new_putget->writers = is_writer; + new_putget->users = 1; + new_putget->armed = 0; + + new_putget->clock = clock_new(new_putget, (t_method)putget_swap); + + new_putget->r = new_putget->a; + new_putget->w = new_putget->b; + + new_putget->previous = pg; + if ( pg) { + pg->next = new_putget; + } else { + PUTGETS = new_putget; + } + + return new_putget; + +} + + +static void putget_unregister(struct putget* pg, int is_writer) { + + //post("Trying to remove %s",pg->name->s_name); + + if ( is_writer) pg->writers = pg->writers - 1; + pg->users = pg->users - 1; + if ( pg->users <= 0) { + //post("Removing last put/get of this name"); + if (pg->previous) { + pg->previous->next = pg->next; + if (pg->next) pg->next->previous = pg->previous; + } else { + PUTGETS = pg->next; + if ( pg->next != NULL) pg->next->previous = NULL; + } + clock_free(pg->clock); + freebytes(pg, sizeof *(pg) ); + } +} + + +static void putget_arm(struct putget* pg) { + + if (!pg->armed) { + pg->armed = 1; + clock_delay(pg->clock, 0); + } + +} + + diff --git a/test/put~.c b/test/put~.c new file mode 100644 index 0000000..9074888 --- /dev/null +++ b/test/put~.c @@ -0,0 +1,89 @@ +#include "putget~.h" + +static t_class *put_tilde_class; + +typedef struct _put_tilde { + t_object x_obj; + //t_sample f_put; + struct putget* pg; + t_sample f; +} t_put_tilde; + +static t_int* put_tilde_perform(t_int *w) +{ + + t_put_tilde *x = (t_put_tilde *)(w[1]); + + if (x->pg && (x->pg->users > x->pg->writers)) { + t_sample *in = (t_sample *)(w[2]); + int n = (int)(w[3]); + t_sample *samples = x->pg->w; + + while (n--) { + *samples = *samples + *in; + samples++; in++; + } + + } + return (w+4); +} + + +static void put_tilde_set(t_put_tilde *x, t_symbol* s) { + + if (gensym("") != s ) { + if ( x->pg ) { + if ( x->pg->name != s) { + putget_unregister(x->pg,1); + x->pg = putget_register(s,1); + } + } else { + x->pg = putget_register(s,1); + } + } + +} + + +static void put_tilde_dsp(t_put_tilde *x, t_signal **sp) +{ + + if ( (int) sp[0]->s_n == 64 ) { + dsp_add(put_tilde_perform, 3, x,sp[0]->s_vec, sp[0]->s_n); + + } else { + error("put~ only works with a block size of 64"); + } + +} + +static void put_tilde_free( t_put_tilde *x) { + + if (x->pg) putget_unregister(x->pg,1); +} + + +static void *put_tilde_new(t_symbol* s) +{ + t_put_tilde *x = (t_put_tilde *)pd_new(put_tilde_class); + + if (gensym("") != s ) x->pg = putget_register(s,1); + + + return (void *)x; +} + +void put_tilde_setup(void) { + put_tilde_class = class_new(gensym("put~"), + (t_newmethod)put_tilde_new, + (t_method)put_tilde_free, sizeof(t_put_tilde), + 0, A_DEFSYM, 0); + + class_addmethod(put_tilde_class, + (t_method)put_tilde_dsp, gensym("dsp"), 0); + + class_addmethod(put_tilde_class, + (t_method)put_tilde_set, gensym("set"), A_SYMBOL, 0); + + CLASS_MAINSIGNALIN(put_tilde_class, t_put_tilde, f); +} -- cgit v1.2.1