mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-15 12:51:49 -05:00
M17 demod: implemented BER display
This commit is contained in:
parent
c3f55af6a6
commit
fe6830e552
@ -44,7 +44,7 @@ if(NOT SERVER_MODE)
|
||||
m17statustextdialog.h
|
||||
)
|
||||
set(TARGET_NAME demodm17)
|
||||
set(TARGET_LIB "Qt5::Widgets")
|
||||
set(TARGET_LIB "Qt5::Widgets" Qt5::Charts)
|
||||
set(TARGET_LIB_GUI "sdrgui")
|
||||
set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR})
|
||||
else()
|
||||
|
@ -242,6 +242,10 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
void getBERT(uint32_t& bertErrors, uint32_t& bertBits) {
|
||||
m_basebandSink->getBERT(bertErrors, bertBits);
|
||||
}
|
||||
|
||||
uint32_t getLSFCount() const { return m_basebandSink->getLSFCount(); }
|
||||
const QString& getSrcCall() const { return m_basebandSink->getSrcCall(); }
|
||||
const QString& getDestcCall() const { return m_basebandSink->getDestcCall(); }
|
||||
|
@ -103,6 +103,10 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
void getBERT(uint32_t& bertErrors, uint32_t& bertBits) {
|
||||
m_sink.getBERT(bertErrors, bertBits);
|
||||
}
|
||||
|
||||
uint32_t getLSFCount() const { return m_sink.getLSFCount(); }
|
||||
const QString& getSrcCall() const { return m_sink.getSrcCall(); }
|
||||
const QString& getDestcCall() const { return m_sink.getDestcCall(); }
|
||||
|
@ -284,6 +284,22 @@ void M17DemodGUI::on_aprsClearTable_clicked()
|
||||
ui->aprsPackets->setRowCount(0);
|
||||
}
|
||||
|
||||
void M17DemodGUI::on_totButton_toggled(bool checked)
|
||||
{
|
||||
m_showBERTotalOrCurrent = checked;
|
||||
ui->curButton->blockSignals(true);
|
||||
ui->curButton->setChecked(!checked);
|
||||
ui->curButton->blockSignals(false);
|
||||
}
|
||||
|
||||
void M17DemodGUI::on_curButton_toggled(bool checked)
|
||||
{
|
||||
m_showBERTotalOrCurrent = !checked;
|
||||
ui->totButton->blockSignals(true);
|
||||
ui->totButton->setChecked(!checked);
|
||||
ui->totButton->blockSignals(false);
|
||||
}
|
||||
|
||||
void M17DemodGUI::onWidgetRolled(QWidget* widget, bool rollDown)
|
||||
{
|
||||
(void) widget;
|
||||
@ -360,7 +376,10 @@ M17DemodGUI::M17DemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
|
||||
m_squelchOpen(false),
|
||||
m_audioSampleRate(-1),
|
||||
m_lsfCount(0),
|
||||
m_tickCount(0)
|
||||
m_tickCount(0),
|
||||
m_lastBERErrors(0),
|
||||
m_lastBERBits(0),
|
||||
m_showBERTotalOrCurrent(true)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
m_helpURL = "plugins/channelrx/demodm17/readme.md";
|
||||
@ -427,6 +446,15 @@ M17DemodGUI::M17DemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
|
||||
ui->dcdLabel->setPixmap(QIcon(":/carrier.png").pixmap(QSize(20, 20)));
|
||||
ui->lockLabel->setPixmap(QIcon(":/locked.png").pixmap(QSize(20, 20)));
|
||||
|
||||
m_berChart.setTheme(QChart::ChartThemeDark);
|
||||
m_berChart.legend()->hide();
|
||||
ui->berChart->setChart(&m_berChart);
|
||||
ui->berChart->setRenderHint(QPainter::Antialiasing);
|
||||
m_berChart.addAxis(&m_berChartXAxis, Qt::AlignBottom);
|
||||
m_berChart.addAxis(&m_berChartYAxis, Qt::AlignLeft);
|
||||
m_berChart.layout()->setContentsMargins(0, 0, 0, 0);
|
||||
m_berChart.setMargins(QMargins(1, 1, 1, 1));
|
||||
|
||||
updateMyPosition();
|
||||
displaySettings();
|
||||
makeUIConnections();
|
||||
@ -503,6 +531,9 @@ void M17DemodGUI::displaySettings()
|
||||
ui->traceDecayText->setText(QString("%1").arg(m_settings.m_traceDecay));
|
||||
m_scopeVisXY->setDecay(m_settings.m_traceDecay);
|
||||
|
||||
ui->totButton->setChecked(m_showBERTotalOrCurrent);
|
||||
ui->curButton->setChecked(!m_showBERTotalOrCurrent);
|
||||
|
||||
updateIndexLabel();
|
||||
|
||||
getRollupContents()->restoreState(m_rollupState);
|
||||
@ -665,6 +696,73 @@ void M17DemodGUI::tick()
|
||||
m_lsfCount = m_m17Demod->getLSFCount();
|
||||
}
|
||||
|
||||
if (((status == 5) || (status == 4)) && (sync_word_type == 3))
|
||||
{
|
||||
uint32_t bertErrors, bertBits;
|
||||
m_m17Demod->getBERT(bertErrors, bertBits);
|
||||
uint32_t bertErrorsDelta = bertErrors - m_lastBERErrors;
|
||||
uint32_t bertBitsDelta = bertBits - m_lastBERBits;
|
||||
m_lastBERErrors = bertErrors;
|
||||
m_lastBERBits = bertBits;
|
||||
|
||||
m_berPoints.append(BERPoint{
|
||||
QDateTime::currentDateTime(),
|
||||
bertErrors,
|
||||
bertBits,
|
||||
bertErrorsDelta,
|
||||
bertBitsDelta
|
||||
});
|
||||
m_currentErrors.append(bertErrorsDelta);
|
||||
|
||||
uint32_t maxY;
|
||||
QLineSeries *series;
|
||||
|
||||
if (m_showBERTotalOrCurrent)
|
||||
{
|
||||
ui->berCounts->setText(tr("%1/%2").arg(bertErrors).arg(bertBits));
|
||||
series = addBERSeries(true, maxY);
|
||||
|
||||
if (bertBits > 0) {
|
||||
ui->berRatio->setText(tr("%1").arg((double) bertErrors / (double) bertBits, 0, 'e', 2));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->berCounts->setText(tr("%1/%2").arg(bertErrorsDelta).arg(bertBitsDelta));
|
||||
series = addBERSeries(false, maxY);
|
||||
|
||||
if (bertBitsDelta > 0) {
|
||||
ui->berRatio->setText(tr("%1").arg((double) bertErrorsDelta / (double) bertBitsDelta, 0, 'e', 2));
|
||||
}
|
||||
}
|
||||
|
||||
if (series)
|
||||
{
|
||||
m_berChart.removeAllSeries();
|
||||
m_berChart.removeAxis(&m_berChartXAxis);
|
||||
m_berChart.removeAxis(&m_berChartYAxis);
|
||||
|
||||
m_berChart.addSeries(series);
|
||||
|
||||
m_berChartXAxis.setRange(m_berPoints.front().m_dateTime, m_berPoints.back().m_dateTime);
|
||||
m_berChartXAxis.setFormat("hh:mm:ss");
|
||||
m_berChart.addAxis(&m_berChartXAxis, Qt::AlignBottom);
|
||||
series->attachAxis(&m_berChartXAxis);
|
||||
|
||||
m_berChartYAxis.setRange(0, maxY == 0 ? 1 : maxY);
|
||||
m_berChart.addAxis(&m_berChartYAxis, Qt::AlignLeft);
|
||||
series->attachAxis(&m_berChartYAxis);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// qDebug("M17DemodGUI::tick: BER reset: status: %d sync_word_type: %d", status, sync_word_type);
|
||||
m_lastBERErrors = 0;
|
||||
m_lastBERBits = 0;
|
||||
m_berPoints.clear();
|
||||
m_currentErrors.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_tickCount++;
|
||||
@ -697,6 +795,37 @@ QString M17DemodGUI::getStatus(int status, int sync_word_type, bool streamElsePa
|
||||
}
|
||||
}
|
||||
|
||||
QLineSeries *M17DemodGUI::addBERSeries(bool total, uint32_t& maxVal)
|
||||
{
|
||||
if (m_berPoints.size() < 2) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QLineSeries *series = new QLineSeries();
|
||||
|
||||
if (!total) {
|
||||
maxVal = *std::max_element(m_currentErrors.begin(), m_currentErrors.end());
|
||||
} else {
|
||||
maxVal = m_berPoints.back().m_totalErrors;
|
||||
}
|
||||
|
||||
for (auto berPoint : m_berPoints)
|
||||
{
|
||||
double x = berPoint.m_dateTime.toMSecsSinceEpoch();
|
||||
double y;
|
||||
|
||||
if (total) {
|
||||
y = berPoint.m_totalErrors;
|
||||
} else {
|
||||
y = berPoint.m_currentErrors;
|
||||
}
|
||||
|
||||
series->append(x, y);
|
||||
}
|
||||
|
||||
return series;
|
||||
}
|
||||
|
||||
void M17DemodGUI::makeUIConnections()
|
||||
{
|
||||
QObject::connect(ui->deltaFrequency, &ValueDialZ::changed, this, &M17DemodGUI::on_deltaFrequency_changed);
|
||||
@ -714,6 +843,8 @@ void M17DemodGUI::makeUIConnections()
|
||||
QObject::connect(ui->audioMute, &QToolButton::toggled, this, &M17DemodGUI::on_audioMute_toggled);
|
||||
QObject::connect(ui->viewStatusLog, &QPushButton::clicked, this, &M17DemodGUI::on_viewStatusLog_clicked);
|
||||
QObject::connect(ui->aprsClearTable, &QPushButton::clicked, this, &M17DemodGUI::on_aprsClearTable_clicked);
|
||||
QObject::connect(ui->totButton, &ButtonSwitch::toggled, this, &M17DemodGUI::on_totButton_toggled);
|
||||
QObject::connect(ui->curButton, &ButtonSwitch::toggled, this, &M17DemodGUI::on_curButton_toggled);
|
||||
}
|
||||
|
||||
void M17DemodGUI::updateAbsoluteCenterFrequency()
|
||||
|
@ -20,6 +20,8 @@
|
||||
#define INCLUDE_M17DEMODGUI_H
|
||||
|
||||
#include <QMenu>
|
||||
#include <QtCharts>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "channel/channelgui.h"
|
||||
#include "dsp/dsptypes.h"
|
||||
@ -72,6 +74,15 @@ protected:
|
||||
void resizeEvent(QResizeEvent* size);
|
||||
|
||||
private:
|
||||
struct BERPoint
|
||||
{
|
||||
QDateTime m_dateTime;
|
||||
uint32_t m_totalErrors;
|
||||
uint32_t m_totalBits;
|
||||
uint32_t m_currentErrors;
|
||||
uint32_t m_currentBits;
|
||||
};
|
||||
|
||||
Ui::M17DemodGUI* ui;
|
||||
PluginAPI* m_pluginAPI;
|
||||
DeviceUISet* m_deviceUISet;
|
||||
@ -92,6 +103,15 @@ private:
|
||||
int m_audioSampleRate;
|
||||
uint32_t m_lsfCount;
|
||||
uint32_t m_tickCount;
|
||||
uint32_t m_lastBERErrors;
|
||||
uint32_t m_lastBERBits;
|
||||
bool m_showBERTotalOrCurrent;
|
||||
|
||||
QChart m_berChart;
|
||||
QDateTimeAxis m_berChartXAxis;
|
||||
QValueAxis m_berChartYAxis;
|
||||
QList<BERPoint> m_berPoints;
|
||||
QList<uint32_t> m_currentErrors;
|
||||
|
||||
float m_myLatitude;
|
||||
float m_myLongitude;
|
||||
@ -112,6 +132,7 @@ private:
|
||||
void updateAbsoluteCenterFrequency();
|
||||
QString getStatus(int status, int sync_word_type, bool streamElsePacket, int packetProtocol);
|
||||
void packetReceived(QByteArray packet);
|
||||
QLineSeries *addBERSeries(bool total, uint32_t& maxVal);
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(QEvent*);
|
||||
@ -131,6 +152,8 @@ private slots:
|
||||
void on_highPassFilter_toggled(bool checked);
|
||||
void on_audioMute_toggled(bool checked);
|
||||
void on_aprsClearTable_clicked();
|
||||
void on_totButton_toggled(bool checked);
|
||||
void on_curButton_toggled(bool checked);
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void onMenuDialogCalled(const QPoint& p);
|
||||
void on_viewStatusLog_clicked();
|
||||
|
@ -1634,6 +1634,150 @@
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="berTab">
|
||||
<property name="toolTip">
|
||||
<string>BER test data</string>
|
||||
</property>
|
||||
<attribute name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/ruler.png</normaloff>:/ruler.png</iconset>
|
||||
</attribute>
|
||||
<attribute name="title">
|
||||
<string/>
|
||||
</attribute>
|
||||
<attribute name="toolTip">
|
||||
<string>BER test</string>
|
||||
</attribute>
|
||||
<widget class="QLabel" name="berCounts">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>80</x>
|
||||
<y>10</y>
|
||||
<width>140</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Errors/Bits counts</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0/1000000</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="berLabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>230</x>
|
||||
<y>10</y>
|
||||
<width>30</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Total BER</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>BER</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="berRatio">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>265</x>
|
||||
<y>10</y>
|
||||
<width>85</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Bit Error Rate</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0.00e+00</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="ButtonSwitch" name="totButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>5</y>
|
||||
<width>36</width>
|
||||
<height>35</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Select total BER counts</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TOT</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="ButtonSwitch" name="curButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>5</y>
|
||||
<width>36</width>
|
||||
<height>35</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Select current BER counts</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CUR</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QChartView" name="berChart">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>43</y>
|
||||
<width>480</width>
|
||||
<height>165</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -1669,6 +1813,11 @@
|
||||
<header>gui/tvscreen.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QChartView</class>
|
||||
<extends>QGraphicsView</extends>
|
||||
<header>QtCharts</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../../sdrgui/resources/res.qrc"/>
|
||||
|
@ -92,6 +92,12 @@ public:
|
||||
viterbiCost = m_viterbiCost;
|
||||
}
|
||||
|
||||
void getBERT(uint32_t& bertErrors, uint32_t& bertBits)
|
||||
{
|
||||
bertErrors = m_prbs.errors();
|
||||
bertBits = m_prbs.bits();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> m_currentPacket;
|
||||
size_t m_packetFrameCounter;
|
||||
|
@ -105,6 +105,10 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
void getBERT(uint32_t& bertErrors, uint32_t& bertBits) {
|
||||
m_m17DemodProcessor.getBERT(bertErrors, bertBits);
|
||||
}
|
||||
|
||||
uint32_t getLSFCount() const { return m_m17DemodProcessor.getLSFCount(); }
|
||||
const QString& getSrcCall() const { return m_m17DemodProcessor.getSrcCall(); }
|
||||
const QString& getDestcCall() const { return m_m17DemodProcessor.getDestcCall(); }
|
||||
|
Loading…
Reference in New Issue
Block a user