changeset 442:6462d0cc8906 prerelease

build_pd_heavy.sh: major refactoring. Safer, nicer, cleaner
author Giulio Moro <giuliomoro@yahoo.it>
date Sun, 19 Jun 2016 00:35:41 +0100
parents b596c72f0382
children a9af964ac18a
files scripts/build_pd_heavy.sh scripts/hvresources/heavy_render.cpp scripts/hvresources/render.cpp
diffstat 3 files changed, 230 insertions(+), 226 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/build_pd_heavy.sh	Sun Jun 19 00:30:48 2016 +0100
+++ b/scripts/build_pd_heavy.sh	Sun Jun 19 00:35:41 2016 +0100
@@ -9,7 +9,6 @@
 
 workingdir=".."
 verbose="0"
-render="0"
 pdpath=""
 NO_UPLOAD="0"
 WATCH="0"
@@ -47,7 +46,7 @@
 usage ()
 {
 printf "\nUSAGE: build_pd.sh [[-i input folder containing _main.pd file ]\
- [-o output folder for new heavy project .c files (default ../projects/heavy/hvtemp)]\
+ [-o output folder for new heavy project .c files (default $projectpath)]\
  [-b bbb path to copy to (default ~/Bela)] | [-h] | [-w|--watch] | [-n|--noupload] | [-r|--release arg]\n"
 printf "\nexample: build_pd.sh -i ../projects/heavy/pd/hello-world -o ../projects/heavy/hello-world\n"
 echo "If --watch is selected, the script will check every 1s for any file that is modified in the source folder, which triggers\
@@ -61,7 +60,7 @@
 
 while [ "$1" != "" ]; do
     case $1 in
-        -b | --bbb )            shift
+        -b | --belaPath )       shift
                                 BBB_BELA_HOME=$1
                                 ;;
         -i | --input )          shift
@@ -75,14 +74,11 @@
                                 ;;
         -v | --verbose )        verbose=1
                                 ;;
-        -r | --render )         shift
-                                render=1
-                                ;;
         -s | --screen )         RUN_WITHOUT_SCREEN="0"
                                 ;;
         -w | --watch )          WATCH=1
                                 ;;
-        -n | --noupload )      NO_UPLOAD=1
+        -n | --noupload )       NO_UPLOAD=1
                                 ;;
         -h | --help )           usage
                                 exit
@@ -93,6 +89,9 @@
     shift
 done
 
+[ -z "$ENZIENAUDIO_COM_PATCH_NAME" ] && ENZIENAUDIO_COM_PATCH_NAME=bbb
+[ "$NO_UPLOAD" -eq 0 ] && [ -z "$pdpath" ] && { echo "Error: a path to the source folder should be provided"; exit 1; }
+
 if [ -z "$release" ]
 then 
   RELEASE_STRING=
@@ -103,56 +102,61 @@
 #create destination folder if it does not exist"
 mkdir -p "$projectpath"
 
