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 (current diff) 3068421c0737 (diff) |
children | a0e24514fc97 |
files | .cproject core/client.cpp include/client.h projects/basic_network/render.cpp |
diffstat | 8 files changed, 420 insertions(+), 150 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/UdpServer.cpp Wed Aug 19 23:11:34 2015 +0100 @@ -0,0 +1,88 @@ +/* + * udpServer.cpp + * + * Created on: 19 May 2015 + * Author: giulio moro + */ +#include "../include/UdpServer.h" + +UdpServer::UdpServer(int aPort){ + init(aPort); +}; +UdpServer::UdpServer(){ + init(0); +} +UdpServer::~UdpServer(){ + //TODO: unbind from port. AFAIK, this involves closing the socket, therefore creating the socket should become part of bindToPort +}; +bool UdpServer::init(int aPort){ + enabled=true; + stTimeOut.tv_sec = 0; //set timeout to 0 + stTimeOut.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); + 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; +}; +int UdpServer::read(//Returns the number of bytes read, or -1 if there was an error. + void *destBuffer, + int maxBytesToRead){ + if(enabled==false) + return -1; + FD_ZERO(&stReadFDS); + FD_SET(inSocket, &stReadFDS); + int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stTimeOut); + if(descriptorReady<0){ //an error occurred + return -1; + } + int numberOfBytes=0; + if (FD_ISSET(inSocket, &stReadFDS)) { + numberOfBytes=recvfrom(inSocket,destBuffer,maxBytesToRead,0,(struct sockaddr *)&from,&fromLength); + if(numberOfBytes<0) + return -1; + } + return numberOfBytes; +}; +int UdpServer::emptySocket(){ + return emptySocket(0); +} +int UdpServer::emptySocket(int maxBytes){//discards up to maxBytes from the socket. Returns the number of bytes discarded. + if(wasteBuffer==NULL) + return -1; + int numberOfBytes=0; + while(int n=read(wasteBuffer, wasteBufferSize)){// calls the read function until it does not return any more bytes (i.e.: socket is empty) + if(n>0) + numberOfBytes+=n; + if(n<0) + return -1; + if(maxBytes>0 && numberOfBytes>=maxBytes) + break; + }; + return numberOfBytes; +} +void* UdpServer::getWaste(){ //returns the last datagram retrieved by emptySocket() + return wasteBuffer; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/intervals.cpp Wed Aug 19 23:11:34 2015 +0100 @@ -0,0 +1,94 @@ +/* + * intervals.h + * + * Created on: 18 May 2015 + * Author: unmanaged + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +#include <native/timer.h> +#include <rtdk.h> + +#include "../include/intervals.h" +void Interval::init(int aNumAverages, int aNumFrames, float aSamplingRate, const char *aName){ + enabled=false; + numAverages=aNumAverages; + intervals=(RTIME *)malloc(sizeof(RTIME)*numAverages); + samplingRate=aSamplingRate; + numFrames=aNumFrames; + maxTimeus=0; + intervalsPointer=0; + sum=0; + startTime=0; + + if(intervals!=0) + enabled=true; + int len=strlen(aName); + name=(char *)malloc(sizeof(char)*(len+1)); + strcpy(name, aName); + if(name == 0) + enabled=false; +}; +Interval::Interval(){ + init(100,1,44100,""); +} +Interval::Interval(int aNumAverages){ + init(aNumAverages,1,44100,""); +} +Interval::Interval(int aNumAverages, int aNumFrames, float aSamplingRate, const char *aName){ + init(aNumAverages,aNumFrames,aSamplingRate,aName); +} +Interval::~Interval(){ + free(intervals); +// free(name); +} +void Interval::setNumFrames(int aNumFrames){ + numFrames=aNumFrames; +}; + +int Interval::start(){ +// printf("start: intervals: 0x%x, intervalsPointer: %d, numAverages: %d\n", intervals,intervalsPointer,numAverages); + if(!enabled) + return 0; + startTime=rt_timer_read(); + return 1; +} +int Interval::resetMax(){ + maxTimeus=0; + return 1; +} +int Interval::split(){ //updates + if(!enabled) + return 0; + int currentInterval=rt_timer_read()-startTime; + RTIME *currentPointer=&(intervals[intervalsPointer]); + sum-=*currentPointer; //take out the oldest value from the sum + *currentPointer=currentInterval; + sum+=*currentPointer; //add the new value to the sum + timeus=((float)sum)/numAverages/1000.0; + maxTimeus=timeus>maxTimeus?timeus:maxTimeus; + intervalsPointer++; + if(intervalsPointer>=(numAverages-1)){ + intervalsPointer=0; + } + return 1; +} +void Interval::setEnabled(bool aActive){ + enabled=aActive; +} +float Interval::getTimeus(){ + return timeus; +} +float Interval::getMaxTimeus(){ + return maxTimeus; +} +void Interval::print(){ + rt_printf(//"sleepTimer time: 29.484us, (1.30 samples, numFrames: 2, 65.01%%). MaxTime: 30.439us, (1.34 samples, 67.12%%)\n"); +"%s time: %.3fus, (%.2f samples, numFrames: %d, %.2f%%). MaxTime: %.3fus, (%.2f samples, %.2f%%)\n", + name, + timeus, timeus/1000000.0*samplingRate, numFrames, timeus/1000000.0*samplingRate/numFrames * 100, + maxTimeus, maxTimeus/1000000.0*samplingRate, maxTimeus/1000000.0*samplingRate/numFrames * 100); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/UdpServer.h Wed Aug 19 23:11:34 2015 +0100 @@ -0,0 +1,51 @@ +/* + * 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 <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; + 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; + int read(void *destBuffer, + int maxBytesToRead); + int emptySocket(); + int emptySocket(int maxBytes); + void *getWaste(); +}; + + + +#endif /* UDPSERVER_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/intervals.h Wed Aug 19 23:11:34 2015 +0100 @@ -0,0 +1,50 @@ +/* + * intervals.h + * + * Created on: 18 May 2015 + * Author: unmanaged + */ + +#ifndef INTERVALS_H_ +#define INTERVALS_H_ + +#define TEN_POW_9 1000000000 + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +#include <native/timer.h> +#include <rtdk.h> + +class Interval +{ + private: + int intervalsPointer; + long sum; + RTIME startTime; + RTIME *intervals; + float maxTimeus; + float timeus; + float samplingRate; //used for getPrint() + int numFrames; + bool enabled; //whether it actually reads the clock or not + int numAverages; + char *name; + void init(int aNumAverages, int aNumFrames, float aSamplingRate, const char *aName); + public: + Interval(); + Interval(int aNumAverages); + Interval(int aNumAverages, int aNumFrames, float aSamplingRate, const char *aName); + ~Interval(); + void setNumFrames(int aNumFrames); + int start(); + int resetMax(); + int split(); + void setEnabled(bool aActive); + float getTimeus(); + float getMaxTimeus(); + void print(); +}; + +#endif /* INTERVALS_H_ */
--- a/projects/basic_network/render.cpp Wed Aug 19 23:03:52 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) -{ -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/resources/tests/UdpClientUdpServerTest.cpp Wed Aug 19 23:11:34 2015 +0100 @@ -0,0 +1,128 @@ +#include "../../include/UdpServer.h" +#include "../../include/UdpClient.h" +#include <unistd.h> + +int test1(UdpServer *server, UdpClient *client){ + int buffer; + int tot=100; + int errors=0; + for(int n=0; n<tot; n++){ + if(client->send(&n,sizeof(int))!=1){ + printf("error: while sending\n"); + errors++; + } + } + for(int n=0; n<tot; n++){ + if(server->read(&buffer,sizeof(int))<0){ + printf("error: unable to read\n"); + errors++; + continue; + }; + if(n!=buffer){ + printf("error: %d!=%d\n",n,buffer); + errors++; + } + } + int n=server->emptySocket(); + if(n!=0) + printf("Error: the socket had %d bytes\n",n); + return errors; +} +int compareStrings(char * str1, char * str2){ + if(strlen(str1)!=strlen(str2)) + return -1; + for(int n=0; n<strlen(str1); n++){ + if(str1[n]!=str2[n]) + return -1; + } + return 0; +} + +int test2(UdpServer *server, UdpClient *client){ + char buffer[1000]; + int tot=100; + int errors=0; + for(int n=0; n<tot; n++){ + int num=sprintf(buffer,"%08.8f",n/1000.0); + client->send(&buffer,sizeof(char)*(num+1)); + } + char auxBuffer[100]; + for(int n=0; n<tot; n++){ + int num=sprintf(auxBuffer,"%08.8f",n/1000.0); + server->read(&buffer,num*sizeof(char)); + if(compareStrings(auxBuffer,buffer)==-1){ + printf("error: %s!=%s\n",auxBuffer,buffer); + errors++; + } + } + + return errors; +} + +int test3(UdpServer *server, UdpClient *client){ + char buffer[1000]; + int tot=100; + int errors=0; + int totNum=0; + for(int n=0; n<tot; n++){ + int num=sprintf(buffer,"%.8f",n/1000.0); + client->send(&buffer,sizeof(char)*(num+1)); + totNum+=1+num; + } + int n=server->emptySocket(); + if(n!=totNum){ + errors=1; + printf("retrieved bytes differs from sent bytes: %d!=%d\n",n,totNum); + } + return errors; +} + + +int main(){ + int port=1234; + char serverName[]="127.0.0.1"; + UdpServer server(port); + UdpClient client(port,serverName); + int errors=0; + int ret=0; + ret=test1(&server,&client); + errors+=ret; + if(ret) + printf("test1 failed with %d errors\n", ret); + else + printf("test1 passed\n"); + + ret=test2(&server,&client); + errors+=ret; + if(ret) + printf("test2 failed with %d errors\n", ret); + else + printf("test2 passed\n"); + + ret=test3(&server,&client); + errors+=ret; + if(ret) + printf("test3 failed with %d errors\n", ret); + else + printf("test3 passed\n"); +//now test if the setPort and setServer methods work + client.~UdpClient(); + server.~UdpServer(); + port=1235; + UdpServer server1; + UdpClient client1; + client1.setPort(port); + client1.setServer(serverName); + if(server1.bindToPort(port)==false){ + printf("unable to bind to port %d\n",port); + errors+=1; + } + ret=test1(&server1, &client1); + errors+=ret; + if(ret) + printf("test1 failed with %d errors\n", ret); + else + printf("test1 passed\n"); + + return errors; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/resources/tests/make_tests.sh Wed Aug 19 23:11:34 2015 +0100 @@ -0,0 +1,7 @@ +#!/bin/bash +mkdir -p build +mkdir -p bin +g++ -o build/UdpServer.o -O2 -c ../../core/UdpServer.cpp &&\ +g++ -O2 -o build/UdpClient.o -c ../../core/UdpClient.cpp && \ +g++ -O2 -o build/UdpClientUdpServerTest.o -c UdpClientUdpServerTest.cpp && \ +g++ -o bin/UdpClientUdpServerTest build/UdpClientUdpServerTest.o build/UdpClient.o build/UdpServer.o