Statistics
| Branch: | Tag: | Revision:

root / gr-qtgui / src / lib / spectrumdisplayform.cc @ 8f134010

History | View | Annotate | Download (26.6 kB)

1
#include <cmath>
2
#include <QColorDialog>
3
#include <QMessageBox>
4
#include <spectrumdisplayform.h>
5
6
int SpectrumDisplayForm::_openGLWaterfall3DFlag = -1;
7
8
SpectrumDisplayForm::SpectrumDisplayForm(bool useOpenGL, QWidget* parent)
9
  : QWidget(parent)
10
{
11
  setupUi(this);
12
13
  _useOpenGL = useOpenGL;
14
  _systemSpecifiedFlag = false;
15
  _intValidator = new QIntValidator(this);
16
  _intValidator->setBottom(0);
17
  _frequencyDisplayPlot = new FrequencyDisplayPlot(FrequencyPlotDisplayFrame);
18
  _waterfallDisplayPlot = new WaterfallDisplayPlot(WaterfallPlotDisplayFrame);
19
20
  if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
21
    //_waterfall3DDisplayPlot = new Waterfall3DDisplayPlot(Waterfall3DPlotDisplayFrame);
22
  }
23
24
  _timeDomainDisplayPlot = new TimeDomainDisplayPlot(TimeDomainDisplayFrame);
25
  _constellationDisplayPlot = new ConstellationDisplayPlot(ConstellationDisplayFrame);
26
  _numRealDataPoints = 1024;
27
  _realFFTDataPoints = new double[_numRealDataPoints];
28
  _averagedValues = new double[_numRealDataPoints];
29
  _historyVector = new std::vector<double*>;
30
  
31
  AvgLineEdit->setRange(0, 500);                 // Set range of Average box value from 0 to 500
32
  MinHoldCheckBox_toggled( false );
33
  MaxHoldCheckBox_toggled( false );
34
  
35
  WaterfallMaximumIntensityWheel->setRange(-200, 0);
36
  WaterfallMaximumIntensityWheel->setTickCnt(50);
37
  WaterfallMinimumIntensityWheel->setRange(-200, 0);
38
  WaterfallMinimumIntensityWheel->setTickCnt(50);
39
  WaterfallMinimumIntensityWheel->setValue(-200);
40
  
41
  if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
42
    Waterfall3DMaximumIntensityWheel->setRange(-200, 0);
43
    Waterfall3DMaximumIntensityWheel->setTickCnt(50);
44
    Waterfall3DMinimumIntensityWheel->setRange(-200, 0);
45
    Waterfall3DMinimumIntensityWheel->setTickCnt(50);
46
    Waterfall3DMinimumIntensityWheel->setValue(-200);
47
  }
48
49
  _peakFrequency = 0;
50
  _peakAmplitude = -HUGE_VAL;
51
  
52
  _noiseFloorAmplitude = -HUGE_VAL;
53
54
  connect(_waterfallDisplayPlot, SIGNAL(UpdatedLowerIntensityLevel(const double)), 
55
          _frequencyDisplayPlot, SLOT(SetLowerIntensityLevel(const double)));
56
  connect(_waterfallDisplayPlot, SIGNAL(UpdatedUpperIntensityLevel(const double)), 
57
          _frequencyDisplayPlot, SLOT(SetUpperIntensityLevel(const double)));
58
  
59
  _frequencyDisplayPlot->SetLowerIntensityLevel(-200);
60
  _frequencyDisplayPlot->SetUpperIntensityLevel(-200);
61
62
  // Load up the acceptable FFT sizes...
63
  FFTSizeComboBox->clear();
64
  for(long fftSize = SpectrumGUIClass::MIN_FFT_SIZE; fftSize <= SpectrumGUIClass::MAX_FFT_SIZE; fftSize *= 2){
65
    FFTSizeComboBox->insertItem(FFTSizeComboBox->count(), QString("%1").arg(fftSize));
66
  }
67
  Reset();
68
69
  ToggleTabFrequency(false);
70
  ToggleTabWaterfall(false);
71
  ToggleTabWaterfall3D(false);
72
  ToggleTabTime(false);
73
  ToggleTabConstellation(false);
74
75
  // Create a timer to update plots at the specified rate
76
  displayTimer = new QTimer(this);
77
  connect(displayTimer, SIGNAL(timeout()), this, SLOT(UpdateGuiTimer()));
