Mercurial > hg > beaglert
changeset 351:09397ded8966 prerelease
merge
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Wed, 08 Jun 2016 02:00:17 +0100 |
parents | ebaeffa5d493 (diff) c6a15a8dee02 (current diff) |
children | 749aa016fa16 |
files | |
diffstat | 2 files changed, 100 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/basic_libpd/render.cpp Tue Jun 07 18:37:11 2016 +0100 +++ b/examples/basic_libpd/render.cpp Wed Jun 08 02:00:17 2016 +0100 @@ -13,7 +13,6 @@ #include <PRU.h> #include <stdio.h> #include "z_libpd.h" -#include "z_queued.h" #include "s_stuff.h" #include <UdpServer.h> #include <Midi.h> @@ -47,15 +46,45 @@ #define PARSE_MIDI AuxiliaryTask libpdReadFilesTask; -AuxiliaryTask libpdProcessMessageQueueTask; -AuxiliaryTask libpdProcessMidiQueueTask; Midi midi; //UdpServer udpServer; +static uint32_t clearDataOut; +static uint32_t setDataOut; void sendDigitalMessage(bool state, unsigned int delay, void* receiverName){ libpd_float((char*)receiverName, (float)state); // rt_printf("%s: %d\n", (char*)receiverName, state); } + +void Bela_floatHook(const char *source, float value){ +// rt_printf("received: %s %f\n", source, value); + // let's make this as optimized as possible for built-in digital Out parsing + // the built-in digital receivers are of the form "bela_digitalOutXX" where XX is between 11 and 26 + static int prefixLength = 15; // strlen("bela_digitalOut") + if(strncmp(source, "bela_digitalOut", prefixLength)==0){ + if(source[prefixLength] != 0){ //the two ifs are used instead of if(strlen(source) >= prefixLength+2) + if(source[prefixLength + 1] != 0){ + // quickly convert the suffix to integer, assuming they are numbers, avoiding to call atoi + int receiver = ((source[prefixLength] - 48) * 10); + receiver += (source[prefixLength+1] - 48); +// rt_printf("received on digital %d value %.0f\n", receiver, value); + unsigned int channel = receiver - 11; // go back to the actual Bela digital channel number + if(channel >= 0 && channel < 16){ //16 is the hardcoded value for the number of digital channels + //TODO: here we should check if this channel has been registered as message-rate output + if(value == 0){ + clearDataOut = setBit(clearDataOut, channel); + setDataOut = clearBit(setDataOut, channel); + } else { + setDataOut = setBit(setDataOut, channel); + clearDataOut = clearBit(clearDataOut, channel); + } +// rt_printf("clear 0x%x set 0x%x\n", clearDataOut, setDataOut); + } + } + } + } +} + char receiverNames[16][21]={ {"bela_digitalIn11"},{"bela_digitalIn12"},{"bela_digitalIn13"},{"bela_digitalIn14"},{"bela_digitalIn15"}, {"bela_digitalIn16"},{"bela_digitalIn17"},{"bela_digitalIn18"},{"bela_digitalIn19"},{"bela_digitalIn20"}, @@ -76,7 +105,10 @@ for(unsigned int ch = 0; ch < context->digitalChannels; ++ch){ dtm[ch] = new DigitalToMessage; dtm[ch]->setCallback(sendDigitalMessage, receiverNames[ch]); - pinMode(context, 0, ch, OUTPUT); + if((ch%2) == 0 ) + pinMode(context, 0, ch, INPUT); + else + pinMode(context, 0, ch, OUTPUT); } } midi.readFrom(0); @@ -96,13 +128,16 @@ fprintf(stderr, "Error: minimum block size must be %d\n", gLibpdBlockSize); return false; } - // init pd - libpd_set_queued_printhook(Bela_printHook); // set this before calling libpd_init - libpd_set_queued_noteonhook(pdnoteon); + // set hooks before calling libpd_init + libpd_set_printhook(Bela_printHook); + libpd_set_floathook(Bela_floatHook); + libpd_set_noteonhook(pdnoteon); //TODO: add hooks for other midi events and generate MIDI output appropriately - libpd_queued_init(); + libpd_init(); //TODO: ideally, we would analyse the ASCII of the patch file and find the in/outs to use libpd_init_audio(gChannelsInUse, gChannelsInUse, context->audioSampleRate); + gInBuf = libpd_get_sys_soundin(); + gOutBuf = libpd_get_sys_soundout(); libpd_start_message(1); // one entry in list libpd_add_float(1.0f); @@ -114,14 +149,29 @@ char folder[] = "./"; // open patch [; pd open file folder( libpd_openfile(file, folder); - gInBuf = libpd_get_sys_soundin(); - gOutBuf = libpd_get_sys_soundout(); + + // bind your receivers here + libpd_bind("bela_digitalOut11"); + libpd_bind("bela_digitalOut12"); + libpd_bind("bela_digitalOut13"); + libpd_bind("bela_digitalOut14"); + libpd_bind("bela_digitalOut15"); + libpd_bind("bela_digitalOut16"); + libpd_bind("bela_digitalOut17"); + libpd_bind("bela_digitalOut18"); + libpd_bind("bela_digitalOut19"); + libpd_bind("bela_digitalOut20"); + libpd_bind("bela_digitalOut21"); + libpd_bind("bela_digitalOut22"); + libpd_bind("bela_digitalOut23"); + libpd_bind("bela_digitalOut24"); + libpd_bind("bela_digitalOut25"); + libpd_bind("bela_digitalOut26"); + libpdReadFilesTask = Bela_createAuxiliaryTask(libpdReadFilesLoop, 60, "libpdReadFiles"); Bela_scheduleAuxiliaryTask(libpdReadFilesTask); - // Higher priority for the midi queue and lower priority for the message queue. Adjust to taste - libpdProcessMidiQueueTask = Bela_createAuxiliaryTask(libpd_queued_receive_midi_messages, 80, "libpdProcessMidiQueue"); - libpdProcessMessageQueueTask = Bela_createAuxiliaryTask(libpd_queued_receive_pd_messages, 70, "libpdProcessMessageQueue"); + return true; } @@ -210,13 +260,13 @@ } #endif /* PARSE_MIDI */ -/* - * 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 - * do not need the for loops before and after libpd_process_float, so you can save quite some - * memory operations. - */ static unsigned int numberOfPdBlocksToProcess = gBufLength / gLibpdBlockSize; + + // these are reset at every audio callback. Persistence across audio callbacks + // is handled by the core code. +// setDataOut = 0; +// clearDataOut = 0; + for(unsigned int tick = 0; tick < numberOfPdBlocksToProcess; ++tick){ unsigned int audioFrameBase = gLibpdBlockSize * tick; unsigned int j; @@ -254,17 +304,31 @@ } //then digital - //TODO: in multiple places we assume that the number of digitals is same as number of audio + //TODO: in multiple places below we assume that the number of digitals is same as number of audio + // digital in at message-rate for(unsigned int n = 0; n < context->digitalChannels; ++n){ - // TODO: note that we consider only the first sample of the block + // note that we consider only the first sample of the block // considering all of them is notably more expensive // TODO: only process the channels marked as such dtm[n]->process(n + 16, &context->digital[audioFrameBase], 1); } + // digital in at signal-rate + for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) { + for (k = 0, p1 = p0 + gLibpdBlockSize * (context->audioChannels + 8); + k < 16; ++k, p1 += gLibpdBlockSize) { + // note that we only write the last sample of the block + // writing all of them is notably more expensive. + + // TODO: only process the channels marked as such + unsigned int digitalFrame = audioFrameBase + j; + *p1 = digitalRead(context, digitalFrame, k); + } + } libpd_process_sys(); // process the block - //digital + //digital out + // digital out at signal-rate for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; ++j, ++p0) { unsigned int digitalFrame = (audioFrameBase + j); for (k = 0, p1 = p0 + gLibpdBlockSize * (context->audioChannels + 8); @@ -273,6 +337,18 @@ digitalWriteOnce(context, digitalFrame, k, *p1 > 0.5); } } + + // digital out at message-rate + if(clearDataOut || setDataOut){ + for (unsigned int frame = audioFrameBase; frame < audioFrameBase + gLibpdBlockSize; ++frame) { + // TODO: only process the channels marked as such + uint32_t outWord = context->digital[frame]; + outWord = outWord | (setDataOut << 16); + outWord = outWord &~ (clearDataOut << 16); + context->digital[frame] = outWord; + } + } + //audio for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; j++, p0++) { for (k = 0, p1 = p0; k < context->audioChannels; k++, p1 += gLibpdBlockSize) { @@ -304,8 +380,6 @@ } } } - Bela_scheduleAuxiliaryTask(libpdProcessMidiQueueTask); - Bela_scheduleAuxiliaryTask(libpdProcessMessageQueueTask); } // cleanup() is called once at the end, after the audio has stopped. @@ -313,6 +387,5 @@ void cleanup(BelaContext *context, void *userData) { - libpd_queued_release(); delete[] dtm; }
--- a/scripts/build_pd_heavy.sh Tue Jun 07 18:37:11 2016 +0100 +++ b/scripts/build_pd_heavy.sh Wed Jun 08 02:00:17 2016 +0100 @@ -169,8 +169,8 @@ # UPDATED_FILES=`rsync -naic --log-format="%f" "$projectpath" "$BBB_BELA_HOME"/source | grep -v "\.$"` # echo "UPDATEDFILES : $UPDATED_FILES" # exit 2 - # remove old executable and heavy context .o/.d files - ssh $BBB_ADDRESS "rm -rf "$BBB_PROJECT_FOLDER/$BBB_PROJECT_NAME; + # sets the date, remove old executable and heavy context .o/.d files + ssh $BBB_ADDRESS "date -s '`date`' > /dev/null; rm -rf "$BBB_PROJECT_FOLDER/$BBB_PROJECT_NAME; SCREEN_NAME=BeagleRT # Make new BeagleRT execut/able and run # It does not look very nice that we type the same things over and over