+# These files will be cleared from $projectpath before calling uploader.py
+#TODO: get a reliable, exhaustive, up-to-date list.
+HEAVY_FILES='Heavy* Hv* Message* Signal*'
 uploadBuildRun(){
     if [ $NO_UPLOAD -eq 0 ]; then
         # remove old static files to avoid obsolete errors
+	# make sure the path is not empty, so avoiding to rm -rf / by mistake 
+	[ -z $projectpath ] && { echo 'ERROR: $projectpath is empty.'; exit 0; } 
         # use -rf to prevent warnings in case they do not exist
-        rm -rf "$projectpath"/Hv* "$projectpath"/Message* "$projectpath"/Control* "$projectpath"/Signal* >/dev/null 2>&1
+        for file in $HEAVY_FILES
+	do 
+	    rm -rf "$projectpath"/$file
+	done
 
         # invoke the online compiler
-        "$BELA_PYTHON27" hvresources/uploader.py "$pdpath"/ -n bbb -g c -o "$projectpath" $RELEASE_STRING;
-        if [ $? -ne 0 ]; then
-        #echo "ERROR: an error occurred while executing the uploader.py script"
-        echo "error"
-        exit 1
-        fi;
+        echo "$BELA_PYTHON27" hvresources/uploader.py "$pdpath"/ -n $ENZIENAUDIO_COM_PATCH_NAME -g c -o "$projectpath" $RELEASE_STRING
+        "$BELA_PYTHON27" hvresources/uploader.py "$pdpath"/ -n $ENZIENAUDIO_COM_PATCH_NAME -g c -o "$projectpath" $RELEASE_STRING ||\
+            { echo "ERROR: an error occurred while executing the uploader.py script"; exit 1; }
     fi;
 
     echo "";
-    #echo "*|*|* Successfully uploaded and converted pd patch into super-fast optimized C code. Brought to you by Heavy! *|*|*";
-    echo "";
+
+    # Test that files have been retrieved from the online compiler.
+    # TODO: find a more reliable way of doing this. e.g.: have uploader.py fail with a non-zero error code.
+    for file in $HEAVY_FILES;
+    do
+        ls "$projectpath"/$file >/dev/null 2>&1 || { echo "The online compiler failed, please try again."; exit 1; }
+    done
+    # Apply any Bela-specific patches here 
+    cp "hvresources/HvUtils.h" $projectpath/;
 
     BBB_PROJECT_FOLDER=$BBB_PROJECT_HOME"/"$BBB_PROJECT_NAME #make sure there is no trailing slash here
     BBB_NETWORK_TARGET_FOLDER=$BBB_ADDRESS:$BBB_PROJECT_FOLDER
 
     # check how to copy/sync render.cpp file...
-    # don't replace render.cpp file if custom one provided in output folder
-    if [ -f $projectpath"/render.cpp" ]; then
-        echo "Found custom render.cpp file in output folder";
-        ssh -t $BBB_ADDRESS "rm ${BBB_PROJECT_FOLDER}/build/render.*" 
+    # check if custom heavy_render.cpp file is provided in the input folder
+    # TODO: extend this to all non-Pd files
+    CUSTOM_RENDER_SOURCE_PATH="$pdpath/heavy_render.cpp"
+    if [ -f "$CUSTOM_RENDER_SOURCE_PATH" ]; then
+        echo "Found custom heavy_render.cpp file in input folder, using that one instead of the default one.";
+        cp "$CUSTOM_RENDER_SOURCE_PATH" "$projectpath/"
     else
-        if [ $render -eq 0 ]; then
-        cp "hvresources/render.cpp" $projectpath/;
-        fi;
-    fi;
+        echo "Using default heavy_render.cpp"
+        cp "hvresources/heavy_render.cpp" $projectpath/
+    fi
+    
+    echo "Updating files on board..."
+    # HvContext* files tend to hang when transferring with rsync because they are very large and -c checksum takes a lot, I guess
+    rsync -ac --out-format="   %n" --no-t --delete-after --exclude='HvContext*' --exclude=build --exclude=$BBB_PROJECT_NAME "$projectpath"/ "$BBB_NETWORK_TARGET_FOLDER" &&\
+        { [ $NO_UPLOAD -eq 0 ] && scp "$projectpath"/HvContext* $BBB_NETWORK_TARGET_FOLDER; } ||\
+	{ echo "ERROR: while synchronizing files with the BBB. Is the board connected?"; exit 1; }
 
-    cp "hvresources/HvUtils.h" $projectpath/;
+    # TODO: this should be run only when Heavy_bbb.h changes. Otherwise render is recompiled every time for no good reason
+    ssh $BBB_ADDRESS "rm -rf ${BBB_PROJECT_FOLDER}/build/render.*" 
 
-    echo "updating files on board..."
-
-    rsync -c -rv --exclude 'HvContext*' "$projectpath"/ "$BBB_NETWORK_TARGET_FOLDER";
-    if [ $NO_UPLOAD -eq 0 ]; then
-        # for whatever reason these big files used to hang when transferring with rsync
-        scp "$projectpath"/HvContext* $BBB_NETWORK_TARGET_FOLDER
-    fi;
-
-    if [ $? -ne 0 ]; then
-    echo "";
-    echo ":( :( :( ERROR: while synchronizing files with the BBB. Is the board connected and the correct SD card inserted? :( :( :(";
-    echo "";
-    exit 1;
-    fi;
-    # exit
     #produce a list of files which content has changed (not just the date)
     #TODO: could be made faster (perhaps) by backing up the folder locally instead of bbb
     # UPDATED_FILES=`rsync -naic --log-format="%f" "$projectpath" "$BBB_BELA_HOME"/source | grep -v "\.$"`
@@ -162,7 +166,7 @@
     if [ $NO_UPLOAD -eq 0 ]; then
         ssh $BBB_ADDRESS "rm -rf "$BBB_PROJECT_FOLDER/$BBB_PROJECT_NAME;
     fi;
-    # Make new Bela execut/able and run
+    # Make new Bela executable and run
     # It does not look very nice that we type the same things over and over
     # but that is because each line is an ssh session in its own right
     MAKE_COMMAND="make stop -C $BBB_BELA_HOME PROJECT='$BBB_PROJECT_NAME' CL='$COMMAND_ARGS'"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/hvresources/heavy_render.cpp	Sun Jun 19 00:35:41 2016 +0100
@@ -0,0 +1,185 @@
+/*
+ * render.cpp
+ *
+ *  Template render.cpp file for on-board heavy compiling
+ *
+ *  N.B. this is currently *not* compatible with foleyDesigner source files!
+ *
+ *  Created on: November 5, 2015
+ *
+ *  Christian Heinrichs
+ *
+ */
+
+#include <Bela.h>
+#include <Midi.h>
+#include <cmath>
+#include "Heavy_bbb.h"
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>
+/*
+ *	HEAVY CONTEXT & BUFFERS
+ */
+
+Hv_bbb *gHeavyContext;
+float *gHvInputBuffers = NULL, *gHvOutputBuffers = NULL;
+int gHvInputChannels = 0, gHvOutputChannels = 0;
+
+float gInverseSampleRate;
+
+/*
+ *	HEAVY FUNCTIONS
+ */
+
+void printHook(double timestampSecs, const char *printLabel, const char *msgString, void *userData) {
+  printf("Message from Heavy patch: [@ %.3f] %s: %s\n", timestampSecs, printLabel, msgString);
+}
+
+static void sendHook(
+    double timestamp, // in milliseconds
+    const char *receiverName,
+    const HvMessage *const m,
+    void *userData) {
+
+  // only react to messages sent to receivers named "hello"
+  if (!strncmp(receiverName, "hello", 5)) {
+  }
+
+}
+
+/*
+ * SETUP, RENDER LOOP & CLEANUP
+ */
+
+Midi midi;
+bool setup(BelaContext *context, void *userData)	{
+
+	/* HEAVY */
+
+	gHeavyContext = hv_bbb_new(context->audioSampleRate);
+
+	gHvInputChannels = hv_getNumInputChannels(gHeavyContext);
+	gHvOutputChannels = hv_getNumOutputChannels(gHeavyContext);
+
+	rt_printf("Starting Heavy context with %d input channels and %d output channels\n",
+			  gHvInputChannels, gHvOutputChannels);
+
+	if(gHvInputChannels != 0) {
+		gHvInputBuffers = (float *)calloc(gHvInputChannels * context->audioFrames,sizeof(float));
+	}
+	if(gHvOutputChannels != 0) {
+		gHvOutputBuffers = (float *)calloc(gHvOutputChannels * context->audioFrames,sizeof(float));
+	}
+
+	gInverseSampleRate = 1.0 / context->audioSampleRate;
+
+	// Set heavy print hook
+	hv_setPrintHook(gHeavyContext, &printHook);
+	// Set heavy send hook
+	hv_setSendHook(gHeavyContext, sendHook);
+
+	midi.readFrom(0);
+	midi.writeTo(0);
+	midi.enableParser(true);
+	return true;
+}
+
+
+void render(BelaContext *context, void *userData)
+{
+
+	// De-interleave the data
+	if(gHvInputBuffers != NULL) {
+		for(int n = 0; n < context->audioFrames; n++) {
+			for(int ch = 0; ch < gHvInputChannels; ch++) {
+				if(ch >= context->audioChannels+context->analogChannels) {
+					// THESE ARE PARAMETER INPUT 'CHANNELS' USED FOR ROUTING
+					// 'sensor' outputs from routing channels of dac~ are passed through here
+					break;
+				} else {
+					// If more than 2 ADC inputs are used in the pd patch, route the analog inputs
+					// i.e. ADC3->analogIn0 etc. (first two are always audio inputs)
+					if(ch >= context->audioChannels)	{
+						int m = n/2;
+						float mIn = context->analogIn[m*context->analogChannels + (ch-context->audioChannels)];
+						gHvInputBuffers[ch * context->audioFrames + n] = mIn;
+					} else {
+						gHvInputBuffers[ch * context->audioFrames + n] = context->audioIn[n * context->audioChannels + ch];
+					}
+				}
+			}
+		}
+	}
+
+	// replacement for bang~ object
+	//hv_vscheduleMessageForReceiver(gHeavyContext, "bbb_bang", 0.0f, "b");
+	{
+		int num;
+		unsigned int hvHashes[3];
+		hvHashes[0] = hv_stringToHash("bela_notein");
+		hvHashes[1] = hv_stringToHash("bela_ctlin");
+		hvHashes[2] = hv_stringToHash("bela_pgmin"); 
+		while((num = midi.getParser()->numAvailableMessages()) > 0){
+			static MidiChannelMessage message;
+			message = midi.getParser()->getNextChannelMessage();
+			switch(message.getType()){
+			case kmmNoteOn: {
+//					message.prettyPrint();
+					float noteNumber = message.getDataByte(0);
+					float velocity = message.getDataByte(1);
+					float channel = message.getChannel();
+//					rt_printf("message: noteNumber: %f, velocity: %f, channel: %f\n", noteNumber, velocity, channel);
+					hv_vscheduleMessageForReceiver(gHeavyContext, hvHashes[0], 0, "fff", noteNumber, velocity, channel);
+				}
+				break;
+			case kmmControlChange: {
+				hv_vscheduleMessageForReceiver(gHeavyContext, hvHashes[1], 0, "fff",
+						(float)message.getDataByte(1), (float)message.getDataByte(0), (float)message.getChannel());
+				}
+				break;
+			case kmmProgramChange:
+				hv_vscheduleMessageForReceiver(gHeavyContext, hvHashes[2], 0, "ff",
+						(float)message.getDataByte(0), (float)message.getChannel());
+				break;
+			}
+		}
+	}
+//	hv_sendFloatToReceiver(gHeavyContext, "notein", 1.123f);
+
+
+	hv_bbb_process_inline(gHeavyContext, gHvInputBuffers, gHvOutputBuffers, context->audioFrames);
+
+	// Interleave the output data
+	if(gHvOutputBuffers != NULL) {
+		for(int n = 0; n < context->audioFrames; n++) {
+
+			for(int ch = 0; ch < gHvOutputChannels; ch++) {
+				if(ch >= context->audioChannels+context->analogChannels) {
+					// THESE ARE SENSOR OUTPUT 'CHANNELS' USED FOR ROUTING
+					// they are the content of the 'sensor output' dac~ channels
+				} else {
+					if(ch >= context->audioChannels)	{
+						int m = n/2;
+						context->analogOut[m * context->analogFrames + (ch-context->audioChannels)] = constrain(gHvOutputBuffers[ch*context->audioFrames + n],0.0,1.0);
+					} else {
+						context->audioOut[n * context->audioChannels + ch] = gHvOutputBuffers[ch * context->audioFrames + n];
+					}
+				}
+			}
+		}
+	}
+
+}
+
+
+void cleanup(BelaContext *context, void *userData)
+{
+
+	hv_bbb_free(gHeavyContext);
+	if(gHvInputBuffers != NULL)
+		free(gHvInputBuffers);
+	if(gHvOutputBuffers != NULL)
+		free(gHvOutputBuffers);
+
+}
--- a/scripts/hvresources/render.cpp	Sun Jun 19 00:30:48 2016 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,185 +0,0 @@
-/*
- * render.cpp
- *
- *  Template render.cpp file for on-board heavy compiling
- *
- *  N.B. this is currently *not* compatible with foleyDesigner source files!
- *
- *  Created on: November 5, 2015
- *
- *  Christian Heinrichs
- *
- */
-
-#include <Bela.h>
-#include <Midi.h>
-#include <cmath>
-#include "Heavy_bbb.h"
-#include <string.h>
-#include <stdlib.h>
-#include <string.h>
-/*
- *	HEAVY CONTEXT & BUFFERS
- */
-
-Hv_bbb *gHeavyContext;
-float *gHvInputBuffers = NULL, *gHvOutputBuffers = NULL;
-int gHvInputChannels = 0, gHvOutputChannels = 0;
-
-float gInverseSampleRate;
-
-/*
- *	HEAVY FUNCTIONS
- */
-
-void printHook(double timestampSecs, const char *printLabel, const char *msgString, void *userData) {
-  printf("Message from Heavy patch: [@ %.3f] %s: %s\n", timestampSecs, printLabel, msgString);
-}
-
-static void sendHook(
-    double timestamp, // in milliseconds
-    const char *receiverName,
-    const HvMessage *const m,
-    void *userData) {
-
-  // only react to messages sent to receivers named "hello"
-  if (!strncmp(receiverName, "hello", 5)) {
-  }
-
-}
-
-/*
- * SETUP, RENDER LOOP & CLEANUP
- */
-
-Midi midi;
-bool setup(BelaContext *context, void *userData)	{
-
-	/* HEAVY */
-
-	gHeavyContext = hv_bbb_new(context->audioSampleRate);
-
-	gHvInputChannels = hv_getNumInputChannels(gHeavyContext);
-	gHvOutputChannels = hv_getNumOutputChannels(gHeavyContext);
-
-	rt_printf("Starting Heavy context with %d input channels and %d output channels\n",
-			  gHvInputChannels, gHvOutputChannels);
-
-	if(gHvInputChannels != 0) {
-		gHvInputBuffers = (float *)calloc(gHvInputChannels * context->audioFrames,sizeof(float));
-	}
-	if(gHvOutputChannels != 0) {
-		gHvOutputBuffers = (float *)calloc(gHvOutputChannels * context->audioFrames,sizeof(float));
-	}
-
-	gInverseSampleRate = 1.0 / context->audioSampleRate;
-
-	// Set heavy print hook
-	hv_setPrintHook(gHeavyContext, &printHook);
-	// Set heavy send hook
-	hv_setSendHook(gHeavyContext, sendHook);
-
-	midi.readFrom(0);
-	midi.writeTo(0);
-	midi.enableParser(true);
-	return true;
-}
-
-
-void render(BelaContext *context, void *userData)
-{
-
-	// De-interleave the data
-	if(gHvInputBuffers != NULL) {
-		for(int n = 0; n < context->audioFrames; n++) {
-			for(int ch = 0; ch < gHvInputChannels; ch++) {
-				if(ch >= context->audioChannels+context->analogChannels) {
-					// THESE ARE PARAMETER INPUT 'CHANNELS' USED FOR ROUTING
-					// 'sensor' outputs from routing channels of dac~ are passed through here
-					break;
-				} else {
-					// If more than 2 ADC inputs are used in the pd patch, route the analog inputs
-					// i.e. ADC3->analogIn0 etc. (first two are always audio inputs)
-					if(ch >= context->audioChannels)	{
-						int m = n/2;
-						float mIn = context->analogIn[m*context->analogChannels + (ch-context->audioChannels)];
-						gHvInputBuffers[ch * context->audioFrames + n] = mIn;
-					} else {
-						gHvInputBuffers[ch * context->audioFrames + n] = context->audioIn[n * context->audioChannels + ch];
-					}
-				}
-			}
-		}
-	}
-
-	// replacement for bang~ object
-	//hv_vscheduleMessageForReceiver(gHeavyContext, "bbb_bang", 0.0f, "b");
-	{
-		int num;
-		unsigned int hvHashes[3];
-		hvHashes[0] = hv_stringToHash("bela_notein");
-		hvHashes[1] = hv_stringToHash("bela_ctlin");
-		hvHashes[2] = hv_stringToHash("bela_pgmin"); 
-		while((num = midi.getParser()->numAvailableMessages()) > 0){
-			static MidiChannelMessage message;
-			message = midi.getParser()->getNextChannelMessage();
-			switch(message.getType()){
-			case kmmNoteOn: {
-//					message.prettyPrint();
-					float noteNumber = message.getDataByte(0);
-					float velocity = message.getDataByte(1);
-					float channel = message.getChannel();
-//					rt_printf("message: noteNumber: %f, velocity: %f, channel: %f\n", noteNumber, velocity, channel);
-					hv_vscheduleMessageForReceiver(gHeavyContext, hvHashes[0], 0, "fff", noteNumber, velocity, channel);
-				}
-				break;
-			case kmmControlChange: {
-				hv_vscheduleMessageForReceiver(gHeavyContext, hvHashes[1], 0, "fff",
-						(float)message.getDataByte(1), (float)message.getDataByte(0), (float)message.getChannel());
-				}
-				break;
-			case kmmProgramChange:
-				hv_vscheduleMessageForReceiver(gHeavyContext, hvHashes[2], 0, "ff",
-						(float)message.getDataByte(0), (float)message.getChannel());
-				break;
-			}
-		}
-	}
-//	hv_sendFloatToReceiver(gHeavyContext, "notein", 1.123f);
-
-
-	hv_bbb_process_inline(gHeavyContext, gHvInputBuffers, gHvOutputBuffers, context->audioFrames);
-
-	// Interleave the output data
-	if(gHvOutputBuffers != NULL) {
-		for(int n = 0; n < context->audioFrames; n++) {
-
-			for(int ch = 0; ch < gHvOutputChannels; ch++) {
-				if(ch >= context->audioChannels+context->analogChannels) {
-					// THESE ARE SENSOR OUTPUT 'CHANNELS' USED FOR ROUTING
-					// they are the content of the 'sensor output' dac~ channels
-				} else {
-					if(ch >= context->audioChannels)	{
-						int m = n/2;
-						context->analogOut[m * context->analogFrames + (ch-context->audioChannels)] = constrain(gHvOutputBuffers[ch*context->audioFrames + n],0.0,1.0);
-					} else {
-						context->audioOut[n * context->audioChannels + ch] = gHvOutputBuffers[ch * context->audioFrames + n];
-					}
-				}
-			}
-		}
-	}
-
-}
-
-
-void cleanup(BelaContext *context, void *userData)
-{
-
-	hv_bbb_free(gHeavyContext);
-	if(gHvInputBuffers != NULL)
-		free(gHvInputBuffers);
-	if(gHvOutputBuffers != NULL)
-		free(gHvOutputBuffers);
-
-}