78
}
79
80
SpectrumDisplayForm::~SpectrumDisplayForm()
81
{
82
  // Qt deletes children when parent is deleted
83
84
  // Don't worry about deleting Display Plots - they are deleted when parents are deleted
85
  delete _intValidator;
86
87
  delete[] _realFFTDataPoints;
88
  delete[] _averagedValues;
89
90
  for(unsigned int count = 0; count < _historyVector->size(); count++){
91
    delete[] _historyVector->operator[](count);
92
  }
93
94
  delete _historyVector;
95
96
  displayTimer->stop();
97
  delete displayTimer;
98
}
99
100
void
101
SpectrumDisplayForm::setSystem( SpectrumGUIClass * newSystem, 
102
                                const uint64_t numFFTDataPoints, 
103
                                const uint64_t numTimeDomainDataPoints )
104
{
105
  ResizeBuffers(numFFTDataPoints, numTimeDomainDataPoints);
106
  
107
  if(newSystem != NULL){
108
    _system = newSystem;
109
    _systemSpecifiedFlag = true;
110
  }
111
  else{
112
    _systemSpecifiedFlag = false;
113
  }
114
}
115
116
void
117
SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdateEvent)
118
{
119
  //_lastSpectrumEvent = (SpectrumUpdateEvent)(*spectrumUpdateEvent);
120
  const std::complex<float>* complexDataPoints = spectrumUpdateEvent->getFFTPoints();
121
  const uint64_t numFFTDataPoints = spectrumUpdateEvent->getNumFFTDataPoints();
122
  const double* realTimeDomainDataPoints = spectrumUpdateEvent->getRealTimeDomainPoints();
123
  const double* imagTimeDomainDataPoints = spectrumUpdateEvent->getImagTimeDomainPoints();
124
  const uint64_t numTimeDomainDataPoints = spectrumUpdateEvent->getNumTimeDomainDataPoints();
125
  const timespec dataTimestamp = spectrumUpdateEvent->getDataTimestamp();
126
  const bool repeatDataFlag = spectrumUpdateEvent->getRepeatDataFlag();
127
  const bool lastOfMultipleUpdatesFlag = spectrumUpdateEvent->getLastOfMultipleUpdateFlag();
128
  const timespec generatedTimestamp = spectrumUpdateEvent->getEventGeneratedTimestamp();
129
130
  // REMEMBER: The dataTimestamp is NOT valid when the repeat data flag is true...
131
  ResizeBuffers(numFFTDataPoints, numTimeDomainDataPoints);
132
133
  // Calculate the Magnitude of the complex point
134
  const std::complex<float>* complexDataPointsPtr = complexDataPoints+numFFTDataPoints/2;
135
  double* realFFTDataPointsPtr = _realFFTDataPoints;
136
137
  // Run this twice to perform the fftshift operation on the data here as well
138
  for(uint64_t point = 0; point < numFFTDataPoints/2; point++){
139
    std::complex<float> pt = (*complexDataPointsPtr) / (float)numFFTDataPoints;
140
    *realFFTDataPointsPtr = 10.0*log10((pt.real() * pt.real() + pt.imag()*pt.imag()) + 1e-20);
141
142
    complexDataPointsPtr++;
143
    realFFTDataPointsPtr++;
144
  }
145
  
146
  // This loop takes the first half of the input data and puts it in the 
147
  // second half of the plotted data
148
  complexDataPointsPtr = complexDataPoints;
149
  for(uint64_t point = 0; point < numFFTDataPoints/2; point++){
150
    std::complex<float> pt = (*complexDataPointsPtr) / (float)numFFTDataPoints;
151
    *realFFTDataPointsPtr = 10.0*log10((pt.real() * pt.real() + pt.imag()*pt.imag()) + 1e-20);
152
153
    complexDataPointsPtr++;
154
    realFFTDataPointsPtr++;
155
  }
156
157
  // Don't update the averaging history if this is repeated data
158
  if(!repeatDataFlag){
159
    _AverageHistory(_realFFTDataPoints);
160
161
    double sumMean;
162
    const double fft_bin_size = (_stopFrequency-_startFrequency) /
163
      static_cast<double>(numFFTDataPoints);
164
165
    // find the peak, sum (for mean), etc
166
    _peakAmplitude = -HUGE_VAL;
167
    sumMean = 0.0;
168
    for(uint64_t number = 0; number < numFFTDataPoints; number++){
169
      // find peak
170
      if(_realFFTDataPoints[number] > _peakAmplitude){
171
        // Calculate the frequency relative to the local bw, adjust for _startFrequency later
172
        _peakFrequency = (static_cast<float>(number) * fft_bin_size);
173
        _peakAmplitude = _realFFTDataPoints[number];
174
      }
175
      sumMean += _realFFTDataPoints[number];
176
    }
177
178
    // calculate the spectral mean
179
    // +20 because for the comparison below we only want to throw out bins
180
    // that are significantly higher (and would, thus, affect the mean more)
181
    const double meanAmplitude = (sumMean / numFFTDataPoints) + 20.0;
182
183
    // now throw out any bins higher than the mean
184
    sumMean = 0.0;
185
    uint64_t newNumDataPoints = numFFTDataPoints;
186
    for(uint64_t number = 0; number < numFFTDataPoints; number++){
187
      if (_realFFTDataPoints[number] <= meanAmplitude)
188
        sumMean += _realFFTDataPoints[number];
189
      else
190
        newNumDataPoints--;
191
    }
192
193
    if (newNumDataPoints == 0)             // in the odd case that all
194
      _noiseFloorAmplitude = meanAmplitude; // amplitudes are equal!
195
    else
196
      _noiseFloorAmplitude = sumMean / newNumDataPoints;
197
  }
198
199
  if(lastOfMultipleUpdatesFlag){
200
    int tabindex = SpectrumTypeTab->currentIndex();
201
    if(tabindex == d_plot_fft) {
202
      _frequencyDisplayPlot->PlotNewData(_averagedValues, numFFTDataPoints, 
203
                                         _noiseFloorAmplitude, _peakFrequency, 
204
                                         _peakAmplitude, d_update_time);
205
    }
206
    if(tabindex == d_plot_time) {
207
      _timeDomainDisplayPlot->PlotNewData(realTimeDomainDataPoints, 
208
                                          imagTimeDomainDataPoints, 
209
                                          numTimeDomainDataPoints,
210
                                          d_update_time);
211
    }
212
    if(tabindex == d_plot_constellation) {
213
      _constellationDisplayPlot->PlotNewData(realTimeDomainDataPoints, 
214
                                             imagTimeDomainDataPoints, 
215
                                             numTimeDomainDataPoints,
216
                                             d_update_time);
217
    }
218
219
    // Don't update the repeated data for the waterfall
220
    if(!repeatDataFlag){
221
      if(tabindex == d_plot_waterfall) {
222
        _waterfallDisplayPlot->PlotNewData(_realFFTDataPoints, numFFTDataPoints, 
223
                                           d_update_time, dataTimestamp, 
224
                                           spectrumUpdateEvent->getDroppedFFTFrames());
225
      }
226
      /*
227
      if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
228
        if( _openGLWaterfall3DFlag == 1 && (tabindex == d_plot_waterfall3d)) {
229
          _waterfall3DDisplayPlot->PlotNewData(_realFFTDataPoints, numFFTDataPoints, 
230
                                               d_update_time, dataTimestamp, 
231
                                               spectrumUpdateEvent->getDroppedFFTFrames());
232
        }
233
      }
234
      */
235
    }
236
237
    
238
    // Tell the system the GUI has been updated
239
    if(_systemSpecifiedFlag){
240
      _system->SetLastGUIUpdateTime(generatedTimestamp);
241
      _system->DecrementPendingGUIUpdateEvents();
242
    }
243
  }
244
}
245
246
void
247
SpectrumDisplayForm::resizeEvent( QResizeEvent *e )
248
{
249
  QSize s;
250
  s.setWidth(FrequencyPlotDisplayFrame->width());
251
  s.setHeight(FrequencyPlotDisplayFrame->height());
252
  emit _frequencyDisplayPlot->resizeSlot(&s);
253
254
  s.setWidth(TimeDomainDisplayFrame->width());
255
  s.setHeight(TimeDomainDisplayFrame->height());
256
  emit _timeDomainDisplayPlot->resizeSlot(&s);
257
258
  s.setWidth(WaterfallPlotDisplayFrame->width());
259
  s.setHeight(WaterfallPlotDisplayFrame->height());
260
  emit _waterfallDisplayPlot->resizeSlot(&s);
261
262
  if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
263
    s.setWidth(Waterfall3DPlotDisplayFrame->width());
264
    s.setHeight(Waterfall3DPlotDisplayFrame->height());
265
    //emit _waterfall3DDisplayPlot->resizeSlot(&s);
266
  }
