diff --git a/pdMultiExample/bin/data/test.pd b/pdMultiExample/bin/data/test.pd index 4d528ed..d21be9a 100644 --- a/pdMultiExample/bin/data/test.pd +++ b/pdMultiExample/bin/data/test.pd @@ -1,21 +1,23 @@ -#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; +#N canvas 406 290 364 189 10; +#X obj 54 53 loadbang; +#X obj 54 120 print; +#X obj 143 124 dac~; +#X obj 54 96 f 0; +#X obj 85 96 + 1; +#X obj 143 42 r \$0-frequency; +#X obj 143 70 osc~; +#X obj 205 116 print \$0-frequency; +#X obj 205 86 loadbang; +#X obj 143 96 *~ 0.5; +#X obj 54 75 metro 100; +#X connect 0 0 10 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; +#X connect 5 0 6 0; +#X connect 5 0 7 0; +#X connect 6 0 9 0; +#X connect 8 0 7 0; +#X connect 9 0 2 0; +#X connect 9 0 2 1; +#X connect 10 0 3 0; diff --git a/pdMultiExample/src/ofApp.cpp b/pdMultiExample/src/ofApp.cpp index 6229aeb..99a66fc 100644 --- a/pdMultiExample/src/ofApp.cpp +++ b/pdMultiExample/src/ofApp.cpp @@ -27,9 +27,10 @@ void ofApp::setup() { int ticksPerBuffer = 8; // 8 * 64 = buffer len of 512 int numInputs = 1; #endif + int numOutputs = 2; // setup OF sound stream - ofSoundStreamSetup(2, numInputs, this, 44100, ofxPd::blockSize()*ticksPerBuffer, 3); + ofSoundStreamSetup(numOutputs, numInputs, this, 44100, ofxPd::blockSize()*ticksPerBuffer, 4); // allocate pd instance handles pdinstance1 = pdinstance_new(); @@ -52,10 +53,17 @@ void ofApp::setup() { // per-instance. The sample rate is still global within Pd but we might // also consider relaxing that restrction. // - if(!pd.init(2, numInputs, 44100, ticksPerBuffer, false)) { - OF_EXIT_APP(1); + if(!pd.init(numOutputs, numInputs, 44100, ticksPerBuffer, false)) { + ofExit(1); } pd.setReceiver(this); + + // allocate instance output buffers + int bufferSize = numOutputs*ticksPerBuffer*ofxPd::blockSize(); + outputBuffer1 = new float[bufferSize]; + outputBuffer2 = new float[bufferSize]; + memset(outputBuffer1, 0, bufferSize); + memset(outputBuffer2, 0, bufferSize); pd_setinstance(pdinstance1); // talk to first pd instance @@ -83,12 +91,12 @@ void ofApp::setup() { // 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 1 ( - pd << StartMessage() << 1.0f << FinishMessage("1003-frequency", "float"); + + // [; pd frequency 220 ( + pd << StartMessage() << 440.0f << FinishMessage("1003-frequency", "float"); - // [; pd frequency 2 ( - pd << StartMessage() << 2.0f << FinishMessage("1004-frequency", "float"); + // [; pd frequency 440 ( + pd << StartMessage() << 880.0f << FinishMessage("1004-frequency", "float"); } //-------------------------------------------------------------- @@ -128,11 +136,17 @@ void ofApp::audioRequested(float * output, int bufferSize, int nChannels) { // process audio output for instance 1 pd_setinstance(pdinstance1); - pd.audioOut(output, bufferSize, nChannels); + pd.audioOut(outputBuffer1, bufferSize, nChannels); // process audio output for instance 2 pd_setinstance(pdinstance2); - pd.audioOut(output, bufferSize, nChannels); + pd.audioOut(outputBuffer2, bufferSize, nChannels); + + // mix the two instance output buffers together + int size = bufferSize*sizeof(float); + for(int i = 0; i < size; i += sizeof(float)) { + output[i] = (outputBuffer1[i] + outputBuffer2[i]) * 0.5f; // mix + } } //-------------------------------------------------------------- diff --git a/pdMultiExample/src/ofApp.h b/pdMultiExample/src/ofApp.h index 8ffc0e7..cbb97a2 100644 --- a/pdMultiExample/src/ofApp.h +++ b/pdMultiExample/src/ofApp.h @@ -55,6 +55,9 @@ class ofApp : public ofBaseApp, public PdReceiver{ ofxPd pd; // pd instance handles, not full fledged ofxPd objects yet , but internal - // pd types which tell libpd to address a searpate internal "instance" + // pd types which tell libpd to address a separate internal "instance" t_pdinstance *pdinstance1, *pdinstance2; + + float* outputBuffer1; //< interleaved audio output buffer for instance 1 + float* outputBuffer2; //< interleaved audio output buffer for instance 2 };