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