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) {