Mercurial > hg > beaglert
changeset 343:4823ee13bcac prerelease
basic_libpd now populates pd's audio buffers directly. Updated libpd.so binary. This required an API change with respect to standard libpdAPI because for some strange reason, accessing sys_audioin and sys_audioout directly from the render.cpp file would return invalid values.
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Mon, 06 Jun 2016 15:15:15 +0100 |
parents | 860c42b3830e |
children | 1c35a5d0ce32 |
files | .cproject examples/basic_libpd/render.cpp libpd.so |
diffstat | 3 files changed, 59 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/.cproject Mon Jun 06 12:21:38 2016 +0100 +++ b/.cproject Mon Jun 06 15:15:15 2016 +0100 @@ -134,7 +134,8 @@ </toolChain> </folderInfo> <sourceEntries> - <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> + <entry excluding="default_main.cpp|audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> + <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="examples/basic_libpd"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_button"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/> @@ -262,7 +263,8 @@ </toolChain> </folderInfo> <sourceEntries> - <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> + <entry excluding="default_main.cpp|audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> + <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="examples/basic_libpd"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_button"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/>
--- a/examples/basic_libpd/render.cpp Mon Jun 06 12:21:38 2016 +0100 +++ b/examples/basic_libpd/render.cpp Mon Jun 06 15:15:15 2016 +0100 @@ -17,16 +17,10 @@ #include <UdpServer.h> #include <Midi.h> - -// setup() is called once before the audio rendering starts. -// Use it to perform any initialisation and allocation which is dependent -// on the period size or sample rate. -// -// userData holds an opaque pointer to a data structure that was passed -// in from the call to initAudio(). -// -// Return true on success; returning false halts the program. -unsigned int gLibpdBlockSize; //make sure this matches the one used to compile libpd +// if you are 100% sure of what value that was used to compile libpd/puredata, then +// you could define this, instead of getting it at runtime. It has proved to give some 0.3% +// performance boost when it is 8 (thanks to vectorize optimizations I guess). +unsigned int gLibpdBlockSize; unsigned int gChannelsInUse = 10; int gBufLength; @@ -200,56 +194,67 @@ */ static unsigned int analogChannelsInUse = min(context->analogChannels, gChannelsInUse - context->audioChannels); static unsigned int numberOfPdBlocksToProcess = gBufLength / gLibpdBlockSize; - for(unsigned int j = 0; j < numberOfPdBlocksToProcess; ++j){ - unsigned int inW = 0; - unsigned int outR = 0; - - for(unsigned int n = 0; n < gLibpdBlockSize; ++n){ //pd buffers are interleaved - for(unsigned int ch = 0; ch < context->audioChannels; ++ch){ //first two channels are audio - gInBuf[inW++] = audioRead(context, n, ch); + for(unsigned int tick = 0; tick < numberOfPdBlocksToProcess; ++tick){ + unsigned int audioOutFrameBase = gLibpdBlockSize * tick; + unsigned int j; + unsigned int k; + float* p0; + float* p1; + for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) { + for (k = 0, p1 = p0; k < context->audioChannels; k++, p1 += gLibpdBlockSize) { + *p1 = audioRead(context, audioOutFrameBase + j, k); } - // then analogs - // this loop resamples by ZOH, as needed, using m - if(context->analogChannels == 8 ){ //hold the value for two frames - for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ - gInBuf[inW++] = analogRead(context, n/2, analogCh); // n/2 wil be the same for n and n+1 when n is even + } + // then analogs + // this loop resamples by ZOH, as needed, using m + if(context->analogChannels == 8 ){ //hold the value for two frames + for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) { + for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + unsigned int analogFrame = (audioOutFrameBase + j) / 2; + *p1 = analogRead(context, analogFrame, k); } - } else if(context->analogChannels == 4){ //write every frame - for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ - gInBuf[inW++] = analogRead(context, n, analogCh); + } + } else if(context->analogChannels == 4){ //write every frame + for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) { + for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + unsigned int analogFrame = audioOutFrameBase + j; + *p1 = analogRead(context, analogFrame, k); } - } else if(context->analogChannels == 2){ //drop every other frame - for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ - gInBuf[inW++] = analogRead(context, n*2, analogCh); + } + } else if(context->analogChannels == 2){ //drop every other frame + for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) { + for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + unsigned int analogFrame = (audioOutFrameBase + j) * 2; + *p1 = analogRead(context, analogFrame, k); } } } libpd_process_sys(); // process the block - for(unsigned int n = 0; n < gLibpdBlockSize; ++n){ //pd buffers are interleaved - unsigned int outAudioFrame = 0; - for(unsigned int ch = 0; ch < context->audioChannels; ++ch){ - audioWrite(context, outAudioFrame, ch, gOutBuf[outR++]); + for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; j++, p0++) { + for (k = 0, p1 = p0; k < context->audioChannels; k++, p1 += gLibpdBlockSize) { + audioWrite(context, audioOutFrameBase + j, k, *p1); } - //and analogs - if(context->analogChannels == 8){ - for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ - float analogOut = gOutBuf[outR++]; - if((n&1) == 0){//write every two frames - analogWrite(context, outAudioFrame/2, analogCh, analogOut); - } else { - // discard this sample - } + } + if(context->analogChannels == 8){ + for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; j += 2, p0 += 2) { //write every two frames + unsigned int analogFrame = (audioOutFrameBase + j) / 2; + for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + analogWrite(context, analogFrame, k, *p1); } - } else if(context->analogChannels == 4){ //write every frame - for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ - float analogOut = gOutBuf[outR++]; - analogWrite(context, outAudioFrame, analogCh, analogOut); + } + } else if(context->analogChannels == 4){ //write every frame + for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; ++j, ++p0) { + unsigned int analogFrame = (audioOutFrameBase + j); + for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + analogWrite(context, analogFrame, k, *p1); } - } else if(context->analogChannels == 2){ //write twice every frame - for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ - float analogOut = gOutBuf[outR++]; - analogWrite(context, 2*outAudioFrame, analogCh, analogOut); - analogWrite(context, 2*outAudioFrame + 1, analogCh, analogOut); + } + } else if(context->analogChannels == 2){ //write every frame twice + for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; j++, p0++) { + for (k = 0, p1 = p0 + gLibpdBlockSize * context->audioChannels; k < analogChannelsInUse; k++, p1 += gLibpdBlockSize) { + int analogFrame = audioOutFrameBase * 2 + j * 2; + analogWrite(context, analogFrame, k, *p1); + analogWrite(context, analogFrame + 1, k, *p1); } } } @@ -264,6 +269,4 @@ void cleanup(BelaContext *context, void *userData) { libpd_queued_release(); -// free(gInBuf); -// free(gOutBuf); }