Imported Upstream version 3.2.2
[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,
13                                    const uint64_t fftSize,
14                                    const double newCenterFrequency,
15                                    const double newStartFrequency,
16                                    const double newStopFrequency)
17 {
18   _dataPoints = maxDataSize;
19   if(_dataPoints < 2){
20     _dataPoints = 2;
21   }
22   _lastDataPointCount = _dataPoints;
23
24   _fftSize = fftSize;
25
26   _pendingGUIUpdateEventsCount = 0;
27   _droppedEntriesCount = 0;
28
29   _centerFrequency = newCenterFrequency;
30   _startFrequency = newStartFrequency;
31   _stopFrequency = newStopFrequency;
32
33 #warning SPECIFY THIS LATER...
34   _windowType = 5;
35
36   timespec_reset(&_lastGUIUpdateTime);
37
38   _windowOpennedFlag = false;
39   _fftBuffersCreatedFlag = false;
40
41   // Create Mutex Lock
42   //_windowStateLock = new MutexClass("_windowStateLock");
43
44   _powerValue = 1;
45 }
46
47 SpectrumGUIClass::~SpectrumGUIClass()
48 {
49   if(GetWindowOpenFlag()){
50     delete _spectrumDisplayForm;
51   }
52
53   if(_fftBuffersCreatedFlag){
54     delete[] _fftPoints;
55     delete[] _realTimeDomainPoints;
56     delete[] _imagTimeDomainPoints;
57   }
58
59   //delete _windowStateLock;
60 }
61
62 void
63 SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent,
64                                      const bool frequency, const bool waterfall,
65                                      const bool waterfall3d, const bool time,
66                                      const bool constellation,
67                                      const bool use_openGL)
68 {
69   //_windowStateLock->Lock();
70
71   if(!_windowOpennedFlag){
72
73     if(!_fftBuffersCreatedFlag){
74       _fftPoints = new std::complex<float>[_dataPoints];
75       _realTimeDomainPoints = new double[_dataPoints];
76       _imagTimeDomainPoints = new double[_dataPoints];
77       _fftBuffersCreatedFlag = true;
78       
79       
80       memset(_fftPoints, 0x0, _dataPoints*sizeof(std::complex<float>));
81       memset(_realTimeDomainPoints, 0x0, _dataPoints*sizeof(double));
82       memset(_imagTimeDomainPoints, 0x0, _dataPoints*sizeof(double));
83     }
84     
85     // Called from the Event Thread
86     _spectrumDisplayForm = new SpectrumDisplayForm(use_openGL, parent);
87     
88     // Toggle Windows on/off
89     _spectrumDisplayForm->ToggleTabFrequency(frequency);
90     _spectrumDisplayForm->ToggleTabWaterfall(waterfall);
91     _spectrumDisplayForm->ToggleTabWaterfall3D(waterfall3d);
92     _spectrumDisplayForm->ToggleTabTime(time);
93     _spectrumDisplayForm->ToggleTabConstellation(constellation);
94
95     _windowOpennedFlag = true;
96
97     _spectrumDisplayForm->setSystem(this, _dataPoints, _fftSize);
98
99     qApp->processEvents();
100   }
101
102   //_windowStateLock->Unlock();
103
104   SetDisplayTitle(_title);
105   Reset();
106
107   qApp->postEvent(_spectrumDisplayForm,
108                   new QEvent(QEvent::Type(QEvent::User+3)));
109
110   qApp->processEvents();
111
112   timespec_reset(&_lastGUIUpdateTime);
113
114   // Draw Blank Display
115   UpdateWindow(false, NULL, 0, NULL, 0, NULL, 0, 1.0, get_highres_clock(), true);
116
117   // Set up the initial frequency axis settings
118   SetFrequencyRange(_centerFrequency, _startFrequency, _stopFrequency);
119
120   // GUI Thread only
121   qApp->processEvents();
122 }
123
124 void
125 SpectrumGUIClass::Reset()
126 {
127   if(GetWindowOpenFlag()) {
128     qApp->postEvent(_spectrumDisplayForm,
129                     new SpectrumFrequencyRangeEvent(_centerFrequency, 
130                                                     _startFrequency, 
131                                                     _stopFrequency));
132     qApp->postEvent(_spectrumDisplayForm, new SpectrumWindowResetEvent());
133   }
134   _droppedEntriesCount = 0;
135   // Call the following function the the Spectrum Window Reset Event window
136   // ResetPendingGUIUpdateEvents();
137 }
138
139 void
140 SpectrumGUIClass::SetDisplayTitle(const std::string newString)
141 {
142   _title.assign(newString);
143
144   if(GetWindowOpenFlag()){
145     qApp->postEvent(_spectrumDisplayForm,
146                     new SpectrumWindowCaptionEvent(_title.c_str()));
147   }
148 }
149
150 bool
151 SpectrumGUIClass::GetWindowOpenFlag()
152 {
153   bool returnFlag = false;
154   //_windowStateLock->Lock();
155   returnFlag =  _windowOpennedFlag;
156   //_windowStateLock->Unlock();
157   return returnFlag;
158 }
159
160
161 void
162 SpectrumGUIClass::SetWindowOpenFlag(const bool newFlag)
163 {
164   //_windowStateLock->Lock();
165   _windowOpennedFlag = newFlag;
166   //_windowStateLock->Unlock();
167 }
168
169 void
170 SpectrumGUIClass::SetFrequencyRange(const double centerFreq,
171                                     const double startFreq,
172                                     const double stopFreq)
173 {
174   //_windowStateLock->Lock();
175   _centerFrequency = centerFreq;
176   _startFrequency = startFreq;
177   _stopFrequency = stopFreq;
178
179   _spectrumDisplayForm->SetFrequencyRange(_centerFrequency,
180                                           _startFrequency,
181                                           _stopFrequency);
182   //_windowStateLock->Unlock();
183 }
184
185 double
186 SpectrumGUIClass::GetStartFrequency() const 
187 {
188   double returnValue = 0.0;
189   //_windowStateLock->Lock();
190   returnValue =  _startFrequency;
191   //_windowStateLock->Unlock();
192   return returnValue;
193 }
194
195 double
196 SpectrumGUIClass::GetStopFrequency() const
197 {
198   double returnValue = 0.0;
199   //_windowStateLock->Lock();
200   returnValue =  _stopFrequency;
201   //_windowStateLock->Unlock();
202   return returnValue;
203 }
204
205 double
206 SpectrumGUIClass::GetCenterFrequency() const
207 {
208   double returnValue = 0.0;
209   //_windowStateLock->Lock();
210   returnValue =  _centerFrequency;
211   //_windowStateLock->Unlock();
212   return returnValue;
213 }
214
215
216 void
217 SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag,
218                                const std::complex<float>* fftBuffer,
219                                const uint64_t inputBufferSize,
220                                const float* realTimeDomainData,
221                                const uint64_t realTimeDomainDataSize,
222                                const float* complexTimeDomainData,
223                                const uint64_t complexTimeDomainDataSize,
224                                const double timePerFFT,
225                                const timespec timestamp,
226                                const bool lastOfMultipleFFTUpdateFlag)
227 {
228   int64_t bufferSize = inputBufferSize;
229   bool repeatDataFlag = false;
230   if(bufferSize > _dataPoints){
231     bufferSize = _dataPoints;
232   }
233   int64_t timeDomainBufferSize = 0;
234
235   if(updateDisplayFlag){
236     if((fftBuffer != NULL) && (bufferSize > 0)){
237       memcpy(_fftPoints, fftBuffer, bufferSize * sizeof(std::complex<float>));
238     }
239
240     // Can't do a memcpy since ths is going from float to double data type
241     if((realTimeDomainData != NULL) && (realTimeDomainDataSize > 0)){
242       const float* realTimeDomainDataPtr = realTimeDomainData;
243
244       double* realTimeDomainPointsPtr = _realTimeDomainPoints;
245       timeDomainBufferSize = realTimeDomainDataSize;
246
247       memset( _imagTimeDomainPoints, 0x0, realTimeDomainDataSize*sizeof(double));
248       for( uint64_t number = 0; number < realTimeDomainDataSize; number++){
249         *realTimeDomainPointsPtr++ = *realTimeDomainDataPtr++;
250       }
251     }
252
253     // Can't do a memcpy since ths is going from float to double data type
254     if((complexTimeDomainData != NULL) && (complexTimeDomainDataSize > 0)){
255       const float* complexTimeDomainDataPtr = complexTimeDomainData;
256
257       double* realTimeDomainPointsPtr = _realTimeDomainPoints;
258       double* imagTimeDomainPointsPtr = _imagTimeDomainPoints;
259
260       timeDomainBufferSize = complexTimeDomainDataSize;
261       for( uint64_t number = 0; number < complexTimeDomainDataSize; number++){
262         *realTimeDomainPointsPtr++ = *complexTimeDomainDataPtr++;
263         *imagTimeDomainPointsPtr++ = *complexTimeDomainDataPtr++;
264       }
265     }
266   }
267
268   // If bufferSize is zero, then just update the display by sending over the old data
269   if(bufferSize < 1){
270     bufferSize = _lastDataPointCount;
271     repeatDataFlag = true;
272   }
273   else{
274     // Since there is data this time, update the count
275     _lastDataPointCount = bufferSize;
276   }
277
278   const timespec currentTime = get_highres_clock();
279   const timespec lastUpdateGUITime = GetLastGUIUpdateTime();
280
281   if((diff_timespec(currentTime, lastUpdateGUITime) > (4*timePerFFT)) &&
282      (GetPendingGUIUpdateEvents() > 0) && !timespec_empty(&lastUpdateGUITime)) {
283     // Do not update the display if too much data is pending to be displayed
284     _droppedEntriesCount++;
285   }
286   else{
287     // Draw the Data
288     IncrementPendingGUIUpdateEvents();
289     qApp->postEvent(_spectrumDisplayForm,
290                     new SpectrumUpdateEvent(_fftPoints, bufferSize,
291                                             _realTimeDomainPoints,
292                                             _imagTimeDomainPoints,
293                                             timeDomainBufferSize,
294                                             timePerFFT, timestamp,
295                                             repeatDataFlag,
296                                             lastOfMultipleFFTUpdateFlag,
297                                             currentTime,
298                                             _droppedEntriesCount));
299     
300     // Only reset the dropped entries counter if this is not
301     // repeat data since repeat data is dropped by the display systems
302     if(!repeatDataFlag){
303       _droppedEntriesCount = 0;
304     }
305   }
306 }
307
308 float
309 SpectrumGUIClass::GetPowerValue() const
310 {
311   float returnValue = 0;
312   //_windowStateLock->Lock();
313   returnValue = _powerValue;
314   //_windowStateLock->Unlock();
315   return returnValue;
316 }
317
318 void
319 SpectrumGUIClass::SetPowerValue(const float value)
320 {
321   //_windowStateLock->Lock();
322   _powerValue = value;
323   //_windowStateLock->Unlock();
324 }
325
326 int
327 SpectrumGUIClass::GetWindowType() const
328 {
329   int returnValue = 0;
330   //_windowStateLock->Lock();
331   returnValue = _windowType;
332   //_windowStateLock->Unlock();
333   return returnValue;
334 }
335
336 void
337 SpectrumGUIClass::SetWindowType(const int newType)
338 {
339   //_windowStateLock->Lock();
340   _windowType = newType;
341   //_windowStateLock->Unlock();
342 }
343
344 int
345 SpectrumGUIClass::GetFFTSize() const
346 {
347   int returnValue = 0;
348   //_windowStateLock->Lock();
349   returnValue = _fftSize;
350   //_windowStateLock->Unlock();
351   return returnValue;
352 }
353
354 int
355 SpectrumGUIClass::GetFFTSizeIndex() const
356 {
357   int fftsize = GetFFTSize();
358   switch(fftsize) {
359   case(1024): return 0; break;
360   case(2048): return 1; break;
361   case(4096): return 2; break;
362   case(8192): return 3; break;
363   case(16384): return 3; break;
364   case(32768): return 3; break;
365   default: return 0;
366   }
367 }
368
369 void
370 SpectrumGUIClass::SetFFTSize(const int newSize)
371 {
372   //_windowStateLock->Lock();
373   _fftSize = newSize;
374   //_windowStateLock->Unlock();
375 }
376
377 timespec
378 SpectrumGUIClass::GetLastGUIUpdateTime() const
379 {
380   timespec returnValue;
381   //_windowStateLock->Lock();
382   returnValue = _lastGUIUpdateTime;
383   //_windowStateLock->Unlock();
384   return returnValue;
385 }
386
387 void
388 SpectrumGUIClass::SetLastGUIUpdateTime(const timespec newTime)
389 {
390   //_windowStateLock->Lock();
391   _lastGUIUpdateTime = newTime;
392   //_windowStateLock->Unlock();
393 }
394
395 unsigned int
396 SpectrumGUIClass::GetPendingGUIUpdateEvents() const
397 {
398   unsigned int returnValue = 0;
399   //_windowStateLock->Lock();
400   returnValue = _pendingGUIUpdateEventsCount;
401   //_windowStateLock->Unlock();
402   return returnValue;
403 }
404
405 void
406 SpectrumGUIClass::IncrementPendingGUIUpdateEvents()
407 {
408   //_windowStateLock->Lock();
409   _pendingGUIUpdateEventsCount++;
410   //_windowStateLock->Unlock();
411 }
412
413 void
414 SpectrumGUIClass::DecrementPendingGUIUpdateEvents()
415 {
416   //_windowStateLock->Lock();
417   if(_pendingGUIUpdateEventsCount > 0){
418     _pendingGUIUpdateEventsCount--;
419   }
420   //_windowStateLock->Unlock();
421 }
422
423 void
424 SpectrumGUIClass::ResetPendingGUIUpdateEvents()
425 {
426   //_windowStateLock->Lock();
427   _pendingGUIUpdateEventsCount = 0;
428   //_windowStateLock->Unlock();
429 }
430
431
432 QWidget*
433 SpectrumGUIClass::qwidget()
434 {
435   return (QWidget*)_spectrumDisplayForm;
436 }
437
438 void
439 SpectrumGUIClass::SetTimeDomainAxis(double min, double max)
440 {
441   _spectrumDisplayForm->SetTimeDomainAxis(min, max);
442 }
443
444 void
445 SpectrumGUIClass::SetConstellationAxis(double xmin, double xmax,
446                                        double ymin, double ymax)
447 {
448   _spectrumDisplayForm->SetConstellationAxis(xmin, xmax, ymin, ymax);
449
450 }
451
452 void
453 SpectrumGUIClass::SetFrequencyAxis(double min, double max)
454 {
455   _spectrumDisplayForm->SetFrequencyAxis(min, max);
456 }
457
458 #endif /* SPECTRUM_GUI_CLASS_CPP */