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