view core/NetworkSend.cpp @ 112:3168919fdb07 scope-refactoring

Fixed a couple inclues after the refactoring
author Giulio Moro <giuliomoro@yahoo.it>
date Wed, 19 Aug 2015 22:56:12 +0100
parents 9928b6366227
children 7dfae7b7ab12
line wrap: on
line source
//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.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();
}