diff --git a/plugins/channelrx/demodbfm/bfmdemodgui.cpp b/plugins/channelrx/demodbfm/bfmdemodgui.cpp index 5074cad04..cda2d6889 100644 --- a/plugins/channelrx/demodbfm/bfmdemodgui.cpp +++ b/plugins/channelrx/demodbfm/bfmdemodgui.cpp @@ -359,7 +359,7 @@ BFMDemodGUI::BFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban ui->glSpectrum->setDisplayWaterfall(false); ui->glSpectrum->setDisplayMaxHold(false); ui->glSpectrum->setSsbSpectrum(true); - m_spectrumVis->configure(m_spectrumVis->getInputMessageQueue(), 64, 10, FFTWindow::BlackmanHarris); + m_spectrumVis->configure(m_spectrumVis->getInputMessageQueue(), 64, 10, 0, FFTWindow::BlackmanHarris); connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); m_channelMarker.blockSignals(true); diff --git a/plugins/channelrx/udpsrc/udpsrcgui.cpp b/plugins/channelrx/udpsrc/udpsrcgui.cpp index 28ba37359..66826ec56 100644 --- a/plugins/channelrx/udpsrc/udpsrcgui.cpp +++ b/plugins/channelrx/udpsrc/udpsrcgui.cpp @@ -187,7 +187,7 @@ UDPSrcGUI::UDPSrcGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam ui->glSpectrum->setSampleRate(ui->sampleRate->text().toInt()); ui->glSpectrum->setDisplayWaterfall(true); ui->glSpectrum->setDisplayMaxHold(true); - m_spectrumVis->configure(m_spectrumVis->getInputMessageQueue(), 64, 10, FFTWindow::BlackmanHarris); + m_spectrumVis->configure(m_spectrumVis->getInputMessageQueue(), 64, 10, 0, FFTWindow::BlackmanHarris); ui->glSpectrum->connectTimer(MainWindow::getInstance()->getMasterTimer()); connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); diff --git a/plugins/channeltx/udpsink/udpsinkgui.cpp b/plugins/channeltx/udpsink/udpsinkgui.cpp index fe2ac399d..4e40e2cce 100644 --- a/plugins/channeltx/udpsink/udpsinkgui.cpp +++ b/plugins/channeltx/udpsink/udpsinkgui.cpp @@ -142,7 +142,7 @@ UDPSinkGUI::UDPSinkGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS ui->glSpectrum->setSampleRate(ui->sampleRate->text().toInt()); ui->glSpectrum->setDisplayWaterfall(true); ui->glSpectrum->setDisplayMaxHold(true); - m_spectrumVis->configure(m_spectrumVis->getInputMessageQueue(), 64, 10, FFTWindow::BlackmanHarris); + m_spectrumVis->configure(m_spectrumVis->getInputMessageQueue(), 64, 10, 0, FFTWindow::BlackmanHarris); ui->glSpectrum->connectTimer(MainWindow::getInstance()->getMasterTimer()); connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); diff --git a/sdrbase/util/movingaverage2d.h b/sdrbase/util/movingaverage2d.h index 9fd270d69..5cdc5e7f3 100644 --- a/sdrbase/util/movingaverage2d.h +++ b/sdrbase/util/movingaverage2d.h @@ -68,7 +68,7 @@ public: T storeAndGetAvg(T v, unsigned int index) { - if (m_depth == 1) + if (m_depth <= 1) { return v; } diff --git a/sdrgui/dsp/spectrumvis.cpp b/sdrgui/dsp/spectrumvis.cpp index f1b98f5eb..27eb7a5c0 100644 --- a/sdrgui/dsp/spectrumvis.cpp +++ b/sdrgui/dsp/spectrumvis.cpp @@ -25,10 +25,12 @@ SpectrumVis::SpectrumVis(Real scalef, GLSpectrum* glSpectrum) : m_needMoreSamples(false), m_scalef(scalef), m_glSpectrum(glSpectrum), + m_averageNb(0), + m_ofs(0), m_mutex(QMutex::Recursive) { setObjectName("SpectrumVis"); - handleConfigure(1024, 0, FFTWindow::BlackmanHarris); + handleConfigure(1024, 0, 0, FFTWindow::BlackmanHarris); } SpectrumVis::~SpectrumVis() @@ -36,9 +38,9 @@ SpectrumVis::~SpectrumVis() delete m_fft; } -void SpectrumVis::configure(MessageQueue* msgQueue, int fftSize, int overlapPercent, FFTWindow::Function window) +void SpectrumVis::configure(MessageQueue* msgQueue, int fftSize, int overlapPercent, unsigned int averagingNb, FFTWindow::Function window) { - MsgConfigureSpectrumVis* cmd = new MsgConfigureSpectrumVis(fftSize, overlapPercent, window); + MsgConfigureSpectrumVis* cmd = new MsgConfigureSpectrumVis(fftSize, overlapPercent, averagingNb, window); msgQueue->push(cmd); } @@ -171,7 +173,7 @@ bool SpectrumVis::handleMessage(const Message& message) if (MsgConfigureSpectrumVis::match(message)) { MsgConfigureSpectrumVis& conf = (MsgConfigureSpectrumVis&) message; - handleConfigure(conf.getFFTSize(), conf.getOverlapPercent(), conf.getWindow()); + handleConfigure(conf.getFFTSize(), conf.getOverlapPercent(), conf.getAverageNb(), conf.getWindow()); return true; } else @@ -180,7 +182,7 @@ bool SpectrumVis::handleMessage(const Message& message) } } -void SpectrumVis::handleConfigure(int fftSize, int overlapPercent, FFTWindow::Function window) +void SpectrumVis::handleConfigure(int fftSize, int overlapPercent, unsigned int averageNb, FFTWindow::Function window) { QMutexLocker mutexLocker(&m_mutex); @@ -212,7 +214,7 @@ void SpectrumVis::handleConfigure(int fftSize, int overlapPercent, FFTWindow::Fu m_overlapSize = (m_fftSize * m_overlapPercent) / 100; m_refillSize = m_fftSize - m_overlapSize; m_fftBufferFill = m_overlapSize; - m_average.resize(fftSize, 10); - m_averageNb = 100; + m_average.resize(fftSize, averageNb); + m_averageNb = averageNb; m_ofs = 20.0f * log10f(1.0f / m_fftSize); } diff --git a/sdrgui/dsp/spectrumvis.h b/sdrgui/dsp/spectrumvis.h index 19995538a..8faa38647 100644 --- a/sdrgui/dsp/spectrumvis.h +++ b/sdrgui/dsp/spectrumvis.h @@ -19,27 +19,30 @@ public: MESSAGE_CLASS_DECLARATION public: - MsgConfigureSpectrumVis(int fftSize, int overlapPercent, FFTWindow::Function window) : + MsgConfigureSpectrumVis(int fftSize, int overlapPercent, unsigned int averageNb, FFTWindow::Function window) : Message(), m_fftSize(fftSize), m_overlapPercent(overlapPercent), + m_averageNb(averageNb), m_window(window) { } int getFFTSize() const { return m_fftSize; } int getOverlapPercent() const { return m_overlapPercent; } + unsigned int getAverageNb() const { return m_averageNb; } FFTWindow::Function getWindow() const { return m_window; } private: int m_fftSize; int m_overlapPercent; + unsigned int m_averageNb; FFTWindow::Function m_window; }; SpectrumVis(Real scalef, GLSpectrum* glSpectrum = 0); virtual ~SpectrumVis(); - void configure(MessageQueue* msgQueue, int fftSize, int overlapPercent, FFTWindow::Function window); + void configure(MessageQueue* msgQueue, int fftSize, int overlapPercent, unsigned int averagingNb, FFTWindow::Function window); virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly); void feedTriggered(const SampleVector::const_iterator& triggerPoint, const SampleVector::const_iterator& end, bool positiveOnly); @@ -71,7 +74,7 @@ private: QMutex m_mutex; - void handleConfigure(int fftSize, int overlapPercent, FFTWindow::Function window); + void handleConfigure(int fftSize, int overlapPercent, unsigned int averageNb, FFTWindow::Function window); }; #endif // INCLUDE_SPECTRUMVIS_H diff --git a/sdrgui/gui/glspectrumgui.cpp b/sdrgui/gui/glspectrumgui.cpp index bfe576d6b..7dab42811 100644 --- a/sdrgui/gui/glspectrumgui.cpp +++ b/sdrgui/gui/glspectrumgui.cpp @@ -8,9 +8,9 @@ GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) : QWidget(parent), ui(new Ui::GLSpectrumGUI), - m_messageQueue(NULL), - m_spectrumVis(NULL), - m_glSpectrum(NULL), + m_messageQueue(0), + m_spectrumVis(0), + m_glSpectrum(0), m_fftSize(1024), m_fftOverlap(0), m_fftWindow(FFTWindow::Hamming), @@ -27,7 +27,11 @@ GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) : m_displayCurrent(false), m_displayHistogram(false), m_displayGrid(false), - m_invert(true) + m_invert(true), + m_averagingMode(AvgModeMoving), + m_averagingIndex(0), + m_averagingMaxScale(2), + m_averagingNb(0) { ui->setupUi(this); for(int ref = 0; ref >= -110; ref -= 5) @@ -66,6 +70,8 @@ void GLSpectrumGUI::resetToDefaults() m_displayHistogram = false; m_displayGrid = false; m_invert = true; + m_averagingMode = AvgModeMoving; + m_averagingIndex = 0; applySettings(); } @@ -90,6 +96,8 @@ QByteArray GLSpectrumGUI::serialize() const s.writeBool(16, m_displayCurrent); s.writeS32(17, m_displayTraceIntensity); s.writeReal(18, m_glSpectrum->getWaterfallShare()); + s.writeS32(19, (int) m_averagingMode); + s.writeS32(20, (qint32) getAveragingValue(m_averagingIndex)); return s.final(); } @@ -102,6 +110,8 @@ bool GLSpectrumGUI::deserialize(const QByteArray& data) return false; } + int tmp; + if(d.getVersion() == 1) { d.readS32(1, &m_fftSize, 1024); d.readS32(2, &m_fftOverlap, 0); @@ -122,6 +132,12 @@ bool GLSpectrumGUI::deserialize(const QByteArray& data) d.readS32(17, &m_displayTraceIntensity, 50); Real waterfallShare; d.readReal(18, &waterfallShare, 0.66); + d.readS32(19, &tmp, 0); + m_averagingMode = tmp < 0 ? AvgModeMoving : tmp > 1 ? AvgModeFixed : (AveragingMode) tmp; + d.readS32(20, &tmp, 0); + m_averagingIndex = getAveragingValue(tmp); + m_averagingNb = getAveragingValue(m_averagingIndex); + m_glSpectrum->setWaterfallShare(waterfallShare); applySettings(); return true; @@ -142,6 +158,8 @@ void GLSpectrumGUI::applySettings() } ui->refLevel->setCurrentIndex(-m_refLevel / 5); ui->levelRange->setCurrentIndex((100 - m_powerRange) / 5); + ui->averaging->setCurrentIndex(m_averagingIndex); + ui->averagingMode->setCurrentIndex((int) m_averagingMode); ui->decay->setSliderPosition(m_decay); ui->holdoff->setSliderPosition(m_histogramLateHoldoff); ui->stroke->setSliderPosition(m_histogramStroke); @@ -171,44 +189,63 @@ void GLSpectrumGUI::applySettings() m_glSpectrum->setDisplayGrid(m_displayGrid); m_glSpectrum->setDisplayGridIntensity(m_displayGridIntensity); - m_spectrumVis->configure(m_messageQueue, m_fftSize, m_fftOverlap, (FFTWindow::Function)m_fftWindow); + if (m_spectrumVis) { + m_spectrumVis->configure(m_messageQueue, m_fftSize, m_fftOverlap, m_averagingNb, (FFTWindow::Function)m_fftWindow); + } } void GLSpectrumGUI::on_fftWindow_currentIndexChanged(int index) { m_fftWindow = index; - if(m_spectrumVis == NULL) - return; - m_spectrumVis->configure(m_messageQueue, m_fftSize, m_fftOverlap, (FFTWindow::Function)m_fftWindow); + if(m_spectrumVis != 0) { + m_spectrumVis->configure(m_messageQueue, m_fftSize, m_fftOverlap, m_averagingNb, (FFTWindow::Function)m_fftWindow); + } } void GLSpectrumGUI::on_fftSize_currentIndexChanged(int index) { m_fftSize = 1 << (7 + index); - if(m_spectrumVis != NULL) - m_spectrumVis->configure(m_messageQueue, m_fftSize, m_fftOverlap, (FFTWindow::Function)m_fftWindow); + if(m_spectrumVis != 0) { + m_spectrumVis->configure(m_messageQueue, m_fftSize, m_fftOverlap, m_averagingNb, (FFTWindow::Function)m_fftWindow); + } +} + +void GLSpectrumGUI::on_averagingMode_currentIndexChanged(int index __attribute__((unused))) +{ +} + +void GLSpectrumGUI::on_averaging_currentIndexChanged(int index) +{ + m_averagingIndex = index; + m_averagingNb = getAveragingValue(index); + if(m_spectrumVis != 0) { + m_spectrumVis->configure(m_messageQueue, m_fftSize, m_fftOverlap, m_averagingNb, (FFTWindow::Function)m_fftWindow); + } } void GLSpectrumGUI::on_refLevel_currentIndexChanged(int index) { m_refLevel = 0 - index * 5; - if(m_glSpectrum != NULL) - m_glSpectrum->setReferenceLevel(m_refLevel); + if(m_glSpectrum != 0) { + m_glSpectrum->setReferenceLevel(m_refLevel); + } } void GLSpectrumGUI::on_levelRange_currentIndexChanged(int index) { m_powerRange = 100 - index * 5; - if(m_glSpectrum != NULL) - m_glSpectrum->setPowerRange(m_powerRange); + if(m_glSpectrum != 0) { + m_glSpectrum->setPowerRange(m_powerRange); + } } void GLSpectrumGUI::on_decay_valueChanged(int index) { m_decay = index; ui->decay->setToolTip(QString("Decay: %1").arg(m_decay)); - if(m_glSpectrum != NULL) - m_glSpectrum->setDecay(m_decay); + if(m_glSpectrum != 0) { + m_glSpectrum->setDecay(m_decay); + } } void GLSpectrumGUI::on_holdoff_valueChanged(int index) @@ -218,7 +255,7 @@ void GLSpectrumGUI::on_holdoff_valueChanged(int index) } m_histogramLateHoldoff = index; //ui->holdoff->setToolTip(QString("Holdoff: %1").arg(m_histogramLateHoldoff)); - if(m_glSpectrum != NULL) { + if(m_glSpectrum != 0) { applySettings(); } } @@ -230,7 +267,7 @@ void GLSpectrumGUI::on_stroke_valueChanged(int index) } m_histogramStroke = index; //ui->stroke->setToolTip(QString("Stroke: %1").arg(m_histogramStroke)); - if(m_glSpectrum != NULL) { + if(m_glSpectrum != 0) { applySettings(); } } @@ -238,63 +275,126 @@ void GLSpectrumGUI::on_stroke_valueChanged(int index) void GLSpectrumGUI::on_waterfall_toggled(bool checked) { m_displayWaterfall = checked; - if(m_glSpectrum != NULL) - m_glSpectrum->setDisplayWaterfall(m_displayWaterfall); + if(m_glSpectrum != 0) { + m_glSpectrum->setDisplayWaterfall(m_displayWaterfall); + } } void GLSpectrumGUI::on_histogram_toggled(bool checked) { m_displayHistogram = checked; - if(m_glSpectrum != NULL) - m_glSpectrum->setDisplayHistogram(m_displayHistogram); + if(m_glSpectrum != 0) { + m_glSpectrum->setDisplayHistogram(m_displayHistogram); + } } void GLSpectrumGUI::on_maxHold_toggled(bool checked) { m_displayMaxHold = checked; - if(m_glSpectrum != NULL) - m_glSpectrum->setDisplayMaxHold(m_displayMaxHold); + if(m_glSpectrum != 0) { + m_glSpectrum->setDisplayMaxHold(m_displayMaxHold); + } } void GLSpectrumGUI::on_current_toggled(bool checked) { m_displayCurrent = checked; - if(m_glSpectrum != NULL) - m_glSpectrum->setDisplayCurrent(m_displayCurrent); + if(m_glSpectrum != 0) { + m_glSpectrum->setDisplayCurrent(m_displayCurrent); + } } void GLSpectrumGUI::on_invert_toggled(bool checked) { m_invert = checked; - if(m_glSpectrum != NULL) - m_glSpectrum->setInvertedWaterfall(m_invert); + if(m_glSpectrum != 0) { + m_glSpectrum->setInvertedWaterfall(m_invert); + } } void GLSpectrumGUI::on_grid_toggled(bool checked) { m_displayGrid = checked; - if(m_glSpectrum != NULL) - m_glSpectrum->setDisplayGrid(m_displayGrid); + if(m_glSpectrum != 0) { + m_glSpectrum->setDisplayGrid(m_displayGrid); + } } void GLSpectrumGUI::on_gridIntensity_valueChanged(int index) { m_displayGridIntensity = index; ui->gridIntensity->setToolTip(QString("Grid intensity: %1").arg(m_displayGridIntensity)); - if(m_glSpectrum != NULL) - m_glSpectrum->setDisplayGridIntensity(m_displayGridIntensity); + if(m_glSpectrum != 0) { + m_glSpectrum->setDisplayGridIntensity(m_displayGridIntensity); + } } void GLSpectrumGUI::on_traceIntensity_valueChanged(int index) { m_displayTraceIntensity = index; ui->traceIntensity->setToolTip(QString("Trace intensity: %1").arg(m_displayTraceIntensity)); - if(m_glSpectrum != NULL) - m_glSpectrum->setDisplayTraceIntensity(m_displayTraceIntensity); + if(m_glSpectrum != 0) { + m_glSpectrum->setDisplayTraceIntensity(m_displayTraceIntensity); + } } void GLSpectrumGUI::on_clearSpectrum_clicked(bool checked __attribute__((unused))) { - if(m_glSpectrum != NULL) - m_glSpectrum->clearSpectrumHistogram(); + if(m_glSpectrum != 0) { + m_glSpectrum->clearSpectrumHistogram(); + } } + +int GLSpectrumGUI::getAveragingIndex(int averagingValue) const +{ + if (averagingValue <= 0) { + return 0; + } + + int v = averagingValue; + int j = 0; + + for (int i = 0; i <= m_averagingMaxScale; i++) + { + if (v < 20) + { + if (v < 2) { + j = 0; + } else if (v < 5) { + j = 1; + } else if (v < 10) { + j = 2; + } else { + j = 3; + } + + return 3*i + j; + } + + v /= 10; + } + + return 3*m_averagingMaxScale + 3; +} + +int GLSpectrumGUI::getAveragingValue(int averagingIndex) const +{ + if (averagingIndex <= 0) { + return 0; + } + + int v = averagingIndex - 1; + int m = pow(10.0, v/3 > m_averagingMaxScale ? m_averagingMaxScale : v/3); + int x; + + if (v % 3 == 0) { + x = 2; + } else if (v % 3 == 1) { + x = 5; + } else if (v % 3 == 2) { + x = 10; + } + + return x * m; +} + diff --git a/sdrgui/gui/glspectrumgui.h b/sdrgui/gui/glspectrumgui.h index 69765777e..e31bf1136 100644 --- a/sdrgui/gui/glspectrumgui.h +++ b/sdrgui/gui/glspectrumgui.h @@ -18,6 +18,12 @@ class SDRGUI_API GLSpectrumGUI : public QWidget, public Serializable { Q_OBJECT public: + enum AveragingMode + { + AvgModeMoving, + AvgModeFixed + }; + explicit GLSpectrumGUI(QWidget* parent = NULL); ~GLSpectrumGUI(); @@ -51,8 +57,14 @@ private: bool m_displayHistogram; bool m_displayGrid; bool m_invert; + AveragingMode m_averagingMode; + int m_averagingIndex; + int m_averagingMaxScale; + unsigned int m_averagingNb; void applySettings(); + int getAveragingIndex(int averaging) const; + int getAveragingValue(int averagingIndex) const; private slots: void on_fftWindow_currentIndexChanged(int index); @@ -64,6 +76,8 @@ private slots: void on_stroke_valueChanged(int index); void on_gridIntensity_valueChanged(int index); void on_traceIntensity_valueChanged(int index); + void on_averagingMode_currentIndexChanged(int index); + void on_averaging_currentIndexChanged(int index); void on_waterfall_toggled(bool checked); void on_histogram_toggled(bool checked); diff --git a/sdrgui/gui/glspectrumgui.ui b/sdrgui/gui/glspectrumgui.ui index b46b17a66..ae9d75396 100644 --- a/sdrgui/gui/glspectrumgui.ui +++ b/sdrgui/gui/glspectrumgui.ui @@ -7,7 +7,7 @@ 0 0 331 - 60 + 59 @@ -104,19 +104,49 @@ - - - - 0 - 0 - - - + + 24 24 + + Trace intensity + + + 100 + + + 1 + + + 50 + + + + + + + Clear spectrum histogram + + + + + + + :/clear.png:/clear.png + + + + 16 + 16 + + + + + + Display phosphor effect spectrum @@ -140,18 +170,6 @@ - - - 0 - 0 - - - - - 24 - 24 - - Display max hold @@ -175,18 +193,6 @@ - - - 0 - 0 - - - - - 24 - 24 - - Display live spectrum @@ -210,18 +216,6 @@ - - - 0 - 0 - - - - - 24 - 24 - - Exchange waterfall and histogram @@ -245,18 +239,6 @@ - - - 0 - 0 - - - - - 24 - 24 - - Display waterfall @@ -283,18 +265,6 @@ - - - 0 - 0 - - - - - 24 - 24 - - Toggle the scale grid @@ -355,13 +325,13 @@ - 30 + 50 0 - 100 + 50 16777215 @@ -373,32 +343,32 @@ - Bartlett + Bart - Blackman-Harris + B-H - Flat Top + FT - Hamming + Ham - Hanning + Han - Rectangle + Rec @@ -411,6 +381,18 @@ 0 + + + 50 + 0 + + + + + 50 + 16777215 + + FFT size @@ -459,16 +441,37 @@ - 0 + 50 0 + + + 50 + 16777215 + + Reference level (dB) QComboBox::AdjustToContents + + + 0 + + + + + -5 + + + + + -10 + + @@ -481,70 +484,135 @@ - 0 + 50 0 + + + 50 + 16777215 + + Range (dB) QComboBox::AdjustToContents + + + 100 + + + + + 50 + + + + + 5 + + - + - 24 - 24 + 50 + 0 - 24 - 24 + 50 + 16777215 - Clear spectrum histogram - - - - - - - :/clear.png:/clear.png - - - - 16 - 16 - + Averaging type + + + Mov + + + + + Fix + + - + + + + 50 + 0 + + - 24 - 24 + 50 + 16777215 - Trace intensity - - - 100 - - - 1 - - - 50 + Number of averaging samples + + + 0 + + + + + 2 + + + + + 5 + + + + + 10 + + + + + 20 + + + + + 50 + + + + + 100 + + + + + 200 + + + + + 500 + + + + + 1k + +