Instance Pd::createInstance() noexcept { Pd& pd = Pd::get(); pd.m_mutex.lock(); Instance instance(pdinstance_new()); pd.m_mutex.unlock(); return instance; }
void pd_init(void) { if (!pd_this) pd_this = pdinstance_new(); mess_init(); obj_init(); conf_init(); glob_init(); garray_init(); }
//-------------------------------------------------------------- void ofApp::setup() { ofSetFrameRate(60); ofSetVerticalSync(true); //ofSetLogLevel("Pd", OF_LOG_VERBOSE); // see verbose info inside // the number of libpd ticks per buffer, // used to compute the audio buffer len: tpb * blocksize (always 64) #ifdef TARGET_LINUX_ARM // longer latency for Raspberry PI int ticksPerBuffer = 32; // 32 * 64 = buffer len of 2048 int numInputs = 0; // no built in mic #else int ticksPerBuffer = 8; // 8 * 64 = buffer len of 512 int numInputs = 1; #endif int numOutputs = 2; // setup OF sound stream ofSoundStreamSetup(numOutputs, numInputs, this, 44100, ofxPd::blockSize()*ticksPerBuffer, 4); // allocate pd instance handles instanceMutex.lock(); pdinstance1 = pdinstance_new(); pdinstance2 = pdinstance_new(); instanceMutex.unlock(); // set a "current" instance before pd.init() or else Pd will make // an unnecessary third "default" instance instanceMutex.lock(); pd_setinstance(pdinstance1); instanceMutex.unlock(); // setup Pd // // set 4th arg to true for queued message passing using an internal ringbuffer, // this is useful if you need to control where and when the message callbacks // happen (ie. within a GUI thread) // // note: you won't see any message prints until update() is called since // the queued messages are processed there, this is normal // // ... here we'd sure like to be able to have number of channels be // per-instance. The sample rate is still global within Pd but we might // also consider relaxing that restrction. // if(!pd.init(numOutputs, numInputs, 44100, ticksPerBuffer, false)) { ofExit(1); } pd.setReceiver(this); // allocate instance output buffers outputBufferSize = numOutputs*ticksPerBuffer*ofxPd::blockSize(); outputBuffer1 = new float[outputBufferSize]; outputBuffer2 = new float[outputBufferSize]; memset(outputBuffer1, 0, outputBufferSize); memset(outputBuffer2, 0, outputBufferSize); instanceMutex.lock(); pd_setinstance(pdinstance1); // talk to first pd instance instanceMutex.unlock(); // audio processing on pd.start(); // open patch pd.openPatch("test.pd"); instanceMutex.lock(); pd_setinstance(pdinstance2); // talk to the second pd instance instanceMutex.unlock(); // audio processing on pd.start(); // open patch pd.openPatch("test.pd"); // The following two messages can be sent without setting the pd instance // and anyhow the symbols are global so they may affect multiple instances. // However, if the messages change anything in the pd instance 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 that $0 is set to 1003, 1004, ... // as patches are opened, it would be better to open the patches with // settable $1, etc parameters to openPatch(). // [; pd frequency 220 ( pd << StartMessage() << 440.0f << FinishMessage("1003-frequency", "float"); // [; pd frequency 440 ( pd << StartMessage() << 880.0f << FinishMessage("1004-frequency", "float"); }
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 following 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 that $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; }