267
268
  s.setWidth(ConstellationDisplayFrame->width());
269
  s.setHeight(ConstellationDisplayFrame->height());
270
  emit _constellationDisplayPlot->resizeSlot(&s);
271
}
272
273
void
274
SpectrumDisplayForm::customEvent( QEvent * e)
275
{
276
  if(e->type() == QEvent::User+3){
277
    if(_systemSpecifiedFlag){
278
      WindowComboBox->setCurrentIndex(_system->GetWindowType());
279
      FFTSizeComboBox->setCurrentIndex(_system->GetFFTSizeIndex());
280
      //FFTSizeComboBox->setCurrentIndex(1);
281
    }
282
283
    waterfallMinimumIntensityChangedCB(WaterfallMinimumIntensityWheel->value());
284
    waterfallMaximumIntensityChangedCB(WaterfallMaximumIntensityWheel->value());
285
286
    // If the video card doesn't support OpenGL then don't display the 3D Waterfall
287
    if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
288
      waterfall3DMinimumIntensityChangedCB(Waterfall3DMinimumIntensityWheel->value());
289
      waterfall3DMaximumIntensityChangedCB(Waterfall3DMaximumIntensityWheel->value());
290
      
291
      // Check for Hardware Acceleration of the OpenGL
292
      /*
293
      if(!_waterfall3DDisplayPlot->format().directRendering()){
294
        // Only ask this once while the program is running...
295
        if(_openGLWaterfall3DFlag == -1){
296
          _openGLWaterfall3DFlag = 0;
297
          if(QMessageBox::warning(this, "OpenGL Direct Rendering NOT Supported", "<center>The system's video card hardware or current drivers do not support direct hardware rendering of the OpenGL modules.</center><br><center>Software rendering is VERY processor intensive.</center><br><center>Do you want to use software rendering?</center>", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape) == QMessageBox::Yes){
298
            _openGLWaterfall3DFlag = 1;
299
          }
300
        }
301
      }
302
      else{
303
        _openGLWaterfall3DFlag = 1;
304
      }
305
      */
306
    }
307
    
308
    if(_openGLWaterfall3DFlag != 1){
309
      ToggleTabWaterfall3D(false);
310
    }
311
312
    // Clear any previous display
313
    Reset();
314
  }
