Miller Does that still prevent multiple instances of a libpd based VST from loading in a host?
Chris On Mon, May 12, 2014 at 10:12 AM, Miller Puckette <m...@ucsd.edu> wrote: > I think the global shared symbol space will cause some confusion (patches > will have to protect their sends and receives, etc., by fabricating local > names using '$' characters. > > Also, it won't be possible to run several Pds concurrently on several > threads - in a threaded environment, each Pd instance will have to lock > all others out while it runs. (There might be a fix for that by replacing > all static variables in Pd by thread-local ones, but this is untested and > I'd hate to do it unless there's a real need for it, since it would involve > systematically changing 100s of variable definitions in Pd.) > > I'm not sure about timing - that depends partly on the libpd release > process > that I'm not involved in. > > cheers > Miller > On Mon, May 12, 2014 at 09:45:25AM -0400, Rob Bairos wrote: > > Hi Miller. > > Thats very exciting news! > > Can you give a brief synopsis of what you think the biggest remaining > > limitations are and a rough timeline as to when a stable multi-instance > > pdlib would be available for general use? > > > > Thanks again! > > Rob Bairos. > > > > > > > > On Sun, May 11, 2014 at 3:00 AM, Miller Puckette <m...@ucsd.edu> wrote: > > > > > To Pd developers... > > > > > > I've adapted Pd to nternally use a "pdinstance" structure to allow > > > multiple schedulers (including DSP chains) to run in one address space. > > > With slight modification (see below) libpd can use this to run separate > > > patches asynchronously. > > > > > > I tried to "instance-ize" all Pd symbols to keep them private but ran > into > > > seemingly insoluble problems, so am leaving all symbols global for now. > > > (So patches used in pdlib, if they want to be usable in a > multiple-instance > > > scenaro, should protect all send/receive/table/delay/etc named objects > with > > > a $[0-9] somewhere. > > > > > > I didn't look hard, but I thnk pdlib now will need a way to send $ > > > arguments > > > to patches via libpd_openfile() somehow. Also, libpd_init_audio() will > > > want to > > > make number of channels per-instance, etc. I've put some relevant > comments > > > in the test program I'll include below (and sorry for the length of > this > > > mail!) > > > > > > Here's how I modified libpd_wrapper/z_libpd.c: > > > > > > 55d54 > > > < sys_time = 0; > > > 110c109 > > > < sched_tick(sys_time + sys_time_per_dsp_tick); > > > --- > > > > sched_tick(); > > > 130c129 > > > < sched_tick(sys_time + sys_time_per_dsp_tick); \ > > > --- > > > > sched_tick(); \ > > > > > > ---------------------- > > > and here (sorry again) is the test program, "pdtest2.c" adapted from > > > libpd-master/samples/c_samples/c/pdtest.c : > > > --------------------- > > > > > > #include <stdio.h> > > > #include "z_libpd.h" > > > #include "m_imp.h" > > > #define TIMEUNITPERMSEC (32. * 441.) > > > > > > void pdprint(const char *s) { > > > printf("%s", s); > > > } > > > > > > void pdnoteon(int ch, int pitch, int vel) { > > > printf("noteon: %d %d %d\n", ch, pitch, vel); > > > } > > > > > > int main(int argc, char **argv) { > > > t_pdinstance *pd1 = pdinstance_new(), *pd2 = pdinstance_new(); > > > if (argc < 3) { > > > fprintf(stderr, "usage: %s file folder\n", argv[0]); > > > return -1; > > > } > > > > > > int srate = 44100; > > > // maybe these two calls should be available per-instnace somehow: > > > libpd_set_printhook(pdprint); > > > libpd_set_noteonhook(pdnoteon); > > > /* set a "current" instance before libpd_init() or else Pd will > make > > > an unnecessary third "default" instance. */ > > > pd_setinstance(pd1); > > > libpd_init(); > > > /* ... here we'd sure like to be able to have number of channels be > > > per-nstance. The sample rate is still global within Pd but we > might > > > also consider relaxing that restrction. */ > > > libpd_init_audio(1, 2, srate); > > > > > > float inbuf[64], outbuf[128]; // one input channel, two output > channels > > > // block size 64, one tick per buffer > > > > > > pd_setinstance(pd1); // talk to first pd instance > > > > > > // compute audio [; pd dsp 1( > > > libpd_start_message(1); // one entry in list > > > libpd_add_float(1.0f); > > > libpd_finish_message("pd", "dsp"); > > > > > > // open patch [; pd open file folder( > > > libpd_openfile(argv[1], argv[2]); > > > > > > pd_setinstance(pd2); > > > > > > // compute audio [; pd dsp 1( > > > libpd_start_message(1); // one entry in list > > > libpd_add_float(1.0f); > > > libpd_finish_message("pd", "dsp"); > > > > > > // open patch [; pd open file folder( > > > libpd_openfile(argv[1], argv[2]); > > > > > > /* the follownig two messages can be sent without setting the pd > > > nstance > > > and anyhow the symbols are global so they may affect multiple > > > instances. > > > However, if the messages change anyhing in the pd instacne > structure > > > (DSP state; current time; list of all canvases n our instance) > those > > > changes will apply to the current Pd nstance, so the earlier > messages, > > > for instance, were sensitive to which was the current one. > > > > > > Note also that I'm using the fact taht $0 is set to 1003, 1004, ... > > > as patches are opened -it would be better to opent the patches with > > > settable $1, etc parameters to libpd_openfile(). */ > > > > > > // [; pd frequency 1 ( > > > libpd_start_message(1); // one entry in list > > > libpd_add_float(1.0f); > > > libpd_finish_message("1003-frequency", "float"); > > > > > > // [; pd frequency 1 ( > > > libpd_start_message(1); // one entry in list > > > libpd_add_float(2.0f); > > > libpd_finish_message("1004-frequency", "float"); > > > > > > // now run pd for ten seconds (logical time) > > > int i, j; > > > for (i = 0; i < 3; i++) { > > > // fill inbuf here > > > pd_setinstance(pd1); > > > libpd_process_float(1, inbuf, outbuf); > > > if (i < 2) > > > { > > > for (j = 0; j < 8; j++) > > > printf("%f ", outbuf[j]); > > > printf("\n"); > > > } > > > pd_setinstance(pd2); > > > libpd_process_float(1, inbuf, outbuf); > > > if (i < 2) > > > { > > > for (j = 0; j < 8; j++) > > > printf("%f ", outbuf[j]); > > > printf("\n"); > > > } > > > } > > > > > > return 0; > > > } > > > > > > ---------------------- > > > I replaced "test.c" as follows: > > > --------------------- > > > > > > #N canvas 406 290 450 300 10; > > > #X obj 97 64 loadbang; > > > #X obj 97 131 print; > > > #X obj 186 106 dac~; > > > #X obj 97 107 f 0; > > > #X obj 128 107 + 1; > > > #X obj 97 86 metro 2; > > > #X obj 185 41 r \$0-frequency; > > > #X obj 188 73 osc~; > > > #X obj 248 127 print \$0-frequency; > > > #X obj 248 97 loadbang; > > > #X connect 0 0 5 0; > > > #X connect 3 0 1 0; > > > #X connect 3 0 4 0; > > > #X connect 4 0 3 1; > > > #X connect 5 0 3 0; > > > #X connect 6 0 7 0; > > > #X connect 6 0 8 0; > > > #X connect 7 0 2 0; > > > #X connect 7 0 2 1; > > > #X connect 9 0 8 0; > > > > > > ---------------------------- > > > and got this output: > > > > > > print: 0 > > > 1003-frequency: bang > > > print: 0 > > > 1004-frequency: bang > > > 1003-frequency: 1 > > > 1004-frequency: 2 > > > 1.000000 1.000000 0.999999 0.999999 0.999998 0.999998 0.999997 0.999997 > > > 1.000000 1.000000 0.999998 0.999998 0.999996 0.999996 0.999995 0.999995 > > > print: 1 > > > 0.999944 0.999944 0.999943 0.999943 0.999942 0.999942 0.999941 0.999941 > > > print: 1 > > > 0.999815 0.999815 0.999810 0.999810 0.999804 0.999804 0.999799 0.999799 > > > print: 2 > > > print: 2 > > > > > > ... Looks like there are 2 schedulers adn DSP chains running :) > > > > > > Miller > > > > > > > > > > > > _______________________________________________ > > > Pd-dev mailing list > > > pd-...@iem.at > > > http://lists.puredata.info/listinfo/pd-dev > > > > > _______________________________________________ > Pd-dev mailing list > Pd-dev@lists.iem.at > http://lists.puredata.info/listinfo/pd-dev >
_______________________________________________ Pd-dev mailing list Pd-dev@lists.iem.at http://lists.puredata.info/listinfo/pd-dev