annotate core/NetworkSend.cpp @ 116:8341df5e404b scope-refactoring

Refactoring
author Giulio Moro <giuliomoro@yahoo.it>
date Wed, 19 Aug 2015 23:22:39 +0100
parents a0e24514fc97
children c692827083e1
rev   line source
giuliomoro@111 1 //scope.cpp
giuliomoro@112 2 #include <NetworkSend.h>
giuliomoro@111 3
giuliomoro@111 4 #define BUILD_FOR_UDPRECEIVE_PLUGIN
giuliomoro@111 5 #define NETWORK_AUDIO_BUFFER_SIZE 302
giuliomoro@111 6
giuliomoro@111 7 //initialize the static members of NetworkSend
giuliomoro@111 8 bool NetworkSend::staticConstructed=false;
giuliomoro@111 9 std::vector<NetworkSend*> NetworkSend::objAddrs(0);
giuliomoro@116 10 AuxiliaryTask NetworkSend::sendDataTask=NULL;
giuliomoro@111 11
giuliomoro@111 12 void transmitAudio(){
giuliomoro@111 13 NetworkSend::sendAllData();
giuliomoro@111 14 }
giuliomoro@111 15
giuliomoro@111 16 void NetworkSend::sendAllData(){
giuliomoro@111 17 for(unsigned int n=0; n<NetworkSend::objAddrs.size(); n++){
giuliomoro@111 18 NetworkSend::objAddrs[n]->sendData();
giuliomoro@111 19 }
giuliomoro@111 20 }
giuliomoro@111 21
giuliomoro@111 22 void NetworkSend::staticConstructor(){
giuliomoro@111 23 if(staticConstructed==true)
giuliomoro@111 24 return;
giuliomoro@111 25 staticConstructed=true;
giuliomoro@116 26 sendDataTask = BeagleRT_createAuxiliaryTask(transmitAudio, 95, "sendDataTask"); //TODO: allow variable priority
giuliomoro@111 27 };
giuliomoro@111 28
giuliomoro@111 29 NetworkSend::NetworkSend()
giuliomoro@111 30 {
giuliomoro@111 31 sampleCount = 0;
giuliomoro@111 32 channel.doneOnTime=true;
giuliomoro@111 33 channel.index=channel.headerLength; //leave space for the heading message (channel, timestamp)
giuliomoro@111 34 channel.activeBuffer=0;
giuliomoro@111 35 channel.readyToBeSent=false;
giuliomoro@111 36 }
giuliomoro@116 37
giuliomoro@111 38 NetworkSend::~NetworkSend(){
giuliomoro@111 39 for(unsigned int n=0; n<objAddrs.size(); n++){ //keep track of deleted instances;
giuliomoro@111 40 if(objAddrs[n]==this){
giuliomoro@111 41 objAddrs.erase(objAddrs.begin()+n);
giuliomoro@111 42 break;
giuliomoro@111 43 }
giuliomoro@111 44 }
giuliomoro@111 45 }
giuliomoro@111 46
giuliomoro@111 47 void NetworkSend::setup(float aSampleRate){
giuliomoro@111 48 setup(aSampleRate, 0, 9999, "192.168.7.1");//channelNumber=0
giuliomoro@111 49 }
giuliomoro@111 50
giuliomoro@111 51 void NetworkSend::setup(float aSampleRate, int aChannelNumber, int aPort, const char *aServer){
giuliomoro@111 52 staticConstructor(); //FIXME: ideally this should be in the constructor, but this is not currently possible
giuliomoro@111 53 //because of limitations in BeagleRT_createAuxiliaryTask()
giuliomoro@111 54 //keep track of added active instances
giuliomoro@111 55 objAddrs.push_back(this);//TODO: this line should be in the constructor, but something weird happens if
giuliomoro@111 56 // an instance of NetworkSend is then declared globally: the constructor gets called,
giuliomoro@111 57 // and objAddrs.size()==1 but when you get to setup, objAddrs.size() has reverted back to 0, without
giuliomoro@111 58 // any destructor being called in between ...
giuliomoro@111 59 setChannelNumber(aChannelNumber);
giuliomoro@111 60 setPort(aPort);
giuliomoro@111 61 setServer(aServer);
giuliomoro@111 62 printf("Channel %d is sending messages to : %s:%d at %fHz\n", getChannelNumber(), aServer, aPort, aSampleRate);
giuliomoro@111 63 }
giuliomoro@111 64
giuliomoro@111 65 void NetworkSend::log(float value){ //TODO: add a vectorized version of this method
giuliomoro@111 66 if(channel.index==(NETWORK_AUDIO_BUFFER_SIZE)){ // when the buffer is ready ...
giuliomoro@111 67 channel.readyToBeSent=true;
giuliomoro@111 68 channel.index=channel.headerLength; //reset the counter
giuliomoro@111 69 if(channel.doneOnTime==false){
giuliomoro@111 70 printf("Network buffer underrun. timestamp: %d :-{\n", (int)channel.buffers[!channel.activeBuffer][1]);
giuliomoro@111 71 }
giuliomoro@111 72 channel.activeBuffer=!channel.activeBuffer; //switch buffer
giuliomoro@111 73 channel.doneOnTime=false;
giuliomoro@116 74 BeagleRT_scheduleAuxiliaryTask(NetworkSend::sendDataTask); //send the buffer
giuliomoro@111 75 //TODO: maybe we should have transmitAudioTask running in a loop instead of scheduling it multiple times?
giuliomoro@111 76 }
giuliomoro@111 77 if(channel.index==channel.headerLength){
giuliomoro@111 78 channel.buffers[channel.activeBuffer][0] = (float)channel.channelNumber; //TODO: this could actually be done just once in setup()
giuliomoro@111 79 channel.buffers[channel.activeBuffer][1]=(float)sampleCount; //timestamp
giuliomoro@111 80 //add here more header fields
giuliomoro@111 81 }
giuliomoro@111 82 channel.buffers[channel.activeBuffer][channel.index++]=value;
giuliomoro@111 83 sampleCount++;
giuliomoro@111 84 };
giuliomoro@111 85
giuliomoro@111 86 void NetworkSend::setServer(const char *aServer){
giuliomoro@111 87 udpClient.setServer(aServer);
giuliomoro@111 88 }
giuliomoro@111 89 void NetworkSend::setPort(int aPort){
giuliomoro@111 90 udpClient.setPort(aPort);
giuliomoro@111 91 }
giuliomoro@111 92
giuliomoro@111 93 void NetworkSend::setChannelNumber(int aChannelNumber){
giuliomoro@111 94 channel.channelNumber=aChannelNumber;
giuliomoro@111 95 };
giuliomoro@111 96 int NetworkSend::getChannelNumber(){
giuliomoro@111 97 return channel.channelNumber;
giuliomoro@111 98 };
giuliomoro@111 99
giuliomoro@111 100 void NetworkSend::sendData(){
giuliomoro@111 101 if(channel.readyToBeSent){
giuliomoro@111 102 channel.readyToBeSent=false;
giuliomoro@111 103 udpClient.send(
giuliomoro@111 104 channel.buffers[!channel.activeBuffer],
giuliomoro@111 105 NETWORK_AUDIO_BUFFER_SIZE*sizeof(float)
giuliomoro@111 106 );
giuliomoro@111 107 channel.doneOnTime=true;
giuliomoro@111 108 }
giuliomoro@111 109 }
giuliomoro@111 110
giuliomoro@111 111 int NetworkSend::getNumInstances(){
giuliomoro@111 112 return objAddrs.size();
giuliomoro@111 113 };
giuliomoro@111 114
giuliomoro@111 115 Scope::Scope(int aNumChannels):
giuliomoro@111 116 channels(aNumChannels)
giuliomoro@111 117 {};
giuliomoro@111 118 Scope::~Scope(){};
giuliomoro@111 119
giuliomoro@111 120 void Scope::log(int channel, float value){
giuliomoro@111 121 if(channel>=getNumChannels()) //TODO: assert this
giuliomoro@111 122 return;
giuliomoro@111 123 channels[channel].log(value);
giuliomoro@111 124 }
giuliomoro@111 125
giuliomoro@111 126 void Scope::setup(){
giuliomoro@111 127 setup(44100, 9999, "127.0.0.1");
giuliomoro@111 128 }
giuliomoro@111 129
giuliomoro@111 130 void Scope::setup(float sampleRate, int aPort, const char* aServer){
giuliomoro@111 131 for(int n=0; n<getNumChannels(); n++){
giuliomoro@111 132 channels[n].setup(sampleRate, n, aPort, aServer);
giuliomoro@111 133 }
giuliomoro@111 134 }
giuliomoro@111 135
giuliomoro@111 136 int Scope::getNumChannels(){
giuliomoro@111 137 return channels.size();
giuliomoro@111 138 }
giuliomoro@111 139
giuliomoro@111 140 void Scope::sendData(){
giuliomoro@111 141 NetworkSend::sendAllData();
giuliomoro@111 142 }