aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2007-07-11 19:44:32 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2007-07-11 19:44:32 +0000
commitb7857a8edb28bbc3a9839eec2cc7cb67695a51ba (patch)
tree9e7e06078b68f34a3e5755b8f0f0a15fedf4669b
parentede66ad78a3c06557c53b2c0b6ee014aa3418e03 (diff)
pipelist is like pipe for lists. It can be used with unpackOSC to delay timetagged messages.
svn path=/trunk/externals/mrpeach/; revision=8021
-rw-r--r--osc/pipelist-help.pd39
-rw-r--r--osc/pipelist.c127
2 files changed, 166 insertions, 0 deletions
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*/