changeset 235:3d41a6fa1830

Merge
author Giulio Moro <giuliomoro@yahoo.it>
date Sun, 10 Apr 2016 04:08:06 +0200
parents 869f5e703844 (current diff) 99b4d81d9c95 (diff)
children cb47043c8c28
files include/Scope.h projects/heavy/pd/hello-midi/hv_ctlin.pd projects/heavy/pd/hello-midi/hv_notein.pd projects/heavy/pd/hello-midi/hv_pgmin.pd
diffstat 36 files changed, 3138 insertions(+), 618 deletions(-) [+]
line wrap: on
line diff
--- a/.cproject	Sat Feb 13 01:51:01 2016 +0000
+++ b/.cproject	Sun Apr 10 04:08:06 2016 +0200
@@ -34,8 +34,11 @@
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/include"/>
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/ne10"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/BeagleRT/include}&quot;"/>
+									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/ne10/"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/"/>
 								</option>
-								<option id="gnu.cpp.compiler.option.other.other.1516989263" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -Wpointer-arith -Wunused-result -D_GNU_SOURCE -D_REENTRANT -D__XENO__" valueType="string"/>
+								<option id="gnu.cpp.compiler.option.other.other.1516989263" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -Wpointer-arith -Wunused-result -D_GNU_SOURCE -D_REENTRANT -D__XENO__ -fpermissive" valueType="string"/>
 								<option id="gnu.cpp.compiler.option.warnings.allwarn.1392851614" name="All warnings (-Wall)" superClass="gnu.cpp.compiler.option.warnings.allwarn" value="true" valueType="boolean"/>
 								<option id="gnu.cpp.compiler.option.dialect.std.904910934" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
 								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1166892316" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
@@ -48,7 +51,10 @@
 									<listOptionValue builtIn="false" value="/usr/xenomai/include"/>
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/include"/>
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/ne10"/>
+									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/BeagleRT/include}&quot;"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/ne10/"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/"/>
 								</option>
 								<option id="gnu.c.compiler.option.misc.other.835792865" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -Wpointer-arith -Wunused-result  -D_GNU_SOURCE -D_REENTRANT -D__XENO__ -std=gnu99" valueType="string"/>
 								<option id="gnu.c.compiler.option.warnings.allwarn.1145989346" name="All warnings (-Wall)" superClass="gnu.c.compiler.option.warnings.allwarn" value="true" valueType="boolean"/>
@@ -60,15 +66,19 @@
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/lib"/>
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/lib/xenomai"/>
 									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/xenomai/lib"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
 									<listOptionValue builtIn="false" value="/usr/lib/arm-linux-gnueabihf"/>
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/lib"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/lib"/>
 								</option>
 								<option id="gnu.cpp.link.option.libs.139390951" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
 									<listOptionValue builtIn="false" value="rt"/>
+									<listOptionValue builtIn="false" value="pd"/>
 									<listOptionValue builtIn="false" value="native"/>
 									<listOptionValue builtIn="false" value="xenomai"/>
+									<listOptionValue builtIn="false" value="sndfile"/>
 								</option>
-								<option id="gnu.cpp.link.option.flags.2096887116" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="-pthread -rdynamic" valueType="string"/>
+								<option id="gnu.cpp.link.option.flags.2096887116" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="-pthread -rdynamic -Wl,-unresolved-symbols=ignore-in-shared-libs" valueType="string"/>
 								<option id="gnu.cpp.link.option.userobjs.537608578" name="Other objects" superClass="gnu.cpp.link.option.userobjs" valueType="userObjs">
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/libprussdrv.a}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/libNE10.a}&quot;"/>
@@ -83,6 +93,9 @@
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/include"/>
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/ne10"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/BeagleRT/include}&quot;"/>
+									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/ne10/"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/"/>
 								</option>
 								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1788972942" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
 							</tool>
@@ -123,7 +136,7 @@
 					<sourceEntries>
 						<entry excluding="default_main.cpp|audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/audio_in_FFT"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_libpd"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/>
 					</sourceEntries>
 				</configuration>
@@ -149,7 +162,7 @@
 					<folderInfo id="cdt.managedbuild.config.gnu.exe.release.1521194538." name="/" resourcePath="">
 						<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.1612059942" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
 							<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.908983575" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
-							<builder arguments="-j6" buildPath="${workspace_loc:/BBB_audio+input/Release}" command="make" id="cdt.managedbuild.target.gnu.builder.exe.release.511190290" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
+							<builder buildPath="${workspace_loc:/BBB_audio+input/Release}" enabledIncrementalBuild="true" id="cdt.managedbuild.target.gnu.builder.exe.release.511190290" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="6" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
 							<tool command="arm-linux-gnueabihf-g++&#10;" id="cdt.managedbuild.tool.gnu.archiver.base.810674388" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
 							<tool command="arm-linux-gnueabihf-gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.163790048" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
 								<option id="gnu.cpp.compiler.exe.release.option.optimization.level.2031085570" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.more" valueType="enumerated"/>
@@ -161,9 +174,11 @@
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/include"/>
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/ne10"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/BeagleRT/include}&quot;"/>
+									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/"/>
 								</option>
 								<option id="gnu.cpp.compiler.option.dialect.std.776548502" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
-								<option id="gnu.cpp.compiler.option.other.other.398422461" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -U_FORTIFY_SOURCE" valueType="string"/>
+								<option id="gnu.cpp.compiler.option.other.other.398422461" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -U_FORTIFY_SOURCE -O3 -march=armv7-a -mtune=cortex-a8 -mfloat-abi=hard -mfpu=neon --fast-math -ftree-vectorize -ftree-vectorizer-verbose=10" valueType="string"/>
 								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.601059736" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
 							</tool>
 							<tool command="arm-linux-gnueabihf-gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.1302828968" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
@@ -176,28 +191,34 @@
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/ne10"/>
 									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/ne10/"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/BeagleRT/include}&quot;"/>
+									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/"/>
 								</option>
 								<option id="gnu.c.compiler.option.include.files.40806287" name="Include files (-include)" superClass="gnu.c.compiler.option.include.files"/>
 								<option id="gnu.c.compiler.option.preprocessor.undef.symbol.980935416" name="Undefined symbols (-U)" superClass="gnu.c.compiler.option.preprocessor.undef.symbol" valueType="undefDefinedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE"/>
 								</option>
+								<option id="gnu.c.compiler.option.misc.other.1568308112" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -O3 -march=armv7-a -mtune=cortex-a8 -mfloat-abi=hard -mfpu=neon --fast-math -ftree-vectorize -ftree-vectorizer-verbose=10" valueType="string"/>
 								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.574072828" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
 							</tool>
 							<tool command="arm-linux-gnueabihf-g++&#10;" id="cdt.managedbuild.tool.gnu.c.linker.exe.release.281634187" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
 							<tool command="arm-linux-gnueabihf-g++" id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.929570421" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
 								<option id="gnu.cpp.link.option.paths.277042583" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/lib"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/lib/xenomai"/>
 									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/xenomai/lib"/>
 									<listOptionValue builtIn="false" value="/usr/lib/arm-linux-gnueabihf"/>
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/lib"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/lib"/>
 								</option>
 								<option id="gnu.cpp.link.option.libs.1930118082" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
 									<listOptionValue builtIn="false" value="rt"/>
+									<listOptionValue builtIn="false" value="pd"/>
 									<listOptionValue builtIn="false" value="native"/>
 									<listOptionValue builtIn="false" value="xenomai"/>
 								</option>
-								<option id="gnu.cpp.link.option.flags.1308374111" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="-pthread -Wpointer-arith" valueType="string"/>
+								<option id="gnu.cpp.link.option.flags.1308374111" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="-pthread -Wpointer-arith -Wl,-unresolved-symbols=ignore-in-shared-libs" valueType="string"/>
 								<option id="gnu.cpp.link.option.userobjs.1473502069" name="Other objects" superClass="gnu.cpp.link.option.userobjs" valueType="userObjs">
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/libprussdrv.a}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/libNE10.a}&quot;"/>
@@ -210,6 +231,9 @@
 							<tool command="arm-linux-gnueabihf-as" id="cdt.managedbuild.tool.gnu.assembler.exe.release.2052985276" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
 								<option id="gnu.both.asm.option.include.paths.1499955275" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/BeagleRT/include}&quot;"/>
+									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/ne10/"/>
+									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/"/>
 								</option>
 								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1212659593" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
 							</tool>
@@ -240,7 +264,7 @@
 					<sourceEntries>
 						<entry excluding="default_main.cpp|audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/audio_in_FFT"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="projects/basic_libpd"/>
 						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/>
 					</sourceEntries>
 				</configuration>
@@ -252,23 +276,23 @@
 		<project id="BBB_audio+input.cdt.managedbuild.target.gnu.exe.1596461844" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
 	</storageModule>
 	<storageModule moduleId="refreshScope" versionNumber="2">
-		<configuration configurationName="Release">
-			<resource resourceType="PROJECT" workspacePath="/BBB_SimpleInstrument"/>
-		</configuration>
 		<configuration configurationName="basic">
 			<resource resourceType="PROJECT" workspacePath="/BeagleRT"/>
 		</configuration>
 		<configuration configurationName="Debug">
 			<resource resourceType="PROJECT" workspacePath="/BBB_SimpleInstrument"/>
 		</configuration>
+		<configuration configurationName="Release">
+			<resource resourceType="PROJECT" workspacePath="/BBB_SimpleInstrument"/>
+		</configuration>
 	</storageModule>
 	<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
 	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
 	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
 	<storageModule moduleId="scannerConfiguration">
 		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1521194538;cdt.managedbuild.config.gnu.exe.release.1521194538.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.163790048;cdt.managedbuild.tool.gnu.cpp.compiler.input.601059736">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1521194538;cdt.managedbuild.config.gnu.exe.release.1521194538.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1302828968;cdt.managedbuild.tool.gnu.c.compiler.input.574072828">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
 		</scannerConfigBuildInfo>
 		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.528876549;cdt.managedbuild.config.gnu.exe.debug.528876549.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.2030825480;cdt.managedbuild.tool.gnu.cpp.compiler.input.1166892316">
 			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
@@ -276,8 +300,8 @@
 		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.528876549;cdt.managedbuild.config.gnu.exe.debug.528876549.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.917207395;cdt.managedbuild.tool.gnu.c.compiler.input.308014221">
 			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
 		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1521194538;cdt.managedbuild.config.gnu.exe.release.1521194538.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1302828968;cdt.managedbuild.tool.gnu.c.compiler.input.574072828">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1521194538;cdt.managedbuild.config.gnu.exe.release.1521194538.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.163790048;cdt.managedbuild.tool.gnu.cpp.compiler.input.601059736">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
 		</scannerConfigBuildInfo>
 	</storageModule>
 </cproject>
--- a/Makefile	Sat Feb 13 01:51:01 2016 +0000
+++ b/Makefile	Sun Apr 10 04:08:06 2016 +0200
@@ -8,7 +8,7 @@
 
 RM := rm -rf
 STATIC_LIBS := ./libprussdrv.a ./libNE10.a
-LIBS := -lrt -lnative -lxenomai -lsndfile
+LIBS := -lrt -lnative -lxenomai -lsndfile -lpd 
 
 INCLUDES := -I./include -I/usr/include/ne10 -I/usr/xenomai/include -I/usr/arm-linux-gnueabihf/include/xenomai/include -I/usr/arm-linux-gnueabihf/include/ne10
 
@@ -36,8 +36,8 @@
 DEFAULT_MAIN_OBJS := ./build/core/default_main.o
 DEFAULT_MAIN_CPP_DEPS := ./build/core/default_main.d
 
-CPP_FLAGS=-O2
-C_FLAGS=-O2
+CPP_FLAGS=-O3 -march=armv7-a -mtune=cortex-a8 -mfloat-abi=hard -mfpu=neon --fast-math -ftree-vectorize 
+C_FLAGS=-O3 -march=armv7-a -mtune=cortex-a8 -mfloat-abi=hard -mfpu=neon --fast-math -ftree-vectorize 
 
 # all = build BeagleRT 
 all: SYNTAX_FLAG :=
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/IirFilter.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,69 @@
+/*
+ * IirFilter.cpp
+ *
+ *  Created on: 17 Sep 2015
+ *      Author: giulio
+ */
+#include "IirFilter.h"
+
+IirFilterStage::IirFilterStage(){
+	for(int n = 0; n < IIR_FILTER_STAGE_COEFFICIENTS; n++){
+		coefficients[n] = 0;
+	}
+	for(int n = 0; n < IIR_FILTER_STAGE_STATES; n++){
+		states[n]=0;
+	}
+}
+void IirFilterStage::setCoefficients(double* newCoefficients){
+	for(int n = 0; n < IIR_FILTER_STAGE_COEFFICIENTS; n++){
+		coefficients[n] = newCoefficients[n];
+	}
+}
+void IirFilterStage::setStates(double* newStates){
+	for(int n = 0; n < IIR_FILTER_STAGE_STATES; n++){
+		states[n] = newStates[n];
+	}
+}
+
+/*	struct IirFilterStage* stages;
+	int numberOfStages;
+*/
+IirFilter::IirFilter(){
+	stages=(IirFilterStage**)0;
+	setNumberOfStages(0);
+}
+IirFilter::IirFilter(int newNumberOfStages){
+	setNumberOfStages(newNumberOfStages);
+}
+IirFilter::IirFilter(int newNumberOfStages, double* newCoefficients){
+	setNumberOfStages(newNumberOfStages);
+	setCoefficients(newCoefficients);
+}
+void IirFilter::dealloc(){
+	if( stages == 0 )
+		return;
+	for(int n = 0; n < numberOfStages; n++){
+		delete stages[n];
+	}
+	delete stages;
+	stages = 0;
+	numberOfStages = 0;
+}
+void IirFilter::setCoefficients(double* newCoefficients){
+	for(int n = 0; n < numberOfStages; n++){
+		stages[n]->setCoefficients(newCoefficients);
+	}
+};
+void IirFilter::setStates(double* newStates){
+	for(int n = 0; n < numberOfStages; n++){
+			stages[n]->setStates(newStates);
+	}
+};
+void IirFilter::setNumberOfStages(int newNumberOfStages){
+	dealloc();
+	numberOfStages=newNumberOfStages;
+	stages = new IirFilterStage*[numberOfStages];
+	for( int n = 0; n < numberOfStages; n++){
+		stages[n] = new IirFilterStage;
+	}
+}
--- a/core/Midi.cpp	Sat Feb 13 01:51:01 2016 +0000
+++ b/core/Midi.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -58,6 +58,11 @@
 			messages[writePointer].setDataByte(elapsedDataBytes, input[n]);
 			elapsedDataBytes++;
 			if(elapsedDataBytes == messages[writePointer].getNumDataBytes()){
+				// done with the current message
+				// call the callback if available
+				if(isCallbackEnabled() == true){
+					messageReadyCallback(getNextChannelMessage(), callbackArg);
+				}
 				waitingForStatus = true;
 				writePointer++;
 				if(writePointer == messages.size()){
@@ -66,6 +71,7 @@
 			}
 		}
 	}
+
 	return consumedBytes;
 };
 