315
  else if(e->type() == 10005){
316
    SpectrumUpdateEvent* spectrumUpdateEvent = (SpectrumUpdateEvent*)e;
317
    newFrequencyData(spectrumUpdateEvent);
318
  }
319
  else if(e->type() == 10008){
320
    setWindowTitle(((SpectrumWindowCaptionEvent*)e)->getLabel());
321
  }
322
  else if(e->type() == 10009){
323
    Reset();
324
    if(_systemSpecifiedFlag){
325
      _system->ResetPendingGUIUpdateEvents();
326
    }
327
  }
328
  else if(e->type() == 10010){
329
    _startFrequency = ((SpectrumFrequencyRangeEvent*)e)->GetStartFrequency();
330
    _stopFrequency = ((SpectrumFrequencyRangeEvent*)e)->GetStopFrequency();
331
    _centerFrequency  = ((SpectrumFrequencyRangeEvent*)e)->GetCenterFrequency();
332
333
    UseRFFrequenciesCB(UseRFFrequenciesCheckBox->isChecked());
334
  }
335
}
336
337
void
338
SpectrumDisplayForm::UpdateGuiTimer()
339
{
340
  // This is called by the displayTimer and redraws the canvases of
341
  // all of the plots.
342
  _frequencyDisplayPlot->canvas()->update();
343
  _waterfallDisplayPlot->canvas()->update();
344
  //if((QGLFormat::hasOpenGL()) && (_useOpenGL))
345
  //_waterfall3DDisplayPlot->canvas()->update();
346
  _timeDomainDisplayPlot->canvas()->update();
347
  _constellationDisplayPlot->canvas()->update();
348
}
349
350
351
void
352
SpectrumDisplayForm::AvgLineEdit_valueChanged( int value )
353
{
354
  SetAverageCount(value);
355
}
356
357
358
void
359
SpectrumDisplayForm::MaxHoldCheckBox_toggled( bool newState )
360
{
361
  MaxHoldResetBtn->setEnabled(newState);
362
  _frequencyDisplayPlot->SetMaxFFTVisible(newState);
363
  MaxHoldResetBtn_clicked();
364
}
365
366
367
void
368
SpectrumDisplayForm::MinHoldCheckBox_toggled( bool newState )
369
{
370
  MinHoldResetBtn->setEnabled(newState);
371
  _frequencyDisplayPlot->SetMinFFTVisible(newState);
372
  MinHoldResetBtn_clicked();
373
}
374
375
376
void
377
SpectrumDisplayForm::MinHoldResetBtn_clicked()
378
{
379
  _frequencyDisplayPlot->ClearMinData();
380
  _frequencyDisplayPlot->replot();
381
}
382
383
384
void
385
SpectrumDisplayForm::MaxHoldResetBtn_clicked()
386
{
387
  _frequencyDisplayPlot->ClearMaxData();
388
  _frequencyDisplayPlot->replot();
389
}
390
391
392
void
393
SpectrumDisplayForm::TabChanged(int index)
394
{
395
  // This might be dangerous to call this with NULL
396
  resizeEvent(NULL);  
397
}
398
399
void
400
SpectrumDisplayForm::SetFrequencyRange(const double newCenterFrequency,
401
                                       const double newStartFrequency, 
402
                                       const double newStopFrequency)
