Mercurial > hg > beaglert
changeset 350:ebaeffa5d493 prerelease
Full implementation of libpd digitals (in and out at message rate). Still messy, needs cleanup, new utilites for setDataOut, clearDataOut, wrapping all this new digital stuff in a class which will be re-usable by Heavy
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Wed, 08 Jun 2016 01:58:35 +0100 |
parents | 6e454ebd9cc4 |
children | 09397ded8966 |
files | examples/basic_libpd/render.cpp |
diffstat | 1 files changed, 75 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/basic_libpd/render.cpp Wed Jun 08 01:55:25 2016 +0100 +++ b/examples/basic_libpd/render.cpp Wed Jun 08 01:58:35 2016 +0100 @@ -49,10 +49,42 @@ 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"}, @@ -73,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, INPUT); + if((ch%2) == 0 ) + pinMode(context, 0, ch, INPUT); + else + pinMode(context, 0, ch, OUTPUT); } } midi.readFrom(0); @@ -101,6 +136,8 @@ 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); @@ -112,8 +149,25 @@ 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); @@ -207,6 +261,12 @@ #endif /* PARSE_MIDI */ 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; @@ -268,7 +328,7 @@ libpd_process_sys(); // process the block //digital out - // digital at message-rate + // 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); @@ -278,6 +338,17 @@ } } + // 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) {