changeset 114:7b351b7d8770 scope-refactoring

Merged ultra-staging into scope-refactoring
author Giulio Moro <giuliomoro@yahoo.it>
date Wed, 19 Aug 2015 23:11:34 +0100
parents 7dfae7b7ab12 (diff) 3068421c0737 (current diff)
children a0e24514fc97
files .cproject core/client.cpp include/client.h projects/basic_network/render.cpp
diffstat 9 files changed, 242 insertions(+), 444 deletions(-) [+]
line wrap: on
line diff
--- a/.cproject	Tue Aug 18 00:35:15 2015 +0100
+++ b/.cproject	Wed Aug 19 23:11:34 2015 +0100
@@ -31,8 +31,6 @@
 								<option id="gnu.cpp.compiler.option.include.paths.2031219124" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
 									<listOptionValue builtIn="false" value="/usr/xenomai/include"/>
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/include"/>
-									<listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/include"/>
-									<listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/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;"/>
 								</option>
@@ -47,10 +45,8 @@
 								<option id="gnu.c.compiler.option.include.paths.358825414" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
 									<listOptionValue builtIn="false" value="/usr/xenomai/include"/>
 									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/include"/>
-									<listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/include"/>
-									<listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/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="/BeagleRT/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"/>
@@ -61,9 +57,10 @@
 								<option id="gnu.cpp.link.option.paths.462980690" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
 									<listOptionValue builtIn="false" value="/usr/xenomai/lib"/>
 									<listOptionValue builtIn="false" value="/usr/local/linaro/arm-linux-gnueabihf/include/xenomai/lib"/>
-									<listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/lib"/>
 									<listOptionValue builtIn="false" value="/usr/lib/arm-linux-gnueabihf"/>
-									<listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/lib/xenomai"/>
+									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/lib"/>
+									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/lib/xenomai"/>
+									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/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"/>
@@ -82,10 +79,6 @@
 							</tool>
 							<tool command="arm-linux-gnueabihf-as" id="cdt.managedbuild.tool.gnu.assembler.exe.debug.37270610" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
 								<option id="gnu.both.asm.option.include.paths.1403814918" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
-									<listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/include/xenomai/include"/>
-									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/xenomai/include"/>
-									<listOptionValue builtIn="false" value="/import/teaching/ECS732/arm-gcc/arm-linux-gnueabihf/include"/>
-									<listOptionValue builtIn="false" value="/usr/arm-linux-gnueabihf/include/ne10"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/BeagleRT/include}&quot;"/>
 								</option>
 								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1788972942" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
@@ -95,6 +88,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" kind="sourcePath" name="projects/scope"/>
 						<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="source"/>
 					</sourceEntries>
 				</configuration>