403
{
404
  double fdiff;
405
  if(UseRFFrequenciesCheckBox->isChecked()) {
406
    fdiff = newCenterFrequency;
407
  }
408
  else {
409
    fdiff = std::max(fabs(newStartFrequency), fabs(newStopFrequency));
410
  }
411
412
  if(fdiff > 0) {
413
    std::string strunits[4] = {"Hz", "kHz", "MHz", "GHz"};
414
    std::string strtime[4] = {"sec", "ms", "us", "ns"};
415
    double units10 = floor(log10(fdiff));
416
    double units3  = std::max(floor(units10 / 3.0), 0.0);
417
    double units = pow(10, (units10-fmod(units10, 3.0)));
418
    int iunit = static_cast<int>(units3);
419
    
420
    _startFrequency = newStartFrequency;
421
    _stopFrequency = newStopFrequency;
422
    _centerFrequency = newCenterFrequency;
423
424
    _frequencyDisplayPlot->SetFrequencyRange(_startFrequency,
425
                                             _stopFrequency,
426
                                             _centerFrequency,
427
                                             UseRFFrequenciesCheckBox->isChecked(),
428
                                             units, strunits[iunit]);
429
    _waterfallDisplayPlot->SetFrequencyRange(_startFrequency,
430
                                             _stopFrequency,
431
                                             _centerFrequency,
432
                                             UseRFFrequenciesCheckBox->isChecked(),
433
                                             units, strunits[iunit]);
434
    if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
435
      /*
436
      _waterfall3DDisplayPlot->SetFrequencyRange(_startFrequency,
437
                                                 _stopFrequency,
438
                                                 _centerFrequency,
439
                                                 UseRFFrequenciesCheckBox->isChecked(),
440
                                                 units, strunits[iunit]);
441
      */
442
    }
443
    _timeDomainDisplayPlot->SetSampleRate(_stopFrequency - _startFrequency,
444
                                          units, strtime[iunit]);
445
  }
446
}
447
448
int
449
SpectrumDisplayForm::GetAverageCount()
450
{
451
  return _historyVector->size();
452
}
453
454
void
455
SpectrumDisplayForm::SetAverageCount(const int newCount)
456
{
457
  if(newCount > -1){
458
    if(newCount != static_cast<int>(_historyVector->size())){
459
      std::vector<double*>::iterator pos;
460
      while(newCount < static_cast<int>(_historyVector->size())){
461
        pos = _historyVector->begin();
462
        delete[] (*pos);
463
        _historyVector->erase(pos);
464
      }
465
466
      while(newCount > static_cast<int>(_historyVector->size())){
467
        _historyVector->push_back(new double[_numRealDataPoints]);
468
      }
469
      AverageDataReset();
470
    }
471
  }
472
}
473
474
void
475
SpectrumDisplayForm::_AverageHistory(const double* newBuffer)
476
{
477
  if(_numRealDataPoints > 0){
478
    if(_historyVector->size() > 0){
479
      memcpy(_historyVector->operator[](_historyEntry), newBuffer,
480
             _numRealDataPoints*sizeof(double));
481
482
      // Increment the next location to store data
483
      _historyEntryCount++;
484
      if(_historyEntryCount > static_cast<int>(_historyVector->size())){
485
        _historyEntryCount = _historyVector->size();
486
      }
487
      _historyEntry = (++_historyEntry)%_historyVector->size();
488
489
      // Total up and then average the values
490
      double sum;
491
      for(uint64_t location = 0; location < _numRealDataPoints; location++){
492
        sum = 0;
493
        for(int number = 0; number < _historyEntryCount; number++){
494
          sum += _historyVector->operator[](number)[location];
495
        }
496
         _averagedValues[location] = sum/static_cast<double>(_historyEntryCount);
497
      }
498
    }
499
    else{
500
      memcpy(_averagedValues, newBuffer, _numRealDataPoints*sizeof(double));
501
    }
502
  }
503
}
504
505
void
506
SpectrumDisplayForm::ResizeBuffers( const uint64_t numFFTDataPoints,
507
                                    const uint64_t /*numTimeDomainDataPoints*/ )
