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