some cleanup as well as adding a way to pass the Qapplication between sinks that...
[debian/gnuradio] / gr-qtgui / src / lib / SpectrumGUIClass.cc
1 #ifndef SPECTRUM_GUI_CLASS_CPP
2 #define SPECTRUM_GUI_CLASS_CPP
3
4 #include <SpectrumGUIClass.h>
5 //Added by qt3to4:
6 #include <QEvent>
7 #include <QCustomEvent>
8
9 const long SpectrumGUIClass::MAX_FFT_SIZE;
10 const long SpectrumGUIClass::MIN_FFT_SIZE;
11
12 SpectrumGUIClass::SpectrumGUIClass(const uint64_t maxDataSize, const uint64_t fftSize, 
13                                    const double newStartFrequency, const double newStopFrequency){
14   _dataPoints = maxDataSize;
15   if(_dataPoints < 2){
16     _dataPoints = 2;
17   }
18   _lastDataPointCount = _dataPoints;
19
20   _fftSize = fftSize;
21
22   _pendingGUIUpdateEventsCount = 0;
23   _droppedEntriesCount = 0;
24
25   _centerFrequency = 0;
26   _startFrequency = newStartFrequency;
27   _stopFrequency = newStopFrequency;
28
29 #warning SPECIFY THIS LATER...
30   _windowType = 5;
31
32   timespec_reset(&_lastGUIUpdateTime);
33
34   _windowOpennedFlag = false;
35   _fftBuffersCreatedFlag = false;
36
37   // Create Mutex Lock
38   //_windowStateLock = new MutexClass("_windowStateLock");
39
40   _powerValue = 1;
41 }
42
43 SpectrumGUIClass::~SpectrumGUIClass(){
44   if(GetWindowOpenFlag()){
45     delete _spectrumDisplayForm;
46   }
47
48   if(_fftBuffersCreatedFlag){
49     delete[] _fftPoints;
50     delete[] _realTimeDomainPoints;
51     delete[] _imagTimeDomainPoints;
52   }
53
54   //delete _windowStateLock;
55 }
56
57 void SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent){
58   //_windowStateLock->Lock();
59
60   if(!_windowOpennedFlag){
61
62     if(!_fftBuffersCreatedFlag){
63       _fftPoints = new std::complex<float>[_dataPoints];
64       _realTimeDomainPoints = new double[_dataPoints];
65       _imagTimeDomainPoints = new double[_dataPoints];
66       _fftBuffersCreatedFlag = true;
67       
68       
69       memset(_fftPoints, 0x0, _dataPoints*sizeof(std::complex<float>));
70       memset(_realTimeDomainPoints, 0x0, _dataPoints*sizeof(double));
71       memset(_imagTimeDomainPoints, 0x0, _dataPoints*sizeof(double));
72     }
73     
74     // Called from the Event Thread
75     _spectrumDisplayForm = new SpectrumDisplayForm(parent);
76
77     _windowOpennedFlag = true;
78
79     _spectrumDisplayForm->setSystem(this, _dataPoints, _fftSize);
80
81     qApp->processEvents();
82   }
83
84   //_windowStateLock->Unlock();
85
86   SetDisplayTitle(_title);
87   Reset();
88
89   qApp->postEvent(_spectrumDisplayForm, new QEvent(QEvent::Type(QEvent::User+3)));
90
91   _spectrumDisplayForm->show();
92
93   qApp->processEvents();
94
95   timespec_reset(&_lastGUIUpdateTime);
96
97   // Draw Blank Display
98   UpdateWindow(false, NULL, 0, NULL, 0, NULL, 0, 1.0, get_highres_clock(), true);
99
100   // GUI Thread only
101   qApp->processEvents();
102 }
103
104 void SpectrumGUIClass::Reset(){
105   if(GetWindowOpenFlag()){
106     qApp->postEvent(_spectrumDisplayForm, new SpectrumFrequencyRangeEvent(_centerFrequency, 
107                                                                           _startFrequency, 
108                                                                           _stopFrequency));
109     qApp->postEvent(_spectrumDisplayForm, new SpectrumWindowResetEvent());
110   }
111   _droppedEntriesCount = 0;
112   // Call the following function the the Spectrum Window Reset Event window
113   // ResetPendingGUIUpdateEvents();
114 }
115
116 void SpectrumGUIClass::SetDisplayTitle(const std::string newString){
117   _title.assign(newString);
118
119   if(GetWindowOpenFlag()){
120     qApp->postEvent(_spectrumDisplayForm, new SpectrumWindowCaptionEvent(_title.c_str()));
121   }
122
123 }
124
125 bool SpectrumGUIClass::GetWindowOpenFlag(){
126   bool returnFlag = false;
127   //_windowStateLock->Lock();
128   returnFlag =  _windowOpennedFlag;
129   //_windowStateLock->Unlock();
130   return returnFlag;
131 }
132
133
134 void SpectrumGUIClass::SetWindowOpenFlag(const bool newFlag){
135   //_windowStateLock->Lock();
136   _windowOpennedFlag = newFlag;
137   //_windowStateLock->Unlock();
138 }
139
140 void SpectrumGUIClass::SetFrequencyRange(const double centerFreq, const double startFreq, const double stopFreq){
141   //_windowStateLock->Lock();
142   _centerFrequency = centerFreq;
143   _startFrequency = startFreq;
144   _stopFrequency = stopFreq;
145   //_windowStateLock->Unlock();
146 }
147
148 double SpectrumGUIClass::GetStartFrequency()const{
149   double returnValue = 0.0;
150   //_windowStateLock->Lock();
151   returnValue =  _startFrequency;
152   //_windowStateLock->Unlock();
153   return returnValue;
154 }
155
156 double SpectrumGUIClass::GetStopFrequency()const{
157   double returnValue = 0.0;
158   //_windowStateLock->Lock();
159   returnValue =  _stopFrequency;
160   //_windowStateLock->Unlock();
161   return returnValue;
162 }
163
164 double SpectrumGUIClass::GetCenterFrequency()const{
165   double returnValue = 0.0;
166   //_windowStateLock->Lock();
167   returnValue =  _centerFrequency;
168   //_windowStateLock->Unlock();
169   return returnValue;
170 }
171
172
173 void SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag, const std::complex<float>* fftBuffer, const uint64_t inputBufferSize, const float* realTimeDomainData, const uint64_t realTimeDomainDataSize, const float* complexTimeDomainData, const uint64_t complexTimeDomainDataSize, const double timePerFFT, const timespec timestamp, const bool lastOfMultipleFFTUpdateFlag){
174
175   int64_t bufferSize = inputBufferSize;
176   bool repeatDataFlag = false;
177   if(bufferSize > _dataPoints){
178     bufferSize = _dataPoints;
179   }
180   int64_t timeDomainBufferSize = 0;
181
182   if( updateDisplayFlag){
183     if((fftBuffer != NULL) && (bufferSize > 0)){
184       memcpy(_fftPoints, fftBuffer, bufferSize * sizeof(std::complex<float>));
185     }
186
187     // Can't do a memcpy since ths is going from float to double data type
188     if((realTimeDomainData != NULL) && (realTimeDomainDataSize > 0)){
189       const float* realTimeDomainDataPtr = realTimeDomainData;
190
191       double* realTimeDomainPointsPtr = _realTimeDomainPoints;
192       timeDomainBufferSize = realTimeDomainDataSize;
193
194       memset( _imagTimeDomainPoints, 0x0, realTimeDomainDataSize*sizeof(double));
195       for( uint64_t number = 0; number < realTimeDomainDataSize; number++){
196         *realTimeDomainPointsPtr++ = *realTimeDomainDataPtr++;
197       }
198     }
199
200     // Can't do a memcpy since ths is going from float to double data type
201     if((complexTimeDomainData != NULL) && (complexTimeDomainDataSize > 0)){
202       const float* complexTimeDomainDataPtr = complexTimeDomainData;
203
204       double* realTimeDomainPointsPtr = _realTimeDomainPoints;
205       double* imagTimeDomainPointsPtr = _imagTimeDomainPoints;
206
207       timeDomainBufferSize = complexTimeDomainDataSize;
208       for( uint64_t number = 0; number < complexTimeDomainDataSize; number++){
209         *realTimeDomainPointsPtr++ = *complexTimeDomainDataPtr++;
210         *imagTimeDomainPointsPtr++ = *complexTimeDomainDataPtr++;
211       }
212     }
213   }
214
215   // If bufferSize is zero, then just update the display by sending over the old data
216   if(bufferSize < 1){
217     bufferSize = _lastDataPointCount;
218     repeatDataFlag = true;
219   }
220   else{
221     // Since there is data this time, update the count
222     _lastDataPointCount = bufferSize;
223   }
224
225   const timespec currentTime = get_highres_clock();
226   const timespec lastUpdateGUITime = GetLastGUIUpdateTime();
227
228   if((diff_timespec(currentTime, lastUpdateGUITime) > (4*timePerFFT)) && (GetPendingGUIUpdateEvents() > 0) && !timespec_empty(&lastUpdateGUITime)){
229     // Do not update the display if too much data is pending to be displayed
230     _droppedEntriesCount++;
231   }
232   else{
233     // Draw the Data
234     IncrementPendingGUIUpdateEvents();
235     qApp->postEvent(_spectrumDisplayForm, new SpectrumUpdateEvent(_fftPoints, bufferSize, _realTimeDomainPoints, _imagTimeDomainPoints, timeDomainBufferSize, timePerFFT, timestamp, repeatDataFlag, lastOfMultipleFFTUpdateFlag, currentTime, _droppedEntriesCount));
236     
237     // Only reset the dropped entries counter if this is not repeat data since repeat data is dropped by the display systems
238     if(!repeatDataFlag){
239       _droppedEntriesCount = 0;
240     }
241   
242     //qApp->wakeUpGuiThread();
243   }
244 }
245
246 float SpectrumGUIClass::GetPowerValue()const{
247   float returnValue = 0;
248   //_windowStateLock->Lock();
249   returnValue = _powerValue;
250   //_windowStateLock->Unlock();
251   return returnValue;
252 }
253
254 void SpectrumGUIClass::SetPowerValue(const float value){
255   //_windowStateLock->Lock();
256   _powerValue = value;
257   //_windowStateLock->Unlock();
258 }
259
260 int SpectrumGUIClass::GetWindowType()const{
261   int returnValue = 0;
262   //_windowStateLock->Lock();
263   returnValue = _windowType;
264   //_windowStateLock->Unlock();
265   return returnValue;
266 }
267
268 void SpectrumGUIClass::SetWindowType(const int newType){
269   //_windowStateLock->Lock();
270   _windowType = newType;
271   //_windowStateLock->Unlock();
272 }
273
274 int SpectrumGUIClass::GetFFTSize()const{
275   int returnValue = 0;
276   //_windowStateLock->Lock();
277   returnValue = _fftSize;
278   //_windowStateLock->Unlock();
279   return returnValue;
280 }
281
282 int SpectrumGUIClass::GetFFTSizeIndex()const{
283   int fftsize = GetFFTSize();
284   switch(fftsize) {
285   case(1024): return 0; break;
286   case(2048): return 1; break;
287   case(4096): return 2; break;
288   case(8192): return 3; break;
289   case(16384): return 3; break;
290   case(32768): return 3; break;
291   default: return 0;
292   }
293 }
294
295 void SpectrumGUIClass::SetFFTSize(const int newSize){
296   //_windowStateLock->Lock();
297   _fftSize = newSize;
298   //_windowStateLock->Unlock();
299 }
300
301 timespec SpectrumGUIClass::GetLastGUIUpdateTime()const{
302   timespec returnValue;
303   //_windowStateLock->Lock();
304   returnValue = _lastGUIUpdateTime;
305   //_windowStateLock->Unlock();
306   return returnValue;
307 }
308
309 void SpectrumGUIClass::SetLastGUIUpdateTime(const timespec newTime){
310   //_windowStateLock->Lock();
311   _lastGUIUpdateTime = newTime;
312   //_windowStateLock->Unlock();
313 }
314
315 unsigned int SpectrumGUIClass::GetPendingGUIUpdateEvents()const{
316   unsigned int returnValue = 0;
317   //_windowStateLock->Lock();
318   returnValue = _pendingGUIUpdateEventsCount;
319   //_windowStateLock->Unlock();
320   return returnValue;
321 }
322
323 void SpectrumGUIClass::IncrementPendingGUIUpdateEvents(){
324   //_windowStateLock->Lock();
325   _pendingGUIUpdateEventsCount++;
326   //_windowStateLock->Unlock();
327 }
328
329 void SpectrumGUIClass::DecrementPendingGUIUpdateEvents(){
330   //_windowStateLock->Lock();
331   if(_pendingGUIUpdateEventsCount > 0){
332     _pendingGUIUpdateEventsCount--;
333   }
334   //_windowStateLock->Unlock();
335 }
336
337 void SpectrumGUIClass::ResetPendingGUIUpdateEvents(){
338   //_windowStateLock->Lock();
339   _pendingGUIUpdateEventsCount = 0;
340   //_windowStateLock->Unlock();
341 }
342
343
344 #endif /* SPECTRUM_GUI_CLASS_CPP */