508
{
509
  // Convert from Complex to Real for certain Displays
510
  if(_numRealDataPoints != numFFTDataPoints){
511
    _numRealDataPoints = numFFTDataPoints;
512
    delete[] _realFFTDataPoints;
513
    delete[] _averagedValues;
514
    
515
    _realFFTDataPoints = new double[_numRealDataPoints];
516
    _averagedValues = new double[_numRealDataPoints];
517
    memset(_realFFTDataPoints, 0x0, _numRealDataPoints*sizeof(double));
518
    
519
    const int historySize = _historyVector->size();
520
    SetAverageCount(0); // Clear the existing history
521
    SetAverageCount(historySize);
522
    
523
    Reset();
524
  }
525
}
526
527
void
528
SpectrumDisplayForm::Reset()
529
{
530
  AverageDataReset();
531
532
  _waterfallDisplayPlot->Reset();
533
  if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
534
    //_waterfall3DDisplayPlot->Reset();
535
  }
536
}
537
538
539
void
540
SpectrumDisplayForm::AverageDataReset()
541
{
542
  _historyEntry = 0;
543
  _historyEntryCount = 0;
544
545
  memset(_averagedValues, 0x0, _numRealDataPoints*sizeof(double));
546
547
  MaxHoldResetBtn_clicked();
548
  MinHoldResetBtn_clicked();
549
}
550
551
552
void
553
SpectrumDisplayForm::closeEvent( QCloseEvent *e )
554
{
555
  if(_systemSpecifiedFlag){
556
    _system->SetWindowOpenFlag(false);
557
  }
558
559
  qApp->processEvents();
560
561
  QWidget::closeEvent(e);
562
}
563
564
565
void
566
SpectrumDisplayForm::WindowTypeChanged( int newItem )
567
{
568
  if(_systemSpecifiedFlag){
569
   _system->SetWindowType(newItem);
570
  }
571
}
572
573
574
void
575
SpectrumDisplayForm::UseRFFrequenciesCB( bool useRFFlag )
576
{
577
  SetFrequencyRange(_centerFrequency, _startFrequency, _stopFrequency);
578
}
579
580
581
void
582
SpectrumDisplayForm::waterfallMaximumIntensityChangedCB( double newValue )
583
{
584
  if(newValue > WaterfallMinimumIntensityWheel->value()){
585
    WaterfallMaximumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0));
586
  }
587
  else{
588
    WaterfallMaximumIntensityWheel->setValue(WaterfallMinimumIntensityWheel->value());
589
  }
590
591
  _waterfallDisplayPlot->SetIntensityRange(WaterfallMinimumIntensityWheel->value(),
592
                                           WaterfallMaximumIntensityWheel->value());
593
}
594
595
596
void
597
SpectrumDisplayForm::waterfallMinimumIntensityChangedCB( double newValue )
598
{
599
  if(newValue < WaterfallMaximumIntensityWheel->value()){
600
    WaterfallMinimumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0));
601
  }
602
  else{
603
    WaterfallMinimumIntensityWheel->setValue(WaterfallMaximumIntensityWheel->value());
604
  }
605
606
  _waterfallDisplayPlot->SetIntensityRange(WaterfallMinimumIntensityWheel->value(),
607
                                           WaterfallMaximumIntensityWheel->value());
608
}
609
610
void
611
SpectrumDisplayForm::waterfall3DMaximumIntensityChangedCB( double newValue )
612
{
613
  if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
614
    if(newValue > Waterfall3DMinimumIntensityWheel->value()){
615
      Waterfall3DMaximumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0));
616
    }
617
    else{
618
      Waterfall3DMaximumIntensityWheel->setValue(Waterfall3DMinimumIntensityWheel->value());
619
    }
620
621
    /*
622
    _waterfall3DDisplayPlot->SetIntensityRange(Waterfall3DMinimumIntensityWheel->value(),
623
                                               Waterfall3DMaximumIntensityWheel->value());
624
    */
625
  }
626
}
627
628
629
void
630
SpectrumDisplayForm::waterfall3DMinimumIntensityChangedCB( double newValue )
631
{
632
  if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
633
    if(newValue < Waterfall3DMaximumIntensityWheel->value()){
634
      Waterfall3DMinimumIntensityLabel->setText(QString("%1 dB").arg(newValue, 0, 'f', 0));
635
    }
636
    else{
637
      Waterfall3DMinimumIntensityWheel->setValue(Waterfall3DMaximumIntensityWheel->value());
638
    }
639
640
    /*
641
    _waterfall3DDisplayPlot->SetIntensityRange(Waterfall3DMinimumIntensityWheel->value(),
642
                                               Waterfall3DMaximumIntensityWheel->value());
643
    */
644
  }