@@ -104,14 +110,12 @@
 }
 
 void Midi::midiInputLoop(){
-	printf("Midi input loop %d\n", objAddrs[kMidiInput].size());
 	for(unsigned int n = 0; n < objAddrs[kMidiInput].size(); n++){
 		objAddrs[kMidiInput][n] -> readInputLoop();
 	}
 }
 
 void Midi::midiOutputLoop(){
-	printf("Midi output loop %d\n", objAddrs[kMidiOutput].size());
 	for(unsigned int n = 0; n < objAddrs[kMidiOutput].size(); n++){
 		objAddrs[kMidiOutput][n] -> writeOutputLoop();
 	}
@@ -132,6 +136,7 @@
 		if(inputBytesWritePointer == inputBytes.size()){ //wrap pointer around
 			inputBytesWritePointer = 0;
 		}
+
 		if(parserEnabled == true && ret > 0){ // if the parser is enabled and there is new data, send the data to it
 			int input;
 			while((input=_getInput()) >= 0){
@@ -168,10 +173,9 @@
 	objAddrs[kMidiInput].push_back(this);
 	inputPort = open("/dev/midi1", O_RDONLY | O_NONBLOCK | O_NOCTTY);
 	if(inputPort < 0){
-		printf("Error occurred while opening midi input port %d: %d", port, inputPort);
 		return -1;
 	} else {
-		printf("Reading from port %d\n", port);
+		printf("Reading from Midi port %d\n", port);
 		BeagleRT_scheduleAuxiliaryTask(midiInputTask);
 		return 1;
 	}
@@ -181,7 +185,6 @@
 	objAddrs[kMidiOutput].push_back(this);
 	outputPort = open("/dev/midi1", O_WRONLY, 0);
 	if(outputPort < 0){
-		printf("Error occurred while opening midi output port %d: %d", port, outputPort);
 		return -1;
 	} else {
 		printf("Writing to Midi port %d\n", port);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/NetworkSend.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,257 @@
+#include "NetworkSend.h"
+
+#ifdef USE_JUCE
+#else
+//initialize the static members of NetworkSend
+bool NetworkSend::staticConstructed=false;
+int NetworkSend::sleepTimeMs;
+bool NetworkSend::threadIsExiting;
+bool NetworkSend::threadRunning;
+std::vector<NetworkSend*> NetworkSend::objAddrs(0);
+AuxiliaryTask NetworkSend::sendDataTask=NULL;
+
+void sendData(){
+	NetworkSend::run();
+}
+void NetworkSend::staticConstructor(){
+	if(staticConstructed==true)
+		return;
+	staticConstructed=true;
+	threadIsExiting=false;
+	threadRunning=false;
+	sendDataTask = BeagleRT_createAuxiliaryTask(::sendData, 95, "sendDataTask"); //TODO: allow variable priority
+}
+void NetworkSend::sendAllData(){
+	for(unsigned int n=0; n<NetworkSend::objAddrs.size(); n++){
+		NetworkSend::objAddrs[n]->sendData();
+	}
+}
+int NetworkSend::getNumInstances(){
+	return objAddrs.size();
+}
+void NetworkSend::startThread(){
+	BeagleRT_scheduleAuxiliaryTask(sendDataTask);
+}
+void NetworkSend::stopThread(){
+	threadIsExiting=true;
+}
+bool NetworkSend::threadShouldExit(){
+	return(gShouldStop || threadIsExiting);
+}
+bool NetworkSend::isThreadRunning(){
+	return threadRunning;
+}
+#endif /* USE_JUCE */
+
+#ifdef USE_JUCE
+NetworkSend::NetworkSend(const String &threadName):
+		Thread(threadName)
+#else
+NetworkSend::NetworkSend()
+#endif /* USE_JUCE */
+{
+	channel.buffers=NULL;
+	channel.doneOnTime=NULL;
+	channel.readyToBeSent=NULL;
+	channel.enabled=false;
+	sleepTimeMs=2; //This should actually be initialized in the staticConstructor for non-Juce code, but doing it here makes it more portable
+	channel.sampleCount=0;
+}
+
+NetworkSend::~NetworkSend(){
+#ifdef USE_JUCE
+	stopThread(1000);
+#else
+	stopThread();
+	for(unsigned int n=0; n<objAddrs.size(); n++){ //keep track of deleted instances;
+		if(objAddrs[n]==this){
+			objAddrs.erase(objAddrs.begin()+n);
+			break;
+		}
+	}
+#endif
+	dealloc();
+}
+void NetworkSend::dealloc(){
+	channel.enabled=false;
+	if(channel.buffers!=NULL){
+		for(int n=0; n<channel.numBuffers; n++){
+			free(channel.buffers[n]);
+			channel.buffers[n]=NULL;
+		}
+		free(channel.buffers);
+		channel.buffers=NULL;
+	}
+	free(channel.readyToBeSent);
+	channel.readyToBeSent=NULL;
+	free(channel.doneOnTime);
+	channel.doneOnTime=NULL;
+}
+void NetworkSend::cleanup(){
+	dealloc();
+}
+
+void NetworkSend::setup(float aSampleRate, int blockSize, int aChannelNumber, int aPort, const char *aServer){
+#ifdef USE_JUCE
+#else
+	staticConstructor(); //FIXME: ideally this should be in the constructor, but this is not currently possible
+						//because of limitations in BeagleRT_createAuxiliaryTask()
+	//keep track of added active instances
+	objAddrs.push_back(this);//TODO: this line should be in the constructor, but something weird happens if
+	// an instance of NetworkSend is then declared globally: the constructor gets called,
+	// and objAddrs.size()==1 but when you get to setup, objAddrs.size() has reverted back to 0, without
+	// any destructor being called in between ... Have a look here
+	// http://stackoverflow.com/questions/7542054/global-vector-emptying-itself-between-calls .
+	// and maybe use accessor function instead of global, as was done in #1374
+#endif /* USE_JUCE */
+	cleanup();
+	int numSamples=blockSize*4>4*channel.bufferLength ? blockSize*4 : 4*channel.bufferLength;
+	channel.numBuffers= (1+numSamples/channel.bufferLength) * 3; //the +1 takes the ceil() of the division
+	channel.buffers=(float**)malloc(channel.numBuffers*sizeof(float*));
+	printf("NumBuffers: %d\n", channel.numBuffers);
+	if(channel.buffers==NULL)
+		return;
+	for(int n=0; n<channel.numBuffers; n++){
+		channel.buffers[n]=(float*)malloc(channel.bufferLength*sizeof(float));
+		if(channel.buffers[n]==NULL)
+			return;
+	}
+	channel.readyToBeSent=(bool*)malloc(channel.numBuffers*sizeof(bool));
+	channel.doneOnTime=(bool*)malloc(channel.numBuffers*sizeof(bool));
+	for(int n=0; n<channel.numBuffers; n++){
+		channel.readyToBeSent[n]=false;
+		channel.doneOnTime[n]=true;
+	}
+	if(channel.readyToBeSent==NULL || channel.doneOnTime==NULL)
+		return;
+	channel.writePointer=channel.headerLength;
+	channel.writeBuffer=0;
+	channel.readBuffer=0;
+	setChannelNumber(aChannelNumber);
+	setPort(aPort); //TODO: check for the return value
+	setServer(aServer); //TODO: check for the return value
+	printf("Channel %d is sending messages to: %s:%d at %fHz\n", getChannelNumber(), aServer, aPort, aSampleRate);
+	channel.enabled=true;
+}
+
+void NetworkSend::log(float value){ //TODO: add a vectorized version of this method
+	if(channel.enabled==false)
+		return;
+	if(channel.writePointer==channel.bufferLength){ // when the buffer is filled ...
+		channel.readyToBeSent[channel.writeBuffer]=true; // flag it as such
+//		printf("Scheduling for send %d\n",(int)channel.buffers[channel.writeBuffer][channel.headerTimestampIndex]);
+		channel.writePointer=channel.headerLength; //reset the writePointer
+		channel.writeBuffer=(channel.writeBuffer+1); //switch buffer
+		if(channel.writeBuffer==channel.numBuffers) // and wrap it
+            channel.writeBuffer=0;
+//		printf("WriteBuffer:%d\n", channel.writeBuffer);
+		if(channel.doneOnTime[channel.writeBuffer]==false){ //check if this buffer's last sending has completed on time ...
+			printf("NetworkSend buffer underrun. timestamp: %d :-{\n",
+					(int)channel.buffers[channel.writeBuffer][channel.headerTimestampIndex]);
+		}
+		channel.doneOnTime[channel.writeBuffer]=false; // ... and then reset the flag
+#ifdef USE_JUCE
+		if(isThreadRunning()==false){
+			startThread(10);
+		}
+#else
+		if(isThreadRunning()==false){
+			startThread();
+		}
+#endif /* USE_JUCE */
+	}
+	if(channel.writePointer==channel.headerLength){ // we are about to start writing in the buffer, let's set the header
+		//set dynamic header values here. Static values are set in setup() and setChannelNumber().
+		channel.buffers[channel.writeBuffer][channel.headerTimestampIndex]=(float)channel.sampleCount; //timestamp
+		channel.sampleCount++;
+		//add here more header fields
+	}
+    channel.buffers[channel.writeBuffer][channel.writePointer++]=value;
+//	sampleCount++;
+};
+
+void NetworkSend::setServer(const char *aServer){
+#ifdef USE_JUCE
+	remoteHostname=String::fromUTF8(aServer);
+#else
+	udpClient.setServer(aServer);
+#endif /* USE_JUCE */
+}
+void NetworkSend::setPort(int aPort){
+#ifdef USE_JUCE
+	remotePortNumber=aPort;
+#else
+	udpClient.setPort(aPort);
+#endif /* USE_JUCE */
+}
+
+void NetworkSend::setChannelNumber(int aChannelNumber){
+	channel.channelNumber=aChannelNumber;
+	for(int n=0; n < channel.numBuffers; n++){ //initialize the header
+		channel.buffers[n][channel.headerChannelIndex]=channel.channelNumber;
+		//add here more static header fields
+	}
+};
+int NetworkSend::getChannelNumber(){
+	return channel.channelNumber;
+};
+
+int NetworkSend::getTimestamp(){
+	return channel.buffers[channel.readBuffer][channel.headerTimestampIndex];
+}
+
+void NetworkSend::sendData(){
+	if(channel.enabled==false)
+		return;
+	while(channel.readyToBeSent[channel.readBuffer]==true){
+		channel.readyToBeSent[channel.readBuffer]=false;
+		void* sourceBuffer=channel.buffers[channel.readBuffer];
+//		printf("Trying to send timestamp %d\n",(int)((float*)sourceBuffer)[channel.headerTimestampIndex]);
+//		printf("ReadBuffer:%d\n", channel.readBuffer);
+		unsigned int numBytesToSend=NETWORK_AUDIO_BUFFER_SIZE*sizeof(float);
+		//TODO: call waitUntilReady before trying to write/send, to avoid blocks! (OR NOT?)
+#ifdef USE_JUCE
+		if(1==udpClient.waitUntilReady(0, 5)){
+			udpClient.write(remoteHostname, remotePortNumber, sourceBuffer, numBytesToSend);
+			channel.doneOnTime[channel.readBuffer]=true;
+			//  printf ("Sent timestamp: %d\n", (int)((float*)sourceBuffer)[1]);
+		} else {
+			//  printf ("Not ready timestamp: %d\n", (int)((float*)sourceBuffer)[1]);
+		}
+#else
+		udpClient.send(sourceBuffer, numBytesToSend);
+//		printf("sent sourceBuffer: %d, channel: %f, timestamp: %f\n", channel.readBuffer, channel.buffers[channel.readBuffer][0],
+//				channel.buffers[channel.readBuffer][1]);
+		channel.doneOnTime[channel.readBuffer]=true;
+#endif /* USE_JUCE */
+		channel.readBuffer++;
+		if(channel.readBuffer==channel.numBuffers)
+			channel.readBuffer=0;
+	}
+}
+
+void NetworkSend::run(){
+#ifdef USE_JUCE
+	//  std::chrono::high_resolution_clock::time_point t1;
+    //  std::chrono::high_resolution_clock::time_point t2;
+    //  std::chrono::high_resolution_clock::time_point t3;
+	while(threadShouldExit()==false){
+		//  t3 = std::chrono::high_resolution_clock::now();
+		//  t1 = std::chrono::high_resolution_clock::now();
+		sendData();
+		//  t2 = std::chrono::high_resolution_clock::now();
+		//  auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>( t3 - t1 ).count();
+		//  auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();
+		//  if(duration2>0)
+			//  std::cout << "Duration is: " << duration2 <<". Whole loop is: " << duration1 << "\n"; 
+		usleep(1000);
+	}
+#else
+	threadRunning=true;
+	while(threadShouldExit()==false){
+		sendAllData();
+		usleep(sleepTimeMs*1000);
+	}
+	threadRunning=false;
+#endif
+}
--- a/core/PRU.cpp	Sat Feb 13 01:51:01 2016 +0000
+++ b/core/PRU.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -99,7 +99,7 @@
 const unsigned int PRU::kPruGPIOTestPin2 = 31;	// GPIO0(31); P9-13
 const unsigned int PRU::kPruGPIOTestPin3 = 26;	// GPIO0(26); P8-14
 
-extern bool gShouldStop;
+extern int gShouldStop;
 extern int gRTAudioVerbose;
 
 // Constructor: specify a PRU number (0 or 1)
@@ -561,12 +561,12 @@
 		// Convert short (16-bit) samples to float
 		// TODO: NEON
 		for(unsigned int n = 0; n < 2 * context->audioFrames; n++)
-			context->audioIn[n] = (float)pru_buffer_audio_adc[n + pru_audio_offset] / 32768.0;
+			context->audioIn[n] = (float)pru_buffer_audio_adc[n + pru_audio_offset] / 32768.0f;
 
 		if(analog_enabled) {
 			// TODO: NEON
 			for(unsigned int n = 0; n < context->analogChannels * context->analogFrames; n++)
-				context->analogIn[n] = (float)pru_buffer_spi_adc[n + pru_spi_offset] / 65536.0;
+				context->analogIn[n] = (float)pru_buffer_spi_adc[n + pru_spi_offset] / 65536.0f;
 
 			if(context->flags & BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST) {
 				// Initialize the output buffer with the values that were in the last frame of the previous output
@@ -614,7 +614,7 @@
 
 			// Convert float back to short for SPI output
 			for(unsigned int n = 0; n < context->analogChannels * context->analogFrames; n++) {
-				int out = context->analogOut[n] * 65536.0;
+				int out = context->analogOut[n] * 65536.0f;
 				if(out < 0) out = 0;
 				else if(out > 65535) out = 65535;
 				pru_buffer_spi_dac[n + pru_spi_offset] = (uint16_t)out;
@@ -630,7 +630,7 @@
         // Convert float back to short for audio
 		// TODO: NEON
 		for(unsigned int n = 0; n < 2 * context->audioFrames; n++) {
-			int out = context->audioOut[n] * 32768.0;
+			int out = context->audioOut[n] * 32768.0f;
 			if(out < -32768) out = -32768;
 			else if(out > 32767) out = 32767;
 			pru_buffer_audio_dac[n + pru_audio_offset] = (int16_t)out;
--- a/core/RTAudio.cpp	Sat Feb 13 01:51:01 2016 +0000
+++ b/core/RTAudio.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -64,7 +64,7 @@
 }
 
 // Flag which tells the audio task to stop
-bool gShouldStop = false;
+int gShouldStop = false;
 
 // general settings
 char gPRUFilename[MAX_PRU_FILENAME_LENGTH];		// Path to PRU binary file (internal code if empty)_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/ReceiveAudioThread.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,313 @@
+#include "ReceiveAudioThread.h"
+
+#ifdef USE_JUCE
+#else
+//initialise static members
+bool ReceiveAudioThread::staticConstructed=false;
+AuxiliaryTask ReceiveAudioThread::receiveDataTask=NULL;
+std::vector<ReceiveAudioThread *> ReceiveAudioThread::objAddrs(0);
+bool ReceiveAudioThread::threadRunning;
+bool ReceiveAudioThread::threadIsExiting;
+int ReceiveAudioThread::sleepTime;
+
+void receiveData(){
+	ReceiveAudioThread::run();
+}
+void ReceiveAudioThread::staticConstructor(){
+	if(staticConstructed==true)
+		return;
+	staticConstructed=true;
+    threadIsExiting=false;
+	receiveDataTask=BeagleRT_createAuxiliaryTask(receiveData, 90, "receiveDataTask"); //TODO: allow different priorities
+}
+#endif /* USE_JUCE */
+
+void ReceiveAudioThread::dealloc(){
+    free(buffer);
+    buffer=NULL;
+    free(stackBuffer);
+    stackBuffer=NULL;
+}
+void ReceiveAudioThread::wrapWritePointer(){
+    //this is not quite a simple wrapping as you would do in a circular buffer,
+    //as there is no guarantee the buffer will be full at all times, given that there must alwas be enough space at the end of it
+    //to hold a full payload
+    // lastValidPointer indicates the last pointer in the buffer containing valid data
+    //
+    if(writePointer+payloadLength+headerLength>bufferLength){ //if we are going to exceed the length of the buffer with the next reading
+        //  lastValidPointer=writePointer+headerLength; //remember where the last valid data are
+        //  for(int n=headerLength;n<lastValidPointer; n++){
+            //  fprintf(fd2, "%f\n",buffer[n]); //DEBUG
+        //  }
+    	writePointer=0; //and reset to beginning of the buffer
+    }
+}
+void ReceiveAudioThread::pushPayload(int startIndex){ //backup the payload samples that will be overwritten by the new header
+    for(int n=0; n<headerLength; n++){
+        stackBuffer[n]=buffer[startIndex+n];
+    }
+}
+void ReceiveAudioThread::popPayload(int startIndex){
+    for(int n=0; n<headerLength; n++){
+        buffer[startIndex+n]=stackBuffer[n];
+    }        
+}
+
+int ReceiveAudioThread::readUdpToBuffer(){
+
+	if(listening==false || bufferReady==false)
+        return 0;
+    if(writePointer<0)
+        return 0;
+    if(socket.waitUntilReady(true, waitForSocketTime)){// TODO: if waitForSocketTime here is >>5, the
+    	// destructor (always or sometimes) never actually gets called, despite run() returns ...see issue #1381
+#ifdef USE_JUCE
+#else
+		lastTime=rt_timer_read();
+//        rt_printf("lastTimeread= %llu\n", lastTime);
+#endif /* USE_JUCE */
+        pushPayload(writePointer); //backup headerLength samples. This could be skipped if writePointer==0
+        //read header+payload
+        int numBytes=socket.read(buffer+writePointer, bytesToRead, true); //read without waiting.
+            //TODO: (if using variable-length payload) validate the actual numBytes read against the size declared in the header
+        if(numBytes<0){
+            printf("error numBytes1\n");
+            return -3; //TODO: something went wrong, you have to discard the rest of the packet!
+        }
+        if(numBytes==0){//TODO: this should not happen unless you actually receive a packet of size zero (is it at all possible?)
+//        	printf("received 0 bytes\n");
+        	return 0;
+        }
+        if(numBytes != bytesToRead){ //this is equivalent to (numBytes<bytesToRead)
+            printf("error numBytes2: %d\n", numBytes);
+            return -4; //TODO: something went wrong, less bytes than expected in the payload.
+        }
+        if(channel!=(int)buffer[writePointer]){
+//        	printf("I am channel %d, but I received data for channel %d\n", channel, (int)buffer[writePointer]);
+        	return -5;
+        }
+        if(buffer[writePointer+1]!=timestamp+1)
+        	printf("missing a timestamp: %d\n",timestamp+1);
+        timestamp=buffer[writePointer+1];
+//        rt_printf("Received a message of length %d, it was on channel %d and timestamp %d\n", numBytes, (int)buffer[writePointer], (int)buffer[writePointer+1]);
+
+        popPayload(writePointer); //restore headerLength payload samples. This could be skipped if writePointer==0
+        //even though we just wrote (payloadLength+headerLength) samples in the buffer,
+        //we only increment by payloadLength. This way, next time a socket.read is performed, we will
+        //backup the last headerLength samples that we just wrote and we will overwrite them with
+        //the header from the new read. After parsing the header we will then restore the backed up samples.
+        //This way we guarantee that, apart from the first headerLength samples, buffer is a circular buffer!
+        writePointer+=payloadLength;
+        wrapWritePointer();
+        return numBytes;
+    }
+    return 0; //timeout occurred
+}
+//USE_JUCE    Thread(threadName),
+#ifdef USE_JUCE
+ReceiveAudioThread::ReceiveAudioThread(const String &threadName) :
+			Thread(threadName),
+#else
+ReceiveAudioThread::ReceiveAudioThread() :
+#endif /* USE_JUCE */
+	socket(0),
+    listening(false),
+    bufferReady(false),
+    buffer(NULL),
+    stackBuffer(NULL),
+    bufferLength(0),
+    lastValidPointer(0),
+    waitForSocketTime(5),
+#ifdef USE_JUCE
+    threadPriority(5)
+#else
+    threadPriority(88)
+#endif /* USE_JUCE */
+{};
+ReceiveAudioThread::~ReceiveAudioThread(){
+#ifdef USE_JUCE
+	stopThread(1000);
+#else
+	stopThread();
+	while(threadRunning){
+		usleep(sleepTime*2);	//wait for thread to stop
+		std::cout<< "Waiting for receiveAudioTask to stop" << std::endl;
+	}
+#endif /* USE_JUCE */
+	//TODO: check if thread stopped, otherwise kill it before dealloc
+    dealloc();
+}
+void ReceiveAudioThread::init(int aPort, int aSamplesPerBlock, int aChannel){
+  dealloc();
+#ifdef USE_JUCE
+#else
+  staticConstructor();
+  objAddrs.push_back(this);//TODO: this line should be in the constructor
+#endif /* USE_JUCE */
+  bindToPort(aPort);
+  channel=aChannel;
+  printf("Channel %d is receiving on port %d\n",aChannel, aPort);
+  //  fd=fopen("output.m","w"); //DEBUG
+  //  fprintf(fd,"var=["); //DEBUG
+  headerLength=2;
+  payloadLength=300; //TODO: make sure that payloadLength and headerLength are the same as the client is sending.
+  bufferLength=10 * std::max(headerLength+(payloadLength*4), headerLength+(aSamplesPerBlock*4)); //there are many considerations that can be done here ...
+                      //We keep a headerLength padding at the beginning of the array to allow full reads from the socket
+  buffer=(float*)malloc(sizeof(float)*bufferLength);
+  if(buffer==NULL) // something wrong
+    return;
+  lastValidPointer=headerLength+ ((bufferLength-headerLength)/payloadLength)*payloadLength;
+  memset(buffer,0,bufferLength*sizeof(float));
+  stackBuffer=(float*)malloc(sizeof(float)*headerLength);
+  if(stackBuffer==NULL) // something wrong
+      return;
+  bufferReady=true;
+  bytesToRead=sizeof(float)*(payloadLength + headerLength);
+  writePointer=-1;
+  readPointer=0;
+  sleepTime=payloadLength/(float)44100 /4.0; //set sleepTime so that you do not check too often or too infrequently
+  timestamp=0;
+#ifdef USE_JUCE
+  startThread(threadPriority);
+#else
+  //TODO: the thread cannot be started here at the moment because init() is called in setup(), where tasks cannot be scheduled
+#endif /* USE_JUCE */
+}
+
+void ReceiveAudioThread::bindToPort(int aPort){
+    listening=socket.bindToPort(aPort);
+#ifdef USE_JUCE
+#else
+    if(listening==false) //this condition is valid also for USE_JUCE, but we do not printf in USE_JUCE
+    	printf("Could not bind to port %d\n",aPort);
+#endif /* USE_JUCE */
+}
+bool ReceiveAudioThread::isListening(){
+    return listening;
+}
+float* ReceiveAudioThread::getCurrentBuffer(int length){ // NOTE: this cannot work all the time unless samplesPerBuffer and payloadLength are multiples
+    //TODO: make it return the number of samples actually available at the specified location
+    if(isListening()==false || length>bufferLength)
+        return NULL;
+    readPointer+=length;
+    if(readPointer>lastValidPointer){
+        readPointer=headerLength;
+    }
+    return buffer+(int)readPointer;
+};
+int ReceiveAudioThread::getSamplesSrc(float *destination, int length,
+		float samplingRateRatio, int numChannelsInDestination,
+		int channelToWriteTo)
+{
+    if (!(samplingRateRatio>0 && samplingRateRatio<=2))
+        return -2;
+    if(isListening()==false)
+        return -1;
+    static int numCalls=0;
+    if(writePointer<0 /*|| (numCalls&16383)==0*/){ //if writePointer has not been initalized yet ...
+#ifdef USE_JUCE
+#else //debug
+    	readPointer = headerLength;
+#endif /* USE_JUCE */
+    	// this cumbersome line means: start writing at a position which is as close as possible
+    	// to the center of the buffer, but still is aligned to (payloadLength*x)+headerLength
+    	// thus allowing buffering to allow clock drift to go either way
+        writePointer = headerLength + ((bufferLength-headerLength)/payloadLength/2)*payloadLength;
+                            // This will help keeping them in sync.
+                            //TODO: handle what happens when the remote stream is interrupted and then restarted
+        printf("write pointer inited at: %d\n", writePointer);
+    }
+    numCalls++;
+    if(length>lastValidPointer) { 
+        //not enough samples available, we fill the buffer with what is available, but the destination buffer will not be filled completely
+        //at this very moment the other thread might be writing at most one payload into the buffer.
+        //To avoid a race condition, we need to let alone the buffer where we are currently writing
+        //as writing the payload also temporarily overwrites the previous headerLength samples, we need to account for them as well
+        //TODO: This assumes that the writePointer and readPointer do not drift. When doing clock synchronization we will find out that it is not true!
+        length=lastValidPointer-payloadLength-headerLength;
+        if(length<0) //no samples available at all! 
+            return 0;
+    }
+    for(int n=0; n<length; n++){
+        destination[n*numChannelsInDestination+channelToWriteTo]=buffer[(int)(0.5+readPointer)];//simple ZOH non-interpolation (nearest neighbour)
+        //  fprintf(fd,"%f, %d, %f;\n",readPointer,writePointer,destination[n]); //DEBUG
+        readPointer+=samplingRateRatio;
+        if((int)(0.5+readPointer)>=lastValidPointer){
+            readPointer=readPointer-lastValidPointer+headerLength;
+        }
+    }
+    return length;
+}
+int ReceiveAudioThread::getSamplesSrc(float *destination, int length, float samplingRateRatio){
+	return getSamplesSrc(destination, length, samplingRateRatio, 1,0);
+	// TODO: rewriting this so that it does not call the override method we can save a multiply and add
+	// for each sample.
+}
+bool ReceiveAudioThread::isBufferReady(){
+    return bufferReady;
+}
+#ifdef USE_JUCE
+#else
+void ReceiveAudioThread::startThread(){
+	BeagleRT_scheduleAuxiliaryTask(receiveDataTask);
+}
+void ReceiveAudioThread::stopThread(){
+	threadIsExiting=true;
+}
+bool ReceiveAudioThread::threadShouldExit(){
+	return(gShouldStop || threadIsExiting );
+}
+RTIME ReceiveAudioThread::getLastTime(){
+	return lastTime;
+}
+#endif /* USE_JUCE */
+int ReceiveAudioThread::getTimestamp(){
+	return timestamp;
+}
+void ReceiveAudioThread::run(){
+    //  fd2=fopen("buffer.m","w"); //DEBUG
+    //  fprintf(fd2, "buf=["); //DEBUG
+	threadRunning=true;
+	int maxCount=10;
+	int count=0;
+	// Clean the socket from anything that is currently in it.
+#ifdef USE_JUCE
+	// this is borrowed from BeagleRT's UdpServer class.
+	int n;
+	do {
+		float waste;
+		if(socket.waitUntilReady(true, 0)==0)
+			break;
+		n=socket.read((void*)&waste, sizeof(float), false);
+		count++;
+		if(n<0){
+			printf("error\n");
+			break;
+		}
+		printf("n: %d\n",n);
+	} while (n>0 && (maxCount<=0 || count<maxCount));
+#else
+	for(unsigned int n=0; n<objAddrs.size(); n++){
+		count=objAddrs[n]->socket.empty(maxCount);
+	}
+#endif /* USE_JUCE */
+	printf("socket emptied with %d reads\n", count);
+
+    while(!threadShouldExit()){ //TODO: check that the socket buffer is empty before starting
+#ifdef USE_JUCE
+        readUdpToBuffer(); // read into the oldBuffer
+        sleep(sleepTime);
+#else
+		for(unsigned int n=0; n<ReceiveAudioThread::objAddrs.size(); n++){
+			ReceiveAudioThread::objAddrs[n]->readUdpToBuffer();
+		}
+		usleep(sleepTime); //TODO: use rt_task_sleep instead
+#endif /* USE_JUCE */
+    }
+    threadRunning=false;
+    printf("Thread is not running \n");
+    //  fprintf(fd,"];readPointer,writePointer,lastValidPointer,destination]=deal(var(:,1), var(:,2), var(:,3), var(:,4));"); //DEBUG
+    //  fclose(fd);//DEBUG
+    //  fprintf(fd2,"];");//DEBUG
+    //  fclose(fd2); //DEBUG
+}
--- a/core/UdpClient.cpp	Sat Feb 13 01:51:01 2016 +0000
+++ b/core/UdpClient.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -1,57 +1,77 @@
-/*
- * udpClient.cpp
- *
- *  Created on: 19 May 2015
- *      Author: giulio moro
- */
-#include "../include/UdpClient.h"
-
-	UdpClient::UdpClient(){
-		outSocket=socket(AF_INET, SOCK_DGRAM, 0);
-		isSetPort=false;
-		isSetServer=false;
-		enabled=false;
-	}
-	UdpClient::UdpClient(int aPort, const char* aServerName){
-		outSocket=socket(AF_INET, SOCK_DGRAM, 0);
-		if(outSocket<0){
-			enabled=false;
-			return;
-		}
-		setPort(aPort);
-		setServer(aServerName);
-		isSetPort=true;
-		isSetServer=true;
-		enabled=true;
-	}
-	UdpClient::~UdpClient(){
-	   close(outSocket);
-	}
-	void UdpClient::setPort(int aPort){
-		port=aPort;
-		destinationServer.sin_port = htons(port);
-		destinationServer.sin_family = AF_INET;
-		isSetPort=true;
-		if(isSetServer){
-			enabled=true;
-		}
-	};
-	void UdpClient::setServer(const char* aServerName){
-		inet_pton(AF_INET,aServerName,&destinationServer.sin_addr);
-		isSetServer=true;
-		if(isSetPort){
-			enabled=true;
-		}
-	};
-	int UdpClient::send(void * message, int size){
-		if(!enabled)
-			return -1;
-		unsigned int length;
-		length=sizeof(struct sockaddr_in);
-		int n=sendto(outSocket,message,size,0,(const struct sockaddr *)&destinationServer,length);
-		if (n < 0){
-			return n;
-		}
-		return 1;
-	};
-
+/*
+ * udpClient.cpp
+ *
+ *  Created on: 19 May 2015
+ *      Author: giulio moro
+ */
+#include "UdpClient.h"
+
+	UdpClient::UdpClient(){
+		outSocket=socket(AF_INET, SOCK_DGRAM, 0);
+		isSetPort=false;
+		isSetServer=false;
+		enabled=false;
+	}
+	UdpClient::UdpClient(int aPort, const char* aServerName){
+		outSocket=socket(AF_INET, SOCK_DGRAM, 0);
+		if(outSocket<0){
+			enabled=false;
+			return;
+		}
+		setPort(aPort);
+		setServer(aServerName);
+		isSetPort=true;
+		isSetServer=true;
+		enabled=true;
+    memset(&stTimeOut, 0, sizeof(struct timeval));
+	}
+	UdpClient::~UdpClient(){
+	   close(outSocket);
+	}
+	void UdpClient::setPort(int aPort){
+		port=aPort;
+		destinationServer.sin_port = htons(port);
+		destinationServer.sin_family = AF_INET;
+		isSetPort=true;
+		if(isSetServer){
+			enabled=true;
+		}
+	};
+	void UdpClient::setServer(const char* aServerName){
+		inet_pton(AF_INET,aServerName,&destinationServer.sin_addr);
+		isSetServer=true;
+		if(isSetPort){
+			enabled=true;
+		}
+	};
+	int UdpClient::send(void * message, int size){
+		if(!enabled)
+			return -1;
+		unsigned int length;
+		length=sizeof(struct sockaddr_in);
+		int n=sendto(outSocket,message,size,0,(const struct sockaddr *)&destinationServer,length);
+		if (n < 0){
+			return n;
+		}
+		return 1;
+	};
+	int UdpClient::write(const char* remoteHostname, int remotePortNumber, void* sourceBuffer, int numBytesToWrite){
+		setServer(remoteHostname);
+		setPort(remotePortNumber);
+		send(sourceBuffer, numBytesToWrite);
+	}
+  int UdpClient::waitUntilReady(bool readyForReading, int timeoutMsecs){
+//	If the socket is ready on return, this returns 1. If it times-out before the socket becomes ready, it returns 0. If an error occurs, it returns -1.
+    if(enabled==false)
+		return -1;
+    if(timeoutMsecs<0)
+		return select(outSocket+1, NULL, &stWriteFDS, NULL, NULL); //calling this with a NULL timeout will block indefinitely
+    FD_ZERO(&stWriteFDS);
+    FD_SET(outSocket, &stWriteFDS);
+	float timeOutSecs=timeoutMsecs*0.001;
+	stTimeOut.tv_sec=(int)timeOutSecs;
+	timeOutSecs-=(int)timeOutSecs;
+	stTimeOut.tv_usec=(int)(timeOutSecs*1000000);
+    int descriptorReady= select(outSocket+1, NULL, &stWriteFDS, NULL, &stTimeOut);
+    return descriptorReady>0? 1 : descriptorReady;
+  }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/UdpServer.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,119 @@
+/*
+ * udpServer.cpp
+ *
+ *  Created on: 19 May 2015
+ *      Author: giulio moro
+ */
+#include "UdpServer.h"
+
+UdpServer::UdpServer(int aPort){
+	init(aPort);
+};
+UdpServer::UdpServer(){
+	init(0);
+}
+UdpServer::~UdpServer(){
+	close();
+};
+bool UdpServer::init(int aPort){
+	enabled=true;
+	stZeroTimeOut.tv_sec = 0; //set timeout to 0
+	stZeroTimeOut.tv_usec = 0;
+	inSocket=socket(AF_INET, SOCK_DGRAM, 0);
+	if (inSocket < 0){
+		enabled=false;
+	}
+	length = sizeof(server);
+	server.sin_family=AF_INET;
+	server.sin_addr.s_addr=INADDR_ANY;
+	enabled=bindToPort(aPort);
+	wasteBufferSize=2048;
+	wasteBuffer=malloc(wasteBufferSize);
+  memset(&stTimeOut,0,sizeof(struct timeval));
+	return enabled;
+}
+
+bool UdpServer::bindToPort(int aPort){
+	port=aPort;
+	if(port<1){
+		enabled=false;
+		return false;
+	}
+	server.sin_port=htons(port);
+	if (bind(inSocket,(struct sockaddr *)&server,length)<0){
+		enabled=false;
+		return false;
+	}
+	enabled=true;
+	return true;
+}
+
+void UdpServer::close(){
+	int ret=::close(inSocket);
+	if(ret != 0)
+		printf("Error while closing socket, errno: %d\n", errno);//Stop receiving data for this socket. If further data arrives, reject it.
+	inSocket=0;
+}
+
+int UdpServer::waitUntilReady(bool readyForReading, int timeoutMsecs){
+//	If the socket is ready on return, this returns 1. If it times-out before the socket becomes ready, it returns 0. If an error occurs, it returns -1.
+	if(enabled==false)
+		return -1;
+	if(timeoutMsecs<0)
+		return select(inSocket+1, &stReadFDS, NULL, NULL, NULL); //calling this with a NULL timeout will block indefinitely
+	FD_ZERO(&stReadFDS);
+	FD_SET(inSocket, &stReadFDS);
+	float timeOutSecs=timeoutMsecs*0.001;
+	stTimeOut.tv_sec=(long int)timeOutSecs;
+	timeOutSecs-=(int)timeOutSecs;
+	long int timeOutUsecs=timeOutSecs*1000000;
+	stTimeOut.tv_usec=timeOutUsecs;
+	int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stTimeOut);
+//	printf("stTimeOut.tv_sec=%ld, stTimeOut.tv_usec=%ld, descriptorReady: \n",stTimeOut.tv_sec,stTimeOut.tv_usec, descriptorReady);
+//	return descriptorReady>0 ? (timeOutUsecs-stTimeOut.tv_usec) : descriptorReady;
+	return descriptorReady>0 ? 1 : descriptorReady;
+}
+
+int UdpServer::read(//Returns the number of bytes read, or -1 if there was an error.
+					void *destBuffer,
+					int maxBytesToRead,
+					bool blockUntilSpecifiedAmountHasArrived)
+{
+	if(enabled==false)
+		return -1;
+	FD_ZERO(&stReadFDS);
+	FD_SET(inSocket, &stReadFDS);
+	int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stZeroTimeOut); //TODO: this is not JUCE-compliant
+	if(descriptorReady<0){ //an error occurred
+		return -1;
+	}
+	int numberOfBytes=0;
+//	do
+	{
+		if (FD_ISSET(inSocket, &stReadFDS))
+		{
+	//		numberOfBytes=recvfrom(inSocket,destBuffer,maxBytesToRead,0,(struct sockaddr *)&from,&fromLength);
+			numberOfBytes+=recv(inSocket,destBuffer,maxBytesToRead-numberOfBytes,0);
+			if(numberOfBytes<0)
+				return -1;
+		}
+	}
+//	while (blockUntilSpecifiedAmountHasArrived && numberOfBytes==maxBytesToRead);
+	return numberOfBytes;
+}
+int UdpServer::empty(){
+	return empty(0);
+}
+int UdpServer::empty(int maxCount){
+	int count=0;
+	int n;
+	do {
+		if(waitUntilReady(true, 0)==0)
+			return 0;
+		float waste;
+		n=read(&waste, sizeof(float), false);
+		count++;
+	} while (n>0 && (maxCount<=0 || maxCount<count));
+	printf("socket emptied with %d reads\n", count);
+	return count;
+}
--- a/include/BeagleRT.h	Sat Feb 13 01:51:01 2016 +0000
+++ b/include/BeagleRT.h	Sun Apr 10 04:08:06 2016 +0200
@@ -271,7 +271,7 @@
  * to indicate that audio processing should terminate. Calling BeagleRT_stopAudio()
  * has the effect of setting this to \c true.
  */
-extern bool gShouldStop;
+extern int gShouldStop;
 
 // *** User-defined render functions ***
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/IirFilter.h	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,86 @@
+/*
+ * IirFilter.h
+ *
+ *  Created on: 17 Sep 2015
+ *      Author: giulio
+ */
+
+#ifndef IIRFILTER_H_
+#define IIRFILTER_H_
+
+#define IIR_FILTER_STAGE_COEFFICIENTS (5)
+#define IIR_FILTER_STAGE_STATES (IIR_FILTER_STAGE_COEFFICIENTS - 1)
+
+class IirFilterStage{ //TODO : to save (some) memory we should only store the coefficients pointers here,
+						//so that IirFilter can share them among multiple stages if needbe)
+private:
+	double coefficients[IIR_FILTER_STAGE_COEFFICIENTS]; // these are b0,b1,b2,a1,a2
+	double states[IIR_FILTER_STAGE_STATES]; // these are xprev, xprevprev, yprev, yprevprev
+public:
+	IirFilterStage();
+	void setCoefficients(double* newCoefficients);
+	void setStates(double* newStates);
+	// this is not meant to be efficient, just of practical use!
+	double process(double in){
+		process(&in, 1);
+		return in;
+	}
+
+	void process(double* inout, int length){
+		// make variables explicit. A smart compiler will optimize these out, right?
+		double b0=coefficients[0];
+		double b1=coefficients[1];
+		double b2=coefficients[2];
+		double a1=coefficients[3];
+		double a2=coefficients[4];
+		double x1 = states[0];
+		double x2=  states[1];
+		double y1 = states[2];
+		double y2 = states[3];
+		for(int n = 0; n < length; n++){
+			double x0 = inout[n];
+			double y = x0 * b0 + x1 * b1 + x2 * b2 +
+					- y1 * a1 - y2 * a2;
+			inout[n] = y;
+			x2 = x1;
+			x1 = x0;
+			y2 = y1;
+			y1 = y;
+		}
+		states[0] = x1;
+		states[1] = x2;
+		states[2] = y1;
+		states[3] = y2;
+	}
+};
+
+class IirFilter{
+private:
+	struct IirFilterStage** stages;
+	int numberOfStages;
+	void dealloc();
+public:
+	IirFilter();
+	IirFilter(int newNumberOfStages);
+	IirFilter(int newNumberOfStages, double *newCoefficients);
+	void setCoefficients(double* newCoefficients);
+	void setStates(double* newStates);
+	void setNumberOfStages(int newNumberOfStages);
+//	double process(double in);
+//	inline void process(double* inout, int length);
+//	inline void process(double* in, double* out, int length);
+	double process(double in){
+		process(&in, 1);
+		return in;
+	};
+	void process(double* inout, int length){
+		for(int n = 0; n < numberOfStages && n < 8/* TODO: this "8" compensates for a memory corruption somewhere on the BBB*/; n++){
+			stages[n]->process(inout, length);
+		}
+	}
+};
+
+
+//void IirFilter::process(double* in, double* out, int length);
+
+#endif /* IIRFILTER_H_ */
--- a/include/Midi.h	Sat Feb 13 01:51:01 2016 +0000
+++ b/include/Midi.h	Sun Apr 10 04:08:06 2016 +0200
@@ -115,6 +115,9 @@
 	unsigned int readPointer;
 	unsigned int elapsedDataBytes;
 	bool waitingForStatus;
+	void (*messageReadyCallback)(MidiChannelMessage,void*);
+	bool callbackEnabled;
+	void* callbackArg;
 public:
 	MidiParser(){
 		waitingForStatus = true;
@@ -122,6 +125,9 @@
 		messages.resize(100); // 100 is the number of messages that can be buffered
 		writePointer = 0;
 		readPointer = 0;
+		callbackEnabled = false;
+		messageReadyCallback = NULL;
+		callbackArg = NULL;
 	}
 
 	/**
@@ -133,23 +139,66 @@
 	 * @return the number of bytes parsed
 	 */
 	int parse(midi_byte_t* input, unsigned int length);
-	int callme(){
-		return readPointer;
+
+	/**
+	 * Sets the callback to call when a new MidiChannelMessage is available
+	 * from the input port.
+	 *
+	 * The callback will be called with two arguments:
+	 *   callback(MidiChannelMessage newMessage, void* arg)
+	 *
+	 * In order to deactivate the callback, call this method with NULL as the
+	 * first argument.
+	 * While the callback is enabled, calling numAvailableMessages() and
+	 * getNextChannelMessage() is still possible, but it will probably always
+	 * return 0 as the callback is called as soon as a new message is available.
+	 *
+	 * @param newCallback the callback function.
+	 * @param arg the second argument to be passed to the callback function.
+	 *
+	 */
+	void setCallback(void (*newCallback)(MidiChannelMessage, void*), void* arg=NULL){
+		callbackArg = arg;
+		messageReadyCallback = newCallback;
+		if(newCallback != NULL){
+			callbackEnabled = true;
+		} else {
+			callbackEnabled = false;
+		}
 	};
+
+	/**
+	 * Checks whether there is a callback currently set to be called
+	 * every time a new input MidiChannelMessage is available from the
+	 * input port.
+	 */
+	bool isCallbackEnabled(){
+		return callbackEnabled;
+	};
+
+	/**
+	 * Returns the number of unread MidiChannelMessage available from the
+	 * input port.
+	 *
+	 */
+
 	int numAvailableMessages(){
 		int num = (writePointer - readPointer + messages.size() ) % messages.size();
 		if(num > 0){
 			int a = a +1;
-			a = callme();
+			a = readPointer;
 		}
 		return num;
 	}
+
 	/**
 	 * Get the oldest channel message in the buffer.
 	 *
 	 * If this method is called when numAvailableMessages()==0, then
 	 * a message with all fields set to zero is returned.
+	 *
 	 * @param type the type of the message to retrieve
+	 *
 	 * @return a copy of the oldest message of the give type in the buffer
 	 */
 	MidiChannelMessage getNextChannelMessage(/*MidiMessageType type*/){
@@ -203,6 +252,21 @@
 	MidiParser* getParser();
 
 	/**
+	 * Sets the callback to call when a new MidiChannelMessage is available
+	 * from the input port.
+	 *
+	 * Internally, it calls enableParser() and the MidiParser::setCallback();
+	 *
+	 * @param newCallback the callback function.
+	 * @param arg the second argument to be passed to the callback function.
+	 */
+	void setParserCallback(void (*callback)(MidiChannelMessage, void*), void* arg=NULL){
+		// if callback is not NULL, also enable the parser
+		enableParser(callback != NULL); //this needs to be first, as it deletes the parser(if exists)
+		getParser()->setCallback(callback, arg);
+	}
+
+	/**
 	 * Open the specified input Midi port and start reading from it.
 	 * @param port Midi port to open
 	 * @return 1 on success, -1 on failure
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/NetworkSend.h	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,115 @@
+//scope.cpp
+#ifndef SCOPE_H_
+#define SCOPE_H_
+
+#ifdef USE_JUCE
+#include <JuceHeader.h>
+#else
+#include <BeagleRT.h> 
+#include <rtdk.h>
+#include <cmath>
+#include <UdpClient.h>
+#include <vector>
+#include <string>
+extern int gShouldStop;
+#endif /* USE_JUCE */
+
+#define NETWORK_AUDIO_BUFFER_SIZE 302
+#define UDP_BUFFER_HEADER_CHANNEL_INDEX 0
+#define UDP_BUFFER_HEADER_TIMESTAMP_INDEX 1
+#define UDP_BUFFER_HEADER_LENGTH 2
+
+struct NetworkBuffer{
+	int channelNumber;
+	int numBuffers;
+	int writeBuffer;
+	int readBuffer;
+	int writePointer;
+	float** buffers;
+	bool* doneOnTime;
+	bool* readyToBeSent;
+	bool enabled;
+	int sampleCount;
+	static const int bufferLength=NETWORK_AUDIO_BUFFER_SIZE;
+	static const int headerLength=UDP_BUFFER_HEADER_LENGTH;
+	static const int headerChannelIndex=UDP_BUFFER_HEADER_CHANNEL_INDEX;
+	static const int headerTimestampIndex=UDP_BUFFER_HEADER_TIMESTAMP_INDEX;
+};
+
+#ifdef USE_JUCE
+class NetworkSend: public Thread {
+#else
+class NetworkSend {
+#endif /* USE_JUCE */
+	float sampleRate;
+#ifdef USE_JUCE
+	DatagramSocket udpClient;
+	int sleepTimeMs;
+	String remoteHostname;
+	int remotePortNumber;
+#else
+	UdpClient udpClient;
+	bool isThreadRunning();
+	static int sleepTimeMs;
+	static bool threadShouldExit();
+	static bool threadIsExiting;
+	static bool threadRunning;
+	static bool staticConstructed;
+	static void staticConstructor();
+	static AuxiliaryTask sendDataTask; //TODO: allow different AuxiliaryTasks for different priorities (e.g.: audio vs scope)
+	static std::vector<NetworkSend *> objAddrs;
+#endif /* USE_JUCE */
+	void dealloc();
+public:
+	NetworkBuffer channel;
+#ifdef USE_JUCE
+	NetworkSend(const String &threadName);
+#else
+	NetworkSend();
+#endif
+	~NetworkSend();
+	void setup(float aSampleRate, int blockSize, int aChannelNumber, int aPort, const char *aServer);
+	void cleanup();
+	void sendData();
+	void log(float value);
+	void setPort(int aPort);
+	void setServer(const char* aServer);
+	void setChannelNumber(int aChannelNumber);
+	int getChannelNumber();
+	int getTimestamp();
+#ifdef USE_JUCE
+	void run();
+#else
+	static int getNumInstances();
+	static void sendAllData();
+    static void startThread();
+    static void stopThread();
+	static void run();
+#endif /* USE_JUCE */
+};
+
+#ifdef USE_JUCE
+#else
+/**
+ * An array of NetworkSend objects with some default parameters
+ *
+ * All sending on the same port (defaults to 9999)
+ * All sending to the same server (defaults to 127.0.0.1)
+*/
+class Scope {
+	std::vector<NetworkSend> channels;
+	void deallocate();
+public:
+	Scope(int aNumChannels);
+	~Scope();
+	void log(int channel, float value);
+    void setup();
+    void setup(float sampleRate, int aPort, const char* aServer);
+    void sendData();
+    void setPort(int port);
+    void setPort(int channel, int port);
+    int getNumChannels();
+};
+#endif /* USE_JUCE */
+
+#endif /* SCOPE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/ReceiveAudioThread.h	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,105 @@
+#ifndef RECEIVEAUDIOTHREAD_H_INCLUDED
+#define RECEIVEAUDIOTHREAD_H_INCLUDED
+
+#ifdef USE_JUCE
+#include <JuceHeader.h>
+#else
+#include <BeagleRT.h>
+#include <UdpServer.h>
+#include <vector>
+#include <iostream>
+#include <native/task.h>
+#include <native/timer.h>
+#include <math.h>
+
+#endif /*USE_JUCE*/
+
+#ifdef USE_JUCE
+class ReceiveAudioThread : public Thread {
+#else
+class ReceiveAudioThread{
+#endif /* USE_JUCE */
+private:
+    //  FILE *fd; //DEBUG
+    //  FILE *fd2; //DEBUG
+#ifdef USE_JUCE
+	DatagramSocket socket;
+#else
+    UdpServer socket;
+#endif /* USE_JUCE */
+    bool listening;
+    bool bufferReady;
+#ifdef USE_JUCE
+    bool threadRunning; //do we really need this ?
+#else
+    static bool threadRunning;
+    static bool threadIsExiting;
+#endif
+    float *buffer;
+    float *stackBuffer;
+    int bufferLength;
+    float readPointer;
+    int writePointer;
+    int lastValidPointer;
+#ifdef USE_JUCE
+    int sleepTime;
+#else
+    static int sleepTime;
+#endif
+    int waitForSocketTime;
+    int payloadLength; //size of the payload of each datagram
+    int headerLength; //size of the header of each datagram
+    int bytesToRead;
+    int threadPriority;
+    int channel;
+    int timestamp;
+    void dealloc();
+    void wrapWritePointer();
+    void pushPayload(int startIndex);
+    void popPayload(int startIndex);
+    int readUdpToBuffer();
+#ifdef USE_JUCE
+#else
+    RTIME lastTime; // Used for clock synchronization
+    static bool threadShouldExit();
+	static bool staticConstructed;
+    static void staticConstructor();
+    static AuxiliaryTask receiveDataTask; //TODO: allow different AuxiliaryTasks for different priorities (e.g.: audio vs scope)
+    static std::vector<ReceiveAudioThread *> objAddrs;
+#endif
+public:
+#ifdef USE_JUCE
+    ReceiveAudioThread(const String &threadName);
+#else
+    ReceiveAudioThread();
+#endif
+    ~ReceiveAudioThread();
+    void init(int port, int aSamplesPerBlock, int channel);
+    void bindToPort(int aPort);
+    bool isListening();
+    float* getCurrentBuffer(int length);
+    /**
+     * Copies the samples to a non-interleaved buffer.
+     */
+    int getSamplesSrc(float *destination, int length, float samplingRateRatio);
+    /**
+     * Copies the samples to an interleaved buffer.
+     */
+    int getSamplesSrc(float *destination, int length,
+    		float samplingRateRatio, int numChannelsInDestination,
+    		int channelToWriteTo);
+    bool isBufferReady();
+    int getTimestamp();
+#ifdef USE_JUCE // if we are in Juce, then we run a separate thread for each receiver
+    		// (as each of them are typically receiving on a mono or stereo track)
+    void run();
+#else
+    RTIME getLastTime();
+    void static run(); //while in BeagleRT we have a single thread that receives for all the instances.
+    //TODO: make run() private in BeagleRT
+    static void startThread();
+    static void stopThread();
+    static int getNumInstances();
+#endif // USE_JUCE
+};
+#endif  // RECEIVEAUDIOTHREAD_H_INCLUDED
--- a/include/Scope.h	Sat Feb 13 01:51:01 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-//scope.cpp
-#include <BeagleRT.h> 
-#include <rtdk.h>
-#include <cmath>
-#include <UdpClient.h>
-
-#define BUILD_FOR_UDPRECEIVE_PLUGIN
-#define NETWORK_AUDIO_BUFFER_SIZE 302
-struct networkAudio{
-	int timestamp;
-	int currentBuffer;
-	int index;
-	float buffers[2][NETWORK_AUDIO_BUFFER_SIZE]; 
-	int doneOnTime;
-	bool toBeSent;
-	UdpClient udpClient;
-};
-
-#define NUM_SCOPE_CHANNELS 6
-
-static void SendScopeData();
-
-class Scope {
-    int sampleCount; 
-    float sampleRate;
-    AuxiliaryTask scopeTask;
-  public:
-    int numChannels;
-    networkAudio channel[NUM_SCOPE_CHANNELS];
-    Scope(){
-        numChannels = NUM_SCOPE_CHANNELS;
-        sampleCount = 0;
-#ifdef BUILD_FOR_UDPRECEIVE_PLUGIN
-        char server[]="192.168.7.1";
-#else
-        char server[]="127.0.0.1";
-#endif /* BUILD_FOR_UDPRECEIVE_PLUGIN */
-        printf("Sending messages to : %s\n", server);
-        for(int n=0; n<numChannels; n++){
-            channel[n].doneOnTime=1;
-            channel[n].index=2; //leave space for the heading message (channel, timestamp)
-            channel[n].timestamp=0;
-            channel[n].currentBuffer=0;
-            channel[n].toBeSent=false;
-            channel[n].udpClient.setServer(server);
-#ifdef BUILD_FOR_UDPRECEIVE_PLUGIN
-            channel[n].udpClient.setPort(9999+n);
-#else
-            channel[n].udpClient.setPort(9999);
-#endif /* BUILD_FOR_UDPRECEIVE_PLUGIN */
-    	}
-    }
-    void setup(float _sampleRate);
-    void log(float channel1=0.0, float channel2=0.0, float channel3=0.0, float channel4=0.0, float channel5=0.0, float channel6=0.0){
-        
-        for(int j=0; j<numChannels; j++){
-			if(channel[j].index==(NETWORK_AUDIO_BUFFER_SIZE)){ // when the buffer is ready ...
-              channel[j].buffers[channel[j].currentBuffer][0] = (float)j;
-              channel[j].buffers[channel[j].currentBuffer][1] = (float)channel[j].timestamp;
-				channel[j].toBeSent=true;
-				channel[j].index=2; //reset the counter
-				if(channel[j].doneOnTime==0)
-					rt_printf("Network buffer underrun :-{\n");
-				channel[j].timestamp=sampleCount;
-				channel[j].currentBuffer=!channel[j].currentBuffer; //switch buffer
-				channel[j].doneOnTime=0;
-				BeagleRT_scheduleAuxiliaryTask(scopeTask); //send the buffer
-			}
-		}
-      
-      	channel[0].buffers[channel[0].currentBuffer][channel[0].index++]=channel1;
-      	channel[1].buffers[channel[1].currentBuffer][channel[1].index++]=channel2;
-      	channel[2].buffers[channel[2].currentBuffer][channel[2].index++]=channel3;
-      	channel[3].buffers[channel[3].currentBuffer][channel[3].index++]=channel4;
-      	channel[4].buffers[channel[4].currentBuffer][channel[4].index++]=channel5;
-      	channel[5].buffers[channel[5].currentBuffer][channel[5].index++]=channel6;
-
-	sampleCount++;
-    }
-};
-
-Scope* gOscilloscopeInstance;
-
-void Scope::setup(float _sampleRate){
-    sampleRate = _sampleRate;
-    gOscilloscopeInstance = this;
-    scopeTask = BeagleRT_createAuxiliaryTask(*SendScopeData, 98, "transmit-receive-audio");
-}
-
-//Scope scope; 
-
-static void SendScopeData(){
-    for(int n=0; n<gOscilloscopeInstance->numChannels; n++){
-		if(gOscilloscopeInstance->channel[n].toBeSent){
-			gOscilloscopeInstance->channel[n].toBeSent=false;
-			gOscilloscopeInstance->channel[n].udpClient.send(
-				gOscilloscopeInstance->channel[n].buffers[!gOscilloscopeInstance->channel[n].currentBuffer],
-				NETWORK_AUDIO_BUFFER_SIZE*sizeof(float)
-			);
-			gOscilloscopeInstance->channel[n].doneOnTime=1;
-		}
-	}
-}
--- a/include/UdpClient.h	Sat Feb 13 01:51:01 2016 +0000
+++ b/include/UdpClient.h	Sun Apr 10 04:08:06 2016 +0200
@@ -23,6 +23,8 @@
 		int port;
 		int enabled;
 		int outSocket;
+    struct timeval stTimeOut;
+    fd_set stWriteFDS;
 		bool isSetPort;
 		bool isSetServer;
 		struct sockaddr_in destinationServer;
@@ -33,6 +35,8 @@
 		void setPort(int aPort);
 		void setServer(const char* aServerName);
 		int send(void* message, int size);
+		int write(const char* remoteHostname, int remotePortNumber, void* sourceBuffer, int numBytesToWrite);
+    int waitUntilReady(bool readyForReading, int timeoutMsecs);
 };
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/UdpServer.h	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,70 @@
+/*
+ * udpServer.h
+ *
+ *  Created on: 19 May 2015
+ *      Author: giulio moro
+ */
+
+#ifndef UDPSERVER_H_
+#define UDPSERVER_H_
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+class UdpServer{
+	private:
+		int port;
+		int enabled;
+		int inSocket;
+		struct sockaddr_in server;
+		struct timeval stTimeOut;
+		struct timeval stZeroTimeOut;
+		fd_set stReadFDS;
+		int size;
+		void *wasteBuffer;
+		int wasteBufferSize;
+		int length;
+		socklen_t fromLength;
+		struct sockaddr_in from;
+	public:
+		UdpServer();
+		UdpServer(int aPort);
+		~UdpServer();
+		bool init(int aPort);
+		bool bindToPort(int aPort);
+		int getBoundPort() const;
+		/*
+		 * Reads bytes from the socket.
+		 *
+		 * Drop-in replacement for JUCE DatagramSocket::read()
+		 *
+			If blockUntilSpecifiedAmountHasArrived is true, the method will block until maxBytesToRead
+			bytes have been read, (or until an error occurs). If this flag is false, the method will
+			return as much data as is currently available without blocking.
+		 */
+		int read(void* destBuffer, int maxBytesToRead, bool blockUntilSpecifiedAmountHasArrived);
+		void close();
+		int empty();
+		int empty(int maxCount);
+		/*
+		 * Waits until the socket is ready for reading or writing.
+		 *
+			Drop-in replacement for JUCE DatagramSocket::waitUntilReady.
+			If readyForReading is true, it will wait until the socket is ready for reading; if false, it will wait until it's ready for writing.
+			If the timeout is < 0, it will wait forever, or else will give up after the specified time.
+			If the socket is ready on return, this returns 1. If it times-out before the socket becomes ready, it returns 0. If an error occurs, it returns -1.
+		 */
+		int waitUntilReady(bool readyForReading, int timeoutMsecs);
+};
+
+
+
+#endif /* UDPSERVER_H_ */
--- a/projects/basic_button/render.cpp	Sat Feb 13 01:51:01 2016 +0000
+++ b/projects/basic_button/render.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -20,6 +20,10 @@
 
 bool setup(BeagleRTContext *context, void *userData)
 {
+	for(unsigned int n=0; n<context->digitalFrames; n++){
+		pinModeFrame(context, 0, P8_08, INPUT);
+		pinModeFrame(context, 0, P8_07, OUTPUT);
+	}
 	return true;
 }
 
@@ -39,11 +43,9 @@
 void render(BeagleRTContext *context, void *userData)
 {
 	for(unsigned int n=0; n<context->digitalFrames; n++){
-    pinModeFrame(context, 0, P8_08, INPUT);
-    int status=digitalReadFrame(context, 0, P8_08); //read the value of the button
-    pinModeFrame(context, 0, P8_07, OUTPUT);
-    digitalWriteFrame(context, n, P8_07, status); //write the status to the LED
-  }
+		int status=digitalReadFrame(context, 0, P8_08); //read the value of the button
+		digitalWriteFrame(context, n, P8_07, status); //write the status to the LED
+	}
 }
 
 // cleanup() is called once at the end, after the audio has stopped.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/basic_libpd/m_pd.h	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,770 @@
+/* Copyright (c) 1997-1999 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */
+
+#ifndef __m_pd_h_
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+extern "C" {
+#endif
+
+#define PD_MAJOR_VERSION 0
+#define PD_MINOR_VERSION 46
+#define PD_BUGFIX_VERSION 6
+#define PD_TEST_VERSION ""
+extern int pd_compatibilitylevel;   /* e.g., 43 for pd 0.43 compatibility */
+
+/* old name for "MSW" flag -- we have to take it for the sake of many old
+"nmakefiles" for externs, which will define NT and not MSW */
+#if defined(NT) && !defined(MSW)
+#define MSW
+#endif
+
+/* These pragmas are only used for MSVC, not MinGW or Cygwin <hans@at.or.at> */
+#ifdef _MSC_VER
+/* #pragma warning( disable : 4091 ) */
+#pragma warning( disable : 4305 )  /* uncast const double to float */
+#pragma warning( disable : 4244 )  /* uncast float/int conversion etc. */
+#pragma warning( disable : 4101 )  /* unused automatic variables */
+#endif /* _MSC_VER */
+
+    /* the external storage class is "extern" in UNIX; in MSW it's ugly. */
+#ifdef _WIN32
+#ifdef PD_INTERNAL
+#define EXTERN __declspec(dllexport) extern
+#else
+#define EXTERN __declspec(dllimport) extern
+#endif /* PD_INTERNAL */
+#else
+#define EXTERN extern
+#endif /* _WIN32 */
+
+    /* and depending on the compiler, hidden data structures are
+    declared differently: */
+#if defined( __GNUC__) || defined( __BORLANDC__ ) || defined( __MWERKS__ )
+#define EXTERN_STRUCT struct
+#else
+#define EXTERN_STRUCT extern struct
+#endif
+
+/* Define some attributes, specific to the compiler */
+#if defined(__GNUC__)
+#define ATTRIBUTE_FORMAT_PRINTF(a, b) __attribute__ ((format (printf, a, b)))
+#else
+#define ATTRIBUTE_FORMAT_PRINTF(a, b)
+#endif
+
+#if !defined(_SIZE_T) && !defined(_SIZE_T_)
+#include <stddef.h>     /* just for size_t -- how lame! */
+#endif
+
+/* Microsoft Visual Studio is not C99, it does not provide stdint.h */
+#ifdef _MSC_VER
+typedef signed __int8     int8_t;
+typedef signed __int16    int16_t;
+typedef signed __int32    int32_t;
+typedef signed __int64    int64_t;
+typedef unsigned __int8   uint8_t;
+typedef unsigned __int16  uint16_t;
+typedef unsigned __int32  uint32_t;
+typedef unsigned __int64  uint64_t;
+#else
+# include <stdint.h>
+#endif
+
+/* for FILE, needed by sys_fopen() and sys_fclose() only */
+#include <stdio.h>
+
+#define MAXPDSTRING 1000        /* use this for anything you want */
+#define MAXPDARG 5              /* max number of args we can typecheck today */
+
+/* signed and unsigned integer types the size of a pointer:  */
+#if !defined(PD_LONGINTTYPE)
+#define PD_LONGINTTYPE long
+#endif
+
+#if !defined(PD_FLOATSIZE)
+  /* normally, our floats (t_float, t_sample,...) are 32bit */
+# define PD_FLOATSIZE 32
+#endif
+
+#if PD_FLOATSIZE == 32
+# define PD_FLOATTYPE float
+/* an unsigned int of the same size as FLOATTYPE: */
+# define PD_FLOATUINTTYPE unsigned int
+
+#elif PD_FLOATSIZE == 64
+# define PD_FLOATTYPE double
+# define PD_FLOATUINTTYPE unsigned long
+#else
+# error invalid FLOATSIZE: must be 32 or 64
+#endif
+
+typedef PD_LONGINTTYPE t_int;       /* pointer-size integer */
+typedef PD_FLOATTYPE t_float;       /* a float type at most the same size */
+typedef PD_FLOATTYPE t_floatarg;    /* float type for function calls */
+
+typedef struct _symbol
+{
+    char *s_name;
+    struct _class **s_thing;
+    struct _symbol *s_next;
+} t_symbol;
+
+EXTERN_STRUCT _array;
+#define t_array struct _array       /* g_canvas.h */
+
+/* pointers to glist and array elements go through a "stub" which sticks
+around after the glist or array is freed.  The stub itself is deleted when
+both the glist/array is gone and the refcount is zero, ensuring that no
+gpointers are pointing here. */
+
+#define GP_NONE 0       /* the stub points nowhere (has been cut off) */
+#define GP_GLIST 1      /* the stub points to a glist element */
+#define GP_ARRAY 2      /* ... or array */
+
+typedef struct _gstub
+{
+    union
+    {
+        struct _glist *gs_glist;    /* glist we're in */
+        struct _array *gs_array;    /* array we're in */
+    } gs_un;
+    int gs_which;                   /* GP_GLIST/GP_ARRAY */
+    int gs_refcount;                /* number of gpointers pointing here */
+} t_gstub;
+
+typedef struct _gpointer           /* pointer to a gobj in a glist */
+{
+    union
+    {   
+        struct _scalar *gp_scalar;  /* scalar we're in (if glist) */
+        union word *gp_w;           /* raw data (if array) */
+    } gp_un;
+    int gp_valid;                   /* number which must match gpointee */
+    t_gstub *gp_stub;               /* stub which points to glist/array */
+} t_gpointer;
+
+typedef union word
+{
+    t_float w_float;
+    t_symbol *w_symbol;
+    t_gpointer *w_gpointer;
+    t_array *w_array;
+    struct _binbuf *w_binbuf;
+    int w_index;
+} t_word;
+
+typedef enum
+{
+    A_NULL,
+    A_FLOAT,
+    A_SYMBOL,
+    A_POINTER,
+    A_SEMI,
+    A_COMMA,
+    A_DEFFLOAT,
+    A_DEFSYM,
+    A_DOLLAR, 
+    A_DOLLSYM,
+    A_GIMME,
+    A_CANT
+}  t_atomtype;
+
+#define A_DEFSYMBOL A_DEFSYM    /* better name for this */
+
+typedef struct _atom
+{
+    t_atomtype a_type;
+    union word a_w;
+} t_atom;
+
+EXTERN_STRUCT _class;
+#define t_class struct _class
+
+EXTERN_STRUCT _outlet;
+#define t_outlet struct _outlet
+
+EXTERN_STRUCT _inlet;
+#define t_inlet struct _inlet
+
+EXTERN_STRUCT _binbuf;
+#define t_binbuf struct _binbuf
+
+EXTERN_STRUCT _clock;
+#define t_clock struct _clock
+
+EXTERN_STRUCT _outconnect;
+#define t_outconnect struct _outconnect
+
+EXTERN_STRUCT _glist;
+#define t_glist struct _glist
+#define t_canvas struct _glist  /* LATER lose this */
+
+typedef t_class *t_pd;      /* pure datum: nothing but a class pointer */
+
+typedef struct _gobj        /* a graphical object */
+{
+    t_pd g_pd;              /* pure datum header (class) */
+    struct _gobj *g_next;   /* next in list */
+} t_gobj;
+
+typedef struct _scalar      /* a graphical object holding data */
+{
+    t_gobj sc_gobj;         /* header for graphical object */
+    t_symbol *sc_template;  /* template name (LATER replace with pointer) */
+    t_word sc_vec[1];       /* indeterminate-length array of words */
+} t_scalar;
+
+typedef struct _text        /* patchable object - graphical, with text */
+{
+    t_gobj te_g;                /* header for graphical object */
+    t_binbuf *te_binbuf;        /* holder for the text */
+    t_outlet *te_outlet;        /* linked list of outlets */
+    t_inlet *te_inlet;          /* linked list of inlets */
+    short te_xpix;              /* x&y location (within the toplevel) */
+    short te_ypix;
+    short te_width;             /* requested width in chars, 0 if auto */
+    unsigned int te_type:2;     /* from defs below */
+} t_text;
+
+#define T_TEXT 0        /* just a textual comment */
+#define T_OBJECT 1      /* a MAX style patchable object */
+#define T_MESSAGE 2     /* a MAX stype message */
+#define T_ATOM 3        /* a cell to display a number or symbol */
+
+#define te_pd te_g.g_pd
+
+   /* t_object is synonym for t_text (LATER unify them) */
+
+typedef struct _text t_object;
+
+#define ob_outlet te_outlet
+#define ob_inlet te_inlet
+#define ob_binbuf te_binbuf
+#define ob_pd te_g.g_pd
+#define ob_g te_g
+
+typedef void (*t_method)(void);
+typedef void *(*t_newmethod)( void);
+
+/* in ARM 64 a varargs prototype generates a different function call sequence
+from a fixed one, so in that special case we make a more restrictive
+definition for t_gotfn.  This will break some code in the "chaos" package
+in Pd extended.  (that code will run incorrectly anyhow so why not catch it
+at compile time anyhow.) */
+#if defined(__APPLE__) && defined(__aarch64__)
+typedef void (*t_gotfn)(void *x);
+#else
+typedef void (*t_gotfn)(void *x, ...);
+#endif
+
+/* ---------------- pre-defined objects and symbols --------------*/
+EXTERN t_pd pd_objectmaker;     /* factory for creating "object" boxes */
+EXTERN t_pd pd_canvasmaker;     /* factory for creating canvases */
+EXTERN t_symbol s_pointer;
+EXTERN t_symbol s_float;
+EXTERN t_symbol s_symbol;
+EXTERN t_symbol s_bang;
+EXTERN t_symbol s_list;
+EXTERN t_symbol s_anything;
+EXTERN t_symbol s_signal;
+EXTERN t_symbol s__N;
+EXTERN t_symbol s__X;
+EXTERN t_symbol s_x;
+EXTERN t_symbol s_y;
+EXTERN t_symbol s_;
+
+/* --------- prototypes from the central message system ----------- */
+EXTERN void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void pd_forwardmess(t_pd *x, int argc, t_atom *argv);
+EXTERN t_symbol *gensym(const char *s);
+EXTERN t_gotfn getfn(t_pd *x, t_symbol *s);
+EXTERN t_gotfn zgetfn(t_pd *x, t_symbol *s);
+EXTERN void nullfn(void);
+EXTERN void pd_vmess(t_pd *x, t_symbol *s, char *fmt, ...);
+
+/* the following macrose are for sending non-type-checkable mesages, i.e.,
+using function lookup but circumventing type checking on arguments.  Only
+use for internal messaging protected by A_CANT so that the message can't
+be generated at patch level. */
+#define mess0(x, s) ((*getfn((x), (s)))((x)))
+typedef void (*t_gotfn1)(void *x, void *arg1);
+#define mess1(x, s, a) ((*(t_gotfn1)getfn((x), (s)))((x), (a)))
+typedef void (*t_gotfn2)(void *x, void *arg1, void *arg2);
+#define mess2(x, s, a,b) ((*(t_gotfn2)getfn((x), (s)))((x), (a),(b)))
+typedef void (*t_gotfn3)(void *x, void *arg1, void *arg2, void *arg3);
+#define mess3(x, s, a,b,c) ((*(t_gotfn3)getfn((x), (s)))((x), (a),(b),(c)))
+typedef void (*t_gotfn4)(void *x,
+    void *arg1, void *arg2, void *arg3, void *arg4);
+#define mess4(x, s, a,b,c,d) \
+    ((*(t_gotfn4)getfn((x), (s)))((x), (a),(b),(c),(d)))
+typedef void (*t_gotfn5)(void *x,
+    void *arg1, void *arg2, void *arg3, void *arg4, void *arg5);
+#define mess5(x, s, a,b,c,d,e) \
+    ((*(t_gotfn5)getfn((x), (s)))((x), (a),(b),(c),(d),(e)))
+
+EXTERN void obj_list(t_object *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN t_pd *pd_newest(void);
+
+/* --------------- memory management -------------------- */
+EXTERN void *getbytes(size_t nbytes);
+EXTERN void *getzbytes(size_t nbytes);
+EXTERN void *copybytes(void *src, size_t nbytes);
+EXTERN void freebytes(void *x, size_t nbytes);
+EXTERN void *resizebytes(void *x, size_t oldsize, size_t newsize);
+
+/* -------------------- atoms ----------------------------- */
+
+#define SETSEMI(atom) ((atom)->a_type = A_SEMI, (atom)->a_w.w_index = 0)
+#define SETCOMMA(atom) ((atom)->a_type = A_COMMA, (atom)->a_w.w_index = 0)
+#define SETPOINTER(atom, gp) ((atom)->a_type = A_POINTER, \
+    (atom)->a_w.w_gpointer = (gp))
+#define SETFLOAT(atom, f) ((atom)->a_type = A_FLOAT, (atom)->a_w.w_float = (f))
+#define SETSYMBOL(atom, s) ((atom)->a_type = A_SYMBOL, \
+    (atom)->a_w.w_symbol = (s))
+#define SETDOLLAR(atom, n) ((atom)->a_type = A_DOLLAR, \
+    (atom)->a_w.w_index = (n))
+#define SETDOLLSYM(atom, s) ((atom)->a_type = A_DOLLSYM, \
+    (atom)->a_w.w_symbol= (s))
+
+EXTERN t_float atom_getfloat(t_atom *a);
+EXTERN t_int atom_getint(t_atom *a);
+EXTERN t_symbol *atom_getsymbol(t_atom *a);
+EXTERN t_symbol *atom_gensym(t_atom *a);
+EXTERN t_float atom_getfloatarg(int which, int argc, t_atom *argv);
+EXTERN t_int atom_getintarg(int which, int argc, t_atom *argv);
+EXTERN t_symbol *atom_getsymbolarg(int which, int argc, t_atom *argv);
+
+EXTERN void atom_string(t_atom *a, char *buf, unsigned int bufsize);
+
+/* ------------------  binbufs --------------- */
+
+EXTERN t_binbuf *binbuf_new(void);
+EXTERN void binbuf_free(t_binbuf *x);
+EXTERN t_binbuf *binbuf_duplicate(t_binbuf *y);
+
+EXTERN void binbuf_text(t_binbuf *x, char *text, size_t size);
+EXTERN void binbuf_gettext(t_binbuf *x, char **bufp, int *lengthp);
+EXTERN void binbuf_clear(t_binbuf *x);
+EXTERN void binbuf_add(t_binbuf *x, int argc, t_atom *argv);
+EXTERN void binbuf_addv(t_binbuf *x, char *fmt, ...);
+EXTERN void binbuf_addbinbuf(t_binbuf *x, t_binbuf *y);
+EXTERN void binbuf_addsemi(t_binbuf *x);
+EXTERN void binbuf_restore(t_binbuf *x, int argc, t_atom *argv);
+EXTERN void binbuf_print(t_binbuf *x);
+EXTERN int binbuf_getnatom(t_binbuf *x);
+EXTERN t_atom *binbuf_getvec(t_binbuf *x);
+EXTERN int binbuf_resize(t_binbuf *x, int newsize);
+EXTERN void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv);
+EXTERN int binbuf_read(t_binbuf *b, char *filename, char *dirname,
+    int crflag);
+EXTERN int binbuf_read_via_canvas(t_binbuf *b, char *filename, t_canvas *canvas,
+    int crflag);
+EXTERN int binbuf_read_via_path(t_binbuf *b, char *filename, char *dirname,
+    int crflag);
+EXTERN int binbuf_write(t_binbuf *x, char *filename, char *dir,
+    int crflag);
+EXTERN void binbuf_evalfile(t_symbol *name, t_symbol *dir);
+EXTERN t_symbol *binbuf_realizedollsym(t_symbol *s, int ac, t_atom *av,
+    int tonew);
+
+/* ------------------  clocks --------------- */
+
+EXTERN t_clock *clock_new(void *owner, t_method fn);
+EXTERN void clock_set(t_clock *x, double systime);
+EXTERN void clock_delay(t_clock *x, double delaytime);
+EXTERN void clock_unset(t_clock *x);
+EXTERN void clock_setunit(t_clock *x, double timeunit, int sampflag);
+EXTERN double clock_getlogicaltime(void);
+EXTERN double clock_getsystime(void); /* OBSOLETE; use clock_getlogicaltime() */
+EXTERN double clock_gettimesince(double prevsystime);
+EXTERN double clock_gettimesincewithunits(double prevsystime,
+    double units, int sampflag);
+EXTERN double clock_getsystimeafter(double delaytime);
+EXTERN void clock_free(t_clock *x);
+
+/* ----------------- pure data ---------------- */
+EXTERN t_pd *pd_new(t_class *cls);
+EXTERN void pd_free(t_pd *x);
+EXTERN void pd_bind(t_pd *x, t_symbol *s);
+EXTERN void pd_unbind(t_pd *x, t_symbol *s);
+EXTERN t_pd *pd_findbyclass(t_symbol *s, t_class *c);
+EXTERN void pd_pushsym(t_pd *x);
+EXTERN void pd_popsym(t_pd *x);
+EXTERN t_symbol *pd_getfilename(void);
+EXTERN t_symbol *pd_getdirname(void);
+EXTERN void pd_bang(t_pd *x);
+EXTERN void pd_pointer(t_pd *x, t_gpointer *gp);
+EXTERN void pd_float(t_pd *x, t_float f);
+EXTERN void pd_symbol(t_pd *x, t_symbol *s);
+EXTERN void pd_list(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void pd_anything(t_pd *x, t_symbol *s, int argc, t_atom *argv);
+#define pd_class(x) (*(x))
+
+/* ----------------- pointers ---------------- */
+EXTERN void gpointer_init(t_gpointer *gp);
+EXTERN void gpointer_copy(const t_gpointer *gpfrom, t_gpointer *gpto);
+EXTERN void gpointer_unset(t_gpointer *gp);
+EXTERN int gpointer_check(const t_gpointer *gp, int headok);
+
+/* ----------------- patchable "objects" -------------- */
+EXTERN t_inlet *inlet_new(t_object *owner, t_pd *dest, t_symbol *s1,
+    t_symbol *s2);
+EXTERN t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp);
+EXTERN t_inlet *floatinlet_new(t_object *owner, t_float *fp);
+EXTERN t_inlet *symbolinlet_new(t_object *owner, t_symbol **sp);
+EXTERN t_inlet *signalinlet_new(t_object *owner, t_float f);
+EXTERN void inlet_free(t_inlet *x);
+
+EXTERN t_outlet *outlet_new(t_object *owner, t_symbol *s);
+EXTERN void outlet_bang(t_outlet *x);
+EXTERN void outlet_pointer(t_outlet *x, t_gpointer *gp);
+EXTERN void outlet_float(t_outlet *x, t_float f);
+EXTERN void outlet_symbol(t_outlet *x, t_symbol *s);
+EXTERN void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
+EXTERN t_symbol *outlet_getsymbol(t_outlet *x);
+EXTERN void outlet_free(t_outlet *x);
+EXTERN t_object *pd_checkobject(t_pd *x);
+
+
+/* -------------------- canvases -------------- */
+
+EXTERN void glob_setfilename(void *dummy, t_symbol *name, t_symbol *dir);
+
+EXTERN void canvas_setargs(int argc, t_atom *argv);
+EXTERN void canvas_getargs(int *argcp, t_atom **argvp);
+EXTERN t_symbol *canvas_getcurrentdir(void);
+EXTERN t_glist *canvas_getcurrent(void);
+EXTERN void canvas_makefilename(t_glist *c, char *file,
+    char *result,int resultsize);
+EXTERN t_symbol *canvas_getdir(t_glist *x);
+EXTERN char sys_font[]; /* default typeface set in s_main.c */
+EXTERN char sys_fontweight[]; /* default font weight set in s_main.c */
+EXTERN int sys_fontwidth(int fontsize);
+EXTERN int sys_fontheight(int fontsize);
+EXTERN void canvas_dataproperties(t_glist *x, t_scalar *sc, t_binbuf *b);
+EXTERN int canvas_open(t_canvas *x, const char *name, const char *ext,
+    char *dirresult, char **nameresult, unsigned int size, int bin);
+
+/* ---------------- widget behaviors ---------------------- */
+
+EXTERN_STRUCT _widgetbehavior;
+#define t_widgetbehavior struct _widgetbehavior
+
+EXTERN_STRUCT _parentwidgetbehavior;
+#define t_parentwidgetbehavior struct _parentwidgetbehavior
+EXTERN t_parentwidgetbehavior *pd_getparentwidget(t_pd *x);
+
+/* -------------------- classes -------------- */
+
+#define CLASS_DEFAULT 0         /* flags for new classes below */
+#define CLASS_PD 1
+#define CLASS_GOBJ 2
+#define CLASS_PATCHABLE 3
+#define CLASS_NOINLET 8
+
+#define CLASS_TYPEMASK 3
+
+
+EXTERN t_class *class_new(t_symbol *name, t_newmethod newmethod,
+    t_method freemethod, size_t size, int flags, t_atomtype arg1, ...);
+EXTERN void class_addcreator(t_newmethod newmethod, t_symbol *s, 
+    t_atomtype type1, ...);
+EXTERN void class_addmethod(t_class *c, t_method fn, t_symbol *sel,
+    t_atomtype arg1, ...);
+EXTERN void class_addbang(t_class *c, t_method fn);
+EXTERN void class_addpointer(t_class *c, t_method fn);
+EXTERN void class_doaddfloat(t_class *c, t_method fn);
+EXTERN void class_addsymbol(t_class *c, t_method fn);
+EXTERN void class_addlist(t_class *c, t_method fn);
+EXTERN void class_addanything(t_class *c, t_method fn);
+EXTERN void class_sethelpsymbol(t_class *c, t_symbol *s);
+EXTERN void class_setwidget(t_class *c, t_widgetbehavior *w);
+EXTERN void class_setparentwidget(t_class *c, t_parentwidgetbehavior *w);
+EXTERN t_parentwidgetbehavior *class_parentwidget(t_class *c);
+EXTERN char *class_getname(t_class *c);
+EXTERN char *class_gethelpname(t_class *c);
+EXTERN char *class_gethelpdir(t_class *c);
+EXTERN void class_setdrawcommand(t_class *c);
+EXTERN int class_isdrawcommand(t_class *c);
+EXTERN void class_domainsignalin(t_class *c, int onset);
+EXTERN void class_set_extern_dir(t_symbol *s);
+#define CLASS_MAINSIGNALIN(c, type, field) \
+    class_domainsignalin(c, (char *)(&((type *)0)->field) - (char *)0)
+
+         /* prototype for functions to save Pd's to a binbuf */
+typedef void (*t_savefn)(t_gobj *x, t_binbuf *b);
+EXTERN void class_setsavefn(t_class *c, t_savefn f);
+EXTERN t_savefn class_getsavefn(t_class *c);
+EXTERN void obj_saveformat(t_object *x, t_binbuf *bb); /* add format to bb */
+
+        /* prototype for functions to open properties dialogs */
+typedef void (*t_propertiesfn)(t_gobj *x, struct _glist *glist);
+EXTERN void class_setpropertiesfn(t_class *c, t_propertiesfn f);
+EXTERN t_propertiesfn class_getpropertiesfn(t_class *c);
+
+#ifndef PD_CLASS_DEF
+#define class_addbang(x, y) class_addbang((x), (t_method)(y))
+#define class_addpointer(x, y) class_addpointer((x), (t_method)(y))
+#define class_addfloat(x, y) class_doaddfloat((x), (t_method)(y))
+#define class_addsymbol(x, y) class_addsymbol((x), (t_method)(y))
+#define class_addlist(x, y) class_addlist((x), (t_method)(y))
+#define class_addanything(x, y) class_addanything((x), (t_method)(y))
+#endif
+
+/* ------------   printing --------------------------------- */
+EXTERN void post(const char *fmt, ...);
+EXTERN void startpost(const char *fmt, ...);
+EXTERN void poststring(const char *s);
+EXTERN void postfloat(t_floatarg f);
+EXTERN void postatom(int argc, t_atom *argv);
+EXTERN void endpost(void);
+EXTERN void error(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
+EXTERN void verbose(int level, const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(2, 3);
+EXTERN void bug(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
+EXTERN void pd_error(void *object, const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(2, 3);
+EXTERN void logpost(const void *object, const int level, const char *fmt, ...)
+    ATTRIBUTE_FORMAT_PRINTF(3, 4);
+EXTERN void sys_logerror(const char *object, const char *s);
+EXTERN void sys_unixerror(const char *object);
+EXTERN void sys_ouch(void);
+
+
+/* ------------  system interface routines ------------------- */
+EXTERN int sys_isreadablefile(const char *name);
+EXTERN int sys_isabsolutepath(const char *dir);
+EXTERN void sys_bashfilename(const char *from, char *to);
+EXTERN void sys_unbashfilename(const char *from, char *to);
+EXTERN int open_via_path(const char *dir, const char *name, const char *ext,
+    char *dirresult, char **nameresult, unsigned int size, int bin);
+EXTERN int sched_geteventno(void);
+EXTERN double sys_getrealtime(void);
+EXTERN int (*sys_idlehook)(void);   /* hook to add idle time computation */
+
+/* Win32's open()/fopen() do not handle UTF-8 filenames so we need
+ * these internal versions that handle UTF-8 filenames the same across
+ * all platforms.  They are recommended for use in external
+ * objectclasses as well so they work with Unicode filenames on Windows */
+EXTERN int sys_open(const char *path, int oflag, ...);
+EXTERN int sys_close(int fd);
+EXTERN FILE *sys_fopen(const char *filename, const char *mode);
+EXTERN int sys_fclose(FILE *stream);
+
+/* ------------  threading ------------------- */ 
+EXTERN void sys_lock(void);
+EXTERN void sys_unlock(void);
+EXTERN int sys_trylock(void);
+
+
+/* --------------- signals ----------------------------------- */
+
+typedef PD_FLOATTYPE t_sample;
+typedef union _sampleint_union {
+  t_sample f;
+  PD_FLOATUINTTYPE i;
+} t_sampleint_union;
+#define MAXLOGSIG 32
+#define MAXSIGSIZE (1 << MAXLOGSIG)
+
+typedef struct _signal
+{
+    int s_n;            /* number of points in the array */
+    t_sample *s_vec;    /* the array */
+    t_float s_sr;         /* sample rate */
+    int s_refcount;     /* number of times used */
+    int s_isborrowed;   /* whether we're going to borrow our array */
+    struct _signal *s_borrowedfrom;     /* signal to borrow it from */
+    struct _signal *s_nextfree;         /* next in freelist */
+    struct _signal *s_nextused;         /* next in used list */
+    int s_vecsize;      /* allocated size of array in points */
+} t_signal;
+
+typedef t_int *(*t_perfroutine)(t_int *args);
+
+EXTERN t_int *plus_perform(t_int *args);
+EXTERN t_int *zero_perform(t_int *args);
+EXTERN t_int *copy_perform(t_int *args);
+
+EXTERN void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n);
+EXTERN void dsp_add_copy(t_sample *in, t_sample *out, int n);
+EXTERN void dsp_add_scalarcopy(t_float *in, t_sample *out, int n);
+EXTERN void dsp_add_zero(t_sample *out, int n);
+
+EXTERN int sys_getblksize(void);
+EXTERN t_float sys_getsr(void);
+EXTERN int sys_get_inchannels(void);
+EXTERN int sys_get_outchannels(void);
+
+EXTERN void dsp_add(t_perfroutine f, int n, ...);
+EXTERN void dsp_addv(t_perfroutine f, int n, t_int *vec);
+EXTERN void pd_fft(t_float *buf, int npoints, int inverse);
+EXTERN int ilog2(int n);
+
+EXTERN void mayer_fht(t_sample *fz, int n);
+EXTERN void mayer_fft(int n, t_sample *real, t_sample *imag);
+EXTERN void mayer_ifft(int n, t_sample *real, t_sample *imag);
+EXTERN void mayer_realfft(int n, t_sample *real);
+EXTERN void mayer_realifft(int n, t_sample *real);
+
+EXTERN float *cos_table;
+#define LOGCOSTABSIZE 9
+#define COSTABSIZE (1<<LOGCOSTABSIZE)
+
+EXTERN int canvas_suspend_dsp(void);
+EXTERN void canvas_resume_dsp(int oldstate);
+EXTERN void canvas_update_dsp(void);
+EXTERN int canvas_dspstate;
+
+/*   up/downsampling */
+typedef struct _resample
+{
+  int method;       /* up/downsampling method ID */
+
+  int downsample; /* downsampling factor */
+  int upsample;   /* upsampling factor */
+
+  t_sample *s_vec;   /* here we hold the resampled data */
+  int      s_n;
+
+  t_sample *coeffs;  /* coefficients for filtering... */
+  int      coefsize;
+
+  t_sample *buffer;  /* buffer for filtering */
+  int      bufsize;
+} t_resample;
+
+EXTERN void resample_init(t_resample *x);
+EXTERN void resample_free(t_resample *x);
+
+EXTERN void resample_dsp(t_resample *x, t_sample *in, int insize, t_sample *out, int outsize, int method);
+EXTERN void resamplefrom_dsp(t_resample *x, t_sample *in, int insize, int outsize, int method);
+EXTERN void resampleto_dsp(t_resample *x, t_sample *out, int insize, int outsize, int method);
+
+/* ----------------------- utility functions for signals -------------- */
+EXTERN t_float mtof(t_float);
+EXTERN t_float ftom(t_float);
+EXTERN t_float rmstodb(t_float);
+EXTERN t_float powtodb(t_float);
+EXTERN t_float dbtorms(t_float);
+EXTERN t_float dbtopow(t_float);
+
+EXTERN t_float q8_sqrt(t_float);
+EXTERN t_float q8_rsqrt(t_float);
+#ifndef N32     
+EXTERN t_float qsqrt(t_float);  /* old names kept for extern compatibility */
+EXTERN t_float qrsqrt(t_float);
+#endif
+/* --------------------- data --------------------------------- */
+
+    /* graphical arrays */
+EXTERN_STRUCT _garray;
+#define t_garray struct _garray
+
+EXTERN t_class *garray_class;
+EXTERN int garray_getfloatarray(t_garray *x, int *size, t_float **vec);
+EXTERN int garray_getfloatwords(t_garray *x, int *size, t_word **vec);
+EXTERN void garray_redraw(t_garray *x);
+EXTERN int garray_npoints(t_garray *x);
+EXTERN char *garray_vec(t_garray *x);
+EXTERN void garray_resize(t_garray *x, t_floatarg f);  /* avoid; use this: */
+EXTERN void garray_resize_long(t_garray *x, long n);   /* better version */
+EXTERN void garray_usedindsp(t_garray *x);
+EXTERN void garray_setsaveit(t_garray *x, int saveit);
+EXTERN t_glist *garray_getglist(t_garray *x);
+EXTERN t_array *garray_getarray(t_garray *x);
+EXTERN t_class *scalar_class;
+
+EXTERN t_float *value_get(t_symbol *s);
+EXTERN void value_release(t_symbol *s);
+EXTERN int value_getfloat(t_symbol *s, t_float *f);
+EXTERN int value_setfloat(t_symbol *s, t_float f);
+
+/* ------- GUI interface - functions to send strings to TK --------- */
+typedef void (*t_guicallbackfn)(t_gobj *client, t_glist *glist);
+
+EXTERN void sys_vgui(char *fmt, ...);
+EXTERN void sys_gui(char *s);
+EXTERN void sys_pretendguibytes(int n);
+EXTERN void sys_queuegui(void *client, t_glist *glist, t_guicallbackfn f);
+EXTERN void sys_unqueuegui(void *client);
+    /* dialog window creation and destruction */
+EXTERN void gfxstub_new(t_pd *owner, void *key, const char *cmd);
+EXTERN void gfxstub_deleteforkey(void *key);
+
+extern t_class *glob_pdobject;  /* object to send "pd" messages */
+
+/*-------------  Max 0.26 compatibility --------------------*/
+
+/* the following reflects the new way classes are laid out, with the class
+   pointing to the messlist and not vice versa. Externs shouldn't feel it. */
+typedef t_class *t_externclass;
+
+EXTERN void c_extern(t_externclass *cls, t_newmethod newroutine,
+    t_method freeroutine, t_symbol *name, size_t size, int tiny, \
+    t_atomtype arg1, ...);
+EXTERN void c_addmess(t_method fn, t_symbol *sel, t_atomtype arg1, ...);
+
+#define t_getbytes getbytes
+#define t_freebytes freebytes
+#define t_resizebytes resizebytes
+#define typedmess pd_typedmess
+#define vmess pd_vmess
+
+/* A definition to help gui objects straddle 0.34-0.35 changes.  If this is
+defined, there is a "te_xpix" field in objects, not a "te_xpos" as before: */
+
+#define PD_USE_TE_XPIX
+
+#ifndef _MSC_VER /* Microoft compiler can't handle "inline" function/macros */
+#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
+/* a test for NANs and denormals.  Should only be necessary on i386. */
+# if PD_FLOATSIZE == 32
+static inline int PD_BADFLOAT(t_sample f) {
+  t_sampleint_union u;
+  u.f=f;
+  return ((u.i & 0x7f800000)==0) || ((u.i&0x7f800000)==0x7f800000);
+}
+/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */
+static inline int PD_BIGORSMALL(t_sample f) {
+  t_sampleint_union u;
+  u.f=f;
+  return ((u.i & 0x60000000)==0) || ((u.i & 0x60000000)==0x60000000);
+}
+# else
+#  warning 64bit mode: BIGORSMALL not implemented yet
+#  define PD_BADFLOAT(f) 0
+#  define PD_BIGORSMALL(f) 0
+# endif
+#else
+# define PD_BADFLOAT(f) 0
+# define PD_BIGORSMALL(f) 0
+#endif
+#else   /* _MSC_VER */
+#define PD_BADFLOAT(f) ((((*(unsigned int*)&(f))&0x7f800000)==0) || \
+    (((*(unsigned int*)&(f))&0x7f800000)==0x7f800000))
+/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */
+#define PD_BIGORSMALL(f) ((((*(unsigned int*)&(f))&0x60000000)==0) || \
+    (((*(unsigned int*)&(f))&0x60000000)==0x60000000))
+#endif /* _MSC_VER */
+    /* get version number at run time */
+EXTERN void sys_getversion(int *major, int *minor, int *bugfix);
+
+EXTERN_STRUCT _pdinstance;
+#define t_pdinstance struct _pdinstance       /* m_imp.h */
+
+/* m_pd.c */
+
+EXTERN t_pdinstance *pdinstance_new( void);
+EXTERN void pd_setinstance(t_pdinstance *x);
+EXTERN void pdinstance_free(t_pdinstance *x);
+EXTERN t_canvas *pd_getcanvaslist(void);
+EXTERN int pd_getdspstate(void);
+
+#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
+}
+#endif
+
+#define __m_pd_h_
+#endif /* __m_pd_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/basic_libpd/main.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,91 @@
+/*
+ * default_main.cpp
+ *
+ *  Created on: Oct 24, 2014
+ *      Author: parallels
+ */
+#include <unistd.h>
+#include <iostream>
+#include <cstdlib>
+#include <libgen.h>
+#include <signal.h>
+#include <getopt.h>
+#include "../include/BeagleRT.h"
+
+using namespace std;
+
+// Handle Ctrl-C by requesting that the audio rendering stop
+void interrupt_handler(int var)
+{
+	gShouldStop = true;
+}
+
+// Print usage information
+void usage(const char * processName)
+{
+	cerr << "Usage: " << processName << " [options]" << endl;
+
+	BeagleRT_usage();
+
+	cerr << "   --help [-h]:                Print this menu\n";
+}
+
+int main(int argc, char *argv[])
+{
+	BeagleRTInitSettings settings;	// Standard audio settings
+
+	struct option customOptions[] =
+	{
+		{"help", 0, NULL, 'h'},
+		{NULL, 0, NULL, 0}
+	};
+
+	// Set default settings
+	BeagleRT_defaultSettings(&settings);
+
+	// Parse command-line arguments
+	while (1) {
+		int c;
+		if ((c = BeagleRT_getopt_long(argc, argv, "h", customOptions, &settings)) < 0)
+				break;
+		switch (c) {
+		case 'h':
+				usage(basename(argv[0]));
+				exit(0);
+		case '?':
+		default:
+				usage(basename(argv[0]));
+				exit(1);
+		}
+	}
+
+	// Initialise the PRU audio device
+	if(BeagleRT_initAudio(&settings, 0) != 0) {
+		cout << "Error: unable to initialise audio" << endl;
+		return -1;
+	}
+
+	// Start the audio device running
+	if(BeagleRT_startAudio()) {
+		cout << "Error: unable to start real-time audio" << endl;
+		return -1;
+	}
+
+	// Set up interrupt handler to catch Control-C and SIGTERM
+	signal(SIGINT, interrupt_handler);
+	signal(SIGTERM, interrupt_handler);
+
+	// Run until told to stop
+	while(!gShouldStop) {
+		usleep(100000);
+	}
+
+	// Stop the audio device
+	BeagleRT_stopAudio();
+
+	// Clean up any resources allocated for audio
+	BeagleRT_cleanupAudio();
+
+	// All done!
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/basic_libpd/render.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,187 @@
+/*
+ * render.cpp
+ *
+ *  Created on: Oct 24, 2014
+ *      Author: parallels
+ */
+
+#include <BeagleRT.h>
+#include <cmath>
+#include <Utilities.h>
+#include <I2c_Codec.h>
+#include <PRU.h>
+#include <stdio.h>
+#include "z_libpd.h"
+#include <UdpServer.h>
+
+// setup() is called once before the audio rendering starts.
+// Use it to perform any initialisation and allocation which is dependent
+// on the period size or sample rate.
+//
+// userData holds an opaque pointer to a data structure that was passed
+// in from the call to initAudio().
+//
+// Return true on success; returning false halts the program.
+#define DEFDACBLKSIZE 8u  //make sure this matches the one used to compile libpd
+
+int gChannelsInUse = 10;
+int gBufLength;
+
+float* gInBuf;
+float* gOutBuf;
+
+void pdnoteon(int ch, int pitch, int vel) {
+  printf("noteon: %d %d %d\n", ch, pitch, vel);
+}
+
+void BeagleRT_printHook(const char *recv){
+	rt_printf("%s", recv);
+}
+
+UdpServer udpServer;
+
+void udpRead(){
+    char dest[100] = {0};
+    while(!gShouldStop){
+    	libpd_sys_microsleep(0);
+        usleep(1000);
+    }
+}
+
+AuxiliaryTask  udpReadTask;
+bool setup(BeagleRTContext *context, void *userData)
+{
+	gChannelsInUse = min((int)(context->analogChannels+context->audioChannels), (int)gChannelsInUse);
+	udpServer.bindToPort(1234);
+
+	// check that we are not running with a blocksize smaller than DEFDACBLKSIZE
+	// it would still work, but the load would be executed unevenly between calls to render
+	if(context->audioFrames < DEFDACBLKSIZE){
+		fprintf(stderr, "Error: minimum block size must be %d\n", DEFDACBLKSIZE);
+		return false;
+	}
+
+	// check that the sampling rate of the analogs is the same as audio if running with
+	// more than 2 channels (that is with analog). If we fix the TODO in render, then
+	// this test is not needed.
+//	if(context->analogFrames != context->audioFrames){
+//		fprintf(stderr, "Error: analog and audio sampling rates must be the same\n");
+//		return false;
+//	}
+	//following lines borrowed from libpd/samples/c/pdtest/pdtest.c
+	// init pd
+	libpd_set_printhook(BeagleRT_printHook); // set this before calling libpd_init
+	libpd_set_noteonhook(pdnoteon);
+	libpd_init();
+	//TODO: analyse the ASCII of the patch file and find the in/outs to use
+	libpd_init_audio(gChannelsInUse, gChannelsInUse, context->audioSampleRate);
+
+	libpd_start_message(1); // one entry in list
+	libpd_add_float(1.0f);
+	libpd_finish_message("pd", "dsp");
+
+	gBufLength = max(DEFDACBLKSIZE, context->audioFrames);
+	unsigned int bufferSize = sizeof(float)*gChannelsInUse*gBufLength;
+	gInBuf = (float*)malloc(bufferSize);
+	gOutBuf = (float*)malloc(bufferSize);
+	// no need to memset to zero
+
+	char file[] = "_main.pd";
+	char folder[] = "./";
+	// open patch       [; pd open file folder(
+	libpd_openfile(file, folder);
+    
+	udpReadTask = BeagleRT_createAuxiliaryTask(udpRead, 60, "udpReadTask");
+	BeagleRT_scheduleAuxiliaryTask(udpReadTask);
+	return true;
+}
+
+// render() is called regularly at the highest priority by the audio engine.
+// Input and output are given from the audio hardware and the other
+// ADCs and DACs (if available). If only audio is available, numMatrixFrames
+// will be 0.
+BeagleRTContext *c;
+void render(BeagleRTContext *context, void *userData)
+{
+	static int inW = 0;
+	static int outR = 0;
+/*
+ *	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 DEFDACBLKSIZE, then you probably
+ *	 do not need the for loops before and after libpd_process_float, so you can save quite some
+ *	 memory operations.
+ */
+	static int analogChannelsInUse = min(context->analogChannels, gChannelsInUse - context->audioChannels);
+	// rt_printf("channelsInUse: %d, analogChannels in Use: %d\n", gChannelsInUse, analogChannelsInUse);
+	for(unsigned int n = 0; n < context->audioFrames; ++n){ //pd buffers are interleaved
+		for(unsigned int ch = 0; ch < context->audioChannels; ++ch){ //first two channels are audio
+			gInBuf[inW++] = audioReadFrame(context, n, ch);
+		}
+		// then analogs
+		// this loop resamples by ZOH, as needed, using m
+		if(context->analogChannels == 8 ){ //hold the value for two frames
+			for(int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){
+				gInBuf[inW++] = analogReadFrame(context, n/2, analogCh); // n/2 wil be the same for n and n+1 when n is even
+			}
+		} else if(context->analogChannels == 4){ //write every frame
+			for(int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){
+				gInBuf[inW++] = analogReadFrame(context, n, analogCh);
+			}
+		} else if(context->analogChannels == 2){ //drop every other frame
+			for(int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){
+				gInBuf[inW++] = analogReadFrame(context, n*2, analogCh);
+			}
+		}
+		if(inW == gBufLength * gChannelsInUse){
+			inW = 0;
+		}
+	}
+	// rt_printf("inW %d\n", inW);
+	if(inW == 0){ //if the buffer is full, process it
+		static int numberOfPdBlocksToProcess = gBufLength/DEFDACBLKSIZE;
+		libpd_process_float(numberOfPdBlocksToProcess, gInBuf, gOutBuf);
+		outR = 0; // reset the read pointer. NOTE: hopefully this is needed only the first time
+	}
+
+	for(unsigned int n = 0; n < context->audioFrames; n++){ //pd buffers are interleaved
+		for(unsigned int ch = 0; ch < context->audioChannels; ++ch){
+			audioWriteFrame(context, n, ch, gOutBuf[outR++]);
+		}
+		//and analogs
+		if(context->analogChannels == 8){
+			for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){
+				float analogOut = gOutBuf[outR++];				
+				if((n&1) == 0){//write every two frames
+					analogWriteFrame(context, n/2, analogCh, analogOut);
+				} else {
+					// discard this sample
+				}
+			}
+		} else if(context->analogChannels == 4){ //write every frame
+			for(int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){
+				float analogOut = gOutBuf[outR++];
+				analogWriteFrame(context, n, analogCh, analogOut);
+			}
+		} else if(context->analogChannels == 2){ //write twice every frame
+			for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){
+				float analogOut = gOutBuf[outR++];
+				analogWriteFrame(context, 2*n, analogCh, analogOut);
+				analogWriteFrame(context, 2*n + 1, analogCh, analogOut);
+			}
+		}
+		if(outR == gBufLength * gChannelsInUse){
+			outR = 0;
+		}
+	}
+	// rt_printf("outR %d, analogChannelsInUse %d, channelsInUse %d\n", 
+	// 	outR , analogChannelsInUse, gChannelsInUse);
+}
+
+// cleanup() is called once at the end, after the audio has stopped.
+// Release any resources that were allocated in setup().
+
+void cleanup(BeagleRTContext *context, void *userData)
+{
+	free(gInBuf);
+	free(gOutBuf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/basic_libpd/s_stuff.h	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,411 @@
+/* Copyright (c) 1997-1999 Miller Puckette.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */
+
+/* Audio and MIDI I/O, and other scheduling and system stuff. */
+
+/* NOTE: this file describes Pd implementation details which may change
+in future releases.  The public (stable) API is in m_pd.h. */  
+
+/* in s_path.c */
+
+typedef struct _namelist    /* element in a linked list of stored strings */
+{
+    struct _namelist *nl_next;  /* next in list */
+    char *nl_string;            /* the string */
+} t_namelist;
+
+t_namelist *namelist_append(t_namelist *listwas, const char *s, int allowdup);
+t_namelist *namelist_append_files(t_namelist *listwas, const char *s);
+void namelist_free(t_namelist *listwas);
+char *namelist_get(t_namelist *namelist, int n);
+void sys_setextrapath(const char *p);
+extern int sys_usestdpath;
+extern t_namelist *sys_externlist;
+extern t_namelist *sys_searchpath;
+extern t_namelist *sys_helppath;
+int sys_open_absolute(const char *name, const char* ext,
+    char *dirresult, char **nameresult, unsigned int size, int bin, int *fdp);
+int sys_trytoopenone(const char *dir, const char *name, const char* ext,
+    char *dirresult, char **nameresult, unsigned int size, int bin);
+t_symbol *sys_decodedialog(t_symbol *s);
+
+/* s_file.c */
+
+void sys_loadpreferences( void);
+void sys_savepreferences( void);
+extern int sys_defeatrt;
+extern t_symbol *sys_flags;
+
+/* s_main.c */
+extern int sys_debuglevel;
+extern int sys_verbose;
+extern int sys_noloadbang;
+extern int sys_nogui;
+extern char *sys_guicmd;
+
+EXTERN int sys_nearestfontsize(int fontsize);
+EXTERN int sys_hostfontsize(int fontsize);
+
+extern int sys_defaultfont;
+EXTERN t_symbol *sys_libdir;    /* library directory for auxilliary files */
+extern t_symbol *sys_guidir;    /* directory holding pd_gui, u_pdsend, etc */
+
+/* s_loader.c */
+
+typedef int (*loader_t)(t_canvas *canvas, char *classname); /* callback type */
+EXTERN int sys_load_lib(t_canvas *canvas, char *filename);
+EXTERN void sys_register_loader(loader_t loader);
+
+/* s_audio.c */
+
+#define SENDDACS_NO 0           /* return values for sys_send_dacs() */
+#define SENDDACS_YES 1 
+#define SENDDACS_SLEPT 2
+
+#define DEFDACBLKSIZE 8
+extern int sys_schedblocksize;  /* audio block size for scheduler */
+extern int sys_hipriority;      /* real-time flag, true if priority boosted */
+EXTERN t_sample *sys_soundout;
+EXTERN t_sample *sys_soundin;
+extern int sys_inchannels;
+extern int sys_outchannels;
+extern int sys_advance_samples; /* scheduler advance in samples */
+extern int sys_blocksize;       /* audio I/O block size in sample frames */
+extern t_float sys_dacsr;
+extern int sys_schedadvance;
+extern int sys_sleepgrain;
+EXTERN void sys_set_audio_settings(int naudioindev, int *audioindev,
+    int nchindev, int *chindev,
+    int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev,
+    int srate, int advance, int callback, int blocksize);
+/* the same as above, but reopens the audio subsystem if needed */
+EXTERN void sys_set_audio_settings_reopen(int naudioindev, int *audioindev,
+    int nchindev, int *chindev,
+    int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev,
+    int srate, int advance, int callback, int blocksize);
+EXTERN void sys_reopen_audio( void);
+EXTERN void sys_close_audio(void);
+    /* return true if the interface prefers always being open (ala jack) : */
+EXTERN int audio_shouldkeepopen( void);
+EXTERN int audio_isopen( void);     /* true if audio interface is open */
+EXTERN int sys_audiodevnametonumber(int output, const char *name);
+EXTERN void sys_audiodevnumbertoname(int output, int devno, char *name,
+    int namesize);
+
+int sys_send_dacs(void);
+void sys_reportidle(void);
+void sys_set_priority(int higher);
+void sys_audiobuf(int nbufs);
+void sys_getmeters(t_sample *inmax, t_sample *outmax);
+void sys_listdevs(void);
+void sys_setblocksize(int n);
+
+EXTERN void sys_get_audio_devs(char *indevlist, int *nindevs,
+                          char *outdevlist, int *noutdevs, int *canmulti, int *cancallback, 
+                          int maxndev, int devdescsize);
+EXTERN void sys_get_audio_apis(char *buf);
+
+/* s_midi.c */
+#define MAXMIDIINDEV 16         /* max. number of input ports */
+#define MAXMIDIOUTDEV 16        /* max. number of output ports */
+extern int sys_midiapi;
+extern int sys_nmidiin;
+extern int sys_nmidiout;
+extern int sys_midiindevlist[];
+extern int sys_midioutdevlist[];
+
+EXTERN void sys_open_midi(int nmidiin, int *midiinvec,
+    int nmidiout, int *midioutvec, int enable);
+
+EXTERN void sys_get_midi_apis(char *buf);
+EXTERN void sys_get_midi_devs(char *indevlist, int *nindevs,
+    char *outdevlist, int *noutdevs, 
+   int maxndev, int devdescsize);
+EXTERN void sys_get_midi_params(int *pnmidiindev, int *pmidiindev,
+    int *pnmidioutdev, int *pmidioutdev);
+EXTERN int sys_mididevnametonumber(int output, const char *name);
+EXTERN void sys_mididevnumbertoname(int output, int devno, char *name,
+    int namesize);
+
+EXTERN void sys_reopen_midi( void);
+EXTERN void sys_close_midi( void);
+EXTERN void sys_putmidimess(int portno, int a, int b, int c);
+EXTERN void sys_putmidibyte(int portno, int a);
+EXTERN void sys_poll_midi(void);
+EXTERN void sys_setmiditimediff(double inbuftime, double outbuftime);
+EXTERN void sys_midibytein(int portno, int byte);
+
+    /* implemented in the system dependent MIDI code (s_midi_pm.c, etc. ) */
+void midi_getdevs(char *indevlist, int *nindevs,
+    char *outdevlist, int *noutdevs, int maxndev, int devdescsize);
+void sys_do_open_midi(int nmidiindev, int *midiindev,
+    int nmidioutdev, int *midioutdev);
+
+#ifdef USEAPI_ALSA
+EXTERN void sys_alsa_putmidimess(int portno, int a, int b, int c);
+EXTERN void sys_alsa_putmidibyte(int portno, int a);
+EXTERN void sys_alsa_poll_midi(void);
+EXTERN void sys_alsa_setmiditimediff(double inbuftime, double outbuftime);
+EXTERN void sys_alsa_midibytein(int portno, int byte);
+EXTERN void sys_alsa_close_midi( void);
+
+
+    /* implemented in the system dependent MIDI code (s_midi_pm.c, etc. ) */
+void midi_alsa_getdevs(char *indevlist, int *nindevs,
+    char *outdevlist, int *noutdevs, int maxndev, int devdescsize);
+void sys_alsa_do_open_midi(int nmidiindev, int *midiindev,
+    int nmidioutdev, int *midioutdev);
+#endif
+
+/* m_sched.c */
+EXTERN void sys_log_error(int type);
+#define ERR_NOTHING 0
+#define ERR_ADCSLEPT 1
+#define ERR_DACSLEPT 2
+#define ERR_RESYNC 3
+#define ERR_DATALATE 4
+
+#define SCHED_AUDIO_NONE 0
+#define SCHED_AUDIO_POLL 1 
+#define SCHED_AUDIO_CALLBACK 2
+void sched_set_using_audio(int flag);
+
+/* s_inter.c */
+
+EXTERN void sys_microsleep(int microsec);
+EXTERN void sys_init_fdpoll(void);
+
+EXTERN void sys_bail(int exitcode);
+EXTERN int sys_pollgui(void);
+
+EXTERN_STRUCT _socketreceiver;
+#define t_socketreceiver struct _socketreceiver
+
+typedef void (*t_socketnotifier)(void *x, int n);
+typedef void (*t_socketreceivefn)(void *x, t_binbuf *b);
+
+EXTERN t_socketreceiver *socketreceiver_new(void *owner,
+    t_socketnotifier notifier, t_socketreceivefn socketreceivefn, int udp);
+EXTERN void socketreceiver_read(t_socketreceiver *x, int fd);
+EXTERN void sys_sockerror(char *s);
+EXTERN void sys_closesocket(int fd);
+
+typedef void (*t_fdpollfn)(void *ptr, int fd);
+EXTERN void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr);
+EXTERN void sys_rmpollfn(int fd);
+#if defined(USEAPI_OSS) || defined(USEAPI_ALSA)
+void sys_setalarm(int microsec);
+#endif
+
+#define API_NONE 0
+#define API_ALSA 1
+#define API_OSS 2
+#define API_MMIO 3
+#define API_PORTAUDIO 4
+#define API_JACK 5
+#define API_SGI 6           /* gone */
+#define API_AUDIOUNIT 7
+#define API_ESD 8           /* no idea what this was, probably gone now */
+#define API_DUMMY 9
+
+    /* figure out which API should be the default.  The one we judge most
+    likely to offer a working device takes precedence so that if you
+    start up Pd for the first time there's a reasonable chance you'll have
+    sound.  (You'd think portaudio would be best but it seems to default
+    to jack on linux, and and on Windows we only use it for ASIO). 
+    If nobody shows up, define DUMMY and make it the default.*/
+#if defined(USEAPI_MMIO)
+# define API_DEFAULT API_MMIO
+# define API_DEFSTRING "MMIO"
+#elif defined(USEAPI_ALSA)
+# define API_DEFAULT API_ALSA
+# define API_DEFSTRING "ALSA"
+#elif defined(USEAPI_OSS)
+# define API_DEFAULT API_OSS
+# define API_DEFSTRING "OSS"
+#elif defined(USEAPI_AUDIOUNIT)
+# define API_DEFAULT API_AUDIOUNIT
+# define API_DEFSTRING "AudioUnit"
+#elif defined(USEAPI_ESD)
+# define API_DEFAULT API_ESD
+# define API_DEFSTRING "ESD (?)"
+#elif defined(USEAPI_PORTAUDIO)
+# define API_DEFAULT API_PORTAUDIO
+# define API_DEFSTRING "portaudio"
+#elif defined(USEAPI_JACK)
+# define API_DEFAULT API_JACK
+# define API_DEFSTRING "Jack audio connection kit"
+#else 
+# ifndef USEAPI_DUMMY   /* we need at least one so bring in the dummy */
+# define USEAPI_DUMMY
+# endif /* USEAPI_DUMMY */
+# define API_DEFAULT API_DUMMY
+# define API_DEFSTRING "dummy audio"
+#endif 
+
+#define DEFAULTAUDIODEV 0
+
+#define MAXAUDIOINDEV 4
+#define MAXAUDIOOUTDEV 4
+
+#define DEFMIDIDEV 0
+
+#define DEFAULTSRATE 44100
+#ifdef _WIN32
+#define DEFAULTADVANCE 80
+#else
+#ifdef __APPLE__
+#define DEFAULTADVANCE 5    /* this is in addition to their own delay */
+#else
+#define DEFAULTADVANCE 25
+#endif
+#endif
+
+typedef void (*t_audiocallback)(void);
+
+int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin,
+    t_sample *soundout, int framesperbuf, int nbuffers,
+    int indeviceno, int outdeviceno, t_audiocallback callback);
+void pa_close_audio(void);
+int pa_send_dacs(void);
+void sys_reportidle(void);
+void pa_listdevs(void);
+void pa_getdevs(char *indevlist, int *nindevs,
+    char *outdevlist, int *noutdevs, int *canmulti, 
+        int maxndev, int devdescsize);
+
+int oss_open_audio(int naudioindev, int *audioindev, int nchindev,
+    int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
+    int *choutdev, int rate, int blocksize);
+void oss_close_audio(void);
+int oss_send_dacs(void);
+void oss_reportidle(void);
+void oss_getdevs(char *indevlist, int *nindevs,
+    char *outdevlist, int *noutdevs, int *canmulti, 
+        int maxndev, int devdescsize);
+
+int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
+    int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
+    int *choutdev, int rate, int blocksize);
+void alsa_close_audio(void);
+int alsa_send_dacs(void);
+void alsa_reportidle(void);
+void alsa_getdevs(char *indevlist, int *nindevs,
+    char *outdevlist, int *noutdevs, int *canmulti, 
+        int maxndev, int devdescsize);
+
+int jack_open_audio(int wantinchans, int wantoutchans, int srate,
+    t_audiocallback callback);
+void jack_close_audio(void);
+int jack_send_dacs(void);
+void jack_reportidle(void);
+void jack_getdevs(char *indevlist, int *nindevs,
+    char *outdevlist, int *noutdevs, int *canmulti, 
+        int maxndev, int devdescsize);
+void jack_listdevs(void);
+
+int mmio_open_audio(int naudioindev, int *audioindev,
+    int nchindev, int *chindev, int naudiooutdev, int *audiooutdev,
+    int nchoutdev, int *choutdev, int rate, int blocksize);
+void mmio_close_audio( void);
+void mmio_reportidle(void);
+int mmio_send_dacs(void);
+void mmio_getdevs(char *indevlist, int *nindevs,
+    char *outdevlist, int *noutdevs, int *canmulti, 
+        int maxndev, int devdescsize);
+
+int audiounit_open_audio(int naudioindev, int *audioindev, int nchindev,
+    int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
+    int *choutdev, int rate);
+void audiounit_close_audio(void);
+int audiounit_send_dacs(void);
+void audiounit_listdevs(void);
+void audiounit_getdevs(char *indevlist, int *nindevs,
+    char *outdevlist, int *noutdevs, int *canmulti, 
+        int maxndev, int devdescsize);
+
+int esd_open_audio(int naudioindev, int *audioindev, int nchindev,
+    int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
+    int *choutdev, int rate);
+void esd_close_audio(void);
+int esd_send_dacs(void);
+void esd_listdevs(void);
+void esd_getdevs(char *indevlist, int *nindevs,
+    char *outdevlist, int *noutdevs, int *canmulti, 
+        int maxndev, int devdescsize);
+
+int dummy_open_audio(int nin, int nout, int sr);
+int dummy_close_audio( void);
+int dummy_send_dacs( void);
+void dummy_getdevs(char *indevlist, int *nindevs, char *outdevlist,
+    int *noutdevs, int *canmulti, int maxndev, int devdescsize);
+void dummy_listdevs( void);
+
+void sys_listmididevs(void);
+EXTERN void sys_set_midi_api(int whichapi);
+EXTERN void sys_set_audio_api(int whichapi);
+EXTERN int sys_audioapi;
+EXTERN void sys_set_audio_state(int onoff);
+
+/* API dependent audio flags and settings */
+void oss_set32bit( void);
+void linux_alsa_devname(char *devname);
+
+EXTERN void sys_get_audio_params(
+    int *pnaudioindev, int *paudioindev, int *chindev,
+    int *pnaudiooutdev, int *paudiooutdev, int *choutdev,
+    int *prate, int *padvance, int *callback, int *blocksize);
+void sys_save_audio_params(
+    int naudioindev, int *audioindev, int *chindev,
+    int naudiooutdev, int *audiooutdev, int *choutdev,
+    int rate, int advance, int callback, int blocksize);
+
+/* s_file.c */
+
+typedef void (*t_printhook)(const char *s);
+extern t_printhook sys_printhook;  /* set this to override printing */
+extern int sys_printtostderr;
+
+/* jsarlo { */
+
+EXTERN double sys_time;
+EXTERN double sys_time_per_dsp_tick;
+EXTERN int sys_externalschedlib;
+
+EXTERN t_sample* get_sys_soundout(void ) ;
+EXTERN t_sample* get_sys_soundin(void ) ;
+EXTERN int* get_sys_main_advance(void ) ;
+EXTERN double* get_sys_time_per_dsp_tick(void ) ;
+EXTERN int* get_sys_schedblocksize(void ) ;
+EXTERN double* get_sys_time(void ) ;
+EXTERN t_float* get_sys_dacsr(void ) ;
+EXTERN int* get_sys_sleepgrain(void ) ;
+EXTERN int* get_sys_schedadvance(void ) ;
+
+EXTERN void sys_clearhist(void );
+EXTERN void sys_initmidiqueue(void );
+EXTERN int sys_addhist(int phase);
+EXTERN void sys_setmiditimediff(double inbuftime, double outbuftime);
+EXTERN void sched_tick( void);
+EXTERN void sys_pollmidiqueue(void );
+EXTERN int sys_pollgui(void );
+EXTERN void sys_setchsr(int chin, int chout, int sr);
+
+EXTERN void inmidi_realtimein(int portno, int cmd);
+EXTERN void inmidi_byte(int portno, int byte);
+EXTERN void inmidi_sysex(int portno, int byte);
+EXTERN void inmidi_noteon(int portno, int channel, int pitch, int velo);
+EXTERN void inmidi_controlchange(int portno,
+                                 int channel,
+                                 int ctlnumber,
+                                 int value);
+EXTERN void inmidi_programchange(int portno, int channel, int value);
+EXTERN void inmidi_pitchbend(int portno, int channel, int value);
+EXTERN void inmidi_aftertouch(int portno, int channel, int value);
+EXTERN void inmidi_polyaftertouch(int portno,
+                                  int channel,
+                                  int pitch,
+                                  int value);
+/* } jsarlo */
+extern t_widgetbehavior text_widgetbehavior;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/basic_libpd/z_libpd.h	Sun Apr 10 04:08:06 2016 +0200
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2010 Peter Brinkmann (peter.brinkmann@gmail.com)
+ *
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+ *
+ * See https://github.com/libpd/libpd/wiki for documentation
+ *
+ */
+
+#ifndef __Z_LIBPD_H__
+#define __Z_LIBPD_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "m_pd.h"
+
+EXTERN int libpd_init(void);
+EXTERN void libpd_clear_search_path(void);
+EXTERN void libpd_add_to_search_path(const char *sym);
+
+EXTERN void *libpd_openfile(const char *basename, const char *dirname);
+EXTERN void libpd_closefile(void *p);
+EXTERN int libpd_getdollarzero(void *p);
+
+EXTERN int libpd_blocksize(void);
+EXTERN int libpd_init_audio(int inChans, int outChans, int sampleRate);
+EXTERN int libpd_process_raw(const float *inBuffer, float *outBuffer);
+EXTERN int libpd_process_short(const int ticks,
+    const short *inBuffer, short *outBuffer);
+EXTERN int libpd_process_float(int ticks,
+    const float *inBuffer, float *outBuffer);
+EXTERN int libpd_process_double(int ticks,
+    const double *inBuffer, double *outBuffer);
+
+EXTERN int libpd_arraysize(const char *name);
+// The parameters of the next two functions are inspired by memcpy.
+EXTERN int libpd_read_array(float *dest, const char *src, int offset, int n);
+EXTERN int libpd_write_array(const char *dest, int offset, float *src, int n);
+
+EXTERN int libpd_bang(const char *recv);
+EXTERN int libpd_float(const char *recv, float x);
+EXTERN int libpd_symbol(const char *recv, const char *sym);
+
+EXTERN void libpd_set_float(t_atom *v, float x);
+EXTERN void libpd_set_symbol(t_atom *v, const char *sym);
+EXTERN int libpd_list(const char *recv, int argc, t_atom *argv);
+EXTERN int libpd_message(const char *recv, const char *msg, int argc, t_atom *argv);
+
+EXTERN int libpd_start_message(int max_length);
+EXTERN void libpd_add_float(float x);
+EXTERN void libpd_add_symbol(const char *sym);
+EXTERN int libpd_finish_list(const char *recv);
+EXTERN int libpd_finish_message(const char *recv, const char *msg);
+
+EXTERN int libpd_exists(const char *sym);
+EXTERN void *libpd_bind(const char *sym);
+EXTERN void libpd_unbind(void *p);
+
+EXTERN int libpd_is_float(t_atom *a);
+EXTERN int libpd_is_symbol(t_atom *a);
+EXTERN float libpd_get_float(t_atom *a);
+EXTERN char *libpd_get_symbol(t_atom *a);
+EXTERN t_atom *libpd_next_atom(t_atom *a);
+
+typedef void (*t_libpd_printhook)(const char *recv);
+typedef void (*t_libpd_banghook)(const char *recv);
+typedef void (*t_libpd_floathook)(const char *recv, float x);
+typedef void (*t_libpd_symbolhook)(const char *recv, const char *sym);
+typedef void (*t_libpd_listhook)(const char *recv, int argc, t_atom *argv);
+typedef void (*t_libpd_messagehook)(const char *recv, const char *msg,
+    int argc, t_atom *argv);
+
+EXTERN void libpd_set_printhook(const t_libpd_printhook hook);
+EXTERN void libpd_set_banghook(const t_libpd_banghook hook);
+EXTERN void libpd_set_floathook(const t_libpd_floathook hook);
+EXTERN void libpd_set_symbolhook(const t_libpd_symbolhook hook);
+EXTERN void libpd_set_listhook(const t_libpd_listhook hook);
+EXTERN void libpd_set_messagehook(const t_libpd_messagehook hook);
+
+EXTERN int libpd_noteon(int channel, int pitch, int velocity);
+EXTERN int libpd_controlchange(int channel, int controller, int value);
+EXTERN int libpd_programchange(int channel, int value);
+EXTERN int libpd_pitchbend(int channel, int value);
+EXTERN int libpd_aftertouch(int channel, int value);
+EXTERN int libpd_polyaftertouch(int channel, int pitch, int value);
+EXTERN int libpd_midibyte(int port, int byte);
+EXTERN int libpd_sysex(int port, int byte);
+EXTERN int libpd_sysrealtime(int port, int byte);
+
+typedef void (*t_libpd_noteonhook)(int channel, int pitch, int velocity);
+typedef void (*t_libpd_controlchangehook)(int channel,
+    int controller, int value);
+typedef void (*t_libpd_programchangehook)(int channel, int value);
+typedef void (*t_libpd_pitchbendhook)(int channel, int value);
+typedef void (*t_libpd_aftertouchhook)(int channel, int value);
+typedef void (*t_libpd_polyaftertouchhook)(int channel, int pitch, int value);
+typedef void (*t_libpd_midibytehook)(int port, int byte);
+
+EXTERN void libpd_set_noteonhook(const t_libpd_noteonhook hook);
+EXTERN void libpd_set_controlchangehook(const t_libpd_controlchangehook hook);
+EXTERN void libpd_set_programchangehook(const t_libpd_programchangehook hook);
+EXTERN void libpd_set_pitchbendhook(const t_libpd_pitchbendhook hook);
+EXTERN void libpd_set_aftertouchhook(const t_libpd_aftertouchhook hook);
+EXTERN void libpd_set_polyaftertouchhook(const t_libpd_polyaftertouchhook hook);
+EXTERN void libpd_set_midibytehook(const t_libpd_midibytehook hook);
+EXTERN void libpd_sys_microsleep(int sleep);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- a/projects/basic_midi/render.cpp	Sat Feb 13 01:51:01 2016 +0000
+++ b/projects/basic_midi/render.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -12,6 +12,25 @@
 #include <rtdk.h>
 #include <cmath>
 
+float gFreq;
+float gPhaseIncrement = 0;
+bool gIsNoteOn = 0;
+int gVelocity = 0;
+float gSamplingPeriod = 0;
+
+void midiMessageCallback(MidiChannelMessage message, void* arg){
+	if(arg != NULL){
+		rt_printf("Message from midi port %d: ", *(int*)arg);
+	}
+	message.prettyPrint();
+	if(message.getType() == kmmNoteOn){
+		gFreq = powf(2, (message.getDataByte(0)-69)/12.0f) * 440;
+		gVelocity = message.getDataByte(1);
+		gPhaseIncrement = 2 * M_PI * gFreq * gSamplingPeriod;
+		gIsNoteOn = gVelocity > 0;
+		rt_printf("v0:%f, ph: %6.5f, gVelocity: %d\n", gFreq, gPhaseIncrement, gVelocity);
+	}
+}
 // setup() is called once before the audio rendering starts.
 // Use it to perform any initialisation and allocation which is dependent
 // on the period size or sample rate.
@@ -21,15 +40,18 @@
 //
 // Return true on success; returning false halts the program.
 Midi midi;
+int gMidiPort0 = 0;
 bool setup(BeagleRTContext *context, void *userData)
 {
-	midi.readFrom(0);
-	midi.writeTo(0);
-//	midi.enableParser(true);
+	midi.readFrom(gMidiPort0);
+	midi.writeTo(gMidiPort0);
+	midi.enableParser(true);
+	midi.setParserCallback(midiMessageCallback, &gMidiPort0);
 	if(context->analogFrames == 0) {
-		rt_printf("Error: this example needs the matrix enabled\n");
+		rt_printf("Error: this example needs the analog I/O to be enabled\n");
 		return false;
 	}
+	gSamplingPeriod = 1/context->audioSampleRate;
 	return true;
 }
 
@@ -38,21 +60,18 @@
 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
 // will be 0.
 
-static midi_byte_t noteOnStatus = 0x90; //on channel 1
 
 enum {kVelocity, kNoteOn, kNoteNumber};
 void render(BeagleRTContext *context, void *userData)
 {
-	static float f0;
-	static float phaseIncrement = 0;
-	static bool noteOn = 0;
-	static int velocity = 0;
+// one way of getting the midi data is to parse them yourself
+//	(you should set midi.enableParser(false) above):
+/*
+	static midi_byte_t noteOnStatus = 0x90; //on channel 1
 	static int noteNumber = 0;
 	static int waitingFor = kNoteOn;
 	static int playingNote = -1;
-/*
 	int message;
-	// one way of getting the midi data is to parse them yourself (you should set midi.enableParser(false) above):
 	while ((message = midi.getInput()) >= 0){
 		rt_printf("%d\n", message);
 		switch(waitingFor){
@@ -92,6 +111,7 @@
 		}
 	}
 */
+	/*
 	int num;
 	//alternatively, you can use the built-in parser (only processes channel messages at the moment).
 	while((num = midi.getParser()->numAvailableMessages()) > 0){
@@ -103,28 +123,31 @@
 			velocity = message.getDataByte(1);
 			phaseIncrement = 2 * M_PI * f0 / context->audioSampleRate;
 			noteOn = velocity > 0;
-			rt_printf("v0:%f, ph: %6.5f, velocity: %d\n", f0, phaseIncrement, velocity);
+			rt_printf("v0:%f, ph: %6.5f, velocity: %d\n", f0, phaseIncrement, gVelocity);
 		}
 	}
-
+	 */
+	// the following block toggles the LED on an Owl pedal
+	// and asks the pedal to return the status of the LED
+	// using MIDI control changes
 	for(unsigned int n = 0; n < context->analogFrames; n++){
 		static int count = 0;
 		static bool state = 0;
 		analogWriteFrameOnce(context, n, 1, state);
 		if(count % 40000 == 0){
 			state = !state;
-			midi_byte_t bytes[6] = {176, 30, state*127, 176, 67, 30}; // toggle the OWL led and ask for the led status
+			midi_byte_t bytes[6] = {176, 30, (char)(state*127), 176, 67, 30}; // toggle the OWL led and ask for the led status
 			midi.writeOutput(bytes, 6);
 		}
 		count++;
 	}
 	for(unsigned int n = 0; n < context->audioFrames; n++){
-		if(noteOn == 1){
+		if(gIsNoteOn == 1){
 			static float phase = 0;
-			phase += phaseIncrement;
+			phase += gPhaseIncrement;
 			if(phase > 2 * M_PI)
 				phase -= 2 * M_PI;
-			float value = sinf(phase) * velocity/128.0f;
+			float value = sinf(phase) * gVelocity/128.0f;
 			audioWriteFrame(context, n, 0, value);
 			audioWriteFrame(context, n, 1, value);
 		} else {
--- a/projects/basic_network/render.cpp	Sat Feb 13 01:51:01 2016 +0000
+++ b/projects/basic_network/render.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -8,42 +8,10 @@
 #include <BeagleRT.h>
 //#include <rtdk.h>
 #include <cmath>
-#include <UdpClient.h>
+#include <NetworkSend.h>
+#include <ReceiveAudioThread.h>
 #include <Utilities.h>
 
-AuxiliaryTask transmitReceiveDataTask;
-
-#define NETWORK_AUDIO_BUFFER_SIZE 400 //1400/4 //maximum payload for a UDP datagram over ethernet is 1472 bytes, I leave some headroom and divide by 4 to get the number of floats
-struct networkAudio{
-	int timestamp;
-	int currentBuffer;
-	int index;
-	float buffers[2][NETWORK_AUDIO_BUFFER_SIZE];
-	int doneOnTime;
-	bool toBeSent;
-	UdpClient udpClient;
-};
-
-float gFrequency;
-float gPhase;
-float gInverseSampleRate;
-int gCount=0;
-//networkData networkObject;
-#define numNetAudio 3
-networkAudio netAudio[numNetAudio];
-AuxiliaryTask printIntervalTask;
-AuxiliaryTask transmitReceiveAudioTask;
-
-void transmitReceiveAudio(){ //transmit and receive audio buffers
-	for(int n=0;n<numNetAudio; n++){
-		if(netAudio[n].toBeSent){
-			netAudio[n].toBeSent=false;
-			netAudio[n].udpClient.send(netAudio[n].buffers[!netAudio[n].currentBuffer],NETWORK_AUDIO_BUFFER_SIZE*sizeof(float));
-			netAudio[n].doneOnTime=1;
-		}
-	}
-}
-
 // setup() is called once before the audio rendering starts.
 // Use it to perform any initialisation and allocation which is dependent
 // on the period size or sample rate.
@@ -52,33 +20,22 @@
 // in from the call to initAudio().
 //
 // Return true on success; returning false halts the program.
+
+NetworkSend networkSend;
+ReceiveAudioThread receive;
+float gFrequency;
+float gInverseSampleRate;
+float gPhase;
 bool setup(BeagleRTContext *context, void *userData)
 {
 	// Retrieve a parameter passed in from the initAudio() call
 	gFrequency = *(float *)userData;
 
+	networkSend.setup(context->audioSampleRate, context->audioFrames, 0, 9999, "192.168.7.1");
+	receive.init(10000, context->audioFrames, 0);
+	receive.startThread();
 	gInverseSampleRate = 1.0 / context->audioSampleRate;
-	gPhase = 0.0;
-
-//	networkObject.counter=&gCount;
-//	networkObject.variables[0]=&gFrequency;
-//	networkObject.variables[1]=&gPhase;
-//	networkObject.numVariables=2;
-	for(int n=0; n<numNetAudio; n++){
-		netAudio[n].doneOnTime=1;
-		netAudio[n].index=0;
-		netAudio[n].currentBuffer=0;
-		netAudio[n].toBeSent=false;
-//		netAudio[n].udpClient.setPort(settings->transmitPort+n);
-//		netAudio[n].udpClient.setServer(settings->serverName);
-		netAudio[n].udpClient.setPort(9999+n);
-		netAudio[n].udpClient.setServer("192.168.7.1");
-	}
-//	setupSockets(settings->receivePort, settings->transmitPort, settings->serverName);
-
-//	transmitReceiveDataTask=createAuxiliaryTask(*transmitReceiveData, 10, "transmit-receive-data");
-//	scheduleAuxiliaryTask(transmitReceiveDataTask); //here it does not work
-	transmitReceiveAudioTask=BeagleRT_createAuxiliaryTask(*transmitReceiveAudio, 98, "transmit-receive-audio");
+	gPhase = 0;
 	return true;
 }
 
@@ -88,57 +45,19 @@
 // will be 0.
 
 void render(BeagleRTContext *context, void *userData)
-{/*
+{
 	for(unsigned int n = 0; n < context->audioFrames; n++) {
 		float out = 0.7f * sinf(gPhase);
 		gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate;
 		if(gPhase > 2.0 * M_PI)
 			gPhase -= 2.0 * M_PI;
 
-		for(unsigned int channel = 0; channel < context->audioChannels; channel++)
-			context->audioOut[n * context->audioChannels + channel] = out;
-
-		if(gCount == 0){
-			BeagleRT_scheduleAuxiliaryTask(transmitReceiveDataTask);
+		networkSend.log(out);
+		float in;
+		int ret = receive.getSamplesSrc(&in, 1, 1);
+		for(unsigned int channel = 0; channel < context->audioChannels; channel++){
+			audioWriteFrame(context, n, channel, in);
 		}
-		gCount++;
-	}
-
-
-*/
-	for(int n = 0; n < context->audioFrames; n++) {
-		float out = 0.7f * sinf(gPhase);
-		gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate;
-		if(gPhase > 2.0 * M_PI)
-			gPhase -= 2.0 * M_PI;
-
-//		for(int channel = 0; channel < context->audioChannels; channel++)
-//			context->audioOut[n * context->audioChannels + channel] = context->audioIn[n * context->audioChannels + 0]+context->audioIn[n * context->audioChannels + 1];
-		context->audioOut[n * context->audioChannels] = context->audioIn[n*context->audioChannels+0];
-		context->audioOut[n * context->audioChannels+1]=out;
-		if(0==gCount){
-//			scheduleAuxiliaryTask(transmitReceiveDataTask);
-		}
-		for(int j=0; j<numNetAudio; j++){
-			if(netAudio[j].index==(NETWORK_AUDIO_BUFFER_SIZE)){ // when the buffer is ready ...
-				netAudio[j].toBeSent=true;
-				netAudio[j].index=0; //reset the counter
-				if(netAudio[j].doneOnTime==0)
-					rt_printf("Network buffer underrun :-{\n");
-				netAudio[j].timestamp=gCount;
-				netAudio[j].currentBuffer=!netAudio[j].currentBuffer; //switch buffer
-				netAudio[j].doneOnTime=0;
-				BeagleRT_scheduleAuxiliaryTask(transmitReceiveAudioTask); //send the buffer
-			}
-		}
-		if((gCount&1)==0){
-			netAudio[1].buffers[netAudio[1].currentBuffer][netAudio[1].index++]=analogReadFrame(context,n/2,0)+context->audioOut[n*context->audioChannels + 0];
-			netAudio[2].buffers[netAudio[2].currentBuffer][netAudio[2].index++]=analogReadFrame(context,n/2,1)+context->audioOut[n*context->audioChannels + 0];
-		}
-		netAudio[0].buffers[netAudio[0].currentBuffer][netAudio[0].index++]=0.5*(out+context->audioOut[n*context->audioChannels + 0]);//copy channel 0 to the buffer
-//		netAudio[1].buffers[netAudio[1].currentBuffer][netAudio[1].index++]=0.5*(out+context->audioOut[n*context->audioChannels + 0]);
-//		netAudio[2].buffers[netAudio[2].currentBuffer][netAudio[2].index++]=0.5*(out+context->audioOut[n*context->audioChannels + 0]);
-		gCount++;
 	}
 }
 
--- a/projects/d-box/logger.cpp	Sat Feb 13 01:51:01 2016 +0000
+++ b/projects/d-box/logger.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -8,7 +8,7 @@
 #include "logger.h"
 
 // main extern vars
-extern bool gShouldStop;
+extern int gShouldStop;
 extern int gVerbose;
 
 // file nanme extern vars
--- a/projects/d-box/sensors.cpp	Sat Feb 13 01:51:01 2016 +0000
+++ b/projects/d-box/sensors.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -22,7 +22,7 @@
 extern vector<OscillatorBank*> gOscBanks;
 extern int gCurrentOscBank;
 extern int gNextOscBank;
-extern bool gShouldStop;
+extern int gShouldStop;
 extern int gVerbose;
 
 float gSensor0LatestTouchPos = 0;	// most recent pitch touch location [0-1] on sensor 0, used by render.cpp
--- a/projects/heavy/pd/hello-midi/_main.pd	Sat Feb 13 01:51:01 2016 +0000
+++ b/projects/heavy/pd/hello-midi/_main.pd	Sun Apr 10 04:08:06 2016 +0200
@@ -1,4 +1,4 @@
-#N canvas 94 174 1280 685 10;
+#N canvas 85 58 1280 685 10;
 #X obj 19 396 dac~ 1 2;
 #X text 39 1 Hello world!;
 #X text 37 11 ============;
@@ -7,11 +7,9 @@
 #X text 202 438 @krighxz / BELA / heavy / 12/2015;
 #X text 226 457 beaglert.cc / enzienaudio.com;
 #X obj 39 132 mtof;
-#X text 140 29 <== the heavy equivalent of ==>;
-#X obj 334 24 notein;
-#X floatatom 79 59 5 0 0 0 - - -, f 5;
-#X floatatom 122 59 5 0 0 0 - - -, f 5;
-#X floatatom 41 63 5 0 0 0 - - -, f 5;
+#X floatatom 79 59 5 0 0 0 - - -;
+#X floatatom 122 59 5 0 0 0 - - -;
+#X floatatom 41 63 5 0 0 0 - - -;
 #X obj 26 170 phasor~ 440;
 #X text 100 363 (the harsh sound of success);
 #X obj 260 83 * 20;
@@ -19,18 +17,12 @@
 #X obj 132 85 loadbang;
 #X msg 131 111 1000;
 #X obj 125 166 sig~;
-#X text 483 121 <== the heavy equivalent of ==>;
-#X text 349 57 <== the heavy equivalent of ==>;
-#X text 682 122 [pgmin];
+#X text 673 121 [pgmin];
 #X obj 218 178 * 10;
 #X obj 30 250 hip~;
 #X obj 26 275 hip~;
 #X obj 20 302 hip~;
 #X obj 19 323 hip~;
-#X obj 40 28 hv_notein 0;
-#X obj 408 122 hv_pgmin 3;
-#X obj 260 60 hv_ctlin 5 0;
-#X obj 220 151 hv_ctlin 6 0;
 #X obj 87 192 lop~ 4;
 #X obj 152 256 line;
 #X obj 200 200 + 50;
@@ -38,43 +30,50 @@
 #X msg 93 114 0;
 #X msg 185 112 0;
 #X obj 29 224 vcf~ 4;
-#X obj 557 54 ctlin 5 0;
-#X obj 323 156 ctlin 6 0;
 #X obj 70 333 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
 1;
 #X obj 42 92 mono;
+#X obj 40 28 bela_notein 0;
+#X obj 260 60 bela_ctlin 5 0;
+#X obj 220 151 bela_ctlin 6 0;
+#X obj 408 121 bela_pgmin 3;
+#X text 537 58 [ctlin];
+#X text 332 27 [notein];
+#X text 140 29 <== the bela equivalent of ==>;
+#X text 349 59 <== the bela equivalent of ==>;
+#X text 483 121 <== the bela equivalent of ==>;
 #X connect 3 0 0 1;
 #X connect 3 0 0 0;
-#X connect 7 0 13 0;
-#X connect 10 0 42 1;
-#X connect 12 0 42 0;
-#X connect 13 0 38 0;
+#X connect 7 0 11 0;
+#X connect 8 0 32 1;
+#X connect 10 0 32 0;
+#X connect 11 0 30 0;
+#X connect 13 0 14 0;
+#X connect 14 0 17 0;
 #X connect 15 0 16 0;
-#X connect 16 0 19 0;
-#X connect 17 0 18 0;
-#X connect 17 0 37 0;
-#X connect 17 0 36 0;
-#X connect 18 0 19 0;
-#X connect 19 0 32 0;
-#X connect 23 0 34 0;
-#X connect 24 0 25 0;
-#X connect 25 0 26 0;
+#X connect 15 0 29 0;
+#X connect 15 0 28 0;
+#X connect 16 0 17 0;
+#X connect 17 0 24 0;
+#X connect 19 0 26 0;
+#X connect 20 0 21 0;
+#X connect 21 0 22 0;
+#X connect 22 0 23 0;
+#X connect 23 0 3 0;
+#X connect 24 0 30 1;
+#X connect 25 0 20 1;
+#X connect 25 0 21 1;
+#X connect 25 0 22 1;
+#X connect 25 0 23 1;
 #X connect 26 0 27 0;
-#X connect 27 0 3 0;
-#X connect 28 0 12 0;
-#X connect 28 1 10 0;
-#X connect 28 2 11 0;
-#X connect 30 0 15 0;
-#X connect 31 0 23 0;
-#X connect 32 0 38 1;
-#X connect 33 0 24 1;
-#X connect 33 0 25 1;
-#X connect 33 0 26 1;
-#X connect 33 0 27 1;
-#X connect 34 0 35 0;
-#X connect 35 0 33 0;
-#X connect 37 0 23 0;
-#X connect 38 0 24 0;
-#X connect 41 0 3 1;
-#X connect 42 0 7 0;
-#X connect 42 1 41 0;
+#X connect 27 0 25 0;
+#X connect 29 0 19 0;
+#X connect 30 0 20 0;
+#X connect 31 0 3 1;
+#X connect 32 0 7 0;
+#X connect 32 1 31 0;
+#X connect 33 0 10 0;
+#X connect 33 1 8 0;
+#X connect 33 2 9 0;
+#X connect 34 0 13 0;
+#X connect 35 0 19 0;
--- a/projects/heavy/pd/hello-midi/countTo.pd	Sat Feb 13 01:51:01 2016 +0000
+++ b/projects/heavy/pd/hello-midi/countTo.pd	Sun Apr 10 04:08:06 2016 +0200
@@ -1,4 +1,4 @@
-#N canvas 586 250 450 300 10;
+#N canvas 584 255 450 300 10;
 #X obj 65 196 outlet;
 #X obj 98 8 inlet;
 #X text 189 49 counts from 0 to the given number -1;
@@ -7,13 +7,12 @@
 #X obj 143 61 f;
 #X obj 100 138 spigot;
 #X obj 129 89 <;
-#X obj 129 113 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
+#X obj 129 113 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
 1;
 #X obj 95 28 t b f b;
 #X obj 92 74 + 1;
-#X obj 43 73 f, f 4;
+#X obj 43 73 f;
 #X obj 63 104 t b f f f;
-#X obj 143 155 spigot;
 #X msg 92 53 0;
 #X obj 16 144 delay 0;
 #X connect 1 0 9 0;
@@ -23,12 +22,12 @@
 #X connect 8 0 6 1;
 #X connect 9 0 11 0;
 #X connect 9 1 5 0;
-#X connect 9 1 14 0;
+#X connect 9 1 13 0;
 #X connect 10 0 11 1;
 #X connect 11 0 12 0;
-#X connect 12 0 15 0;
+#X connect 12 0 14 0;
 #X connect 12 1 0 0;
 #X connect 12 2 7 0;
 #X connect 12 3 10 0;
-#X connect 14 0 11 1;
-#X connect 15 0 6 0;
+#X connect 13 0 11 1;
+#X connect 14 0 6 0;
--- a/projects/heavy/pd/hello-midi/hv_ctlin.pd	Sat Feb 13 01:51:01 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-#N canvas 554 204 703 475 10;
-#X obj -107 -439 outlet;
-#X obj -52 -441 outlet;
-#X obj -61 -743 r ctlin;
-#X obj -68 -719 unpack f f f;
-#X obj -6 -441 outlet;
-#X obj -74 -548 spigot;
-#X text -109 -420 value;
-#X text -55 -420 number;
-#X obj 51 -732 loadbang;
-#X obj 17 -677 \$1;
-#X obj -34 -656 == \$1;
-#X obj -41 -571 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1
-0 1;
-#X obj -76 -521 unpack f f f;
-#X obj -17 -623 ||;
-#X obj 17 -653 == 0;
-#X text -90 -859 Emulates ctlin \, except number of outlets is fixed.
-;
-#X obj 68 -623 ||;
-#X obj 102 -653 == 0;
-#X obj 52 -656 == \$2;
-#X obj 102 -677 \$2;
-#X obj 17 -593 &&;
-#X obj 51 -707 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
--1 -1;
-#X text 13 -571 If (inputController==\$1 || \$1==0) && (inputChannel==\$2
-|| \$2==0);
-#X text 37 -818 Known issue: trying to select inputController 0 will
-result i accepting all controllers (because a pd external cannot tell
-the difference between \$1 been explicitely set to 0 and the patch
-not having any argument);
-#X text 2 -420 channel;
-#X obj -104 -678 pack f f f;
-#X obj -80 -462 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
--1 -1;
-#X floatatom -79 -488 5 0 0 0 - - -;
-#X obj -39 -458 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
--1 -1;
-#X floatatom -38 -484 5 0 0 0 - - -;
-#X obj 12 -464 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
--1 -1;
-#X floatatom 13 -490 5 0 0 0 - - -;
-#X msg -44 -818 1 2 3;
-#X msg -6 -805 1 5 7;
-#X msg -97 -815 1 5 6;
-#X msg -100 -776 1 4 7;
-#X obj -96 -841 r hv_ctlin;
-#X obj -38 -778 s ctlin;
-#X connect 2 0 3 0;
-#X connect 3 0 25 0;
-#X connect 3 1 10 0;
-#X connect 3 1 25 1;
-#X connect 3 2 18 0;
-#X connect 3 2 25 2;
-#X connect 5 0 12 0;
-#X connect 8 0 21 0;
-#X connect 9 0 14 0;
-#X connect 10 0 13 0;
-#X connect 11 0 5 1;
-#X connect 12 0 0 0;
-#X connect 12 0 27 0;
-#X connect 12 1 1 0;
-#X connect 12 1 29 0;
-#X connect 12 2 4 0;
-#X connect 12 2 31 0;
-#X connect 13 0 20 0;
-#X connect 14 0 13 1;
-#X connect 16 0 20 1;
-#X connect 17 0 16 1;
-#X connect 18 0 16 0;
-#X connect 19 0 17 0;
-#X connect 20 0 11 0;
-#X connect 21 0 9 0;
-#X connect 21 0 19 0;
-#X connect 25 0 5 0;
-#X connect 27 0 26 0;
-#X connect 29 0 28 0;
-#X connect 31 0 30 0;
-#X connect 32 0 37 0;
-#X connect 33 0 37 0;
-#X connect 34 0 37 0;
-#X connect 35 0 37 0;
-#X connect 36 0 37 0;
--- a/projects/heavy/pd/hello-midi/hv_notein.pd	Sat Feb 13 01:51:01 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-#N canvas 730 58 629 685 10;
-#X obj 84 -361 outlet;
-#X obj 155 -367 outlet;
-#X obj 131 -658 unpack f f f;
-#X obj 211 -370 outlet;
-#X obj 133 -477 spigot;
-#X obj 258 -661 loadbang;
-#X obj 224 -606 \$1;
-#X obj 173 -585 == \$1;
-#X obj 166 -500 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1
-0 1;
-#X obj 133 -450 unpack f f f;
-#X obj 190 -552 ||;
-#X obj 224 -582 == 0;
-#X obj 258 -636 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
--1 -1;
-#X text 150 -777 Emulates notein \, except number of outlets is fixed.
-;
-#X text 82 -343 notenumber;
-#X text 151 -353 velocity;
-#X text 210 -356 channel;
-#X text 219 -531 If (inputChannel==\$1 || \$1==0);
-#X msg 50 -758 123 46 3;
-#X obj 105 -610 pack f f f;
-#X msg 8 -739 123 46 2;
-#X obj 72 -414 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
--1 -1;
-#X floatatom 74 -432 5 0 0 0 - - -;
-#X obj 135 -394 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
--1 -1;
-#X floatatom 137 -412 5 0 0 0 - - -;
-#X obj 188 -391 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
--1 -1;
-#X floatatom 190 -409 5 0 0 0 - - -;
-#X obj 121 -730 s notein;
-#X obj 130 -693 r notein;
-#X obj 125 -758 r hv_notein;
-#X connect 2 0 19 0;
-#X connect 2 1 19 1;
-#X connect 2 2 7 0;
-#X connect 2 2 19 2;
-#X connect 4 0 9 0;
-#X connect 5 0 12 0;
-#X connect 6 0 11 0;
-#X connect 7 0 10 0;
-#X connect 8 0 4 1;
-#X connect 9 0 0 0;
-#X connect 9 0 22 0;
-#X connect 9 1 1 0;
-#X connect 9 1 24 0;
-#X connect 9 2 3 0;
-#X connect 9 2 26 0;
-#X connect 10 0 8 0;
-#X connect 11 0 10 1;
-#X connect 12 0 6 0;
-#X connect 18 0 27 0;
-#X connect 19 0 4 0;
-#X connect 20 0 27 0;
-#X connect 22 0 21 0;
-#X connect 24 0 23 0;
-#X connect 26 0 25 0;
-#X connect 28 0 2 0;
-#X connect 29 0 27 0;
--- a/projects/heavy/pd/hello-midi/hv_pgmin.pd	Sat Feb 13 01:51:01 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-#N canvas 623 197 587 546 10;
-#X obj 108 68 outlet;
-#X obj 209 66 outlet;
-#X obj 141 -41 spigot;
-#X obj 232 -219 loadbang;
-#X obj 232 -170 \$1;
-#X obj 181 -149 == \$1;
-#X obj 174 -64 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
-1;
-#X obj 198 -116 ||;
-#X obj 232 -146 == 0;
-#X obj 232 -194 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
--1 -1;
-#X obj 124 -234 unpack f f;
-#X obj 141 -13 unpack f f;
-#X text 87 91 program number;
-#X text 217 87 channel;
-#X text 228 -64 If (channel==\$1 || \$1==0);
-#X text 202 -300 emulates pgmin except it always has 2 outlets and
-requires the input parameters to be explicitely set. Set them to 0
-to avoid filtering;
-#X text 297 -213 It'd be nicer with [t l l] but have to compensate
-for the fact that it is not supported by heavy;
-#X obj 112 -162 pack f f;
-#X floatatom 107 10 5 0 0 0 - - -;
-#X msg 80 -270 2 3;
-#X msg 63 -292 2 1;
-#X obj 98 34 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
--1;
-#X floatatom 185 16 5 0 0 0 - - -;
-#X obj 176 40 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
--1;
-#X obj 124 -303 r hv_pgmin;
-#X obj 126 -282 s pgmin;
-#X obj 128 -258 r pgmin;
-#X connect 2 0 11 0;
-#X connect 3 0 9 0;
-#X connect 4 0 8 0;
-#X connect 5 0 7 0;
-#X connect 6 0 2 1;
-#X connect 7 0 6 0;
-#X connect 8 0 7 1;
-#X connect 9 0 4 0;
-#X connect 10 0 17 0;
-#X connect 10 1 5 0;
-#X connect 10 1 17 1;
-#X connect 11 0 0 0;
-#X connect 11 0 18 0;
-#X connect 11 1 1 0;
-#X connect 11 1 22 0;
-#X connect 17 0 2 0;
-#X connect 18 0 21 0;
-#X connect 19 0 25 0;
-#X connect 20 0 25 0;
-#X connect 22 0 23 0;
-#X connect 24 0 25 0;
-#X connect 26 0 10 0;
--- a/projects/scope/render.cpp	Sat Feb 13 01:51:01 2016 +0000
+++ b/projects/scope/render.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -1,12 +1,14 @@
 #include <BeagleRT.h> 
-#include <Scope.h>
+#include <NetworkSend.h>
+#include <ReceiveAudioThread.h>
 #include <cmath>
 
 float gPhase1, gPhase2;
 float gFrequency1, gFrequency2;
 float gInverseSampleRate;
 
-Scope scope;    //create a scope object
+Scope scope(2);   //create a scope object with 2 channels
+NetworkSend networkSend;
 
 // initialise_render() is called once before the audio rendering starts.
 // Use it to perform any initialisation and allocation which is dependent
@@ -16,9 +18,17 @@
 // in from the call to initAudio().
 //
 // Return true on success; returning false halts the program.
+ReceiveAudioThread receiveAudio0;
+ReceiveAudioThread receiveAudio1;
 bool setup(BeagleRTContext *context, void *userData)
 {
-	scope.setup(context->audioSampleRate);  //call this once in setup to initialise the scope
+	receiveAudio0.init(9999, context->audioFrames, 0);
+	receiveAudio1.init(10000, context->audioFrames, 1);
+
+	scope.setup();  //call this once in setup to initialise the scope
+	scope.setPort(0, 9999);
+	scope.setPort(1, 10000);
+//	networkSend.setup(context->audioSampleRate, 0, 9999, "192.168.7.1");
 	 
 	gInverseSampleRate = 1.0/context->audioSampleRate;
 	
@@ -27,6 +37,7 @@
 	
 	gFrequency1 = 200.0;
 	gFrequency2 = 201.0;
+
 	return true; 
 }
 
@@ -37,33 +48,48 @@
 
 void render(BeagleRTContext *context, void *userData)
 {
+	static int count=0;
+	if(count==0){
+		printf("startHread\n");
+		ReceiveAudioThread::startThread();
+	}
 	for(unsigned int n = 0; n < context->audioFrames; n++) {
 	    
-	    float chn1 = sinf(gPhase1);
-	    float chn2 = sinf(gPhase2);
-	    
-	    float chn3 = context->audioIn[n*2 + 0];
-	    float chn4 = context->audioIn[n*2 + 1];
-	    
-	    float chn5 = context->analogIn[(int)n/2*8 + 0];
-	    float chn6 = context->analogIn[(int)n/2*8 + 1];
+		float chn0 = sinf(gPhase1);
+		float chn1 = sinf(gPhase2);
+
+    //  float chn2 = context->audioIn[n*2 + 0];
+    //  float chn3 = context->audioIn[n*2 + 1];
+
+    //  float chn4 = context->analogIn[(int)n/2*8 + 0];
+    //  float chn5 = context->analogIn[(int)n/2*8 + 1];
+			scope.log(0, chn0);
+		  scope.log(1, chn1);
+		//  scope.log(2, chn2);
+		//  scope.log(3, chn3);
+		//  scope.log(4, chn4);
+		//  scope.log(5, chn5);
 	    
 //	    scope.log(chn1, chn2, chn3, chn4, chn5, chn6);
-	    scope.log(chn1);
 	    //call this once every audio frame
 	    //takes six or fewer floats as parameters
 	    //first parameter becomes channel 1 etc
 	    //to view, click the 'oscilloscope' button on the toolbar while BeagleRT is NOT running
 	    //then click the big red button on the toolbar on this page
 	    
-	    gPhase1 += 2.0 * M_PI * gFrequency1 * gInverseSampleRate;
-	    gPhase2 += 2.0 * M_PI * gFrequency2 * gInverseSampleRate;
+	    gPhase1 += 2.0 * M_PI * gFrequency1 * gInverseSampleRate * ((count&4095)/4096.0+1);
+			gPhase2 += 2.0 * M_PI * gFrequency2 * gInverseSampleRate;
 		if(gPhase1 > 2.0 * M_PI)
 			gPhase1 -= 2.0 * M_PI;
 		if(gPhase2 > 2.0 * M_PI)
 			gPhase2 -= 2.0 * M_PI;
 		
 	}
+	if(count>0){
+		int readPointer0=receiveAudio0.getSamplesSrc(context->audioOut, context->audioFrames, 1, 2, 0);
+		int readPointer1=receiveAudio1.getSamplesSrc(context->audioOut, context->audioFrames, 1, 2, 1);
+	}
+	count++;
 }
 
 // cleanup_render() is called once at the end, after the audio has stopped.
--- a/scripts/hvresources/render.cpp	Sat Feb 13 01:51:01 2016 +0000
+++ b/scripts/hvresources/render.cpp	Sun Apr 10 04:08:06 2016 +0200
@@ -127,16 +127,16 @@
 					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, "hv_notein", 0, "fff", noteNumber, velocity, channel);
+					hv_vscheduleMessageForReceiver(gHeavyContext, "bela_notein", 0, "fff", noteNumber, velocity, channel);
 				}
 				break;
 			case kmmControlChange: {
-				hv_vscheduleMessageForReceiver(gHeavyContext, "hv_ctlin", 0, "fff",
+				hv_vscheduleMessageForReceiver(gHeavyContext, "bela_ctlin", 0, "fff",
 						(float)message.getDataByte(1), (float)message.getDataByte(0), (float)message.getChannel());
 				}
 				break;
 			case kmmProgramChange:
-				hv_vscheduleMessageForReceiver(gHeavyContext, "hv_pgmin", 0, "ff",
+				hv_vscheduleMessageForReceiver(gHeavyContext, "bela_pgmin", 0, "ff",
 						(float)message.getDataByte(0), (float)message.getChannel());
 				break;
 			}
--- a/scripts/hvresources/uploader.py	Sat Feb 13 01:51:01 2016 +0000
+++ b/scripts/hvresources/uploader.py	Sun Apr 10 04:08:06 2016 +0200
@@ -1,6 +1,4 @@
-#!/usr/bin/python
-
-# Copyright 2015 Section6. All Rights Reserved.
+# Copyright 2015,2016 Enzien Audio, Ltd. All Rights Reserved.
 
 import argparse
 import getpass
@@ -13,7 +11,6 @@
 import time
 import urlparse
 import zipfile
-import sys
 
 class Colours:
     purple = "\033[95m"
@@ -47,19 +44,27 @@
         description="Compiles a Pure Data file.")
     parser.add_argument(
         "input_dir",
-        help="A directory containing _main.pd. The entire directory will be uploaded.")
+        help="A directory containing _main.pd. All .pd files in the directory structure will be uploaded.")
     parser.add_argument(
         "-n", "--name",
         default="heavy",
-        help="Patch name. If it doesn't exist, the uploader will fail. Make sure that it exists on the Heavy website.")
+        help="Patch name. If it doesn't exist on the Heavy site, the uploader will fail.")
     parser.add_argument(
         "-g", "--gen",
         nargs="+",
         default=["c"],
-        help="List of generator outputs. Currently supported generators are 'c' and 'js'.")
+        help="List of generator outputs. Currently supported generators are "
+            "'c', 'js', 'pdext', 'pdext-osx', 'unity', 'unity-osx', "
+            "'unity-win-x86', 'unity-win-x86_64', 'wwise', 'wwise-win-x86_64', "
+            "'vst2' ,'vst2-osx', and 'vst2-win-x86_64'.")
     parser.add_argument(
         "-b",
-        help="All files will be placed in the output directory, placed in their own subdirectory corresonding to the generator name.",
+        help="All files will be placed in the output directory, placed in their own subdirectory corresponding to the generator name.",
+        action="count")
+    parser.add_argument(
+        "-y",
+        help="Extract only the generated C files. Static files are deleted. "
+            "Only effective for the 'c' generator.",
         action="count")
     parser.add_argument(
         "-o", "--out",
@@ -80,12 +85,16 @@
         action="count")
     parser.add_argument(
         "--noverify",
-        help="Don't verify the SSL connection. Generally a bad idea.",
+        help="Don't verify the SSL connection. This is generally a very bad idea.",
         action="count")
     parser.add_argument(
         "-v", "--verbose",
         help="Show debugging information.",
         action="count")
