From b7857a8edb28bbc3a9839eec2cc7cb67695a51ba Mon Sep 17 00:00:00 2001 From: Martin Peach Date: Wed, 11 Jul 2007 19:44:32 +0000 Subject: pipelist is like pipe for lists. It can be used with unpackOSC to delay timetagged messages. svn path=/trunk/externals/mrpeach/; revision=8021 --- osc/pipelist-help.pd | 39 ++++++++++++++++ osc/pipelist.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 osc/pipelist-help.pd create mode 100644 osc/pipelist.c diff --git a/osc/pipelist-help.pd b/osc/pipelist-help.pd new file mode 100644 index 0000000..4fc2038 --- /dev/null +++ b/osc/pipelist-help.pd @@ -0,0 +1,39 @@ +#N canvas 170 252 558 300 10; +#X obj 112 129 pipelist 1000; +#X msg 198 83 5000; +#X floatatom 198 107 5 0 0 0 - - -; +#X floatatom 222 42 5 0 0 0 - - -; +#X floatatom 181 42 5 0 0 0 - - -; +#X obj 112 62 pack s s 3 4 5; +#X obj 112 0 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 +-1; +#X msg 135 -1 tik; +#X msg 57 13 alpha; +#X msg 50 41 beta; +#X floatatom 63 90 5 0 0 0 - - -; +#X obj 112 196 print; +#X obj 130 107 symbol; +#X msg 135 83 bb; +#X text 195 1 pipelist delays lists.; +#X text 237 106 Delay time is in milliseconds.; +#X text 208 131 Argument sets initial delay time.; +#X text 242 218 2007/07/11 Martin Peach; +#X text 229 182 see also:; +#X obj 305 183 pipe; +#X obj 339 183 delay; +#X obj 379 183 timer; +#X obj 135 21 symbol; +#X connect 0 0 11 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 3 0 5 4; +#X connect 4 0 5 3; +#X connect 5 0 0 0; +#X connect 6 0 5 0; +#X connect 7 0 22 0; +#X connect 8 0 5 0; +#X connect 9 0 5 0; +#X connect 10 0 0 0; +#X connect 12 0 0 0; +#X connect 13 0 12 0; +#X connect 22 0 5 1; diff --git a/osc/pipelist.c b/osc/pipelist.c new file mode 100644 index 0000000..14e9e7b --- /dev/null +++ b/osc/pipelist.c @@ -0,0 +1,127 @@ +/* pipelist.c 20070711 Martin Peach based on pipe from x_time.c */ +#include "m_pd.h" +/* -------------------------- pipe -------------------------- */ + +static t_class *pipelist_class; + +typedef struct _hang +{ + t_clock *h_clock; + struct _hang *h_next; + struct _pipelist *h_owner; + int h_n; /* number of atoms in h_list */ + t_atom *h_atoms; /* pointer to a list of h_n t_atoms */ +} t_hang; + +typedef struct _pipelist +{ + t_object x_obj; + float x_deltime; + t_outlet *x_pipelistout; + t_hang *x_hang; +} t_pipelist; + +static void *pipelist_new(t_symbol *s, int argc, t_atom *argv); +static void pipelist_hang_free(t_hang *h); +static void pipelist_hang_tick(t_hang *h); +static void pipelist_list(t_pipelist *x, t_symbol *s, int ac, t_atom *av); +static void pipelist_flush(t_pipelist *x); +static void pipelist_clear(t_pipelist *x); +void pipelist_setup(void); + +static void *pipelist_new(t_symbol *s, int argc, t_atom *argv) +{ + t_pipelist *x = (t_pipelist *)pd_new(pipelist_class); + float deltime; + + if (argc) + { /* We accept one argument to set the delay time, ignore any further args */ + if (argv[0].a_type != A_FLOAT) + { + char stupid[80]; + atom_string(&argv[argc-1], stupid, 79); + post("pipelist: %s: bad time delay value", stupid); + deltime = 0; + } + else deltime = argv[argc-1].a_w.w_float; + } + else deltime = 0; + + x->x_pipelistout = outlet_new(&x->x_obj, &s_list); + floatinlet_new(&x->x_obj, &x->x_deltime); + x->x_hang = NULL; + x->x_deltime = deltime; + return (x); +} + +static void pipelist_hang_free(t_hang *h) +{ + freebytes(h->h_atoms, h->h_n*sizeof(t_atom)); + clock_free(h->h_clock); + freebytes(h, sizeof(t_hang)); +} + +static void pipelist_hang_tick(t_hang *h) +{ + t_pipelist *x = h->h_owner; + t_hang *h2, *h3; + + /* excise h from the linked list of hangs */ + if (x->x_hang == h) x->x_hang = h->h_next; + else for (h2 = x->x_hang; ((h3 = h2->h_next)!=NULL); h2 = h3) + { + if (h3 == h) + { + h2->h_next = h3->h_next; + break; + } + } + /* output h's list */ + outlet_list(x->x_pipelistout, &s_list, h->h_n, h->h_atoms); + /* free h */ + pipelist_hang_free(h); +} + +static void pipelist_list(t_pipelist *x, t_symbol *s, int ac, t_atom *av) +{ + t_hang *h = (t_hang *)getbytes(sizeof(t_hang)); + int i; + + h->h_n = ac; + h->h_atoms = (t_atom *)getbytes(h->h_n*sizeof(t_atom)); + + for (i = 0; i < h->h_n; ++i) + h->h_atoms[i] = av[i]; + h->h_next = x->x_hang; + x->x_hang = h; + h->h_owner = x; + h->h_clock = clock_new(h, (t_method)pipelist_hang_tick); + clock_delay(h->h_clock, (x->x_deltime >= 0 ? x->x_deltime : 0)); +} + +static void pipelist_flush(t_pipelist *x) +{ + while (x->x_hang) pipelist_hang_tick(x->x_hang); +} + +static void pipelist_clear(t_pipelist *x) +{ + t_hang *hang; + while ((hang = x->x_hang) != NULL) + { + x->x_hang = hang->h_next; + pipelist_hang_free(hang); + } +} + +void pipelist_setup(void) +{ + pipelist_class = class_new(gensym("pipelist"), + (t_newmethod)pipelist_new, (t_method)pipelist_clear, + sizeof(t_pipelist), 0, A_GIMME, 0); + class_addlist(pipelist_class, pipelist_list); + class_addmethod(pipelist_class, (t_method)pipelist_flush, gensym("flush"), 0); + class_addmethod(pipelist_class, (t_method)pipelist_clear, gensym("clear"), 0); +} + +/* end of pipelist.c*/ -- cgit v1.2.1