Mercurial > hg > beaglert
diff core/NetworkSend.cpp @ 111:9928b6366227 scope-refactoring
Refactored the Scope class into NetworkSend and Scope classes. No need for a global pointer anymore!
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Wed, 19 Aug 2015 22:40:05 +0100 |
parents | |
children | 3168919fdb07 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/NetworkSend.cpp Wed Aug 19 22:40:05 2015 +0100 @@ -0,0 +1,144 @@ +//scope.cpp +#include <Scope.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.timestamp=0; + 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(); +}