Mercurial > hg > beaglert
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=""${workspace_loc:/BeagleRT/include}""/> </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=""${workspace_loc:/BeagleRT/include}""/> + <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=""${workspace_loc:/BeagleRT/include}""/> </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 "kill -s 2 \`pidof ${BuildArtifactFileName}\` 2>/dev/null; sleep 0.6"; 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 "kill -s 2 \`pidof ${BuildArtifactFileName}\` 2>/dev/null"; 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");