Mercurial > hg > beaglert
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 } |