From 22c0a77781368cddcbd273009d3c55a765e9200a Mon Sep 17 00:00:00 2001 From: Miller Puckette Date: Mon, 8 Dec 2008 20:14:40 +0000 Subject: 0.42-0test06 svn path=/trunk/; revision=10432 --- pd/extra/pd~/pd~-help.pd | 95 ++++++++++++++++++++++------- pd/extra/pd~/pd~.c | 152 +++++++++++++++++++++++------------------------ pd/extra/pd~/test.pd | 29 --------- 3 files changed, 148 insertions(+), 128 deletions(-) delete mode 100644 pd/extra/pd~/test.pd (limited to 'pd/extra/pd~') diff --git a/pd/extra/pd~/pd~-help.pd b/pd/extra/pd~/pd~-help.pd index a845f453..8bc357e0 100644 --- a/pd/extra/pd~/pd~-help.pd +++ b/pd/extra/pd~/pd~-help.pd @@ -1,20 +1,75 @@ -#N canvas 353 325 450 300 10; -#X msg 52 86 foo bar baz; -#X obj 209 52 osc~ 440; -#X obj 74 211 env~ 8192; -#X floatatom 77 243 5 0 0 0 - - -; -#X obj 285 204 r a; -#X obj 281 232 print a; -#X msg 315 81 \; pd dsp 1; -#X obj 70 166 pd~ test.pd; -#X msg 66 20 pd~ stop; -#X msg 77 42 pd~ start; -#X msg 86 61 pd~ restart; -#X connect 0 0 7 0; -#X connect 1 0 7 0; -#X connect 2 0 3 0; -#X connect 4 0 5 0; -#X connect 7 0 2 0; -#X connect 8 0 7 0; -#X connect 9 0 7 0; -#X connect 10 0 7 0; +#N canvas 12 0 566 872 12; +#X msg 31 406 foo bar baz; +#X obj 189 466 osc~ 440; +#X obj 127 645 env~ 8192; +#X floatatom 127 694 5 0 0 0 - - -; +#X msg 434 807 \; pd dsp 1; +#X msg 24 332 pd~ stop; +#X obj 127 670 i; +#X obj 241 643 env~ 8192; +#X floatatom 241 693 5 0 0 0 - - -; +#X obj 241 669 i; +#X obj 123 489 *~; +#X obj 158 490 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 189 490 *~; +#X obj 224 491 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 434 781 loadbang; +#X obj 14 691 print x; +#X msg 15 309 pd~ start pd~-subprocess.pd; +#X obj 14 532 pd~ -ninsig 2 -noutsig 2 -fifo 20; +#X obj 37 20 pd~; +#X text 69 22 - run a pd sub-process; +#X text 27 57 The pd~ object starts and manages a Pd sub-process that +can communicate with the super-process (this one) via audio channels +and/or Pd messages. In this way you can take advantage of multi-core +CPUs \, and/or use Pd features from within Max (if you're using the +Max version of pd~).; +#X text 24 251 Sending a new "start" message will stop the sub-process +and start a new one. If you just want to stop the sub-process \, send +"stop".; +#X text 33 353 Any message besides "pd~" is sent to the sub-process. +For instance \, the message below sends "bar baz" to any object in +the sub-process named "foo" \, such as a "receive" object.; +#X text 43 430 Audio signals appear in adc~ objects in the sub-process. +The sub-process doesn't open real audio devices.; +#X text 281 473 Creation args:; +#X text 265 490 -insig sets input audio channels; +#X text 266 508 -outsig sets output channels; +#X text 269 542 -fifo sets round-trip delay in blocks; +#X text 272 559 -pddir sets Pd directory \, e.g. \,; +#X text 299 574 .../Pd-0.42.app/Contents/Resources; +#X text 272 590 -scheddir sets scheduler dir \, e.g. \,; +#X text 297 607 .../.../Resources/extra/pd~; +#X text 267 524 -sr sets sample rate; +#X text 20 716 The first outlet reports messages the sub-process sends +us via "stdout" objects. Any other outlets are signals corresponding +to "dac~" objects in the sub-process.; +#X text 10 784 ATTENTION: DSP must be running in this process for the +sub-process to run. This is because its clock is slaved to audio I/O +it gets from us!; +#X text 359 849 Updated for Pd version 0.42.; +#X text 24 138 Messages with "pd~" selector control the sub-process. +"pd~ start" takes as arguments any startup arguments you wish to send +the sub-process. For example \, specify "-nogui" to stop the sub-process's +GUI from appearing. You don't have to specify the number of channels +in and out \, since that's set by creation arguments below. Audio config +arguments arguments (-audiobuf \, -audiodev \, etc.) are ignored.; +#X connect 0 0 17 0; +#X connect 1 0 10 0; +#X connect 1 0 12 0; +#X connect 2 0 6 0; +#X connect 5 0 17 0; +#X connect 6 0 3 0; +#X connect 7 0 9 0; +#X connect 9 0 8 0; +#X connect 10 0 17 0; +#X connect 11 0 10 1; +#X connect 12 0 17 1; +#X connect 13 0 12 1; +#X connect 14 0 4 0; +#X connect 16 0 17 0; +#X connect 17 0 15 0; +#X connect 17 1 2 0; +#X connect 17 2 7 0; diff --git a/pd/extra/pd~/pd~.c b/pd/extra/pd~/pd~.c index 92783e8a..49b398b3 100644 --- a/pd/extra/pd~/pd~.c +++ b/pd/extra/pd~/pd~.c @@ -70,14 +70,13 @@ typedef struct _pd_tilde #ifdef PD t_object x_obj; t_clock *x_clock; + t_outlet *x_outlet1; /* for messages back from subproc */ + t_canvas *x_canvas; #endif /* PD */ #ifdef MSP t_pxobject x_obj; - void *obex; - void *x_cookedout; + void *x_outlet1; void *x_clock; - short x_vol; - #endif /* MSP */ FILE *x_infd; FILE *x_outfd; @@ -91,7 +90,6 @@ typedef struct _pd_tilde float x_sr; t_symbol *x_pddir; t_symbol *x_schedlibdir; - char *x_pdargs; t_sample **x_insig; t_sample **x_outsig; } t_pd_tilde; @@ -168,7 +166,8 @@ static void pd_tilde_readmessages(t_pd_tilde *x) } static void pd_tilde_donew(t_pd_tilde *x, char *pddir, char *schedlibdir, - char *pdargs, int ninsig, int noutsig, int fifo, float samplerate) + char *patchdir, char *pdargs, int ninsig, int noutsig, int fifo, + float samplerate) { int i, pid, pipe1[2], pipe2[2]; char cmdbuf[MAXPDSTRING], pdexecbuf[MAXPDSTRING], schedbuf[MAXPDSTRING]; @@ -197,8 +196,9 @@ static void pd_tilde_donew(t_pd_tilde *x, char *pddir, char *schedlibdir, goto fail1; } } - snprintf(cmdbuf, MAXPDSTRING, "%s -schedlib %s/pdsched %s\n", - pdexecbuf, schedlibdir, pdargs); + snprintf(cmdbuf, MAXPDSTRING, +"%s -schedlib %s/pdsched -path %s -inchannels %d -outchannels %d -r %g %s\n", + pdexecbuf, schedlibdir, patchdir, ninsig, noutsig, samplerate, pdargs); #if 0 #ifdef PD fprintf(stderr, "%s", cmdbuf); @@ -368,25 +368,53 @@ static void pd_tilde_dsp(t_pd_tilde *x, t_signal **sp) static void pd_tilde_pdtilde(t_pd_tilde *x, t_symbol *s, int argc, t_atom *argv) { - t_symbol *sel = ((argc > 0 && argv->a_type == A_SYMBOL) ? argv->a_w.w_symbol : gensym("?")); + t_symbol *sel = ((argc > 0 && argv->a_type == A_SYMBOL) ? + argv->a_w.w_symbol : gensym("?")); + char *patchdir; if (sel == gensym("start")) { - if (!x->x_infd) - pd_tilde_donew(x, x->x_pddir->s_name, x->x_schedlibdir->s_name, - x->x_pdargs, x->x_ninsig, x->x_noutsig, x->x_fifo, x->x_sr); - } - else if (sel == gensym("stop")) - { + char pdargstring[MAXPDSTRING]; if (x->x_infd) pd_tilde_close(x); + pdargstring[0] = 0; + argc--; argv++; +#ifdef PD + while (argc--) + { + atom_string(argv++, pdargstring + strlen(pdargstring), + MAXPDSTRING - strlen(pdargstring)); + if (strlen(pdargstring) < MAXPDSTRING-1) + strcat(pdargstring, " "); + } + patchdir = canvas_getdir(x->x_canvas)->s_name; +#endif +#ifdef MAX + while (argc--) + { + if (argv->a_type == A_SYM) + strncat(pdargstring, argv->a_w.w_sym->s_name, + MAXPDSTRING - strlen(pdargstring)-3); + else if (argv->a_type == A_LONG) + snprintf(pdargstring+strlen(pdargstring), + MAXPDSTRING - strlen(pdargstring)-3, "%ld", + argv->a_w.w_long); + else if (argv->a_type == A_FLOAT) + snprintf(pdargstring+strlen(pdargstring), + MAXPDSTRING - strlen(pdargstring)-3, "%f", + argv->a_w.w_float); + strcat(pdargstring, " "); + argv++; + } + patchdir = "."; +#endif + pd_tilde_donew(x, x->x_pddir->s_name, x->x_schedlibdir->s_name, + patchdir, pdargstring, x->x_ninsig, x->x_noutsig, x->x_fifo, + x->x_sr); } - else if (sel == gensym("restart")) + else if (sel == gensym("stop")) { if (x->x_infd) pd_tilde_close(x); - if (!x->x_infd) - pd_tilde_donew(x, x->x_pddir->s_name, x->x_schedlibdir->s_name, - x->x_pdargs, x->x_ninsig, x->x_noutsig, x->x_fifo, x->x_sr); } else ERROR "pd~: unknown control message: %s", sel->s_name); } @@ -398,7 +426,6 @@ static void pd_tilde_free(t_pd_tilde *x) #endif pd_tilde_close(x); clock_free(x->x_clock); - free(x->x_pdargs); } /* -------------------------- Pd glue ------------------------- */ @@ -420,19 +447,11 @@ static void pd_tilde_tick(t_pd_tilde *x) { if (vec[i].a_type == A_SEMI) { - if (i > messstart + 1) - { - t_pd *whom; - if (vec[messstart].a_type != A_SYMBOL) - bug("pd_tilde_tick"); - else if (!(whom = vec[messstart].a_w.w_symbol->s_thing)) - ERROR "%s: no such object", - vec[messstart].a_w.w_symbol->s_name); - else if (vec[messstart+1].a_type == A_SYMBOL) - typedmess(whom, vec[messstart+1].a_w.w_symbol, - i-messstart-2, vec+(messstart+2)); - else pd_list(whom, 0, i-messstart-1, vec+(messstart+1)); - } + if (i > messstart && vec[messstart].a_type == A_SYMBOL) + outlet_anything(x->x_outlet1, vec[messstart].a_w.w_symbol, + i-(messstart+1), vec+(messstart+1)); + else if (i > messstart) + outlet_list(x->x_outlet1, 0, i-messstart, vec+messstart); messstart = i+1; } } @@ -468,8 +487,7 @@ static void *pd_tilde_new(t_symbol *s, int argc, t_atom *argv) t_sample **g; t_symbol *pddir = sys_guidir, *scheddir = gensym(class_gethelpdir(pd_tilde_class)); - char pdargstring[MAXPDSTRING]; - fprintf(stderr, "pd %s, sched %s\n", pddir->s_name, scheddir->s_name); + /* fprintf(stderr, "pd %s, sched %s\n", pddir->s_name, scheddir->s_name); */ while (argc > 0) { t_symbol *firstarg = atom_getsymbolarg(0, argc, argv); @@ -505,24 +523,15 @@ static void *pd_tilde_new(t_symbol *s, int argc, t_atom *argv) } else break; } -#if 0 - { - pd_error(x, -"usage: pd~ [-sr #] [-ninsig #] [-noutsig #] [-fifo #] [-pddir <>]"); - post( -"... [-scheddir <>] [pd-argument...]"); - argc = 0; - } -#endif - - pdargstring[0] = 0; - while (argc--) + + if (argc) { - atom_string(argv++, pdargstring + strlen(pdargstring), - MAXPDSTRING - strlen(pdargstring)); - if (strlen(pdargstring) < MAXPDSTRING-1) - strcat(pdargstring, " "); + pd_error(x, +"usage: pd~ [-sr #] [-ninsig #] [-noutsig #] [-fifo #] [-pddir <>]"); + post( +"... [-scheddir <>]"); } + x->x_clock = clock_new(x, (t_method)pd_tilde_tick); x->x_insig = (t_sample **)getbytes(ninsig * sizeof(*x->x_insig)); x->x_outsig = (t_sample **)getbytes(noutsig * sizeof(*x->x_outsig)); @@ -532,15 +541,15 @@ static void *pd_tilde_new(t_symbol *s, int argc, t_atom *argv) x->x_sr = sr; x->x_pddir = pddir; x->x_schedlibdir = scheddir; - x->x_pdargs = malloc(strlen(pdargstring)+1); x->x_infd = 0; x->x_outfd = 0; x->x_outfd = 0; x->x_childpid = -1; x->x_msgbuf = 0; - strcpy(x->x_pdargs, pdargstring); + x->x_canvas = canvas_getcurrent(); for (j = 1, g = x->x_insig; j < ninsig; j++, g++) inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + x->x_outlet1 = outlet_new(&x->x_obj, 0); for (j = 0, g = x->x_outsig; j < noutsig; j++, g++) outlet_new(&x->x_obj, &s_signal); signal(SIGPIPE, SIG_IGN); @@ -556,7 +565,7 @@ void pd_tilde_setup(void) class_addmethod(pd_tilde_class, (t_method)pd_tilde_dsp, gensym("dsp"), 0); class_addmethod(pd_tilde_class, (t_method)pd_tilde_pdtilde, gensym("pd~"), A_GIMME, 0); class_addanything(pd_tilde_class, pd_tilde_anything); - post("pd~ version 0.1"); + post("pd~ version 0.2"); } #endif @@ -651,7 +660,8 @@ int main() class_register(CLASS_BOX, c); pd_tilde_class = c; - return (0); + post("pd~ version 0.2"); + return (0); } static void *pd_tilde_new(t_symbol *s, long ac, t_atom *av) @@ -659,7 +669,6 @@ static void *pd_tilde_new(t_symbol *s, long ac, t_atom *av) int ninsig = 2, noutsig = 2, fifo = 5, j; float sr = sys_getsr(); t_symbol *pddir = gensym("."), *scheddir = gensym("."); - char pdargstring[MAXPDSTRING]; t_pd_tilde *x; if (x = (t_pd_tilde *)object_alloc(pd_tilde_class)) @@ -705,30 +714,17 @@ static void *pd_tilde_new(t_symbol *s, long ac, t_atom *av) } if (scheddir == gensym(".") && pddir != gensym(".")) { - char *pds = pddir->s_name; + char *pds = pddir->s_name, scheddirstring[MAXPDSTRING]; int l = strlen(pds); if (l >= 4 && (!strcmp(pds+l-3, "bin") || !strcmp(pds+l-4, "bin/"))) - snprintf(pdargstring, MAXPDSTRING, "%s/../extra/pd~", pds); - else snprintf(pdargstring, MAXPDSTRING, "%s/extra/pd~", pds); - scheddir = gensym(pdargstring); - } - pdargstring[0] = 0; - while (ac--) - { - char buf[80]; - if (av->a_type == A_SYM) - strncat(pdargstring, av->a_w.w_sym->s_name, MAXPDSTRING - strlen(pdargstring)-3); - else if (av->a_type == A_LONG) - snprintf(pdargstring+strlen(pdargstring), MAXPDSTRING - strlen(pdargstring)-3, "%ld", - av->a_w.w_long); - else if (av->a_type == A_FLOAT) - snprintf(pdargstring+strlen(pdargstring), MAXPDSTRING - strlen(pdargstring)-3, "%f", - av->a_w.w_float); - strcat(pdargstring, " "); - av++; + snprintf(scheddirstring, MAXPDSTRING, "%s/../extra/pd~", pds); + else snprintf(scheddirstring, MAXPDSTRING, "%s/extra/pd~", pds); + scheddir = gensym(scheddirstring); } - post("pd~: pddir %s scheddir %s args %s", - pddir->s_name, scheddir->s_name, pdargstring); + if (ac) + post("pd~: warning: ignoring extra arguments"); + post("pd~: pddir %s scheddir %s", + pddir->s_name, scheddir->s_name); dsp_setup((t_pxobject *)x, ninsig); for (j = 0; j < noutsig; j++) outlet_new((t_pxobject *)x, "signal"); @@ -741,13 +737,11 @@ static void *pd_tilde_new(t_symbol *s, long ac, t_atom *av) x->x_sr = sr; x->x_pddir = pddir; x->x_schedlibdir = scheddir; - x->x_pdargs = malloc(strlen(pdargstring)+1); x->x_infd = 0; x->x_outfd = 0; x->x_outfd = 0; x->x_childpid = -1; x->x_msgbuf = 0; - strcpy(x->x_pdargs, pdargstring); } return (x); } diff --git a/pd/extra/pd~/test.pd b/pd/extra/pd~/test.pd deleted file mode 100644 index ca95baec..00000000 --- a/pd/extra/pd~/test.pd +++ /dev/null @@ -1,29 +0,0 @@ -#N canvas 643 132 450 300 10; -#X obj 65 58 r foo; -#X obj 62 100 print foo; -#X obj 244 59 adc~; -#X obj 238 102 env~ 8192; -#X floatatom 236 140 5 0 0 0 - - -; -#X obj 145 130 osc~ 440; -#X obj 287 204 stdout; -#X msg 307 153 a b c; -#X msg 307 42 \; pd dsp 1; -#X floatatom 238 173 5 0 0 0 - - -; -#X msg 149 34 a b c; -#X obj 62 157 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 --1; -#X obj 44 187 del 1000; -#X obj 26 249 print bang; -#X obj 59 219 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 --1; -#X obj 155 234 dac~ 1 2 3 4; -#X obj 168 189 sig~ 0.5; -#X connect 0 0 1 0; -#X connect 2 0 3 0; -#X connect 3 0 4 0; -#X connect 4 0 9 0; -#X connect 7 0 6 0; -#X connect 10 0 1 0; -#X connect 11 0 12 0; -#X connect 12 0 13 0; -#X connect 12 0 14 0; -- cgit v1.2.1