// ======================== // = JACK AUDIO CALLBACKS = // ======================== int process(jack_nframes_t nframes, void *arg) { // Get pointers to the input and output signals sample_t *in1 = (sample_t *) jack_port_get_buffer(portI1, nframes); sample_t *in2 = (sample_t *) jack_port_get_buffer(portI2, nframes); sample_t *out1 = (sample_t *) jack_port_get_buffer(portO1, nframes); sample_t *out2 = (sample_t *) jack_port_get_buffer(portO2, nframes); // Jack uses mono ports and pd expects interleaved stereo buffers. for(unsigned int i=0; i<nframes; i++) { input[i*2] = *in1; input[(i*2)+1] = *in2; in1++; in2++; } // DSP Magic ;) // The Jack server only seems to run fine at 256 samples per frame and libpd only processess samples // in chunks (ticks) of n*64 samples at a time. We need to set the ticksPerBuffer to 4. libpd_process_float(4, input, output); for(unsigned int i=0; i<nframes; i++) { *out1 = output[i*2]; *out2 = output[(i*2)+1]; out1++; out2++; } return 0; }
int main(int argc, char **argv) { if (argc < 3) { fprintf(stderr, "usage: %s file folder\n", argv[0]); return -1; } // init pd int srate = 44100; libpd_printhook = (t_libpd_printhook) pdprint; libpd_init(); libpd_init_audio(1, 2, srate, 1); float inbuf[64], outbuf[128]; // one input channel, two output channels // block size 64, one tick per buffer // compute audio [; pd dsp 1( libpd_start_message(); libpd_add_float(1.0f); libpd_finish_message("pd", "dsp"); // open patch [; pd open file folder( libpd_start_message(); libpd_add_symbol(argv[1]); libpd_add_symbol(argv[2]); libpd_finish_message("pd", "open"); // now run pd for ten seconds (logical time) int i; for (i = 0; i < 10 * srate / 64; i++) { // fill inbuf here libpd_process_float(inbuf, outbuf); // use outbuf here } return 0; }
// ======================== // = JACK AUDIO CALLBACKS = // ======================== int process(jack_nframes_t nframes, void *arg){ // Get pointers to the input and output signals sample_t *in1 = (sample_t *) jack_port_get_buffer(portI1, nframes); sample_t *in2 = (sample_t *) jack_port_get_buffer(portI2, nframes); sample_t *out1 = (sample_t *) jack_port_get_buffer(portO1, nframes); sample_t *out2 = (sample_t *) jack_port_get_buffer(portO2, nframes); // Jack uses mono ports and pd expects interleaved stereo buffers. for(unsigned int i=0; i<nframes; i++){ input[i*2] = *in1; input[(i*2)+1] = *in2; in1++; in2++; } // DSP Magic ;) libpd_process_float(input, output); for(unsigned int i=0; i<nframes; i++){ *out1 = output[i*2]; *out2 = output[(i*2)+1]; out1++; out2++; } return 0; }
JNIEXPORT jint JNICALL Java_org_puredata_core_PdBase_process__I_3F_3F (JNIEnv *env, jclass cls, jint ticks, jfloatArray inBuffer, jfloatArray outBuffer) { if (!inBuffer || !outBuffer) return -10; float *pIn = (*env)->GetFloatArrayElements(env, inBuffer, NULL); float *pOut = (*env)->GetFloatArrayElements(env, outBuffer, NULL); pthread_mutex_lock(&mutex); jint err = libpd_process_float((int) ticks, pIn, pOut); pthread_mutex_unlock(&mutex); (*env)->ReleaseFloatArrayElements(env, inBuffer, pIn, 0); (*env)->ReleaseFloatArrayElements(env, outBuffer, pOut, 0); return err; }
static void runawhile(int num_ticks) { int ticksleft = num_ticks*1000; while (ticksleft > 0) { // fill inbuf here libpd_process_float(1, inbuf, outbuf); // use outbuf here sys_pollgui(); usleep(1451); /* 1 tick is about 1.45 msec */ ticksleft -= 1; } }
bool PdBase::processFloat(int ticks, float* inBuffer, float* outBuffer) { return libpd_process_float(ticks, inBuffer, outBuffer) == 0; }
bool PdBase::processFloat(int ticks, const float* inBuffer, float* outBuffer) { _LOCK(); bool ret = libpd_process_float(ticks, inBuffer, outBuffer) == 0; _UNLOCK(); return ret; }
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; }