+    parser.add_argument(
+        "-t", "--token",
+        help="Use the specified token.",
+    )
     args = parser.parse_args()
 
     domain = args.domain or "https://enzienaudio.com"
@@ -94,11 +103,14 @@
 
     # token should be stored in ~/.heavy/token
     token_path = os.path.expanduser(os.path.join("~/", ".heavy", "token"))
-    if os.path.exists(token_path) and not args.z:
+
+    if args.token is not None:
+        # check if token has been passed as a command line arg...
+        post_data["credentials"] = {"token": args.token}
+    elif os.path.exists(token_path) and not args.z:
+        # ...or if it is stored in the user's home directory
         with open(token_path, "r") as f:
-            post_data["credentials"] = {
-                "token": f.read()
-            }
+            post_data["credentials"] = {"token": f.read()}
     else:
         # otherwise, get the username and password
         post_data["credentials"] = {
@@ -127,7 +139,13 @@
     post_data["name"] = args.name
 
     # the outputs to generate (always include c)
-    __SUPPORTED_GENERATOR_SET = {"c", "js"}
+    __SUPPORTED_GENERATOR_SET = {
+        "c", "js",
+        "pdext", "pdext-osx",
+        "unity", "unity-osx", "unity-win-x86", "unity-win-x86_64",
+        "wwise", "wwise-win-x86_64",
+        "vst2", "vst2-osx", "vst2-win-x86_64",
+    }
     post_data["gen"] = list(({"c"} | set(args.gen)) & __SUPPORTED_GENERATOR_SET)
 
     # upload the job, get the response back
@@ -141,6 +159,7 @@
 
     if r.status_code != requests.codes.ok:
         shutil.rmtree(temp_dir) # clean up the temporary directory
+        print "Getting a weird error? Get the latest uploader at https://enzienaudio.com/static/uploader.py"
         r.raise_for_status() # raise an exception
 
     # decode the JSON API response
@@ -193,7 +212,9 @@
           "type": "file"
         }
       ],
