From bf62693093a4b9907335db98d5e548df20682bcd Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 23 Feb 2021 01:06:25 +0100 Subject: [PATCH] DATV demod: implemented gauge meters for MER and CNR. Implements #784 --- plugins/channelrx/demoddatv/datvdemod.h | 2 + .../channelrx/demoddatv/datvdemodbaseband.h | 2 + plugins/channelrx/demoddatv/datvdemodgui.cpp | 11 +- plugins/channelrx/demoddatv/datvdemodgui.ui | 101 ++++++++++++++---- plugins/channelrx/demoddatv/datvdemodsink.cpp | 26 +++-- plugins/channelrx/demoddatv/datvdemodsink.h | 11 +- plugins/channelrx/demoddatv/datvgauge.h | 83 ++++++++++++++ 7 files changed, 204 insertions(+), 32 deletions(-) create mode 100644 plugins/channelrx/demoddatv/datvgauge.h diff --git a/plugins/channelrx/demoddatv/datvdemod.h b/plugins/channelrx/demoddatv/datvdemod.h index ee5029399..42b1e19a6 100644 --- a/plugins/channelrx/demoddatv/datvdemod.h +++ b/plugins/channelrx/demoddatv/datvdemod.h @@ -68,6 +68,8 @@ public: void SetTVScreen(TVScreen *objScreen) { m_basebandSink->setTVScreen(objScreen); } void setMERLabel(QLabel *merLabel) { m_basebandSink->setMERLabel(merLabel); } void setCNRLabel(QLabel *cnrLabel) { m_basebandSink->setCNRLabel(cnrLabel); } + void setMERMeter(LevelMeterSignalDB *merMeter) { m_basebandSink->setMERMeter(merMeter); } + void setCNRMeter(LevelMeterSignalDB *cnrMeter) { m_basebandSink->setCNRMeter(cnrMeter); } DATVideostream *SetVideoRender(DATVideoRender *objScreen) { return m_basebandSink->SetVideoRender(objScreen); } bool audioActive() { return m_basebandSink->audioActive(); } bool audioDecodeOK() { return m_basebandSink->audioDecodeOK(); } diff --git a/plugins/channelrx/demoddatv/datvdemodbaseband.h b/plugins/channelrx/demoddatv/datvdemodbaseband.h index 2a923ffc0..3b456fbbd 100644 --- a/plugins/channelrx/demoddatv/datvdemodbaseband.h +++ b/plugins/channelrx/demoddatv/datvdemodbaseband.h @@ -88,6 +88,8 @@ public: void setTVScreen(TVScreen *tvScreen) { m_sink.setTVScreen(tvScreen); } void setMERLabel(QLabel *merLabel) { m_sink.setMERLabel(merLabel); } void setCNRLabel(QLabel *cnrLabel) { m_sink.setCNRLabel(cnrLabel); } + void setMERMeter(LevelMeterSignalDB *merMeter) { m_sink.setMERMeter(merMeter); } + void setCNRMeter(LevelMeterSignalDB *cnrMeter) { m_sink.setCNRMeter(cnrMeter); } void setMessageQueueToGUI(MessageQueue *messageQueue) { m_sink.setMessageQueueToGUI(messageQueue); } void setBasebandSampleRate(int sampleRate); //!< To be used when supporting thread is stopped DATVideostream *SetVideoRender(DATVideoRender *objScreen) { return m_sink.SetVideoRender(objScreen); } diff --git a/plugins/channelrx/demoddatv/datvdemodgui.cpp b/plugins/channelrx/demoddatv/datvdemodgui.cpp index 7e9a58fb4..89287cb56 100644 --- a/plugins/channelrx/demoddatv/datvdemodgui.cpp +++ b/plugins/channelrx/demoddatv/datvdemodgui.cpp @@ -191,12 +191,22 @@ DATVDemodGUI::DATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet, Ba connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &))); connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); + ui->merMeter->setColorTheme(LevelMeterSignalDB::ColorCyanAndBlue); + ui->merMeter->setRange(0, 30); + ui->merMeter->setAverageSmoothing(2); + + ui->cnrMeter->setColorTheme(LevelMeterSignalDB::ColorGreenAndBlue); + ui->cnrMeter->setRange(0, 30); + ui->cnrMeter->setAverageSmoothing(2); + m_objDATVDemod = (DATVDemod*) rxChannel; m_objDATVDemod->setMessageQueueToGUI(getInputMessageQueue()); m_objDATVDemod->SetTVScreen(ui->screenTV); m_objDATVDemod->setMERLabel(ui->merText); m_objDATVDemod->setCNRLabel(ui->cnrText); + m_objDATVDemod->setMERMeter(ui->merMeter); + m_objDATVDemod->setCNRMeter(ui->cnrMeter); connect(m_objDATVDemod->SetVideoRender(ui->screenTV_2), &DATVideostream::onDataPackets, this, &DATVDemodGUI::on_StreamDataAvailable); connect(ui->screenTV_2, &DATVideoRender::onMetaDataChanged, this, &DATVDemodGUI::on_StreamMetaDataChanged); @@ -240,7 +250,6 @@ DATVDemodGUI::DATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet, Ba CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute); connect(audioMuteRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioSelect())); - resetToDefaults(); // does applySettings() } diff --git a/plugins/channelrx/demoddatv/datvdemodgui.ui b/plugins/channelrx/demoddatv/datvdemodgui.ui index aa3e76eab..cdbc4f65e 100644 --- a/plugins/channelrx/demoddatv/datvdemodgui.ui +++ b/plugins/channelrx/demoddatv/datvdemodgui.ui @@ -7,7 +7,7 @@ 0 0 530 - 444 + 476 @@ -188,7 +188,7 @@ 0 40 526 - 400 + 431 @@ -735,8 +735,8 @@ - 10 - 260 + 0 + 310 481 33 @@ -828,13 +828,16 @@ - 10 - 300 + 0 + 250 481 31 - + + + 6 + @@ -842,6 +845,31 @@ + + + + + 0 + 0 + + + + + 180 + 24 + + + + + Liberation Mono + 8 + + + + SNR estimation + + + @@ -858,6 +886,21 @@ + + + + + + 0 + 280 + 481 + 31 + + + + + 6 + @@ -865,6 +908,31 @@ + + + + + 0 + 0 + + + + + 180 + 24 + + + + + Liberation Mono + 8 + + + + SNR estimation + + + @@ -881,19 +949,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -1199,6 +1254,12 @@ QToolButton
gui/buttonswitch.h
+ + LevelMeterSignalDB + QWidget +
gui/levelmeter.h
+ 1 +
diff --git a/plugins/channelrx/demoddatv/datvdemodsink.cpp b/plugins/channelrx/demoddatv/datvdemodsink.cpp index 4e36c05ac..77b108d1f 100644 --- a/plugins/channelrx/demoddatv/datvdemodsink.cpp +++ b/plugins/channelrx/demoddatv/datvdemodsink.cpp @@ -39,6 +39,8 @@ DATVDemodSink::DATVDemodSink() : m_objRenderThread(nullptr), m_merLabel(nullptr), m_cnrLabel(nullptr), + m_merMeter(nullptr), + m_cnrMeter(nullptr), m_audioFifo(48000), m_blnRenderingVideo(false), m_blnStartStopVideo(false), @@ -96,6 +98,14 @@ void DATVDemodSink::setCNRLabel(QLabel *cnrLabel) { m_cnrLabel = cnrLabel; } +void DATVDemodSink::setMERMeter(LevelMeterSignalDB *merMeter) { + m_merMeter = merMeter; +} + +void DATVDemodSink::setCNRMeter(LevelMeterSignalDB *cnrMeter) { + m_cnrMeter = cnrMeter; +} + DATVideostream *DATVDemodSink::SetVideoRender(DATVideoRender *objScreen) { m_objRegisteredVideoRender = objScreen; @@ -783,12 +793,12 @@ void DATVDemodSink::InitDATVFramework() r_scope_symbols->calculate_cstln_points(); } - if (m_merLabel) { - r_merGauge = new leansdr::datvgaugelabel(m_objScheduler, *p_mer, m_merLabel); + if (m_merLabel && m_merMeter) { + r_merGauge = new leansdr::datvgauge(m_objScheduler, *p_mer, m_merLabel, m_merMeter); } - if (m_cnrLabel) { - r_cnrGauge = new leansdr::datvgaugelabel(m_objScheduler, *p_cnr, m_cnrLabel); + if (m_cnrLabel && m_cnrMeter) { + r_cnrGauge = new leansdr::datvgauge(m_objScheduler, *p_cnr, m_cnrLabel, m_cnrMeter); } // DECONVOLUTION AND SYNCHRONIZATION @@ -1095,12 +1105,12 @@ void DATVDemodSink::InitDATVS2Framework() r_scope_symbols_dvbs2->calculate_cstln_points(); } - if (m_merLabel) { - r_merGauge = new leansdr::datvgaugelabel(m_objScheduler, *p_mer, m_merLabel); + if (m_merLabel && m_merMeter) { + r_merGauge = new leansdr::datvgauge(m_objScheduler, *p_mer, m_merLabel, m_merMeter); } - if (m_cnrLabel) { - r_cnrGauge = new leansdr::datvgaugelabel(m_objScheduler, *p_cnr, m_cnrLabel); + if (m_cnrLabel && m_cnrMeter) { + r_cnrGauge = new leansdr::datvgauge(m_objScheduler, *p_cnr, m_cnrLabel, m_cnrMeter); } // Bit-flipping mode. diff --git a/plugins/channelrx/demoddatv/datvdemodsink.h b/plugins/channelrx/demoddatv/datvdemodsink.h index 7d7ccffb0..7bdfb4922 100644 --- a/plugins/channelrx/demoddatv/datvdemodsink.h +++ b/plugins/channelrx/demoddatv/datvdemodsink.h @@ -28,7 +28,7 @@ #include "leansdr/iess.h" #include "datvconstellation.h" -#include "datvgaugelabel.h" +#include "datvgauge.h" #include "datvdvbs2constellation.h" #include "datvvideoplayer.h" #include "datvideostream.h" @@ -49,6 +49,7 @@ class TVScreen; class DATVideoRender; class QLabel; +class LevelMeterSignalDB; class DATVDemodSink : public ChannelSampleSink { public: @@ -60,6 +61,8 @@ public: bool setTVScreen(TVScreen *objScreen); void setMERLabel(QLabel *merLabel); void setCNRLabel(QLabel *cnrLabel); + void setMERMeter(LevelMeterSignalDB *merMeter); + void setCNRMeter(LevelMeterSignalDB *cnrMeter); DATVideostream * SetVideoRender(DATVideoRender *objScreen); bool audioActive(); bool audioDecodeOK(); @@ -275,8 +278,8 @@ private: //CONSTELLATION leansdr::datvconstellation *r_scope_symbols; leansdr::datvdvbs2constellation *r_scope_symbols_dvbs2; - leansdr::datvgaugelabel *r_merGauge; - leansdr::datvgaugelabel *r_cnrGauge; + leansdr::datvgauge *r_merGauge; + leansdr::datvgauge *r_cnrGauge; //*************** DATV PARAMETERS *************** TVScreen *m_objRegisteredTVScreen; @@ -286,6 +289,8 @@ private: DATVideoRenderThread *m_objRenderThread; QLabel *m_merLabel; QLabel *m_cnrLabel; + LevelMeterSignalDB *m_merMeter; + LevelMeterSignalDB *m_cnrMeter; // Audio AudioFifo m_audioFifo; diff --git a/plugins/channelrx/demoddatv/datvgauge.h b/plugins/channelrx/demoddatv/datvgauge.h new file mode 100644 index 000000000..f283674f7 --- /dev/null +++ b/plugins/channelrx/demoddatv/datvgauge.h @@ -0,0 +1,83 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2021 Edouard Griffiths, F4EXB // +// using LeanSDR Framework (C) 2016 F4DAV // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef DATVGAUGE_H +#define DATVGAUGE_H + +#include +#include + +#include "leansdr/framework.h" +#include "leansdr/sdr.h" + +#include "gui/levelmeter.h" + +namespace leansdr { + +struct datvgauge: runnable +{ + leansdr::pipereader m_in; + QLabel *m_label; + LevelMeterSignalDB *m_levelMeter; + static const int m_nbAvg = 5; + leansdr::f32 m_samples[m_nbAvg]; + leansdr::f32 m_sum; + int m_index; + + datvgauge( + scheduler *sch, + leansdr::pipebuf &in, + QLabel *label = nullptr, + LevelMeterSignalDB *levelMeter = nullptr, + const char *_name = nullptr + ) : + runnable(sch, _name ? _name : in.name), + m_in(in), + m_label(label), + m_levelMeter(levelMeter) + { + std::fill(m_samples, m_samples+m_nbAvg, 0); + m_sum = 0; + m_index = 0; + } + + virtual void run() + { + while (m_in.readable() >= 1) + { + leansdr::f32 *p = m_in.rd(); + leansdr::f32& oldest = m_samples[m_index++]; + m_sum += *p - oldest; + oldest = *p; + leansdr::f32 avg = m_sum/m_nbAvg; + m_index = (m_index + 1) % m_nbAvg; + + m_levelMeter->levelChanged(avg/30.0, *p/30.0, m_nbAvg); + m_label->setText(QString("%1").arg(avg, 0, 'f', 1)); + m_in.read(1); + + if (m_index == m_nbAvg) { + m_index = 0; + } + } + } +}; + +} // namespace leansdr + +#endif // DATVGAUGE_H