@@ -114,7 +108,7 @@
 				</extensions>
 			</storageModule>
 			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1521194538" name="Release" parent="cdt.managedbuild.config.gnu.exe.release" postannouncebuildStep="Stopping process on BBB and copying new binary" postbuildStep="ssh root@192.168.7.2 &quot;kill -s 2 \`pidof ${BuildArtifactFileName}\` 2&gt;/dev/null; sleep 0.6&quot;; scp ${BuildArtifactFilePrefix}${BuildArtifactFileName} root@192.168.7.2:~/beaglert/ ; echo 'done copying' | wall">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1521194538" name="Release" parent="cdt.managedbuild.config.gnu.exe.release" postannouncebuildStep="Stopping process on BBB and copying new binary" postbuildStep="ssh root@192.168.7.2 &quot;kill -s 2 \`pidof ${BuildArtifactFileName}\` 2&gt;/dev/null&quot;; scp ${BuildArtifactFilePrefix}${BuildArtifactFileName} root@192.168.7.2:~/beaglert/ ; echo 'done copying' | wall">
 					<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"/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/NetworkSend.cpp	Wed Aug 19 23:11:34 2015 +0100
@@ -0,0 +1,143 @@
+//scope.cpp
+#include <NetworkSend.h>
+
+#define BUILD_FOR_UDPRECEIVE_PLUGIN
+#define NETWORK_AUDIO_BUFFER_SIZE 302
+
+//initialize the static members of NetworkSend
+bool NetworkSend::staticConstructed=false;
+std::vector<NetworkSend*> NetworkSend::objAddrs(0);
+AuxiliaryTask NetworkSend::transmitAudioTask=NULL;
+
+void transmitAudio(){
+	NetworkSend::sendAllData();
+}
+
+void NetworkSend::sendAllData(){
+	for(unsigned int n=0; n<NetworkSend::objAddrs.size(); n++){
+		NetworkSend::objAddrs[n]->sendData();
+	}
+}
+
+void NetworkSend::staticConstructor(){
+	if(staticConstructed==true)
+		return;
+	staticConstructed=true;
+	transmitAudioTask = BeagleRT_createAuxiliaryTask(transmitAudio, 95, "transmitAudioTask"); //TODO: allow variable priority
+};
+
+NetworkSend::NetworkSend()
+{
+	sampleCount = 0;
+	channel.doneOnTime=true;
+	channel.index=channel.headerLength; //leave space for the heading message (channel, timestamp)
+	channel.activeBuffer=0;
+	channel.readyToBeSent=false;
+}
+NetworkSend::~NetworkSend(){
+	for(unsigned int n=0; n<objAddrs.size(); n++){ //keep track of deleted instances;
+		if(objAddrs[n]==this){
+			objAddrs.erase(objAddrs.begin()+n);
+			break;
+		}
+	}
+}
+
+void NetworkSend::setup(float aSampleRate){
+	setup(aSampleRate, 0, 9999, "192.168.7.1");//channelNumber=0
+}
+
+void NetworkSend::setup(float aSampleRate, int aChannelNumber, int aPort, const char *aServer){
+	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 ...
+	setChannelNumber(aChannelNumber);
+	setPort(aPort);
+	setServer(aServer);
+	printf("Channel %d is sending messages to : %s:%d at %fHz\n", getChannelNumber(), aServer, aPort, aSampleRate);
+}
+
+
+void NetworkSend::log(float value){ //TODO: add a vectorized version of this method
+	if(channel.index==(NETWORK_AUDIO_BUFFER_SIZE)){ // when the buffer is ready ...
+		channel.readyToBeSent=true;
+		channel.index=channel.headerLength; //reset the counter
+		if(channel.doneOnTime==false){
+			printf("Network buffer underrun. timestamp: %d :-{\n", (int)channel.buffers[!channel.activeBuffer][1]);
+		}
+		channel.timestamp=sampleCount;
+		channel.activeBuffer=!channel.activeBuffer; //switch buffer
+		channel.doneOnTime=false;
+		BeagleRT_scheduleAuxiliaryTask(NetworkSend::transmitAudioTask); //send the buffer
+		//TODO: maybe we should have transmitAudioTask running in a loop instead of scheduling it multiple times?
+	}
+	if(channel.index==channel.headerLength){
+		channel.buffers[channel.activeBuffer][0] = (float)channel.channelNumber; //TODO: this could actually be done just once in setup()
+		channel.buffers[channel.activeBuffer][1]=(float)sampleCount; //timestamp
+		//add here more header fields
+	}
+    channel.buffers[channel.activeBuffer][channel.index++]=value;
+	sampleCount++;
+};
+
+void NetworkSend::setServer(const char *aServer){
+	udpClient.setServer(aServer);
+}
+void NetworkSend::setPort(int aPort){
+	udpClient.setPort(aPort);
+}
+
+void NetworkSend::setChannelNumber(int aChannelNumber){
+	channel.channelNumber=aChannelNumber;
+};
+int NetworkSend::getChannelNumber(){
+	return channel.channelNumber;
+};
+
+void NetworkSend::sendData(){
+	if(channel.readyToBeSent){
+		channel.readyToBeSent=false;
+		udpClient.send(
+			channel.buffers[!channel.activeBuffer],
+			NETWORK_AUDIO_BUFFER_SIZE*sizeof(float)
+		);
+		channel.doneOnTime=true;
+	}
+}
+
+int NetworkSend::getNumInstances(){
+	return objAddrs.size();
+};
+
+Scope::Scope(int aNumChannels):
+		channels(aNumChannels)
+{};
+Scope::~Scope(){};
+
+void Scope::log(int channel, float value){
+	if(channel>=getNumChannels()) //TODO: assert this
+		return;
+	channels[channel].log(value);
+}
+
+void Scope::setup(){
+	setup(44100, 9999, "127.0.0.1");
+}
+
+void Scope::setup(float sampleRate, int aPort, const char* aServer){
+	for(int n=0; n<getNumChannels(); n++){
+		channels[n].setup(sampleRate, n, aPort, aServer);
+	}
+}
+
+int Scope::getNumChannels(){
+	return channels.size();
+}
+
+void Scope::sendData(){
+	NetworkSend::sendAllData();
+}
--- a/core/client.cpp	Tue Aug 18 00:35:15 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-///* UDP client in the internet domain */
-
-#include <ctype.h>
-#include <sys/time.h>
-#include <fcntl.h>
-#include "../include/client.h"
-#include <unistd.h>
-#include <rtdk.h>
-
-#define MESSAGE_BUFF_LEN 1024
-#define MAX_VAR_STRING 20
-
-struct sockaddr_in outServer, inServer;
-int outSock, inSock, n, length;
-socklen_t fromlen;
-struct sockaddr_in from;
-char inBuffer[1024];
-char variableString[MAX_VAR_STRING];
-
-int setupSockets(int receivePort, int transmitPort, char const*serverName){
-	//setup transmitter
-	printf("receivePort: %d; transmitPort: %d; serverName: %s\n",receivePort, transmitPort, serverName);
-	outSock= socket(AF_INET, SOCK_DGRAM, 0);
-	outServer.sin_port = htons(transmitPort);
-	if (outSock < 0){
-		error("Opening out socket");
-		return -1;
-	}
-	outServer.sin_family = AF_INET;
-	inet_pton(AF_INET,serverName,&outServer.sin_addr);
-
-	//setup receiver
-	inSock=socket(AF_INET, SOCK_DGRAM, 0);
-	if (inSock < 0){
-		return -1;
-		error("Opening in socket");
-	}
-	length = sizeof(inServer);
-	inServer.sin_family=AF_INET;
-	inServer.sin_addr.s_addr=INADDR_ANY;
-	inServer.sin_port=htons(receivePort);
-	if (bind(inSock,(struct sockaddr *)&inServer,length)<0)
-	   error("binding");
-	fromlen = sizeof(struct sockaddr_in);
-	return 0;
-}
-int sendMessage(networkData message)
-{
-   unsigned int length;
-   char buffer[MESSAGE_BUFF_LEN];
-   length=sizeof(struct sockaddr_in);
-   int k=0;
-   k=sprintf(buffer+k, "%8d;",*message.counter);
-   for(int j=0; j<message.numVariables; j++){
-	   k+=sprintf(buffer+k, "%.3f;",*message.variables[j]);
-	   if(k>MESSAGE_BUFF_LEN - 20) //safety margin
-		   continue;
-   }
-   sprintf(buffer+k,"\n");
-  // printf(buffer);
-   n=sendto(outSock,buffer,
-            strlen(buffer),0,(const struct sockaddr *)&outServer,length);
-   if (n < 0) error("Sendto");
-   return 0;
-}
-
-int sendAudio(networkAudio *audio)
-{
-   unsigned int length;
-   length=sizeof(struct sockaddr_in);
-//   for(int k=0; k<NETWORK_AU	DIO_BUFFER_SIZE; k++)
-//	   printf("%f\n",audio.buffers[!audio.currentBuffer][k]);
-   n=sendto(outSock,audio->buffers[!audio->currentBuffer],NETWORK_AUDIO_BUFFER_SIZE*sizeof(float),0,(const struct sockaddr *)&outServer,length);
-   if (n < 0) error("Sendto");
-   audio->doneOnTime=1;
-   return 0;
-}
-
-int receiveMessage(networkData message){
-	struct timeval stTimeOut;
-	fd_set stReadFDS;
-	FD_ZERO(&stReadFDS);
-	// Timeout of one second
-	stTimeOut.tv_sec = 0;
-	stTimeOut.tv_usec = 0;
-	FD_SET(inSock, &stReadFDS);
-
-	int t = select(inSock+1, &stReadFDS, NULL, NULL, &stTimeOut);
-	if (t == -1) {
-		rt_fprintf(stderr, "Call to select() failed");
-		return -1;
-	}
-	else if (t != 0) {
-		if (FD_ISSET(inSock, &stReadFDS)) {
-//			printf("There is data pending to be read..."); // Read data with recv()
-			int n = recvfrom(inSock,inBuffer,1024,0,(struct sockaddr *)&from,&fromlen);
-			if (n < 0){
-				rt_fprintf(stderr,"Error while receiving");
-				return -1;
-			}
-			printf("Received a datagram: ");
-			printf(inBuffer);
-			//the worst parser ever
-			int previousN=0;
-			int currentVariable=0;
-			for(int n=0; inBuffer[n]!=0 && currentVariable<message.numVariables && n-previousN<MAX_VAR_STRING && n<MESSAGE_BUFF_LEN; n++){ //scan the string
-				if(inBuffer[n]==';'||inBuffer[n]==0||inBuffer[n]=='\n'){ // if you find a separator or you are at the end of the string, parse the variable
-					int j=0;
-					inBuffer[n]=0;	 //set the semicolon to 0 ...
-					while( (variableString[j++]=inBuffer[previousN++]) );; // ... so that this will stop when it gets there
-					rt_printf("variable %d: %s\n", currentVariable, variableString);
-					*(message.variables[currentVariable])=atof(variableString);
-					n++; //increment to step after the semicolon
-					previousN=n;
-					currentVariable++;
-				}
-			}
-		}
-	}
-	return 0;
-}
-
-void closeSockets(){
-   close(outSock);
-   close(inSock);
-}
-void error(const char *msg)
-{
-    perror(msg);
-    exit(0);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/NetworkSend.h	Wed Aug 19 23:11:34 2015 +0100
@@ -0,0 +1,66 @@
+//scope.cpp
+#ifndef SCOPE_H_
+#define SCOPE_H_
+
+#include <BeagleRT.h> 
+#include <rtdk.h>
+#include <cmath>
+#include <UdpClient.h>
+#include <vector>
+
+#define NETWORK_AUDIO_BUFFER_SIZE 302
+
+struct NetworkBuffer{
+	int channelNumber;
+	int activeBuffer;
+	int index;
+	float buffers[2][NETWORK_AUDIO_BUFFER_SIZE];
+	bool doneOnTime;
+	bool readyToBeSent;
+	static const int headerLength=2;
+};
+
+class NetworkSend {
+    int sampleCount; 
+    float sampleRate;
+	UdpClient udpClient;
+	static bool staticConstructed;
+    static void staticConstructor();
+    static AuxiliaryTask transmitAudioTask; //TODO: allow different AuxiliaryTasks for different priorities (e.g.: audio vs scope)
+    static std::vector<NetworkSend *> objAddrs;
+  public:
+    NetworkBuffer channel;
+    NetworkSend();
+    ~NetworkSend();
+    void setup(float aSampleRate);
+    void setup(float aSampleRate, int aChannelNumber, int aPort, const char *aServer);
+    void sendData();
+    void log(float value);
+    void setPort(int aPort);
+    void setServer(const char* aServer);
+    void setChannelNumber(int aChannelNumber);
+    int getChannelNumber();
+    static int getNumInstances();
+    static void sendAllData();
+};
+
+/**
+ * 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 getNumChannels();
+};
+#endif /* SCOPE_H */
--- a/include/Scope.h	Tue Aug 18 00:35:15 2015 +0100
+++ /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/client.h	Tue Aug 18 00:35:15 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/* UDP client in the internet domain */
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-struct networkData{
-	int *counter;
-	float *variables[16];
-	int numVariables;
-};
-#define NETWORK_AUDIO_BUFFER_SIZE 100 //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;
-};
-
-void error(const char *);
-int setupSockets(int receivePort, int transmitPort, char const*serverName);
-int sendMessage(networkData message);
-int sendAudio(networkAudio *audio);
-int receiveMessage(networkData message);
-void closeSockets();
--- a/projects/basic_network/render.cpp	Tue Aug 18 00:35:15 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/*
- * render.cpp
- *
- *  Created on: Oct 24, 2014
- *      Author: parallels
- */
-
-#include <BeagleRT.h>
-//#include <rtdk.h>
-#include <cmath>
-#include <UdpClient.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.
-//
-// 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.
-bool setup(BeagleRTContext *context, void *userData)
-{
-	// Retrieve a parameter passed in from the initAudio() call
-	gFrequency = *(float *)userData;
-
-	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");
-	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.
-
-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);
-		}
-		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++;
-	}
-}
-
-// 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)
-{
-}
--- a/projects/scope/render.cpp	Tue Aug 18 00:35:15 2015 +0100
+++ b/projects/scope/render.cpp	Wed Aug 19 23:11:34 2015 +0100
@@ -1,12 +1,13 @@
 #include <BeagleRT.h> 
-#include <Scope.h>
+#include <NetworkSend.h>
 #include <cmath>
 
 float gPhase1, gPhase2;
 float gFrequency1, gFrequency2;
 float gInverseSampleRate;
 
-Scope scope;    //create a scope object
+Scope scope(6);   //create a scope object with 6 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 +17,11 @@
 // in from the call to initAudio().
 //
 // Return true on success; returning false halts the program.
+
 bool setup(BeagleRTContext *context, void *userData)
 {
-	scope.setup(context->audioSampleRate);  //call this once in setup to initialise the scope
+	scope.setup();  //call this once in setup to initialise the scope
+//	networkSend.setup(context->audioSampleRate, 0, 9999, "192.168.7.1");
 	 
 	gInverseSampleRate = 1.0/context->audioSampleRate;
 	
@@ -27,6 +30,7 @@
 	
 	gFrequency1 = 200.0;
 	gFrequency2 = 201.0;
+
 	return true; 
 }
 
@@ -37,26 +41,32 @@
 
 void render(BeagleRTContext *context, void *userData)
 {
+	static int count=0;
 	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;
+	    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;
@@ -64,6 +74,7 @@
 			gPhase2 -= 2.0 * M_PI;
 		
 	}
+	count++;
 }
 
 // cleanup_render() is called once at the end, after the audio has stopped.
--- a/resources/network/udp-server.c	Tue Aug 18 00:35:15 2015 +0100
+++ b/resources/network/udp-server.c	Wed Aug 19 23:11:34 2015 +0100
@@ -47,8 +47,9 @@
        n = recvfrom(sock,buf,2048,0,(struct sockaddr *)&from,&fromlen);
        if (n < 0) error("recvfrom");
        printf("Received a datagram of size %d: \n", n);
-       for(i=0; i<n/sizeof(float); i+=8)
-	       printf("[%05d]: %+f, %+f, %+f, %+f, %+f, %+f, %+f, %+f\n",i,buf[0+i],buf[1+i],buf[2+i],buf[3+i],buf[4+i],buf[5+i],buf[6+i],buf[7+i]);
+       printf("Header: channel: %d, timestamp: %d\n", (int)buf[0], (int)buf[1]);
+       for(i=2; i<n/sizeof(float); i+=8)
+	       printf("%+f, %+f, %+f, %+f, %+f, %+f, %+f, %+f\n",i,buf[0+i],buf[1+i],buf[2+i],buf[3+i],buf[4+i],buf[5+i],buf[6+i],buf[7+i]);
        n = sendto(sock,"Got your message\n",17,
                   0,(struct sockaddr *)&from,fromlen);
        if (n  < 0) error("sendto");