SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
glspectrumgui.cpp
Go to the documentation of this file.
1 #include "gui/glspectrumgui.h"
2 #include "dsp/fftwindow.h"
3 #include "dsp/spectrumvis.h"
4 #include "gui/glspectrum.h"
6 #include "ui_glspectrumgui.h"
7 
8 GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) :
9  QWidget(parent),
10  ui(new Ui::GLSpectrumGUI),
11  m_messageQueueToVis(0),
12  m_spectrumVis(0),
13  m_glSpectrum(0),
14  m_fftSize(1024),
15  m_fftOverlap(0),
16  m_fftWindow(FFTWindow::Hamming),
17  m_refLevel(0),
18  m_powerRange(100),
19  m_decay(1),
20  m_decayDivisor(1),
21  m_histogramStroke(30),
22  m_displayGridIntensity(5),
23  m_displayTraceIntensity(50),
24  m_displayWaterfall(true),
25  m_invertedWaterfall(false),
26  m_displayMaxHold(false),
27  m_displayCurrent(false),
28  m_displayHistogram(false),
29  m_displayGrid(false),
30  m_invert(true),
31  m_averagingMode(AvgModeNone),
32  m_averagingIndex(0),
33  m_averagingMaxScale(5),
34  m_averagingNb(0)
35 {
36  ui->setupUi(this);
37  on_linscale_toggled(false);
38  ui->refLevel->clear();
39  for(int ref = 0; ref >= -110; ref -= 5)
40  ui->refLevel->addItem(QString("%1").arg(ref));
41  ui->levelRange->clear();
42  for(int range = 100; range >= 5; range -= 5)
43  ui->levelRange->addItem(QString("%1").arg(range));
45  connect(&m_messageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
46 }
47 
49 {
50  delete ui;
51 }
52 
53 void GLSpectrumGUI::setBuddies(MessageQueue* messageQueue, SpectrumVis* spectrumVis, GLSpectrum* glSpectrum)
54 {
55  m_messageQueueToVis = messageQueue;
56  m_spectrumVis = spectrumVis;
57  m_glSpectrum = glSpectrum;
59  applySettings();
60 }
61 
63 {
64  m_fftSize = 1024;
65  m_fftOverlap = 0;
67  m_refLevel = 0;
68  m_powerRange = 100;
69  m_decay = 1;
70  m_decayDivisor = 1;
71  m_histogramStroke = 30;
73  m_displayWaterfall = true;
74  m_invertedWaterfall = false;
75  m_displayMaxHold = false;
76  m_displayHistogram = false;
77  m_displayGrid = false;
78  m_invert = true;
80  m_averagingIndex = 0;
81  m_linear = false;
82  applySettings();
83 }
84 
85 QByteArray GLSpectrumGUI::serialize() const
86 {
87  SimpleSerializer s(1);
88  s.writeS32(1, m_fftSize);
89  s.writeS32(2, m_fftOverlap);
90  s.writeS32(3, m_fftWindow);
91  s.writeReal(4, m_refLevel);
92  s.writeReal(5, m_powerRange);
97  s.writeS32(10, m_decay);
98  s.writeBool(11, m_displayGrid);
99  s.writeBool(12, m_invert);
101  s.writeS32(14, m_decayDivisor);
106  s.writeS32(19, (int) m_averagingMode);
108  s.writeBool(21, m_linear);
109  return s.final();
110 }
111 
112 bool GLSpectrumGUI::deserialize(const QByteArray& data)
113 {
114  SimpleDeserializer d(data);
115 
116  if(!d.isValid()) {
117  resetToDefaults();
118  return false;
119  }
120 
121  int tmp;
122 
123  if(d.getVersion() == 1) {
124  d.readS32(1, &m_fftSize, 1024);
125  d.readS32(2, &m_fftOverlap, 0);
127  d.readReal(4, &m_refLevel, 0);
128  d.readReal(5, &m_powerRange, 100);
129  d.readBool(6, &m_displayWaterfall, true);
130  d.readBool(7, &m_invertedWaterfall, false);
131  d.readBool(8, &m_displayMaxHold, false);
132  d.readBool(9, &m_displayHistogram, false);
133  d.readS32(10, &m_decay, 1);
134  d.readBool(11, &m_displayGrid, false);
135  d.readBool(12, &m_invert, true);
136  d.readS32(13, &m_displayGridIntensity, 5);
137  d.readS32(14, &m_decayDivisor, 1);
138  d.readS32(15, &m_histogramStroke, 30);
139  d.readBool(16, &m_displayCurrent, false);
140  d.readS32(17, &m_displayTraceIntensity, 50);
141  Real waterfallShare;
142  d.readReal(18, &waterfallShare, 0.66);
143  d.readS32(19, &tmp, 0);
144  m_averagingMode = tmp < 0 ? AvgModeNone : tmp > 3 ? AvgModeMax : (AveragingMode) tmp;
145  d.readS32(20, &tmp, 0);
148  d.readBool(21, &m_linear, false);
149 
150  m_glSpectrum->setWaterfallShare(waterfallShare);
151  applySettings();
152  return true;
153  } else {
154  resetToDefaults();
155  return false;
156  }
157 }
158 
160 {
161  ui->fftWindow->setCurrentIndex(m_fftWindow);
162  for(int i = 0; i < 6; i++) {
163  if(m_fftSize == (1 << (i + 7))) {
164  ui->fftSize->setCurrentIndex(i);
165  break;
166  }
167  }
168  ui->refLevel->setCurrentIndex(-m_refLevel / 5);
169  ui->levelRange->setCurrentIndex((100 - m_powerRange) / 5);
170  ui->averaging->setCurrentIndex(m_averagingIndex);
171  ui->averagingMode->setCurrentIndex((int) m_averagingMode);
172  ui->linscale->setChecked(m_linear);
173  ui->decay->setSliderPosition(m_decay);
174  ui->decayDivisor->setSliderPosition(m_decayDivisor);
175  ui->stroke->setSliderPosition(m_histogramStroke);
176  ui->waterfall->setChecked(m_displayWaterfall);
177  ui->maxHold->setChecked(m_displayMaxHold);
178  ui->current->setChecked(m_displayCurrent);
179  ui->histogram->setChecked(m_displayHistogram);
180  ui->invert->setChecked(m_invert);
181  ui->grid->setChecked(m_displayGrid);
182  ui->gridIntensity->setSliderPosition(m_displayGridIntensity);
183 
184  ui->decay->setToolTip(QString("Decay: %1").arg(m_decay));
185  ui->decayDivisor->setToolTip(QString("Decay divisor: %1").arg(m_decayDivisor));
186  ui->stroke->setToolTip(QString("Stroke: %1").arg(m_histogramStroke));
187  ui->gridIntensity->setToolTip(QString("Grid intensity: %1").arg(m_displayGridIntensity));
188  ui->traceIntensity->setToolTip(QString("Trace intensity: %1").arg(m_displayTraceIntensity));
189 
202 
203  if (m_spectrumVis) {
205  m_fftSize,
206  m_fftOverlap,
208  m_averagingMode,
210  m_linear);
211  }
212 
214 }
215 
217 {
218  m_fftWindow = index;
219  if(m_spectrumVis != 0) {
221  m_fftSize,
222  m_fftOverlap,
226  m_linear);
227  }
228 }
229 
231 {
232  m_fftSize = 1 << (7 + index);
233  if(m_spectrumVis != 0) {
235  m_fftSize,
236  m_fftOverlap,
240  m_linear);
241  }
243 }
244 
246 {
247  m_averagingMode = index < 0 ? AvgModeNone : index > 3 ? AvgModeMax : (AveragingMode) index;
248 
250  {
253  m_averagingNb = m_averagingNb > 1000 ? 1000 : m_averagingNb;
254  }
255  else
256  {
259  }
260 
261  if(m_spectrumVis != 0) {
263  m_fftSize,
264  m_fftOverlap,
268  m_linear);
269  }
270 
271  if (m_glSpectrum != 0)
272  {
275  } else {
277  }
278  }
279 }
280 
282 {
283  m_averagingIndex = index;
285 
286  if(m_spectrumVis != 0) {
288  m_fftSize,
289  m_fftOverlap,
293  m_linear);
294  }
295 
296  if (m_glSpectrum != 0)
297  {
300  } else {
302  }
303  }
304 
306 }
307 
309 {
310  m_linear = checked;
311 
312  if(m_spectrumVis != 0) {
314  m_fftSize,
315  m_fftOverlap,
319  m_linear);
320  }
321 
322  if(m_glSpectrum != 0)
323  {
324  Real refLevel = m_linear ? pow(10.0, m_refLevel/10.0) : m_refLevel;
325  Real powerRange = m_linear ? pow(10.0, m_refLevel/10.0) : m_powerRange;
326  qDebug("GLSpectrumGUI::on_linscale_toggled: refLevel: %e powerRange: %e", refLevel, powerRange);
327  m_glSpectrum->setReferenceLevel(refLevel);
328  m_glSpectrum->setPowerRange(powerRange);
330  }
331 }
332 
334 {
335  m_refLevel = 0 - index * 5;
336 
337  if(m_glSpectrum != 0)
338  {
339  Real refLevel = m_linear ? pow(10.0, m_refLevel/10.0) : m_refLevel;
340  Real powerRange = m_linear ? pow(10.0, m_refLevel/10.0) : m_powerRange;
341  qDebug("GLSpectrumGUI::on_refLevel_currentIndexChanged: refLevel: %e ", refLevel);
342  m_glSpectrum->setReferenceLevel(refLevel);
343  m_glSpectrum->setPowerRange(powerRange);
344  }
345 }
346 
348 {
349  m_powerRange = 100 - index * 5;
350 
351  if(m_glSpectrum != 0)
352  {
353  Real refLevel = m_linear ? pow(10.0, m_refLevel/10.0) : m_refLevel;
354  Real powerRange = m_linear ? pow(10.0, m_refLevel/10.0) : m_powerRange;
355  qDebug("GLSpectrumGUI::on_levelRange_currentIndexChanged: powerRange: %e", powerRange);
356  m_glSpectrum->setReferenceLevel(refLevel);
357  m_glSpectrum->setPowerRange(powerRange);
358  }
359 }
360 
362 {
363  m_decay = index;
364  ui->decay->setToolTip(QString("Decay: %1").arg(m_decay));
365  if(m_glSpectrum != 0) {
367  }
368 }
369 
371 {
372  m_decayDivisor = index;
373  //ui->decayDivisor->setToolTip(QString("Decay divisor: %1").arg(m_decayDivisor));
374  if(m_glSpectrum != 0) {
375  applySettings();
376  }
377 }
378 
380 {
381  m_histogramStroke = index;
382  //ui->stroke->setToolTip(QString("Stroke: %1").arg(m_histogramStroke));
383  if(m_glSpectrum != 0) {
384  applySettings();
385  }
386 }
387 
389 {
390  m_displayWaterfall = checked;
391  if(m_glSpectrum != 0) {
393  }
394 }
395 
397 {
398  m_displayHistogram = checked;
399  if(m_glSpectrum != 0) {
401  }
402 }
403 
405 {
406  m_displayMaxHold = checked;
407  if(m_glSpectrum != 0) {
409  }
410 }
411 
413 {
414  m_displayCurrent = checked;
415  if(m_glSpectrum != 0) {
417  }
418 }
419 
421 {
422  m_invert = checked;
423  if(m_glSpectrum != 0) {
425  }
426 }
427 
429 {
430  m_displayGrid = checked;
431  if(m_glSpectrum != 0) {
433  }
434 }
435 
437 {
438  m_displayGridIntensity = index;
439  ui->gridIntensity->setToolTip(QString("Grid intensity: %1").arg(m_displayGridIntensity));
440  if(m_glSpectrum != 0) {
442  }
443 }
444 
446 {
447  m_displayTraceIntensity = index;
448  ui->traceIntensity->setToolTip(QString("Trace intensity: %1").arg(m_displayTraceIntensity));
449  if(m_glSpectrum != 0) {
451  }
452 }
453 
455 {
456  (void) checked;
457  if(m_glSpectrum != 0) {
459  }
460 }
461 
462 int GLSpectrumGUI::getAveragingIndex(int averagingValue) const
463 {
464  if (averagingValue <= 1) {
465  return 0;
466  }
467 
468  int v = averagingValue;
469  int j = 0;
470 
471  for (int i = 0; i <= m_averagingMaxScale; i++)
472  {
473  if (v < 20)
474  {
475  if (v < 2) {
476  j = 0;
477  } else if (v < 5) {
478  j = 1;
479  } else if (v < 10) {
480  j = 2;
481  } else {
482  j = 3;
483  }
484 
485  return 3*i + j;
486  }
487 
488  v /= 10;
489  }
490 
491  return 3*m_averagingMaxScale + 3;
492 }
493 
494 int GLSpectrumGUI::getAveragingValue(int averagingIndex) const
495 {
496  if (averagingIndex <= 0) {
497  return 1;
498  }
499 
500  int v = averagingIndex - 1;
501  int m = pow(10.0, v/3 > m_averagingMaxScale ? m_averagingMaxScale : v/3);
502  int x = 1;
503 
504  if (v % 3 == 0) {
505  x = 2;
506  } else if (v % 3 == 1) {
507  x = 5;
508  } else if (v % 3 == 2) {
509  x = 10;
510  }
511 
512  return x * m;
513 }
514 
516 {
517  int index = ui->averaging->currentIndex();
518  ui->averaging->clear();
519  ui->averaging->addItem(QString("1"));
520 
521  for (int i = 0; i <= m_averagingMaxScale; i++)
522  {
523  QString s;
524  int m = pow(10.0, i);
525  int x = 2*m;
526  setNumberStr(x, s);
527  ui->averaging->addItem(s);
528  x = 5*m;
529  setNumberStr(x, s);
530  ui->averaging->addItem(s);
531  x = 10*m;
532  setNumberStr(x, s);
533  ui->averaging->addItem(s);
534  }
535 
536  ui->averaging->setCurrentIndex(index >= ui->averaging->count() ? ui->averaging->count() - 1 : index);
537 }
538 
539 void GLSpectrumGUI::setNumberStr(int n, QString& s)
540 {
541  if (n < 1000) {
542  s = tr("%1").arg(n);
543  } else if (n < 100000) {
544  s = tr("%1k").arg(n/1000);
545  } else if (n < 1000000) {
546  s = tr("%1e5").arg(n/100000);
547  } else if (n < 1000000000) {
548  s = tr("%1M").arg(n/1000000);
549  } else {
550  s = tr("%1G").arg(n/1000000000);
551  }
552 }
553 
554 void GLSpectrumGUI::setNumberStr(float v, int decimalPlaces, QString& s)
555 {
556  if (v < 1e-6) {
557  s = tr("%1n").arg(v*1e9, 0, 'f', decimalPlaces);
558  } else if (v < 1e-3) {
559  s = tr("%1ยต").arg(v*1e6, 0, 'f', decimalPlaces);
560  } else if (v < 1.0) {
561  s = tr("%1m").arg(v*1e3, 0, 'f', decimalPlaces);
562  } else if (v < 1e3) {
563  s = tr("%1").arg(v, 0, 'f', decimalPlaces);
564  } else if (v < 1e6) {
565  s = tr("%1k").arg(v*1e-3, 0, 'f', decimalPlaces);
566  } else if (v < 1e9) {
567  s = tr("%1M").arg(v*1e-6, 0, 'f', decimalPlaces);
568  } else {
569  s = tr("%1G").arg(v*1e-9, 0, 'f', decimalPlaces);
570  }
571 }
572 
574 {
575  if (m_glSpectrum)
576  {
577  QString s;
578  float averagingTime = (m_fftSize * (m_averagingNb == 0 ? 1 : m_averagingNb)) / (float) m_glSpectrum->getSampleRate();
579  setNumberStr(averagingTime, 2, s);
580  ui->averaging->setToolTip(QString("Number of averaging samples (avg time: %1s)").arg(s));
581  }
582  else
583  {
584  ui->averaging->setToolTip(QString("Number of averaging samples"));
585  }
586 }
587 
589 {
591  {
593  return true;
594  }
595 
596  return false;
597 }
598 
600 {
601  Message* message;
602 
603  while ((message = m_messageQueue.pop()) != 0)
604  {
605  qDebug("GLSpectrumGUI::handleInputMessages: message: %s", message->getIdentifier());
606 
607  if (handleMessage(*message))
608  {
609  delete message;
610  }
611  }
612 }
bool m_displayCurrent
Definition: glspectrumgui.h:59
Message * pop()
Pop message from queue.
Ui::GLSpectrumGUI * ui
Definition: glspectrumgui.h:39
qint32 m_fftOverlap
Definition: glspectrumgui.h:47
int m_displayTraceIntensity
Definition: glspectrumgui.h:55
void on_refLevel_currentIndexChanged(int index)
void setDisplayGrid(bool display)
Definition: glspectrum.cpp:280
void setTimingRate(qint32 timingRate)
Definition: glspectrum.cpp:221
void on_fftSize_currentIndexChanged(int index)
qint32 getSampleRate() const
Definition: glspectrum.h:86
void setDisplayTraceIntensity(int intensity)
Definition: glspectrum.cpp:297
void on_gridIntensity_valueChanged(int index)
void setPowerRange(Real powerRange)
Definition: glspectrum.cpp:189
bool m_invertedWaterfall
Definition: glspectrumgui.h:57
void on_clearSpectrum_clicked(bool checked)
Real getWaterfallShare() const
Definition: glspectrum.h:95
qint32 m_fftWindow
Definition: glspectrumgui.h:48
MessageQueue * m_messageQueueToVis
Definition: glspectrumgui.h:41
qint32 m_fftSize
Definition: glspectrumgui.h:46
MessageQueue m_messageQueue
Definition: glspectrumgui.h:44
void on_grid_toggled(bool checked)
void setReferenceLevel(Real referenceLevel)
Definition: glspectrum.cpp:182
void resetToDefaults()
void setBuddies(MessageQueue *messageQueue, SpectrumVis *spectrumVis, GLSpectrum *glSpectrum)
bool m_linear
linear else logarithmic scale
Definition: glspectrumgui.h:67
void on_averagingMode_currentIndexChanged(int index)
void setDisplayHistogram(bool display)
Definition: glspectrum.cpp:272
bool readBool(quint32 id, bool *result, bool def=false) const
void setDecay(int decay)
Definition: glspectrum.cpp:196
bool isValid() const
void on_averaging_currentIndexChanged(int index)
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
void setDecayDivisor(int decayDivisor)
Definition: glspectrum.cpp:201
void on_stroke_valueChanged(int index)
void setAveragingToolitp()
bool m_displayHistogram
Definition: glspectrumgui.h:60
void setDisplayCurrent(bool display)
Definition: glspectrum.cpp:264
void on_waterfall_toggled(bool checked)
bool m_displayWaterfall
Definition: glspectrumgui.h:56
void on_traceIntensity_valueChanged(int index)
bool readS32(quint32 id, qint32 *result, qint32 def=0) const
SpectrumVis * m_spectrumVis
Definition: glspectrumgui.h:42
void on_decayDivisor_valueChanged(int index)
void setMessageQueueToGUI(MessageQueue *messageQueue)
Definition: glspectrum.h:90
int32_t i
Definition: decimators.h:244
void setInvertedWaterfall(bool inv)
Definition: glspectrum.cpp:248
void on_linscale_toggled(bool checked)
static bool match(const Message *message)
Definition: message.cpp:45
bool m_displayMaxHold
Definition: glspectrumgui.h:58
void on_current_toggled(bool checked)
void writeS32(quint32 id, qint32 value)
void setHistoStroke(int stroke)
Definition: glspectrum.cpp:206
quint32 getVersion() const
void on_maxHold_toggled(bool checked)
void handleInputMessages()
void on_invert_toggled(bool checked)
GLSpectrum * m_glSpectrum
Definition: glspectrumgui.h:43
int m_averagingMaxScale
Max power of 10 multiplier to 2,5,10 base ex: 2 -> 2,5,10,20,50,100,200,500,1000. ...
Definition: glspectrumgui.h:65
virtual QByteArray serialize() const
void writeReal(quint32 id, Real value)
void on_levelRange_currentIndexChanged(int index)
bool readReal(quint32 id, Real *result, Real def=0) const
bool handleMessage(const Message &message)
void setNumberStr(int n, QString &s)
void on_decay_valueChanged(int index)
void setLinear(bool linear)
Definition: glspectrum.cpp:308
void writeBool(quint32 id, bool value)
GLSpectrumGUI(QWidget *parent=NULL)
virtual const char * getIdentifier() const
Definition: message.cpp:35
void on_fftWindow_currentIndexChanged(int index)
AveragingMode m_averagingMode
Definition: glspectrumgui.h:63
void configure(MessageQueue *msgQueue, int fftSize, int overlapPercent, unsigned int averagingNb, int averagingMode, FFTWindow::Function window, bool m_linear)
Definition: spectrumvis.cpp:44
int m_displayGridIntensity
Definition: glspectrumgui.h:54
void setAveragingCombo()
void setDisplayGridIntensity(int intensity)
Definition: glspectrum.cpp:286
int getAveragingValue(int averagingIndex) const
void setWaterfallShare(Real waterfallShare)
void on_histogram_toggled(bool checked)
void clearSpectrumHistogram()
Definition: glspectrum.cpp:535
float Real
Definition: dsptypes.h:42
const QByteArray & final()
void setDisplayMaxHold(bool display)
Definition: glspectrum.cpp:256
virtual bool deserialize(const QByteArray &data)
unsigned int m_averagingNb
Definition: glspectrumgui.h:66
int getAveragingIndex(int averaging) const
void setDisplayWaterfall(bool display)
Definition: glspectrum.cpp:228