summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorf4exb <f4exb06@gmail.com>2024-05-23 18:51:54 +0200
committerf4exb <f4exb06@gmail.com>2024-05-23 18:51:54 +0200
commit4d5958f6304a1eefe231bdbafc90920b4b67e9d3 (patch)
tree930a02b3a844757cd8b603698c6684bc3ad97480
parent5841290df433549ebdcaa274f19e432defec8a0e (diff)
Morse Decoder: added option to show decoder thershold trace or not
-rw-r--r--doc/img/MorseDecoder_M.pngbin0 -> 2749 bytes
-rw-r--r--doc/img/MorseDecoder_Mag.pngbin0 -> 5264 bytes
-rw-r--r--doc/img/MorseDecoder_X.pngbin0 -> 4137 bytes
-rw-r--r--doc/img/MorseDecoder_Y.pngbin0 -> 4028 bytes
-rw-r--r--doc/img/MorseDecoder_plugin.pngbin73505 -> 74126 bytes
-rw-r--r--doc/img/MorseDecoder_plugin.xcfbin354430 -> 363026 bytes
-rw-r--r--plugins/feature/morsedecoder/morsedecoder.cpp4
-rw-r--r--plugins/feature/morsedecoder/morsedecodergui.cpp9
-rw-r--r--plugins/feature/morsedecoder/morsedecodergui.h1
-rw-r--r--plugins/feature/morsedecoder/morsedecodergui.ui36
-rw-r--r--plugins/feature/morsedecoder/morsedecodersettings.cpp9
-rw-r--r--plugins/feature/morsedecoder/morsedecodersettings.h1
-rw-r--r--plugins/feature/morsedecoder/morsedecoderworker.cpp2
-rw-r--r--plugins/feature/morsedecoder/readme.md21
-rw-r--r--sdrbase/resources/webapi/doc/html2/index.html6
-rw-r--r--sdrbase/resources/webapi/doc/swagger/include/MorseDecoder.yaml6
-rw-r--r--swagger/sdrangel/api/swagger/include/MorseDecoder.yaml6
-rw-r--r--swagger/sdrangel/code/html2/index.html6
-rw-r--r--swagger/sdrangel/code/qt5/client/SWGMorseDecoderSettings.cpp23
-rw-r--r--swagger/sdrangel/code/qt5/client/SWGMorseDecoderSettings.h6
20 files changed, 123 insertions, 13 deletions
diff --git a/doc/img/MorseDecoder_M.png b/doc/img/MorseDecoder_M.png
new file mode 100644
index 000000000..0ad0af60b
--- /dev/null
+++ b/doc/img/MorseDecoder_M.png
Binary files differ
diff --git a/doc/img/MorseDecoder_Mag.png b/doc/img/MorseDecoder_Mag.png
new file mode 100644
index 000000000..aeb75799d
--- /dev/null
+++ b/doc/img/MorseDecoder_Mag.png
Binary files differ
diff --git a/doc/img/MorseDecoder_X.png b/doc/img/MorseDecoder_X.png
new file mode 100644
index 000000000..c563789dd
--- /dev/null
+++ b/doc/img/MorseDecoder_X.png
Binary files differ
diff --git a/doc/img/MorseDecoder_Y.png b/doc/img/MorseDecoder_Y.png
new file mode 100644
index 000000000..d3a44c918
--- /dev/null
+++ b/doc/img/MorseDecoder_Y.png
Binary files differ
diff --git a/doc/img/MorseDecoder_plugin.png b/doc/img/MorseDecoder_plugin.png
index 728e32c06..da6045ab6 100644
--- a/doc/img/MorseDecoder_plugin.png
+++ b/doc/img/MorseDecoder_plugin.png
Binary files differ
diff --git a/doc/img/MorseDecoder_plugin.xcf b/doc/img/MorseDecoder_plugin.xcf
index 5698911b3..f2adbae76 100644
--- a/doc/img/MorseDecoder_plugin.xcf
+++ b/doc/img/MorseDecoder_plugin.xcf
Binary files differ
diff --git a/plugins/feature/morsedecoder/morsedecoder.cpp b/plugins/feature/morsedecoder/morsedecoder.cpp
index e380f9592..a8c324089 100644
--- a/plugins/feature/morsedecoder/morsedecoder.cpp
+++ b/plugins/feature/morsedecoder/morsedecoder.cpp
@@ -526,6 +526,7 @@ void MorseDecoder::webapiFormatFeatureSettings(
response.getMorseDecoderSettings()->setLogEnabled(settings.m_logEnabled ? 1 : 0);
response.getMorseDecoderSettings()->setAuto(settings.m_auto ? 1 : 0);
+ response.getMorseDecoderSettings()->setShowThreshold(settings.m_showThreshold ? 1 : 0);
if (settings.m_scopeGUI)
{
@@ -600,6 +601,9 @@ void MorseDecoder::webapiUpdateFeatureSettings(
if (featureSettingsKeys.contains("auto")) {
settings.m_auto = response.getMorseDecoderSettings()->getAuto() != 0;
}
+ if (featureSettingsKeys.contains("showThreshold")) {
+ settings.m_showThreshold = response.getMorseDecoderSettings()->getShowThreshold() != 0;
+ }
if (settings.m_scopeGUI && featureSettingsKeys.contains("scopeGUI")) {
settings.m_scopeGUI->updateFrom(featureSettingsKeys, response.getMorseDecoderSettings()->getScopeConfig());
}
diff --git a/plugins/feature/morsedecoder/morsedecodergui.cpp b/plugins/feature/morsedecoder/morsedecodergui.cpp
index adb574fc1..500a129b2 100644
--- a/plugins/feature/morsedecoder/morsedecodergui.cpp
+++ b/plugins/feature/morsedecoder/morsedecodergui.cpp
@@ -242,6 +242,7 @@ void MorseDecoderGUI::displaySettings()
blockApplySettings(true);
getRollupContents()->restoreState(m_rollupState);
ui->statLock->setChecked(!m_settings.m_auto);
+ ui->showThreshold->setChecked(m_settings.m_showThreshold);
ui->logFilename->setToolTip(QString(".txt log filename: %1").arg(m_settings.m_logFilename));
ui->logEnable->setChecked(m_settings.m_logEnabled);
blockApplySettings(false);
@@ -356,6 +357,13 @@ void MorseDecoderGUI::on_statLock_toggled(bool checked)
applySettings();
}
+void MorseDecoderGUI::on_showThreshold_clicked(bool checked)
+{
+ m_settings.m_showThreshold = checked;
+ m_settingsKeys.append("showThreshold");
+ applySettings();
+}
+
void MorseDecoderGUI::on_logEnable_clicked(bool checked)
{
m_settings.m_logEnabled = checked;
@@ -437,6 +445,7 @@ void MorseDecoderGUI::makeUIConnections()
QObject::connect(ui->channels, qOverload<int>(&QComboBox::currentIndexChanged), this, &MorseDecoderGUI::on_channels_currentIndexChanged);
QObject::connect(ui->channelApply, &QPushButton::clicked, this, &MorseDecoderGUI::on_channelApply_clicked);
QObject::connect(ui->statLock, &QToolButton::toggled, this, &MorseDecoderGUI::on_statLock_toggled);
+ QObject::connect(ui->showThreshold, &ButtonSwitch::clicked, this, &MorseDecoderGUI::on_showThreshold_clicked);
QObject::connect(ui->logEnable, &ButtonSwitch::clicked, this, &MorseDecoderGUI::on_logEnable_clicked);
QObject::connect(ui->logFilename, &QToolButton::clicked, this, &MorseDecoderGUI::on_logFilename_clicked);
QObject::connect(ui->clearTable, &QPushButton::clicked, this, &MorseDecoderGUI::on_clearTable_clicked);
diff --git a/plugins/feature/morsedecoder/morsedecodergui.h b/plugins/feature/morsedecoder/morsedecodergui.h
index a5035c43b..9da8e01d6 100644
--- a/plugins/feature/morsedecoder/morsedecodergui.h
+++ b/plugins/feature/morsedecoder/morsedecodergui.h
@@ -92,6 +92,7 @@ private slots:
void on_channels_currentIndexChanged(int index);
void on_channelApply_clicked();
void on_statLock_toggled(bool checked);
+ void on_showThreshold_clicked(bool checked);
void on_clearTable_clicked();
void on_logEnable_clicked(bool checked=false);
void on_logFilename_clicked();
diff --git a/plugins/feature/morsedecoder/morsedecodergui.ui b/plugins/feature/morsedecoder/morsedecodergui.ui
index 018e87276..8d1592be5 100644
--- a/plugins/feature/morsedecoder/morsedecodergui.ui
+++ b/plugins/feature/morsedecoder/morsedecodergui.ui
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>422</width>
+ <width>492</width>
<height>754</height>
</rect>
</property>
@@ -18,7 +18,7 @@
</property>
<property name="minimumSize">
<size>
- <width>422</width>
+ <width>492</width>
<height>407</height>
</size>
</property>
@@ -36,13 +36,13 @@
<rect>
<x>0</x>
<y>10</y>
- <width>420</width>
+ <width>490</width>
<height>121</height>
</rect>
</property>
<property name="minimumSize">
<size>
- <width>420</width>
+ <width>490</width>
<height>0</height>
</size>
</property>
@@ -349,6 +349,26 @@
</widget>
</item>
<item>
+ <widget class="ButtonSwitch" name="showThreshold">
+ <property name="minimumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Show GGMorse decoder threshold on scope imaginary trace</string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../../../sdrgui/resources/res.qrc">
+ <normaloff>:/slopep_icon.png</normaloff>:/slopep_icon.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -421,7 +441,7 @@
<rect>
<x>0</x>
<y>130</y>
- <width>420</width>
+ <width>490</width>
<height>271</height>
</rect>
</property>
@@ -433,7 +453,7 @@
</property>
<property name="minimumSize">
<size>
- <width>420</width>
+ <width>490</width>
<height>0</height>
</size>
</property>
@@ -451,13 +471,13 @@
<rect>
<x>10</x>
<y>400</y>
- <width>420</width>
+ <width>490</width>
<height>341</height>
</rect>
</property>
<property name="minimumSize">
<size>
- <width>420</width>
+ <width>490</width>
<height>0</height>
</size>
</property>
diff --git a/plugins/feature/morsedecoder/morsedecodersettings.cpp b/plugins/feature/morsedecoder/morsedecodersettings.cpp
index 94a028f4a..c07d07979 100644
--- a/plugins/feature/morsedecoder/morsedecodersettings.cpp
+++ b/plugins/feature/morsedecoder/morsedecodersettings.cpp
@@ -52,6 +52,7 @@ void MorseDecoderSettings::resetToDefaults()
m_logFilename = "cw_log.txt";
m_logEnabled = false;
m_auto = true;
+ m_showThreshold = false;
}
QByteArray MorseDecoderSettings::serialize() const
@@ -83,6 +84,7 @@ QByteArray MorseDecoderSettings::serialize() const
s.writeString(25, m_logFilename);
s.writeBool(26, m_logEnabled);
s.writeBool(27, m_auto);
+ s.writeBool(28, m_showThreshold);
return s.final();
}
@@ -148,6 +150,7 @@ bool MorseDecoderSettings::deserialize(const QByteArray& data)
d.readString(25, &m_logFilename, "cw_log.txt");
d.readBool(26, &m_logEnabled, false);
d.readBool(27, &m_auto, true);
+ d.readBool(28, &m_showThreshold, false);
return true;
}
@@ -202,6 +205,9 @@ void MorseDecoderSettings::applySettings(const QStringList& settingsKeys, const
if (settingsKeys.contains("auto")) {
m_auto = settings.m_auto;
}
+ if (settingsKeys.contains("showThreshold")) {
+ m_showThreshold = settings.m_showThreshold;
+ }
if (settingsKeys.contains("logEnabled")) {
m_logEnabled = settings.m_logEnabled;
}
@@ -256,6 +262,9 @@ QString MorseDecoderSettings::getDebugString(const QStringList& settingsKeys, bo
if (settingsKeys.contains("auto") || force) {
ostr << " m_auto: " << m_auto;
}
+ if (settingsKeys.contains("showThreshold") || force) {
+ ostr << " m_showThreshold: " << m_showThreshold;
+ }
if (settingsKeys.contains("logEnabled") || force) {
ostr << " m_logEnabled: " << m_logEnabled;
}
diff --git a/plugins/feature/morsedecoder/morsedecodersettings.h b/plugins/feature/morsedecoder/morsedecodersettings.h
index a6b39454a..f83b119a0 100644
--- a/plugins/feature/morsedecoder/morsedecodersettings.h
+++ b/plugins/feature/morsedecoder/morsedecodersettings.h
@@ -42,6 +42,7 @@ struct MorseDecoderSettings
QString m_logFilename;
bool m_logEnabled;
bool m_auto; //!< Auto pitch and speed
+ bool m_showThreshold; //!< Show decoder threshold on scope imaginary trace
MorseDecoderSettings();
void resetToDefaults();
diff --git a/plugins/feature/morsedecoder/morsedecoderworker.cpp b/plugins/feature/morsedecoder/morsedecoderworker.cpp
index 297ced2fb..bfa1655fc 100644
--- a/plugins/feature/morsedecoder/morsedecoderworker.cpp
+++ b/plugins/feature/morsedecoder/morsedecoderworker.cpp
@@ -229,7 +229,7 @@ int MorseDecoderWorker::processBuffer(QByteArray& bytesBuffer)
int itrace = ftrace * i;
int ithres = fthres * i;
float re = trace[itrace];
- float im = thresholds[ithres];
+ float im = m_settings.m_showThreshold ? thresholds[ithres] : 3.16227766017e-2; // -30dB
i++;
s = Sample(re*SDR_RX_SCALEF, im*SDR_RX_SCALEF);
}
diff --git a/plugins/feature/morsedecoder/readme.md b/plugins/feature/morsedecoder/readme.md
index 68ec78417..299fb3bfb 100644
--- a/plugins/feature/morsedecoder/readme.md
+++ b/plugins/feature/morsedecoder/readme.md
@@ -65,7 +65,11 @@ Lock the pitch and speed to the current values detected by GGMorse. Unlock to re
<h3>11: Decoder cost factor</h3>
-This is the GGMorse decoder cost factor. Successful decodes yield to just a few millis.
+This is the GGMorse decoder cost factor. Successful decodes yield from a few millis to a few tens of millis.
+
+<h3>11a: Show decoder theshold</h3>
+
+Enable or disable the GGMorse decoder threshold display on the imaginary trace of the scope.
<h3>12: Start/stop Logging Messages to .txt file</h3>
@@ -88,6 +92,19 @@ This area shows the decoded text. New text appears every 3 seconds which is the
This scope display shows waveforms related to the decoding with GGMorse.
* On the real part it shows the average output of the Goertzel filter as exposed by GGMorse and that is used for decoding.
- * On the imaginary part it shows the threshold level being used in GGMorse for decoding. It is not necessary on the same scale as the Goertzel output.
+ * On the imaginary part
+ * When the show decoder threshold is set (11a) it shows the threshold level being used in GGMorse for decoding. It is not necessary on the same scale as the Goertzel output.
+ * When the show decoder threshold is not set (11a) a constant 0.0316227766017 is applied which corresponds to a power of -30 dB.
The elemetary trace length is 3 seconds. This is the time window used by GGMorse thus a new trace appears every 3 seconds. The actual traces are interpolated to fit in the 4800 samples of the elementary trace. Thus the sample rate is a fixed 1.6 kS/s.
+
+The best settings to visualize the Goertzel waveform is the following:
+
+* For "Real" (X) and "Imag" (Y) display mode:
+ * For the X trace (real): ![Morse decoder X settings](../../../doc/img/MorseDecoder_X.png)
+ * For the Y trace (imag): ![Morse decoder Y settings](../../../doc/img/MorseDecoder_Y.png)
+
+
+* For "MagDB" display mode (X trace): ![Morse decoder Mag settings](../../../doc/img/MorseDecoder_Mag.png)
+
+Note: the scope display has memories so you can come back to previous waveforms using the "M" dial button: ![Morse decoder memorise](../../../doc/img/MorseDecoder_M.png). You can also save and load traces.
diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html
index 5c6e0d0a5..15bab9f4e 100644
--- a/sdrbase/resources/webapi/doc/html2/index.html
+++ b/sdrbase/resources/webapi/doc/html2/index.html
@@ -10557,6 +10557,10 @@ margin-bottom: 20px;
"type" : "integer",
"description" : "Auto detect CW pitch and keying speed\n * 1 - auto detect\n * 0 - use last values\n"
},
+ "showThreshold" : {
+ "type" : "integer",
+ "description" : "Show GGMorse decoder threshold on the imaginary part of the scope trace\n * 1 - show\n * 0 - do not show\n"
+ },
"reverseAPIFeatureSetIndex" : {
"type" : "integer"
},
@@ -59052,7 +59056,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
- Generated 2024-05-21T02:18:43.789+02:00
+ Generated 2024-05-23T18:36:35.471+02:00
</div>
</div>
</div>
diff --git a/sdrbase/resources/webapi/doc/swagger/include/MorseDecoder.yaml b/sdrbase/resources/webapi/doc/swagger/include/MorseDecoder.yaml
index e7d88a8a2..ff4396559 100644
--- a/sdrbase/resources/webapi/doc/swagger/include/MorseDecoder.yaml
+++ b/sdrbase/resources/webapi/doc/swagger/include/MorseDecoder.yaml
@@ -42,6 +42,12 @@ MorseDecoderSettings:
Auto detect CW pitch and keying speed
* 1 - auto detect
* 0 - use last values
+ showThreshold:
+ type: integer
+ description: >
+ Show GGMorse decoder threshold on the imaginary part of the scope trace
+ * 1 - show
+ * 0 - do not show
reverseAPIFeatureSetIndex:
type: integer
reverseAPIFeatureIndex:
diff --git a/swagger/sdrangel/api/swagger/include/MorseDecoder.yaml b/swagger/sdrangel/api/swagger/include/MorseDecoder.yaml
index eb2b10cc6..623ae8a5c 100644
--- a/swagger/sdrangel/api/swagger/include/MorseDecoder.yaml
+++ b/swagger/sdrangel/api/swagger/include/MorseDecoder.yaml
@@ -42,6 +42,12 @@ MorseDecoderSettings:
Auto detect CW pitch and keying speed
* 1 - auto detect
* 0 - use last values
+ showThreshold:
+ type: integer
+ description: >
+ Show GGMorse decoder threshold on the imaginary part of the scope trace
+ * 1 - show
+ * 0 - do not show
reverseAPIFeatureSetIndex:
type: integer
reverseAPIFeatureIndex:
diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html
index 5c6e0d0a5..15bab9f4e 100644
--- a/swagger/sdrangel/code/html2/index.html
+++ b/swagger/sdrangel/code/html2/index.html
@@ -10557,6 +10557,10 @@ margin-bottom: 20px;
"type" : "integer",
"description" : "Auto detect CW pitch and keying speed\n * 1 - auto detect\n * 0 - use last values\n"
},
+ "showThreshold" : {
+ "type" : "integer",
+ "description" : "Show GGMorse decoder threshold on the imaginary part of the scope trace\n * 1 - show\n * 0 - do not show\n"
+ },
"reverseAPIFeatureSetIndex" : {
"type" : "integer"
},
@@ -59052,7 +59056,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
- Generated 2024-05-21T02:18:43.789+02:00
+ Generated 2024-05-23T18:36:35.471+02:00
</div>
</div>
</div>
diff --git a/swagger/sdrangel/code/qt5/client/SWGMorseDecoderSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGMorseDecoderSettings.cpp
index 8bcbf0d12..ced5d223c 100644
--- a/swagger/sdrangel/code/qt5/client/SWGMorseDecoderSettings.cpp
+++ b/swagger/sdrangel/code/qt5/client/SWGMorseDecoderSettings.cpp
@@ -50,6 +50,8 @@ SWGMorseDecoderSettings::SWGMorseDecoderSettings() {
m_log_enabled_isSet = false;
_auto = 0;
m__auto_isSet = false;
+ show_threshold = 0;
+ m_show_threshold_isSet = false;
reverse_api_feature_set_index = 0;
m_reverse_api_feature_set_index_isSet = false;
reverse_api_feature_index = 0;
@@ -88,6 +90,8 @@ SWGMorseDecoderSettings::init() {
m_log_enabled_isSet = false;
_auto = 0;
m__auto_isSet = false;
+ show_threshold = 0;
+ m_show_threshold_isSet = false;
reverse_api_feature_set_index = 0;
m_reverse_api_feature_set_index_isSet = false;
reverse_api_feature_index = 0;
@@ -121,6 +125,7 @@ SWGMorseDecoderSettings::cleanup() {
+
if(scope_config != nullptr) {
delete scope_config;
}
@@ -162,6 +167,8 @@ SWGMorseDecoderSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&_auto, pJson["auto"], "qint32", "");
+ ::SWGSDRangel::setValue(&show_threshold, pJson["showThreshold"], "qint32", "");
+
::SWGSDRangel::setValue(&reverse_api_feature_set_index, pJson["reverseAPIFeatureSetIndex"], "qint32", "");
::SWGSDRangel::setValue(&reverse_api_feature_index, pJson["reverseAPIFeatureIndex"], "qint32", "");
@@ -219,6 +226,9 @@ SWGMorseDecoderSettings::asJsonObject() {
if(m__auto_isSet){
obj->insert("auto", QJsonValue(_auto));
}
+ if(m_show_threshold_isSet){
+ obj->insert("showThreshold", QJsonValue(show_threshold));
+ }
if(m_reverse_api_feature_set_index_isSet){
obj->insert("reverseAPIFeatureSetIndex", QJsonValue(reverse_api_feature_set_index));
}
@@ -346,6 +356,16 @@ SWGMorseDecoderSettings::setAuto(qint32 _auto) {
}
qint32
+SWGMorseDecoderSettings::getShowThreshold() {
+ return show_threshold;
+}
+void
+SWGMorseDecoderSettings::setShowThreshold(qint32 show_threshold) {
+ this->show_threshold = show_threshold;
+ this->m_show_threshold_isSet = true;
+}
+
+qint32
SWGMorseDecoderSettings::getReverseApiFeatureSetIndex() {
return reverse_api_feature_set_index;
}
@@ -423,6 +443,9 @@ SWGMorseDecoderSettings::isSet(){
if(m__auto_isSet){
isObjectUpdated = true; break;
}
+ if(m_show_threshold_isSet){
+ isObjectUpdated = true; break;
+ }
if(m_reverse_api_feature_set_index_isSet){
isObjectUpdated = true; break;
}
diff --git a/swagger/sdrangel/code/qt5/client/SWGMorseDecoderSettings.h b/swagger/sdrangel/code/qt5/client/SWGMorseDecoderSettings.h
index 1e2fd98b9..e7fac5e14 100644
--- a/swagger/sdrangel/code/qt5/client/SWGMorseDecoderSettings.h
+++ b/swagger/sdrangel/code/qt5/client/SWGMorseDecoderSettings.h
@@ -77,6 +77,9 @@ public:
qint32 getAuto();
void setAuto(qint32 _auto);
+ qint32 getShowThreshold();
+ void setShowThreshold(qint32 show_threshold);
+
qint32 getReverseApiFeatureSetIndex();
void setReverseApiFeatureSetIndex(qint32 reverse_api_feature_set_index);
@@ -126,6 +129,9 @@ private:
qint32 _auto;
bool m__auto_isSet;
+ qint32 show_threshold;
+ bool m_show_threshold_isSet;
+
qint32 reverse_api_feature_set_index;
bool m_reverse_api_feature_set_index_isSet;