Mercurial > hg > beaglert
changeset 341:7af9c5be3434 prerelease
libpd: using smaller blocksizes for processing, so that events can be scheduled more accurately
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Mon, 06 Jun 2016 03:31:22 +0100 |
parents | 69d86429a1cf |
children | 860c42b3830e |
files | examples/basic_libpd/render.cpp |
diffstat | 1 files changed, 52 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/basic_libpd/render.cpp Mon Jun 06 02:37:30 2016 +0100 +++ b/examples/basic_libpd/render.cpp Mon Jun 06 03:31:22 2016 +0100 @@ -118,11 +118,13 @@ void render(BelaContext *context, void *userData) { int num; + // the safest thread-safe option to handle MIDI input is to process the MIDI buffer + // from the audio thread. #ifdef PARSE_MIDI while((num = midi.getParser()->numAvailableMessages()) > 0){ static MidiChannelMessage message; message = midi.getParser()->getNextChannelMessage(); -// message.prettyPrint(); // use this to print beautified message (channel, data bytes) + //message.prettyPrint(); // use this to print beautified message (channel, data bytes) switch(message.getType()){ case kmmNoteOn: { @@ -193,8 +195,8 @@ } #endif /* PARSE_MIDI */ - static unsigned int inW = 0; - static unsigned int outR = 0; + unsigned int inW = 0; + unsigned int outR = 0; /* * NOTE: if you are only using audio (or only analogs) and you are using interleaved buffers * and the blocksize of Bela is the same as gLibPdBlockSize, then you probably @@ -202,72 +204,64 @@ * memory operations. */ static unsigned int analogChannelsInUse = min(context->analogChannels, gChannelsInUse - context->audioChannels); + static unsigned int numberOfPdBlocksToProcess = gBufLength / gLibpdBlockSize; // rt_printf("channelsInUse: %d, analogChannels in Use: %d\n", gChannelsInUse, analogChannelsInUse); - for(unsigned int n = 0; n < context->audioFrames; ++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); - } - // 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 + for(unsigned int j = 0; j < numberOfPdBlocksToProcess; ++j){ + int oldInW = inW; + 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); } - } 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 == 2){ //drop every other frame - for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ - gInBuf[inW++] = analogRead(context, n*2, analogCh); + // 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 + } + } 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 == 2){ //drop every other frame + for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ + gInBuf[inW++] = analogRead(context, n*2, analogCh); + } } } - if(inW == gBufLength * gChannelsInUse){ - inW = 0; - } - } - // rt_printf("inW %d\n", inW); - if(inW == 0){ //if the buffer is full, process it - static int numberOfPdBlocksToProcess = gBufLength/gLibpdBlockSize; // TODO: see if we can rewrite libpd_process_float so that it takes a buffer // of interleaved channels of arbitrary length rather than a series of // stacked buffers of size gLibPdBlockSize as it currently does. - libpd_process_float(numberOfPdBlocksToProcess, gInBuf, gOutBuf); - outR = 0; // reset the read pointer. NOTE: hopefully this is needed only the first time - } - - for(unsigned int n = 0; n < context->audioFrames; n++){ //pd buffers are interleaved - for(unsigned int ch = 0; ch < context->audioChannels; ++ch){ - audioWrite(context, n, ch, gOutBuf[outR++]); - } - //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, n/2, analogCh, analogOut); - } else { - // discard this sample + // This would allow to use the buffers as they are rather than having to copy them + libpd_process_float(1, &gInBuf[oldInW], &gOutBuf[oldInW]); + for(unsigned int n = 0; n < gLibpdBlockSize; ++n){ //pd buffers are interleaved + unsigned int outAudioFrame = n + j * gLibpdBlockSize; + for(unsigned int ch = 0; ch < context->audioChannels; ++ch){ + audioWrite(context, outAudioFrame, ch, gOutBuf[outR++]); + } + //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 + } + } + } 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 == 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 == 4){ //write every frame - for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ - float analogOut = gOutBuf[outR++]; - analogWrite(context, n, analogCh, analogOut); - } - } else if(context->analogChannels == 2){ //write twice every frame - for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ - float analogOut = gOutBuf[outR++]; - analogWrite(context, 2*n, analogCh, analogOut); - analogWrite(context, 2*n + 1, analogCh, analogOut); - } - } - if(outR == gBufLength * gChannelsInUse){ - outR = 0; } } - // rt_printf("outR %d, analogChannelsInUse %d, channelsInUse %d\n", - // outR , analogChannelsInUse, gChannelsInUse); Bela_scheduleAuxiliaryTask(libpdProcessMidiQueueTask); Bela_scheduleAuxiliaryTask(libpdProcessMessageQueueTask); }