-      "warnings": [],
+      "warnings": [
+        {"details": "blah blah blah"}
+      ],
       "meta": {
         "token": "11AS0qPRmjTUHEMSovPEvzjodnzB1xaz"
       }
@@ -209,22 +230,32 @@
 
     # update the api token, if present
     if "token" in reply_json.get("meta",{}) and not args.x:
-        if not os.path.exists(os.path.dirname(token_path)):
-            os.makedirs(os.path.dirname(token_path)) # ensure that the .heavy directory exists
-        with open(token_path, "w") as f:
-            f.write(reply_json["meta"]["token"])
-        os.chmod(token_path, stat.S_IRUSR | stat.S_IWUSR) # force rw------- permissions on the file
+        if args.token is not None:
+            if reply_json["meta"]["token"] != args.token:
+                print "WARNING: Token returned by API is not the same as the "
+                "token supplied at the command line. (old = %s, new = %s)".format(
+                    args.token,
+                    reply_json["meta"]["token"])
+        else:
+            if not os.path.exists(os.path.dirname(token_path)):
+                # ensure that the .heavy directory exists
+                os.makedirs(os.path.dirname(token_path))
+            with open(token_path, "w") as f:
+                f.write(reply_json["meta"]["token"])
+            # force rw------- permissions on the file
+            os.chmod(token_path, stat.S_IRUSR | stat.S_IWUSR)
 
     # print any warnings