645
}
646
647
648
void
649
SpectrumDisplayForm::FFTComboBoxSelectedCB( const QString &fftSizeString )
650
{
651
  if(_systemSpecifiedFlag){
652
    _system->SetFFTSize(fftSizeString.toLong());
653
  }
654
}
655
656
657
void
658
SpectrumDisplayForm::WaterfallAutoScaleBtnCB()
659
{
660
  double minimumIntensity = _noiseFloorAmplitude - 5;
661
  if(minimumIntensity < WaterfallMinimumIntensityWheel->minValue()){
662
    minimumIntensity = WaterfallMinimumIntensityWheel->minValue();
663
  }
664
  WaterfallMinimumIntensityWheel->setValue(minimumIntensity);
665
  double maximumIntensity = _peakAmplitude + 10;
666
  if(maximumIntensity > WaterfallMaximumIntensityWheel->maxValue()){
667
    maximumIntensity = WaterfallMaximumIntensityWheel->maxValue();
668
  }
669
  WaterfallMaximumIntensityWheel->setValue(maximumIntensity);
670
  waterfallMaximumIntensityChangedCB(maximumIntensity);
671
}
672
673
void
674
SpectrumDisplayForm::Waterfall3DAutoScaleBtnCB()
675
{
676
  if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
677
    double minimumIntensity = _noiseFloorAmplitude - 5;
678
    if(minimumIntensity < Waterfall3DMinimumIntensityWheel->minValue()){
679
      minimumIntensity = Waterfall3DMinimumIntensityWheel->minValue();
680
    }
681
    Waterfall3DMinimumIntensityWheel->setValue(minimumIntensity);
682
    double maximumIntensity = _peakAmplitude + 10;
683
    if(maximumIntensity > Waterfall3DMaximumIntensityWheel->maxValue()){
684
      maximumIntensity = Waterfall3DMaximumIntensityWheel->maxValue();
685
    }
686
    Waterfall3DMaximumIntensityWheel->setValue(maximumIntensity);
687
    waterfallMaximumIntensityChangedCB(maximumIntensity);
688
  }
689
}
690
691
void
692
SpectrumDisplayForm::WaterfallIntensityColorTypeChanged( int newType )
693
{
694
  QColor lowIntensityColor;
695
  QColor highIntensityColor;
696
  if(newType == WaterfallDisplayPlot::INTENSITY_COLOR_MAP_TYPE_USER_DEFINED){
697
    // Select the Low Intensity Color
698
    lowIntensityColor = _waterfallDisplayPlot->GetUserDefinedLowIntensityColor();
699
    if(!lowIntensityColor.isValid()){
700
      lowIntensityColor = Qt::black;
701
    }
702
    QMessageBox::information(this, "Low Intensity Color Selection", "In the next window, select the low intensity color for the waterfall display",  QMessageBox::Ok);
703
    lowIntensityColor = QColorDialog::getColor(lowIntensityColor, this);
704
    
705
    // Select the High Intensity Color
706
    highIntensityColor = _waterfallDisplayPlot->GetUserDefinedHighIntensityColor();
707
    if(!highIntensityColor.isValid()){
708
      highIntensityColor = Qt::white;
709
    }
710
    QMessageBox::information(this, "High Intensity Color Selection", "In the next window, select the high intensity color for the waterfall display",  QMessageBox::Ok);
711
    highIntensityColor = QColorDialog::getColor(highIntensityColor, this);
712
  }
713
  
714
  _waterfallDisplayPlot->SetIntensityColorMapType(newType, lowIntensityColor, highIntensityColor);
715
}
716
717
void
718
SpectrumDisplayForm::Waterfall3DIntensityColorTypeChanged( int newType )
719
{
720
  if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
721
    QColor lowIntensityColor;
722
    QColor highIntensityColor;
723
    if(newType == Waterfall3DDisplayPlot::INTENSITY_COLOR_MAP_TYPE_USER_DEFINED){
724
      // Select the Low Intensity Color
725
      lowIntensityColor = _waterfallDisplayPlot->GetUserDefinedLowIntensityColor();
726
      if(!lowIntensityColor.isValid()){
727
        lowIntensityColor = Qt::black;
728
      }
729
      QMessageBox::information(this, "Low Intensity Color Selection", "In the next window, select the low intensity color for the waterfall display",  QMessageBox::Ok);
730
      lowIntensityColor = QColorDialog::getColor(lowIntensityColor, this);
731
      
732
      // Select the High Intensity Color
733
      highIntensityColor = _waterfallDisplayPlot->GetUserDefinedHighIntensityColor();
734
      if(!highIntensityColor.isValid()){
735
        highIntensityColor = Qt::white;
736
      }
737
      QMessageBox::information(this, "High Intensity Color Selection", "In the next window, select the high intensity color for the waterfall display",  QMessageBox::Ok);
738
      highIntensityColor = QColorDialog::getColor(highIntensityColor, this);
739
    }
740
    /*
741
    _waterfall3DDisplayPlot->SetIntensityColorMapType(newType, lowIntensityColor,
742
                                                      highIntensityColor);
743
    */
744
  }
745
}
746
747
748
void
749
SpectrumDisplayForm::ToggleTabFrequency(const bool state)
750
{
751
  if(state == true) {
752
    if(d_plot_fft == -1) {
753
      SpectrumTypeTab->addTab(FrequencyPage, "Frequency Display");
754
      d_plot_fft = SpectrumTypeTab->count()-1;
755
    }
756
  }
757
  else {
758
    SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(FrequencyPage));
759
    d_plot_fft = -1;
760
  }
761
}
762
763
void
764
SpectrumDisplayForm::ToggleTabWaterfall(const bool state)
765
{
766
  if(state == true) {
767
    if(d_plot_waterfall == -1) {
768
      SpectrumTypeTab->addTab(WaterfallPage, "Waterfall Display");
769
      d_plot_waterfall = SpectrumTypeTab->count()-1;
770
    }
771
  }
772
  else {
773
    SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(WaterfallPage));
774
    d_plot_waterfall = -1;
775
  }
776
}
777
778
void
779
SpectrumDisplayForm::ToggleTabWaterfall3D(const bool state)
780
{
781
  if(state == true) {
782
    /*
783
    if((QGLFormat::hasOpenGL()) && (_useOpenGL)) {
784
      if(d_plot_waterfall3d == -1) {
785
        SpectrumTypeTab->addTab(Waterfall3DPage, "3D Waterfall Display");
786
        d_plot_waterfall3d = SpectrumTypeTab->count()-1;
787
      }
788
    }
789
    */
790
    SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(Waterfall3DPage));
791
    d_plot_waterfall3d = -1;
792
    fprintf(stderr, "\nWARNING: The Waterfall3D plot has been disabled until we get it working.\n\n");
793
  }
794
  else {
795
    SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(Waterfall3DPage));
796
    d_plot_waterfall3d = -1;
797
  }
798
}
799
800
void
801
SpectrumDisplayForm::ToggleTabTime(const bool state)
802
{
803
  if(state == true) {
804
    if(d_plot_time == -1) {
805
      SpectrumTypeTab->addTab(TimeDomainPage, "Time Domain Display");
806
      d_plot_time = SpectrumTypeTab->count()-1;
807
    }
808
  }
809
  else {
810
    SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(TimeDomainPage));
811
    d_plot_time = -1;
812
  }
813
}
814
815
void
816
SpectrumDisplayForm::ToggleTabConstellation(const bool state)
817
{
818
  if(state == true) {
819
    if(d_plot_constellation == -1) {
820
      SpectrumTypeTab->addTab(ConstellationPage, "Constellation Display");
821
      d_plot_constellation = SpectrumTypeTab->count()-1;
822
    }
823
  }
824
  else {
825
    SpectrumTypeTab->removeTab(SpectrumTypeTab->indexOf(ConstellationPage));
826
    d_plot_constellation = -1;
827
  }
828
}
829
830
831
void
832
SpectrumDisplayForm::SetTimeDomainAxis(double min, double max)
833
{
834
  _timeDomainDisplayPlot->set_yaxis(min, max);
835
}
836
837
void
838
SpectrumDisplayForm::SetConstellationAxis(double xmin, double xmax,
839
                                                double ymin, double ymax)
840
{
841
  _constellationDisplayPlot->set_axis(xmin, xmax, ymin, ymax);
842
}
843
844
void
845
SpectrumDisplayForm::SetConstellationPenSize(int size)
846
{
847
  _constellationDisplayPlot->set_pen_size( size );
848
}
849
850
void
851
SpectrumDisplayForm::SetFrequencyAxis(double min, double max)
852
{
853
  _frequencyDisplayPlot->set_yaxis(min, max);
854
}
855
856
void
857
SpectrumDisplayForm::SetUpdateTime(double t)
858
{
859
  d_update_time = t;
860
  // QTimer class takes millisecond input
861
  displayTimer->start(d_update_time*1000);
862
}