-    for x in r_json["warnings"]:
-        print "{0}Warning:{1} {2}".format(Colours.yellow, Colours.end, x["detail"])
+    for i,x in enumerate(r_json.get("warnings",[])):
+        print "{3}) {0}Warning:{1} {2}".format(
+            Colours.yellow, Colours.end, x["detail"], i+1)
 
     # check for errors
     if len(r_json.get("errors",[])) > 0:
         shutil.rmtree(temp_dir) # clean up the temporary directory
-        for x in r_json["errors"]:
-            print "{0}Error:{1} {2}".format(Colours.red, Colours.end, x["detail"])
-        sys.exit(1)
+        for i,x in enumerate(r_json["errors"]):
+            print "{3}) {0}Error:{1} {2}".format(
+                Colours.red, Colours.end, x["detail"], i+1)
         return
 
     # retrieve all requested files
@@ -251,6 +282,12 @@
                 os.makedirs(target_dir) # ensure that the output directory exists
             __unzip(c_zip_path, target_dir)
 
+            if g == "c" and args.y:
+                keep_files = ("_{0}.h".format(args.name), "_{0}.c".format(args.name))
+                for f in os.listdir(target_dir):
+                    if not f.endswith(keep_files):
+                        os.remove(os.path.join(target_dir, f));
+
             print "{0} files placed in {1}".format(g, target_dir)
         else:
             print "{0}Warning:{1} {2} files could not be retrieved.".format(
@@ -260,10 +297,9 @@
     # delete the temporary directory
     shutil.rmtree(temp_dir)
 
-    print "Job URL", reply_json["data"]["links"]["self"]
+    print "Job URL:", reply_json["data"]["links"]["self"]
     print "Total request time: {0}ms".format(int(1000.0*(time.time()-tick)))
-
-    sys.exit(0)
+    print "Heavy version:", reply_json["meta"]["version"]
 
 def __get_file_url_for_generator(json_api, g):
     """Returns the file link for a specific generator.