mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 01:55:48 -05:00
commit
74977c88d3
1
.gitignore
vendored
1
.gitignore
vendored
@ -43,3 +43,4 @@ obj-x86_64-linux-gnu/*
|
||||
|
||||
/rescuesdriq/vendor/
|
||||
/rescuesdriq/Godeps/
|
||||
/.vs
|
||||
|
@ -107,6 +107,7 @@ option(ENABLE_CHANNELTX_MODATV "Enable channeltx modatv plugin" ON)
|
||||
option(ENABLE_CHANNELTX_MOD802.15.4 "Enable channeltx mod802.15.4 plugin" ON)
|
||||
option(ENABLE_CHANNELTX_REMOTESOURCE "Enable channeltx remotesource plugin" ON)
|
||||
option(ENABLE_CHANNELTX_FILESOURCE "Enable channeltx filesource plugin" ON)
|
||||
option(ENABLE_CHANNELTX_MODRTTY "Enable channeltx modrtty plugin" ON)
|
||||
|
||||
# Channel MIMO enablers
|
||||
option(ENABLE_CHANNELMIMO "Enable channelmimo plugins" ON)
|
||||
|
BIN
doc/img/RTTYMod_plugin.png
Normal file
BIN
doc/img/RTTYMod_plugin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
@ -227,6 +227,8 @@ void DSCDemodSink::receiveBit(bool bit)
|
||||
m_dscDecoder.init(m_phasingPatterns[i].m_offset);
|
||||
m_gotSOP = true;
|
||||
m_bitCount = 0;
|
||||
m_rssiMagSqSum = 0.0;
|
||||
m_rssiMagSqCount = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -329,6 +329,8 @@ void NavtexDemodSink::receiveBit(bool bit)
|
||||
m_gotSOP = true;
|
||||
m_bitCount = 0;
|
||||
m_sitorBDecoder.init();
|
||||
m_rssiMagSqSum = 0.0;
|
||||
m_rssiMagSqCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -79,7 +79,12 @@ Specifies whether bits are transmitted least-significant-bit first (LSB) or most
|
||||
|
||||
<h3>14: Mark/Space Frequency</h3>
|
||||
|
||||
When unchecked, the mark frequency is the higher frequency, when checked the space frequency is higher.
|
||||
When unchecked, the mark frequency is the higher RF frequency, when checked the space frequency is higher.
|
||||
|
||||
This should be unchecked when transmitter is using LSB AFSK and checked for USB AFSK and DWD
|
||||
[1](https://www.dwd.de/EN/specialusers/shipping/broadcast_en/brodcast_rtty_1_052014.pdf?__blob=publicationFile&v=1)
|
||||
[2](https://www.dwd.de/EN/specialusers/shipping/broadcast_en/broadcast_rtty_2_052014.pdf?__blob=publicationFile&v=1)
|
||||
shipping weather broadcasts.
|
||||
|
||||
<h3>15: Suppress CR LF</h3>
|
||||
|
||||
@ -101,3 +106,4 @@ Click to specify the name of the .txt file which received characters are logged
|
||||
|
||||
The received text area shows characters as they are received.
|
||||
|
||||
Holding the cursor over an acronym may show a tooltip with the decoded acronym.
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "plugin/pluginapi.h"
|
||||
#include "util/simpleserializer.h"
|
||||
#include "util/db.h"
|
||||
#include "util/rtty.h"
|
||||
#include "gui/basicchannelsettingsdialog.h"
|
||||
#include "gui/devicestreamselectiondialog.h"
|
||||
#include "dsp/dspengine.h"
|
||||
@ -482,6 +483,8 @@ RttyDemodGUI::RttyDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb
|
||||
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
|
||||
ui->text->addAcronyms(Rtty::m_acronyms);
|
||||
|
||||
ui->scopeContainer->setVisible(false);
|
||||
|
||||
// Hide developer only settings
|
||||
|
@ -916,7 +916,7 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="text">
|
||||
<widget class="AcronymView" name="text">
|
||||
<property name="toolTip">
|
||||
<string>Received text</string>
|
||||
</property>
|
||||
@ -1293,6 +1293,12 @@
|
||||
<header>gui/glscopegui.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>AcronymView</class>
|
||||
<extends>QTextEdit</extends>
|
||||
<header>gui/acronymview.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>deltaFrequency</tabstop>
|
||||
|
@ -154,8 +154,8 @@ void RttyDemodSink::processOneSample(Complex &ci)
|
||||
m_expIdx = (m_expIdx + 1) % m_expLength;
|
||||
//Complex exp = m_exp[m_sampleIdx];
|
||||
//qDebug() << "IQ " << real(ci) << imag(ci);
|
||||
Complex corr1 = ci * exp;
|
||||
Complex corr2 = ci * std::conj(exp);
|
||||
Complex corr1 = ci * std::conj(exp); // Conj is high/mark freq (as for matched filter, we need to time reverse and take conjugate)
|
||||
Complex corr2 = ci * exp; // Low/space freq
|
||||
|
||||
// Filter
|
||||
Real abs1, abs2;
|
||||
@ -238,6 +238,8 @@ void RttyDemodSink::processOneSample(Complex &ci)
|
||||
m_clockCount = 0;
|
||||
m_clock = false;
|
||||
m_cycleCount = 0;
|
||||
m_rssiMagSqSum = 0.0;
|
||||
m_rssiMagSqCount = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1,5 +1,9 @@
|
||||
project(mod)
|
||||
|
||||
if (ENABLE_CHANNELTX_MODRTTY)
|
||||
add_subdirectory(modrtty)
|
||||
endif()
|
||||
|
||||
if (ENABLE_CHANNELTX_MODAIS)
|
||||
add_subdirectory(modais)
|
||||
endif()
|
||||
|
@ -288,6 +288,7 @@ void PacketModGUI::preEmphasisSelect(const QPoint& p)
|
||||
{
|
||||
FMPreemphasisDialog dialog(m_settings.m_preEmphasisTau, m_settings.m_preEmphasisHighFreq);
|
||||
dialog.move(p);
|
||||
new DialogPositioner(&dialog, false);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
@ -301,6 +302,7 @@ void PacketModGUI::bpfSelect(const QPoint& p)
|
||||
{
|
||||
PacketModBPFDialog dialog(m_settings.m_bpfLowCutoff, m_settings.m_bpfHighCutoff, m_settings.m_bpfTaps);
|
||||
dialog.move(p);
|
||||
new DialogPositioner(&dialog, false);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
@ -315,6 +317,7 @@ void PacketModGUI::repeatSelect(const QPoint& p)
|
||||
{
|
||||
PacketModRepeatDialog dialog(m_settings.m_repeatDelay, m_settings.m_repeatCount);
|
||||
dialog.move(p);
|
||||
new DialogPositioner(&dialog, false);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
@ -339,6 +342,7 @@ void PacketModGUI::txSettingsSelect(const QPoint& p)
|
||||
m_settings.m_writeToFile);
|
||||
|
||||
dialog.move(p);
|
||||
new DialogPositioner(&dialog, false);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
|
@ -349,7 +349,7 @@ void PacketModSource::applySettings(const PacketModSettings& settings, bool forc
|
||||
<< " symbolSpan: " << settings.m_symbolSpan
|
||||
<< " channelSampleRate:" << m_channelSampleRate
|
||||
<< " baud:" << settings.m_baud;
|
||||
m_pulseShape.create(settings.m_beta, m_settings.m_symbolSpan, m_channelSampleRate/settings.m_baud);
|
||||
m_pulseShape.create(settings.m_beta, settings.m_symbolSpan, m_channelSampleRate/settings.m_baud);
|
||||
}
|
||||
if ((settings.m_polynomial != m_settings.m_polynomial) || force)
|
||||
m_scrambler.setPolynomial(settings.m_polynomial);
|
||||
|
69
plugins/channeltx/modrtty/CMakeLists.txt
Normal file
69
plugins/channeltx/modrtty/CMakeLists.txt
Normal file
@ -0,0 +1,69 @@
|
||||
project(modrtty)
|
||||
|
||||
set(modrtty_SOURCES
|
||||
rttymod.cpp
|
||||
rttymodbaseband.cpp
|
||||
rttymodsource.cpp
|
||||
rttymodplugin.cpp
|
||||
rttymodsettings.cpp
|
||||
rttymodwebapiadapter.cpp
|
||||
)
|
||||
|
||||
set(modrtty_HEADERS
|
||||
rttymod.h
|
||||
rttymodbaseband.h
|
||||
rttymodsource.h
|
||||
rttymodplugin.h
|
||||
rttymodsettings.h
|
||||
rttymodwebapiadapter.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
||||
)
|
||||
|
||||
if(NOT SERVER_MODE)
|
||||
set(modrtty_SOURCES
|
||||
${modrtty_SOURCES}
|
||||
rttymodgui.cpp
|
||||
rttymodgui.ui
|
||||
rttymodrepeatdialog.cpp
|
||||
rttymodrepeatdialog.ui
|
||||
rttymodtxsettingsdialog.cpp
|
||||
rttymodtxsettingsdialog.ui
|
||||
)
|
||||
set(modrtty_HEADERS
|
||||
${modrtty_HEADERS}
|
||||
rttymodgui.h
|
||||
rttymodrepeatdialog.h
|
||||
rttymodtxsettingsdialog.h
|
||||
)
|
||||
set(TARGET_NAME modrtty)
|
||||
set(TARGET_LIB "Qt::Widgets")
|
||||
set(TARGET_LIB_GUI "sdrgui")
|
||||
set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR})
|
||||
else()
|
||||
set(TARGET_NAME modrttysrv)
|
||||
set(TARGET_LIB "")
|
||||
set(TARGET_LIB_GUI "")
|
||||
set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR})
|
||||
endif()
|
||||
|
||||
add_library(${TARGET_NAME} SHARED
|
||||
${modrtty_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(${TARGET_NAME}
|
||||
Qt::Core
|
||||
${TARGET_LIB}
|
||||
sdrbase
|
||||
${TARGET_LIB_GUI}
|
||||
swagger
|
||||
)
|
||||
|
||||
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
|
||||
|
||||
# Install debug symbols
|
||||
if (WIN32)
|
||||
install(FILES $<TARGET_PDB_FILE:${TARGET_NAME}> CONFIGURATIONS Debug RelWithDebInfo DESTINATION ${INSTALL_FOLDER} )
|
||||
endif()
|
138
plugins/channeltx/modrtty/readme.md
Normal file
138
plugins/channeltx/modrtty/readme.md
Normal file
@ -0,0 +1,138 @@
|
||||
<h1>RTTY Modulator Plugin</h1>
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
This plugin can be used to modulate RTTY (Radioteletype) encoded text.
|
||||
RTTY uses BFSK (Binary Frequency Shift Keying), where transmission of data alternates between two frequencies,
|
||||
the mark frequency and the space frequency. The RTTY Modulator should be centered in between these frequencies.
|
||||
The baud rate, frequency shift (difference between mark and space frequencies), filter bandwidth and baudot character set are configurable.
|
||||
|
||||
<h2>Interface</h2>
|
||||
|
||||
The top and bottom bars of the channel window are described [here](../../../sdrgui/channel/readme.md)
|
||||
|
||||
![RTTY Modulator plugin GUI](../../../doc/img/RTTYMod_plugin.png)
|
||||
|
||||
<h3>1: Frequency shift from center frequency of transmission</h3>
|
||||
|
||||
Use the wheels to adjust the frequency shift in Hz from the center frequency of transmission. Left click on a digit sets the cursor position at this digit. Right click on a digit sets all digits on the right to zero. This effectively floors value at the digit position. Wheels are moved with the mousewheel while pointing at the wheel or by selecting the wheel with the left mouse click and using the keyboard arrows. Pressing shift simultaneously moves digit by 5 and pressing control moves it by 2.
|
||||
|
||||
<h3>2: Channel power</h3>
|
||||
|
||||
Average total power in dB relative to a +/- 1.0 amplitude signal generated in the pass band.
|
||||
|
||||
<h3>3: Channel mute</h3>
|
||||
|
||||
Use this button to toggle mute for this channel.
|
||||
|
||||
<h3>4: Mode</h3>
|
||||
|
||||
Contains a list of common baud rate and frequency shift settings. To specify your own, set this option to Custom.
|
||||
|
||||
45.45/170 is common for amateur RTTY.
|
||||
|
||||
<h3>5: Baud</h3>
|
||||
|
||||
Specifies the baud rate in symbols (bits) per second.
|
||||
|
||||
<h3>6: Frequency Shift</h3>
|
||||
|
||||
Adjusts the frequency shift (different between mark and space frequencies) in Hz.
|
||||
|
||||
<h3>7: RF Bandwidth</h3>
|
||||
|
||||
This specifies the bandwidth of a LPF that is applied to the output signal to limit the RF bandwidth.
|
||||
|
||||
<h3>8: Gain</h3>
|
||||
|
||||
Adjusts the gain in dB from -60 to 0dB.
|
||||
|
||||
<h3>9: Level meter in %</h3>
|
||||
|
||||
- top bar (beige): average value
|
||||
- bottom bar (brown): instantaneous peak value
|
||||
- tip vertical bar (bright red): peak hold value
|
||||
|
||||
<h3>10: UDP</h3>
|
||||
|
||||
When checked, a UDP port is opened to receive text from other features or applications that will be transmitted.
|
||||
|
||||
<h3>11: UDP address</h3>
|
||||
|
||||
IP address of the interface to open the UDP port on, to receive text to be transmitted.
|
||||
|
||||
<h3>12: UDP port</h3>
|
||||
|
||||
UDP port number to receive text to be transmitted on.
|
||||
|
||||
<h3>13: Baudot Character Set</h3>
|
||||
|
||||
Specifies the Baudot character set used to encode the text to transmit. The following character sets are supported:
|
||||
|
||||
* ITA 2
|
||||
* UK
|
||||
* European
|
||||
* US
|
||||
* Russian
|
||||
* Murray
|
||||
|
||||
<h3>14: Bit Ordering</h3>
|
||||
|
||||
Specifies whether bits are transmitted least-significant-bit first (LSB) or most-significant-bit first (MSB).
|
||||
|
||||
<h3>15: Mark/Space Frequency</h3>
|
||||
|
||||
When unchecked, the mark frequency is the higher RF frequency, when checked the space frequency is higher.
|
||||
|
||||
<h3>16: Unshift on Space</h3>
|
||||
|
||||
When checked, the Baudot character set will shift to letters when a space character (' ') is transmitted.
|
||||
|
||||
<h3>17: Repeat</h3>
|
||||
|
||||
Check this button to repeatedly transmit a packet. Right click to open the dialog to adjust the number of times the packet should be repeated.
|
||||
|
||||
<h3>18: Clear Transmitted Text</h3>
|
||||
|
||||
Press to clear the transmitted text.
|
||||
|
||||
<h3>19: Text to Transmit</h3>
|
||||
|
||||
Enter text to transmit. Pressing return will transmit the text and clear this field. Press the arrow to display and select a list of pre-defined text or previously transmitted text to enter in to the field.
|
||||
|
||||
The list of pre-defined text can be customised via the Transmit Settings dialog (20).
|
||||
|
||||
<h3>20: TX</h3>
|
||||
|
||||
Press to transmit the current text. The text field will not be cleared.
|
||||
|
||||
Right click to open a dialog to adjust additional Transmit Settings, including the list of pre-defined text.
|
||||
|
||||
Predefined text supports the following variable substitutions:
|
||||
|
||||
* ${callsign} - Gets replaced with the station name from Preferences > My Position
|
||||
* ${location} = Gets replaced with the Maidenhead locator for the position specified under Preferences > My Position
|
||||
|
||||
The substitutions are applied when the Transmit Settings dialog is closed.
|
||||
|
||||
<h3>21: Transmitted Text</h3>
|
||||
|
||||
The trasnmitted text area shows characters as they are transmitted.
|
||||
|
||||
Holding the cursor over an acronym may show a tooltip with the decoded acronym.
|
||||
|
||||
<h2>API</h2>
|
||||
|
||||
Full details of the API can be found in the Swagger documentation. Below are a few examples.
|
||||
|
||||
To transmit the current text simply send a "tx" action:
|
||||
|
||||
curl -X POST "http://127.0.0.1:8091/sdrangel/deviceset/0/channel/0/actions" -d '{"channelType": "RTTYMod", "direction": 1, "RTTYModActions": { "tx": 1 }}'
|
||||
|
||||
To transmit text specified on the command line:
|
||||
|
||||
curl -X POST "http://127.0.0.1:8091/sdrangel/deviceset/0/channel/0/actions" -d '{"channelType": "RTTYMod", "direction": 1, "RTTYModActions": { "tx": 1, "payload": {"text": "CQ CQ CQ anyone using SDRangel CQ" }}}'
|
||||
|
||||
To set the baud rate and frequency shift:
|
||||
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/deviceset/0/channel/0/settings" -d '{"channelType": "RTTYMod", "direction": 1, "RTTYModSettings": {"baud": 45.45, "frequencyShift": 170 }}'
|
932
plugins/channeltx/modrtty/rttymod.cpp
Normal file
932
plugins/channeltx/modrtty/rttymod.cpp
Normal file
@ -0,0 +1,932 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QTime>
|
||||
#include <QDebug>
|
||||
#include <QMutexLocker>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkDatagram>
|
||||
#include <QNetworkReply>
|
||||
#include <QBuffer>
|
||||
#include <QUdpSocket>
|
||||
#include <QThread>
|
||||
|
||||
#include "SWGChannelSettings.h"
|
||||
#include "SWGWorkspaceInfo.h"
|
||||
#include "SWGChannelReport.h"
|
||||
#include "SWGChannelActions.h"
|
||||
#include "SWGRTTYModReport.h"
|
||||
#include "SWGRTTYModActions.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <complex.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "dsp/dspengine.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "device/deviceapi.h"
|
||||
#include "feature/feature.h"
|
||||
#include "util/db.h"
|
||||
#include "util/crc.h"
|
||||
#include "maincore.h"
|
||||
|
||||
#include "rttymodbaseband.h"
|
||||
#include "rttymod.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(RttyMod::MsgConfigureRttyMod, Message)
|
||||
MESSAGE_CLASS_DEFINITION(RttyMod::MsgTx, Message)
|
||||
MESSAGE_CLASS_DEFINITION(RttyMod::MsgReportTx, Message)
|
||||
MESSAGE_CLASS_DEFINITION(RttyMod::MsgTXText, Message)
|
||||
|
||||
const char* const RttyMod::m_channelIdURI = "sdrangel.channeltx.modrtty";
|
||||
const char* const RttyMod::m_channelId = "RTTYMod";
|
||||
|
||||
RttyMod::RttyMod(DeviceAPI *deviceAPI) :
|
||||
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSource),
|
||||
m_deviceAPI(deviceAPI),
|
||||
m_spectrumVis(SDR_TX_SCALEF),
|
||||
m_sampleRate(48000),
|
||||
m_udpSocket(nullptr)
|
||||
{
|
||||
setObjectName(m_channelId);
|
||||
|
||||
m_thread = new QThread(this);
|
||||
m_basebandSource = new RttyModBaseband();
|
||||
m_basebandSource->setSpectrumSampleSink(&m_spectrumVis);
|
||||
m_basebandSource->setChannel(this);
|
||||
m_basebandSource->moveToThread(m_thread);
|
||||
|
||||
applySettings(m_settings, true);
|
||||
|
||||
m_deviceAPI->addChannelSource(this);
|
||||
m_deviceAPI->addChannelSourceAPI(this);
|
||||
|
||||
m_networkManager = new QNetworkAccessManager();
|
||||
QObject::connect(
|
||||
m_networkManager,
|
||||
&QNetworkAccessManager::finished,
|
||||
this,
|
||||
&RttyMod::networkManagerFinished
|
||||
);
|
||||
}
|
||||
|
||||
RttyMod::~RttyMod()
|
||||
{
|
||||
closeUDP();
|
||||
QObject::connect(
|
||||
m_networkManager,
|
||||
&QNetworkAccessManager::finished,
|
||||
this,
|
||||
&RttyMod::networkManagerFinished
|
||||
);
|
||||
delete m_networkManager;
|
||||
m_deviceAPI->removeChannelSourceAPI(this);
|
||||
m_deviceAPI->removeChannelSource(this);
|
||||
delete m_basebandSource;
|
||||
delete m_thread;
|
||||
}
|
||||
|
||||
void RttyMod::setDeviceAPI(DeviceAPI *deviceAPI)
|
||||
{
|
||||
if (deviceAPI != m_deviceAPI)
|
||||
{
|
||||
m_deviceAPI->removeChannelSourceAPI(this);
|
||||
m_deviceAPI->removeChannelSource(this);
|
||||
m_deviceAPI = deviceAPI;
|
||||
m_deviceAPI->addChannelSource(this);
|
||||
m_deviceAPI->addChannelSinkAPI(this);
|
||||
}
|
||||
}
|
||||
|
||||
void RttyMod::start()
|
||||
{
|
||||
qDebug("RttyMod::start");
|
||||
m_basebandSource->reset();
|
||||
m_thread->start();
|
||||
}
|
||||
|
||||
void RttyMod::stop()
|
||||
{
|
||||
qDebug("RttyMod::stop");
|
||||
m_thread->exit();
|
||||
m_thread->wait();
|
||||
}
|
||||
|
||||
void RttyMod::pull(SampleVector::iterator& begin, unsigned int nbSamples)
|
||||
{
|
||||
m_basebandSource->pull(begin, nbSamples);
|
||||
}
|
||||
|
||||
bool RttyMod::handleMessage(const Message& cmd)
|
||||
{
|
||||
if (MsgConfigureRttyMod::match(cmd))
|
||||
{
|
||||
MsgConfigureRttyMod& cfg = (MsgConfigureRttyMod&) cmd;
|
||||
qDebug() << "RttyMod::handleMessage: MsgConfigureRttyMod";
|
||||
|
||||
applySettings(cfg.getSettings(), cfg.getForce());
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgTx::match(cmd))
|
||||
{
|
||||
MsgTx* msg = new MsgTx((const MsgTx&)cmd);
|
||||
m_basebandSource->getInputMessageQueue()->push(msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgTXText::match(cmd))
|
||||
{
|
||||
MsgTXText* msg = new MsgTXText((const MsgTXText&)cmd);
|
||||
m_basebandSource->getInputMessageQueue()->push(msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (DSPSignalNotification::match(cmd))
|
||||
{
|
||||
// Forward to the source
|
||||
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
|
||||
DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy
|
||||
qDebug() << "RttyMod::handleMessage: DSPSignalNotification";
|
||||
m_basebandSource->getInputMessageQueue()->push(rep);
|
||||
// Forward to GUI if any
|
||||
if (getMessageQueueToGUI()) {
|
||||
getMessageQueueToGUI()->push(new DSPSignalNotification(notif));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MainCore::MsgChannelDemodQuery::match(cmd))
|
||||
{
|
||||
qDebug() << "RttyMod::handleMessage: MsgChannelDemodQuery";
|
||||
sendSampleRateToDemodAnalyzer();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void RttyMod::setCenterFrequency(qint64 frequency)
|
||||
{
|
||||
RttyModSettings settings = m_settings;
|
||||
settings.m_inputFrequencyOffset = frequency;
|
||||
applySettings(settings, false);
|
||||
|
||||
if (m_guiMessageQueue) // forward to GUI if any
|
||||
{
|
||||
MsgConfigureRttyMod *msgToGUI = MsgConfigureRttyMod::create(settings, false);
|
||||
m_guiMessageQueue->push(msgToGUI);
|
||||
}
|
||||
}
|
||||
|
||||
void RttyMod::applySettings(const RttyModSettings& settings, bool force)
|
||||
{
|
||||
qDebug() << "RttyMod::applySettings:"
|
||||
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
|
||||
<< " m_baud: " << settings.m_baud
|
||||
<< " m_rfBandwidth: " << settings.m_rfBandwidth
|
||||
<< " m_frequencyShift: " << settings.m_frequencyShift
|
||||
<< " m_gain: " << settings.m_gain
|
||||
<< " m_channelMute: " << settings.m_channelMute
|
||||
<< " m_repeat: " << settings.m_repeat
|
||||
<< " m_repeatCount: " << settings.m_repeatCount
|
||||
<< " m_text: " << settings.m_text
|
||||
<< " m_characterSet: " << settings.m_characterSet
|
||||
<< " m_unshiftOnSpace: " << settings.m_unshiftOnSpace
|
||||
<< " m_msbFirst: " << settings.m_msbFirst
|
||||
<< " m_spaceHigh: " << settings.m_spaceHigh
|
||||
<< " m_prefixCRLF: " << settings.m_prefixCRLF
|
||||
<< " m_postfixCRLF: " << settings.m_postfixCRLF
|
||||
<< " m_useReverseAPI: " << settings.m_useReverseAPI
|
||||
<< " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
|
||||
<< " m_reverseAPIAddress: " << settings.m_reverseAPIPort
|
||||
<< " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex
|
||||
<< " m_reverseAPIChannelIndex: " << settings.m_reverseAPIChannelIndex
|
||||
<< " force: " << force;
|
||||
|
||||
QList<QString> reverseAPIKeys;
|
||||
|
||||
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) {
|
||||
reverseAPIKeys.append("inputFrequencyOffset");
|
||||
}
|
||||
|
||||
if ((settings.m_baud != m_settings.m_baud) || force) {
|
||||
reverseAPIKeys.append("baud");
|
||||
}
|
||||
|
||||
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) {
|
||||
reverseAPIKeys.append("rfBandwidth");
|
||||
}
|
||||
|
||||
if ((settings.m_frequencyShift != m_settings.m_frequencyShift) || force) {
|
||||
reverseAPIKeys.append("frequencyShift");
|
||||
}
|
||||
|
||||
if ((settings.m_gain != m_settings.m_gain) || force) {
|
||||
reverseAPIKeys.append("gain");
|
||||
}
|
||||
|
||||
if ((settings.m_channelMute != m_settings.m_channelMute) || force) {
|
||||
reverseAPIKeys.append("channelMute");
|
||||
}
|
||||
|
||||
if ((settings.m_repeat != m_settings.m_repeat) || force) {
|
||||
reverseAPIKeys.append("repeat");
|
||||
}
|
||||
|
||||
if ((settings.m_repeatCount != m_settings.m_repeatCount) || force) {
|
||||
reverseAPIKeys.append("repeatCount");
|
||||
}
|
||||
|
||||
if ((settings.m_lpfTaps != m_settings.m_lpfTaps) || force) {
|
||||
reverseAPIKeys.append("lpfTaps");
|
||||
}
|
||||
|
||||
if ((settings.m_rfNoise != m_settings.m_rfNoise) || force) {
|
||||
reverseAPIKeys.append("rfNoise");
|
||||
}
|
||||
|
||||
if ((settings.m_text != m_settings.m_text) || force) {
|
||||
reverseAPIKeys.append("text");
|
||||
}
|
||||
|
||||
if ((settings.m_beta != m_settings.m_beta) || force) {
|
||||
reverseAPIKeys.append("beta");
|
||||
}
|
||||
|
||||
if ((settings.m_symbolSpan != m_settings.m_symbolSpan) || force) {
|
||||
reverseAPIKeys.append("symbolSpan");
|
||||
}
|
||||
|
||||
if ((settings.m_characterSet != m_settings.m_characterSet) || force) {
|
||||
reverseAPIKeys.append("characterSet");
|
||||
}
|
||||
|
||||
if ((settings.m_unshiftOnSpace != m_settings.m_unshiftOnSpace) || force) {
|
||||
reverseAPIKeys.append("unshiftOnSpace");
|
||||
}
|
||||
|
||||
if ((settings.m_msbFirst != m_settings.m_msbFirst) || force) {
|
||||
reverseAPIKeys.append("msbFirst");
|
||||
}
|
||||
|
||||
if ((settings.m_spaceHigh != m_settings.m_spaceHigh) || force) {
|
||||
reverseAPIKeys.append("spaceHigh");
|
||||
}
|
||||
|
||||
if ((settings.m_prefixCRLF != m_settings.m_prefixCRLF) || force) {
|
||||
reverseAPIKeys.append("prefixCRLF");
|
||||
}
|
||||
|
||||
if ((settings.m_postfixCRLF != m_settings.m_postfixCRLF) || force) {
|
||||
reverseAPIKeys.append("postfixCRLF");
|
||||
}
|
||||
|
||||
if ((settings.m_udpEnabled != m_settings.m_udpEnabled) || force) {
|
||||
reverseAPIKeys.append("udpEnabled");
|
||||
}
|
||||
|
||||
if ((settings.m_udpAddress != m_settings.m_udpAddress) || force) {
|
||||
reverseAPIKeys.append("udpAddress");
|
||||
}
|
||||
|
||||
if ((settings.m_udpPort != m_settings.m_udpPort) || force) {
|
||||
reverseAPIKeys.append("udpPort");
|
||||
}
|
||||
|
||||
if ( (settings.m_udpEnabled != m_settings.m_udpEnabled)
|
||||
|| (settings.m_udpAddress != m_settings.m_udpAddress)
|
||||
|| (settings.m_udpPort != m_settings.m_udpPort)
|
||||
|| force)
|
||||
{
|
||||
if (settings.m_udpEnabled)
|
||||
openUDP(settings);
|
||||
else
|
||||
closeUDP();
|
||||
}
|
||||
|
||||
if (m_settings.m_streamIndex != settings.m_streamIndex)
|
||||
{
|
||||
if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only
|
||||
{
|
||||
m_deviceAPI->removeChannelSourceAPI(this);
|
||||
m_deviceAPI->removeChannelSource(this, m_settings.m_streamIndex);
|
||||
m_deviceAPI->addChannelSource(this, settings.m_streamIndex);
|
||||
m_deviceAPI->addChannelSourceAPI(this);
|
||||
}
|
||||
|
||||
reverseAPIKeys.append("streamIndex");
|
||||
}
|
||||
|
||||
RttyModBaseband::MsgConfigureRttyModBaseband *msg = RttyModBaseband::MsgConfigureRttyModBaseband::create(settings, force);
|
||||
m_basebandSource->getInputMessageQueue()->push(msg);
|
||||
|
||||
if (settings.m_useReverseAPI)
|
||||
{
|
||||
bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
|
||||
(m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) ||
|
||||
(m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) ||
|
||||
(m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex) ||
|
||||
(m_settings.m_reverseAPIChannelIndex != settings.m_reverseAPIChannelIndex);
|
||||
webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
|
||||
}
|
||||
|
||||
QList<ObjectPipe*> pipes;
|
||||
MainCore::instance()->getMessagePipes().getMessagePipes(this, "settings", pipes);
|
||||
|
||||
if (pipes.size() > 0) {
|
||||
sendChannelSettings(pipes, reverseAPIKeys, settings, force);
|
||||
}
|
||||
|
||||
m_settings = settings;
|
||||
}
|
||||
|
||||
QByteArray RttyMod::serialize() const
|
||||
{
|
||||
return m_settings.serialize();
|
||||
}
|
||||
|
||||
bool RttyMod::deserialize(const QByteArray& data)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
if (!m_settings.deserialize(data))
|
||||
{
|
||||
m_settings.resetToDefaults();
|
||||
success = false;
|
||||
}
|
||||
|
||||
MsgConfigureRttyMod *msg = MsgConfigureRttyMod::create(m_settings, true);
|
||||
m_inputMessageQueue.push(msg);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void RttyMod::sendSampleRateToDemodAnalyzer()
|
||||
{
|
||||
QList<ObjectPipe*> pipes;
|
||||
MainCore::instance()->getMessagePipes().getMessagePipes(this, "reportdemod", pipes);
|
||||
|
||||
if (pipes.size() > 0)
|
||||
{
|
||||
for (const auto& pipe : pipes)
|
||||
{
|
||||
MessageQueue* messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(
|
||||
this,
|
||||
getSourceChannelSampleRate()
|
||||
);
|
||||
messageQueue->push(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int RttyMod::webapiSettingsGet(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
response.setRttyModSettings(new SWGSDRangel::SWGRTTYModSettings());
|
||||
response.getRttyModSettings()->init();
|
||||
webapiFormatChannelSettings(response, m_settings);
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
int RttyMod::webapiWorkspaceGet(
|
||||
SWGSDRangel::SWGWorkspaceInfo& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
response.setIndex(m_settings.m_workspaceIndex);
|
||||
return 200;
|
||||
}
|
||||
|
||||
int RttyMod::webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
RttyModSettings settings = m_settings;
|
||||
webapiUpdateChannelSettings(settings, channelSettingsKeys, response);
|
||||
|
||||
MsgConfigureRttyMod *msg = MsgConfigureRttyMod::create(settings, force);
|
||||
m_inputMessageQueue.push(msg);
|
||||
|
||||
if (m_guiMessageQueue) // forward to GUI if any
|
||||
{
|
||||
MsgConfigureRttyMod *msgToGUI = MsgConfigureRttyMod::create(settings, force);
|
||||
m_guiMessageQueue->push(msgToGUI);
|
||||
}
|
||||
|
||||
webapiFormatChannelSettings(response, settings);
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
void RttyMod::webapiUpdateChannelSettings(
|
||||
RttyModSettings& settings,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response)
|
||||
{
|
||||
if (channelSettingsKeys.contains("inputFrequencyOffset")) {
|
||||
settings.m_inputFrequencyOffset = response.getRttyModSettings()->getInputFrequencyOffset();
|
||||
}
|
||||
if (channelSettingsKeys.contains("baud")) {
|
||||
settings.m_baud = response.getRttyModSettings()->getBaud();
|
||||
}
|
||||
if (channelSettingsKeys.contains("rfBandwidth")) {
|
||||
settings.m_rfBandwidth = response.getRttyModSettings()->getRfBandwidth();
|
||||
}
|
||||
if (channelSettingsKeys.contains("frequencyShift")) {
|
||||
settings.m_frequencyShift = response.getRttyModSettings()->getFrequencyShift();
|
||||
}
|
||||
if (channelSettingsKeys.contains("gain")) {
|
||||
settings.m_gain = response.getRttyModSettings()->getGain();
|
||||
}
|
||||
if (channelSettingsKeys.contains("channelMute")) {
|
||||
settings.m_channelMute = response.getRttyModSettings()->getChannelMute() != 0;
|
||||
}
|
||||
if (channelSettingsKeys.contains("repeat")) {
|
||||
settings.m_repeat = response.getRttyModSettings()->getRepeat() != 0;
|
||||
}
|
||||
if (channelSettingsKeys.contains("repeatCount")) {
|
||||
settings.m_repeatCount = response.getRttyModSettings()->getRepeatCount();
|
||||
}
|
||||
if (channelSettingsKeys.contains("lpfTaps")) {
|
||||
settings.m_lpfTaps = response.getRttyModSettings()->getLpfTaps();
|
||||
}
|
||||
if (channelSettingsKeys.contains("rfNoise")) {
|
||||
settings.m_rfNoise = response.getRttyModSettings()->getRfNoise() != 0;
|
||||
}
|
||||
if (channelSettingsKeys.contains("text")) {
|
||||
settings.m_text = *response.getRttyModSettings()->getText();
|
||||
}
|
||||
if (channelSettingsKeys.contains("beta")) {
|
||||
settings.m_beta = response.getRttyModSettings()->getBeta();
|
||||
}
|
||||
if (channelSettingsKeys.contains("symbolSpan")) {
|
||||
settings.m_symbolSpan = response.getRttyModSettings()->getSymbolSpan();
|
||||
}
|
||||
if (channelSettingsKeys.contains("characterSet")) {
|
||||
settings.m_characterSet = (Baudot::CharacterSet) response.getRttyModSettings()->getCharacterSet();
|
||||
}
|
||||
if (channelSettingsKeys.contains("unshiftOnSpace")) {
|
||||
settings.m_unshiftOnSpace = response.getRttyModSettings()->getUnshiftOnSpace();
|
||||
}
|
||||
if (channelSettingsKeys.contains("msbFirst")) {
|
||||
settings.m_msbFirst = response.getRttyModSettings()->getMsbFirst();
|
||||
}
|
||||
if (channelSettingsKeys.contains("spaceHigh")) {
|
||||
settings.m_spaceHigh = response.getRttyModSettings()->getSpaceHigh();
|
||||
}
|
||||
if (channelSettingsKeys.contains("prefixCRLF")) {
|
||||
settings.m_prefixCRLF = response.getRttyModSettings()->getPrefixCrlf();
|
||||
}
|
||||
if (channelSettingsKeys.contains("postfixCRLF")) {
|
||||
settings.m_postfixCRLF = response.getRttyModSettings()->getPostfixCrlf();
|
||||
}
|
||||
if (channelSettingsKeys.contains("rgbColor")) {
|
||||
settings.m_rgbColor = response.getRttyModSettings()->getRgbColor();
|
||||
}
|
||||
if (channelSettingsKeys.contains("title")) {
|
||||
settings.m_title = *response.getRttyModSettings()->getTitle();
|
||||
}
|
||||
if (channelSettingsKeys.contains("streamIndex")) {
|
||||
settings.m_streamIndex = response.getRttyModSettings()->getStreamIndex();
|
||||
}
|
||||
if (channelSettingsKeys.contains("useReverseAPI")) {
|
||||
settings.m_useReverseAPI = response.getRttyModSettings()->getUseReverseApi() != 0;
|
||||
}
|
||||
if (channelSettingsKeys.contains("reverseAPIAddress")) {
|
||||
settings.m_reverseAPIAddress = *response.getRttyModSettings()->getReverseApiAddress();
|
||||
}
|
||||
if (channelSettingsKeys.contains("reverseAPIPort")) {
|
||||
settings.m_reverseAPIPort = response.getRttyModSettings()->getReverseApiPort();
|
||||
}
|
||||
if (channelSettingsKeys.contains("reverseAPIDeviceIndex")) {
|
||||
settings.m_reverseAPIDeviceIndex = response.getRttyModSettings()->getReverseApiDeviceIndex();
|
||||
}
|
||||
if (channelSettingsKeys.contains("reverseAPIChannelIndex")) {
|
||||
settings.m_reverseAPIChannelIndex = response.getRttyModSettings()->getReverseApiChannelIndex();
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpEnabled")) {
|
||||
settings.m_udpEnabled = response.getRttyModSettings()->getUdpEnabled();
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpAddress")) {
|
||||
settings.m_udpAddress = *response.getRttyModSettings()->getUdpAddress();
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpPort")) {
|
||||
settings.m_udpPort = response.getRttyModSettings()->getUdpPort();
|
||||
}
|
||||
if (settings.m_channelMarker && channelSettingsKeys.contains("channelMarker")) {
|
||||
settings.m_channelMarker->updateFrom(channelSettingsKeys, response.getRttyModSettings()->getChannelMarker());
|
||||
}
|
||||
if (settings.m_rollupState && channelSettingsKeys.contains("rollupState")) {
|
||||
settings.m_rollupState->updateFrom(channelSettingsKeys, response.getRttyModSettings()->getRollupState());
|
||||
}
|
||||
}
|
||||
|
||||
int RttyMod::webapiReportGet(
|
||||
SWGSDRangel::SWGChannelReport& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
response.setRttyModReport(new SWGSDRangel::SWGRTTYModReport());
|
||||
response.getRttyModReport()->init();
|
||||
webapiFormatChannelReport(response);
|
||||
return 200;
|
||||
}
|
||||
|
||||
int RttyMod::webapiActionsPost(
|
||||
const QStringList& channelActionsKeys,
|
||||
SWGSDRangel::SWGChannelActions& query,
|
||||
QString& errorMessage)
|
||||
{
|
||||
SWGSDRangel::SWGRTTYModActions *swgRttyModActions = query.getRttyModActions();
|
||||
|
||||
if (swgRttyModActions)
|
||||
{
|
||||
if (channelActionsKeys.contains("tx"))
|
||||
{
|
||||
if (swgRttyModActions->getTx() != 0)
|
||||
{
|
||||
if (channelActionsKeys.contains("payload")
|
||||
&& (swgRttyModActions->getPayload()->getText()))
|
||||
{
|
||||
MsgTXText *msg = MsgTXText::create(
|
||||
*swgRttyModActions->getPayload()->getText()
|
||||
);
|
||||
m_basebandSource->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
MsgTx *msg = MsgTx::create();
|
||||
m_basebandSource->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
return 202;
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = "Must contain tx action";
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = "Unknown RTTYMod action";
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = "Missing RTTYModActions in query";
|
||||
return 400;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RttyMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const RttyModSettings& settings)
|
||||
{
|
||||
response.getRttyModSettings()->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
|
||||
response.getRttyModSettings()->setBaud(settings.m_baud);
|
||||
response.getRttyModSettings()->setRfBandwidth(settings.m_rfBandwidth);
|
||||
response.getRttyModSettings()->setFrequencyShift(settings.m_frequencyShift);
|
||||
response.getRttyModSettings()->setGain(settings.m_gain);
|
||||
response.getRttyModSettings()->setChannelMute(settings.m_channelMute ? 1 : 0);
|
||||
response.getRttyModSettings()->setRepeat(settings.m_repeat ? 1 : 0);
|
||||
response.getRttyModSettings()->setRepeatCount(settings.m_repeatCount);
|
||||
response.getRttyModSettings()->setLpfTaps(settings.m_lpfTaps);
|
||||
response.getRttyModSettings()->setRfNoise(settings.m_rfNoise ? 1 : 0);
|
||||
|
||||
if (response.getRttyModSettings()->getText()) {
|
||||
*response.getRttyModSettings()->getText() = settings.m_text;
|
||||
} else {
|
||||
response.getRttyModSettings()->setText(new QString(settings.m_text));
|
||||
}
|
||||
|
||||
response.getRttyModSettings()->setPulseShaping(settings.m_pulseShaping ? 1 : 0);
|
||||
response.getRttyModSettings()->setBeta(settings.m_beta);
|
||||
response.getRttyModSettings()->setSymbolSpan(settings.m_symbolSpan);
|
||||
|
||||
response.getRttyModSettings()->setCharacterSet((int) settings.m_characterSet);
|
||||
response.getRttyModSettings()->setSymbolSpan(settings.m_symbolSpan);
|
||||
response.getRttyModSettings()->setUnshiftOnSpace(settings.m_unshiftOnSpace);
|
||||
response.getRttyModSettings()->setMsbFirst(settings.m_msbFirst);
|
||||
response.getRttyModSettings()->setSpaceHigh(settings.m_spaceHigh);
|
||||
response.getRttyModSettings()->setPrefixCrlf(settings.m_prefixCRLF);
|
||||
response.getRttyModSettings()->setPostfixCrlf(settings.m_postfixCRLF);
|
||||
|
||||
response.getRttyModSettings()->setUdpEnabled(settings.m_udpEnabled);
|
||||
response.getRttyModSettings()->setUdpAddress(new QString(settings.m_udpAddress));
|
||||
response.getRttyModSettings()->setUdpPort(settings.m_udpPort);
|
||||
|
||||
response.getRttyModSettings()->setRgbColor(settings.m_rgbColor);
|
||||
|
||||
if (response.getRttyModSettings()->getTitle()) {
|
||||
*response.getRttyModSettings()->getTitle() = settings.m_title;
|
||||
} else {
|
||||
response.getRttyModSettings()->setTitle(new QString(settings.m_title));
|
||||
}
|
||||
|
||||
response.getRttyModSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
|
||||
|
||||
if (response.getRttyModSettings()->getReverseApiAddress()) {
|
||||
*response.getRttyModSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress;
|
||||
} else {
|
||||
response.getRttyModSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
|
||||
}
|
||||
|
||||
response.getRttyModSettings()->setReverseApiPort(settings.m_reverseAPIPort);
|
||||
response.getRttyModSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex);
|
||||
response.getRttyModSettings()->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex);
|
||||
|
||||
if (settings.m_channelMarker)
|
||||
{
|
||||
if (response.getRttyModSettings()->getChannelMarker())
|
||||
{
|
||||
settings.m_channelMarker->formatTo(response.getRttyModSettings()->getChannelMarker());
|
||||
}
|
||||
else
|
||||
{
|
||||
SWGSDRangel::SWGChannelMarker *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
|
||||
settings.m_channelMarker->formatTo(swgChannelMarker);
|
||||
response.getRttyModSettings()->setChannelMarker(swgChannelMarker);
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.m_rollupState)
|
||||
{
|
||||
if (response.getRttyModSettings()->getRollupState())
|
||||
{
|
||||
settings.m_rollupState->formatTo(response.getRttyModSettings()->getRollupState());
|
||||
}
|
||||
else
|
||||
{
|
||||
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
|
||||
settings.m_rollupState->formatTo(swgRollupState);
|
||||
response.getRttyModSettings()->setRollupState(swgRollupState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RttyMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
|
||||
{
|
||||
response.getRttyModReport()->setChannelPowerDb(CalcDb::dbPower(getMagSq()));
|
||||
response.getRttyModReport()->setChannelSampleRate(m_basebandSource->getChannelSampleRate());
|
||||
}
|
||||
|
||||
void RttyMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const RttyModSettings& settings, bool force)
|
||||
{
|
||||
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
|
||||
webapiFormatChannelSettings(channelSettingsKeys, swgChannelSettings, settings, force);
|
||||
|
||||
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
|
||||
.arg(settings.m_reverseAPIAddress)
|
||||
.arg(settings.m_reverseAPIPort)
|
||||
.arg(settings.m_reverseAPIDeviceIndex)
|
||||
.arg(settings.m_reverseAPIChannelIndex);
|
||||
m_networkRequest.setUrl(QUrl(channelSettingsURL));
|
||||
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
QBuffer *buffer = new QBuffer();
|
||||
buffer->open((QBuffer::ReadWrite));
|
||||
buffer->write(swgChannelSettings->asJson().toUtf8());
|
||||
buffer->seek(0);
|
||||
|
||||
// Always use PATCH to avoid passing reverse API settings
|
||||
QNetworkReply *reply = m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
|
||||
buffer->setParent(reply);
|
||||
|
||||
delete swgChannelSettings;
|
||||
}
|
||||
|
||||
void RttyMod::sendChannelSettings(
|
||||
const QList<ObjectPipe*>& pipes,
|
||||
QList<QString>& channelSettingsKeys,
|
||||
const RttyModSettings& settings,
|
||||
bool force)
|
||||
{
|
||||
for (const auto& pipe : pipes)
|
||||
{
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
|
||||
if (messageQueue)
|
||||
{
|
||||
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
|
||||
webapiFormatChannelSettings(channelSettingsKeys, swgChannelSettings, settings, force);
|
||||
MainCore::MsgChannelSettings *msg = MainCore::MsgChannelSettings::create(
|
||||
this,
|
||||
channelSettingsKeys,
|
||||
swgChannelSettings,
|
||||
force
|
||||
);
|
||||
messageQueue->push(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RttyMod::webapiFormatChannelSettings(
|
||||
QList<QString>& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings *swgChannelSettings,
|
||||
const RttyModSettings& settings,
|
||||
bool force
|
||||
)
|
||||
{
|
||||
swgChannelSettings->setDirection(1); // single source (Tx)
|
||||
swgChannelSettings->setOriginatorChannelIndex(getIndexInDeviceSet());
|
||||
swgChannelSettings->setOriginatorDeviceSetIndex(getDeviceSetIndex());
|
||||
swgChannelSettings->setChannelType(new QString(m_channelId));
|
||||
swgChannelSettings->setRttyModSettings(new SWGSDRangel::SWGRTTYModSettings());
|
||||
SWGSDRangel::SWGRTTYModSettings *swgRttyModSettings = swgChannelSettings->getRttyModSettings();
|
||||
|
||||
// transfer data that has been modified. When force is on transfer all data except reverse API data
|
||||
|
||||
if (channelSettingsKeys.contains("inputFrequencyOffset") || force) {
|
||||
swgRttyModSettings->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
|
||||
}
|
||||
if (channelSettingsKeys.contains("baud") || force) {
|
||||
swgRttyModSettings->setBaud((int) settings.m_baud);
|
||||
}
|
||||
if (channelSettingsKeys.contains("rfBandwidth") || force) {
|
||||
swgRttyModSettings->setRfBandwidth(settings.m_rfBandwidth);
|
||||
}
|
||||
if (channelSettingsKeys.contains("frequencyShift") || force) {
|
||||
swgRttyModSettings->setFrequencyShift(settings.m_frequencyShift);
|
||||
}
|
||||
if (channelSettingsKeys.contains("gain") || force) {
|
||||
swgRttyModSettings->setGain(settings.m_gain);
|
||||
}
|
||||
if (channelSettingsKeys.contains("channelMute") || force) {
|
||||
swgRttyModSettings->setChannelMute(settings.m_channelMute ? 1 : 0);
|
||||
}
|
||||
if (channelSettingsKeys.contains("repeat") || force) {
|
||||
swgRttyModSettings->setRepeat(settings.m_repeat ? 1 : 0);
|
||||
}
|
||||
if (channelSettingsKeys.contains("repeatCount") || force) {
|
||||
swgRttyModSettings->setRepeatCount(settings.m_repeatCount);
|
||||
}
|
||||
if (channelSettingsKeys.contains("lpfTaps")) {
|
||||
swgRttyModSettings->setLpfTaps(settings.m_lpfTaps);
|
||||
}
|
||||
if (channelSettingsKeys.contains("rfNoise")) {
|
||||
swgRttyModSettings->setRfNoise(settings.m_rfNoise ? 1 : 0);
|
||||
}
|
||||
if (channelSettingsKeys.contains("text")) {
|
||||
swgRttyModSettings->setText(new QString(settings.m_text));
|
||||
}
|
||||
if (channelSettingsKeys.contains("beta")) {
|
||||
swgRttyModSettings->setBeta(settings.m_beta);
|
||||
}
|
||||
if (channelSettingsKeys.contains("symbolSpan")) {
|
||||
swgRttyModSettings->setSymbolSpan(settings.m_symbolSpan);
|
||||
}
|
||||
if (channelSettingsKeys.contains("characterSet")) {
|
||||
swgRttyModSettings->setCharacterSet((int) settings.m_characterSet);
|
||||
}
|
||||
if (channelSettingsKeys.contains("unshiftOnSpace")) {
|
||||
swgRttyModSettings->setUnshiftOnSpace(settings.m_unshiftOnSpace);
|
||||
}
|
||||
if (channelSettingsKeys.contains("msbFirst")) {
|
||||
swgRttyModSettings->setMsbFirst(settings.m_msbFirst);
|
||||
}
|
||||
if (channelSettingsKeys.contains("spaceHigh")) {
|
||||
swgRttyModSettings->setSpaceHigh(settings.m_spaceHigh);
|
||||
}
|
||||
if (channelSettingsKeys.contains("prefixCRLF")) {
|
||||
swgRttyModSettings->setPrefixCrlf(settings.m_prefixCRLF);
|
||||
}
|
||||
if (channelSettingsKeys.contains("postfixCRLF")) {
|
||||
swgRttyModSettings->setPostfixCrlf(settings.m_postfixCRLF);
|
||||
}
|
||||
if (channelSettingsKeys.contains("rgbColor") || force) {
|
||||
swgRttyModSettings->setRgbColor(settings.m_rgbColor);
|
||||
}
|
||||
if (channelSettingsKeys.contains("title") || force) {
|
||||
swgRttyModSettings->setTitle(new QString(settings.m_title));
|
||||
}
|
||||
if (channelSettingsKeys.contains("streamIndex") || force) {
|
||||
swgRttyModSettings->setStreamIndex(settings.m_streamIndex);
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpEnabled") || force) {
|
||||
swgRttyModSettings->setUdpEnabled(settings.m_udpEnabled);
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpAddress") || force) {
|
||||
swgRttyModSettings->setUdpAddress(new QString(settings.m_udpAddress));
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpPort") || force) {
|
||||
swgRttyModSettings->setUdpPort(settings.m_udpPort);
|
||||
}
|
||||
|
||||
if (settings.m_channelMarker && (channelSettingsKeys.contains("channelMarker") || force))
|
||||
{
|
||||
SWGSDRangel::SWGChannelMarker *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
|
||||
settings.m_channelMarker->formatTo(swgChannelMarker);
|
||||
swgRttyModSettings->setChannelMarker(swgChannelMarker);
|
||||
}
|
||||
|
||||
if (settings.m_rollupState && (channelSettingsKeys.contains("rollupState") || force))
|
||||
{
|
||||
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
|
||||
settings.m_rollupState->formatTo(swgRollupState);
|
||||
swgRttyModSettings->setRollupState(swgRollupState);
|
||||
}
|
||||
}
|
||||
|
||||
void RttyMod::networkManagerFinished(QNetworkReply *reply)
|
||||
{
|
||||
QNetworkReply::NetworkError replyError = reply->error();
|
||||
|
||||
if (replyError)
|
||||
{
|
||||
qWarning() << "RttyMod::networkManagerFinished:"
|
||||
<< " error(" << (int) replyError
|
||||
<< "): " << replyError
|
||||
<< ": " << reply->errorString();
|
||||
}
|
||||
else
|
||||
{
|
||||
QString answer = reply->readAll();
|
||||
answer.chop(1); // remove last \n
|
||||
qDebug("RttyMod::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
double RttyMod::getMagSq() const
|
||||
{
|
||||
return m_basebandSource->getMagSq();
|
||||
}
|
||||
|
||||
void RttyMod::setLevelMeter(QObject *levelMeter)
|
||||
{
|
||||
connect(m_basebandSource, SIGNAL(levelChanged(qreal, qreal, int)), levelMeter, SLOT(levelChanged(qreal, qreal, int)));
|
||||
}
|
||||
|
||||
uint32_t RttyMod::getNumberOfDeviceStreams() const
|
||||
{
|
||||
return m_deviceAPI->getNbSinkStreams();
|
||||
}
|
||||
|
||||
int RttyMod::getSourceChannelSampleRate() const
|
||||
{
|
||||
return m_basebandSource->getSourceChannelSampleRate();
|
||||
}
|
||||
|
||||
void RttyMod::openUDP(const RttyModSettings& settings)
|
||||
{
|
||||
closeUDP();
|
||||
m_udpSocket = new QUdpSocket();
|
||||
if (!m_udpSocket->bind(QHostAddress(settings.m_udpAddress), settings.m_udpPort))
|
||||
qCritical() << "RttyMod::openUDP: Failed to bind to port " << settings.m_udpAddress << ":" << settings.m_udpPort << ". Error: " << m_udpSocket->error();
|
||||
else
|
||||
qDebug() << "RttyMod::openUDP: Listening for text on " << settings.m_udpAddress << ":" << settings.m_udpPort;
|
||||
connect(m_udpSocket, &QUdpSocket::readyRead, this, &RttyMod::udpRx);
|
||||
}
|
||||
|
||||
void RttyMod::closeUDP()
|
||||
{
|
||||
if (m_udpSocket != nullptr)
|
||||
{
|
||||
disconnect(m_udpSocket, &QUdpSocket::readyRead, this, &RttyMod::udpRx);
|
||||
delete m_udpSocket;
|
||||
m_udpSocket = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void RttyMod::udpRx()
|
||||
{
|
||||
while (m_udpSocket->hasPendingDatagrams())
|
||||
{
|
||||
QNetworkDatagram datagram = m_udpSocket->receiveDatagram();
|
||||
MsgTXText *msg = MsgTXText::create(QString(datagram.data()));
|
||||
m_basebandSource->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void RttyMod::setMessageQueueToGUI(MessageQueue* queue) {
|
||||
ChannelAPI::setMessageQueueToGUI(queue);
|
||||
m_basebandSource->setMessageQueueToGUI(queue);
|
||||
}
|
246
plugins/channeltx/modrtty/rttymod.h
Normal file
246
plugins/channeltx/modrtty/rttymod.h
Normal file
@ -0,0 +1,246 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016-2019 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PLUGINS_CHANNELTX_MODRTTY_RTTYMOD_H_
|
||||
#define PLUGINS_CHANNELTX_MODRTTY_RTTYMOD_H_
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <QRecursiveMutex>
|
||||
#include <QNetworkRequest>
|
||||
|
||||
#include "dsp/basebandsamplesource.h"
|
||||
#include "dsp/spectrumvis.h"
|
||||
#include "channel/channelapi.h"
|
||||
#include "util/message.h"
|
||||
|
||||
#include "rttymodsettings.h"
|
||||
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class QThread;
|
||||
class QUdpSocket;
|
||||
class DeviceAPI;
|
||||
class RttyModBaseband;
|
||||
class ObjectPipe;
|
||||
|
||||
class RttyMod : public BasebandSampleSource, public ChannelAPI {
|
||||
public:
|
||||
class MsgConfigureRttyMod : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const RttyModSettings& getSettings() const { return m_settings; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigureRttyMod* create(const RttyModSettings& settings, bool force)
|
||||
{
|
||||
return new MsgConfigureRttyMod(settings, force);
|
||||
}
|
||||
|
||||
private:
|
||||
RttyModSettings m_settings;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigureRttyMod(const RttyModSettings& settings, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgTx : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
static MsgTx* create() {
|
||||
return new MsgTx();
|
||||
}
|
||||
|
||||
private:
|
||||
MsgTx() :
|
||||
Message()
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgReportTx : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const QString& getText() const { return m_text; }
|
||||
int getBufferedCharacters() const { return m_bufferedCharacters; }
|
||||
|
||||
static MsgReportTx* create(const QString& text, int bufferedCharacters) {
|
||||
return new MsgReportTx(text, bufferedCharacters);
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_text;
|
||||
int m_bufferedCharacters;
|
||||
|
||||
MsgReportTx(const QString& text, int bufferedCharacters) :
|
||||
Message(),
|
||||
m_text(text),
|
||||
m_bufferedCharacters(bufferedCharacters)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgTXText : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
static MsgTXText* create(QString text)
|
||||
{
|
||||
return new MsgTXText(text);
|
||||
}
|
||||
|
||||
QString m_text;
|
||||
|
||||
private:
|
||||
|
||||
MsgTXText(QString text) :
|
||||
Message(),
|
||||
m_text(text)
|
||||
{ }
|
||||
};
|
||||
|
||||
//=================================================================
|
||||
|
||||
RttyMod(DeviceAPI *deviceAPI);
|
||||
virtual ~RttyMod();
|
||||
virtual void destroy() { delete this; }
|
||||
virtual void setDeviceAPI(DeviceAPI *deviceAPI);
|
||||
virtual DeviceAPI *getDeviceAPI() { return m_deviceAPI; }
|
||||
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void pull(SampleVector::iterator& begin, unsigned int nbSamples);
|
||||
virtual void pushMessage(Message *msg) { m_inputMessageQueue.push(msg); }
|
||||
virtual QString getSourceName() { return objectName(); }
|
||||
|
||||
virtual void getIdentifier(QString& id) { id = objectName(); }
|
||||
virtual QString getIdentifier() const { return objectName(); }
|
||||
virtual void getTitle(QString& title) { title = m_settings.m_title; }
|
||||
virtual qint64 getCenterFrequency() const { return m_settings.m_inputFrequencyOffset; }
|
||||
virtual void setCenterFrequency(qint64 frequency);
|
||||
|
||||
virtual QByteArray serialize() const;
|
||||
virtual bool deserialize(const QByteArray& data);
|
||||
|
||||
virtual int getNbSinkStreams() const { return 1; }
|
||||
virtual int getNbSourceStreams() const { return 0; }
|
||||
|
||||
virtual qint64 getStreamCenterFrequency(int streamIndex, bool sinkElseSource) const
|
||||
{
|
||||
(void) streamIndex;
|
||||
(void) sinkElseSource;
|
||||
return m_settings.m_inputFrequencyOffset;
|
||||
}
|
||||
|
||||
virtual int webapiSettingsGet(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiWorkspaceGet(
|
||||
SWGSDRangel::SWGWorkspaceInfo& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiReportGet(
|
||||
SWGSDRangel::SWGChannelReport& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiActionsPost(
|
||||
const QStringList& channelActionsKeys,
|
||||
SWGSDRangel::SWGChannelActions& query,
|
||||
QString& errorMessage);
|
||||
|
||||
static void webapiFormatChannelSettings(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
const RttyModSettings& settings);
|
||||
|
||||
static void webapiUpdateChannelSettings(
|
||||
RttyModSettings& settings,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response);
|
||||
|
||||
SpectrumVis *getSpectrumVis() { return &m_spectrumVis; }
|
||||
double getMagSq() const;
|
||||
void setLevelMeter(QObject *levelMeter);
|
||||
uint32_t getNumberOfDeviceStreams() const;
|
||||
int getSourceChannelSampleRate() const;
|
||||
void setMessageQueueToGUI(MessageQueue* queue) override;
|
||||
|
||||
static const char* const m_channelIdURI;
|
||||
static const char* const m_channelId;
|
||||
|
||||
private:
|
||||
enum RateState {
|
||||
RSInitialFill,
|
||||
RSRunning
|
||||
};
|
||||
|
||||
DeviceAPI* m_deviceAPI;
|
||||
QThread *m_thread;
|
||||
RttyModBaseband* m_basebandSource;
|
||||
RttyModSettings m_settings;
|
||||
SpectrumVis m_spectrumVis;
|
||||
|
||||
SampleVector m_sampleBuffer;
|
||||
QRecursiveMutex m_settingsMutex;
|
||||
|
||||
int m_sampleRate;
|
||||
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
QNetworkRequest m_networkRequest;
|
||||
QUdpSocket *m_udpSocket;
|
||||
|
||||
virtual bool handleMessage(const Message& cmd);
|
||||
void applySettings(const RttyModSettings& settings, bool force = false);
|
||||
void sendSampleRateToDemodAnalyzer();
|
||||
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
|
||||
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const RttyModSettings& settings, bool force);
|
||||
void sendChannelSettings(
|
||||
const QList<ObjectPipe*>& pipes,
|
||||
QList<QString>& channelSettingsKeys,
|
||||
const RttyModSettings& settings,
|
||||
bool force
|
||||
);
|
||||
void webapiFormatChannelSettings(
|
||||
QList<QString>& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings *swgChannelSettings,
|
||||
const RttyModSettings& settings,
|
||||
bool force
|
||||
);
|
||||
void openUDP(const RttyModSettings& settings);
|
||||
void closeUDP();
|
||||
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void udpRx();
|
||||
};
|
||||
|
||||
|
||||
#endif /* PLUGINS_CHANNELTX_MODRTTY_RTTYMOD_H_ */
|
200
plugins/channeltx/modrtty/rttymodbaseband.cpp
Normal file
200
plugins/channeltx/modrtty/rttymodbaseband.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "dsp/upchannelizer.h"
|
||||
#include "dsp/dspengine.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
|
||||
#include "rttymodbaseband.h"
|
||||
#include "rttymod.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(RttyModBaseband::MsgConfigureRttyModBaseband, Message)
|
||||
|
||||
RttyModBaseband::RttyModBaseband()
|
||||
{
|
||||
m_sampleFifo.resize(SampleSourceFifo::getSizePolicy(48000));
|
||||
m_channelizer = new UpChannelizer(&m_source);
|
||||
|
||||
qDebug("RttyModBaseband::RttyModBaseband");
|
||||
QObject::connect(
|
||||
&m_sampleFifo,
|
||||
&SampleSourceFifo::dataRead,
|
||||
this,
|
||||
&RttyModBaseband::handleData,
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
|
||||
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
}
|
||||
|
||||
RttyModBaseband::~RttyModBaseband()
|
||||
{
|
||||
delete m_channelizer;
|
||||
}
|
||||
|
||||
void RttyModBaseband::reset()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
m_sampleFifo.reset();
|
||||
}
|
||||
|
||||
void RttyModBaseband::setChannel(ChannelAPI *channel)
|
||||
{
|
||||
m_source.setChannel(channel);
|
||||
}
|
||||
|
||||
void RttyModBaseband::pull(const SampleVector::iterator& begin, unsigned int nbSamples)
|
||||
{
|
||||
unsigned int part1Begin, part1End, part2Begin, part2End;
|
||||
m_sampleFifo.read(nbSamples, part1Begin, part1End, part2Begin, part2End);
|
||||
SampleVector& data = m_sampleFifo.getData();
|
||||
|
||||
if (part1Begin != part1End)
|
||||
{
|
||||
std::copy(
|
||||
data.begin() + part1Begin,
|
||||
data.begin() + part1End,
|
||||
begin
|
||||
);
|
||||
}
|
||||
|
||||
unsigned int shift = part1End - part1Begin;
|
||||
|
||||
if (part2Begin != part2End)
|
||||
{
|
||||
std::copy(
|
||||
data.begin() + part2Begin,
|
||||
data.begin() + part2End,
|
||||
begin + shift
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModBaseband::handleData()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
SampleVector& data = m_sampleFifo.getData();
|
||||
unsigned int ipart1begin;
|
||||
unsigned int ipart1end;
|
||||
unsigned int ipart2begin;
|
||||
unsigned int ipart2end;
|
||||
qreal rmsLevel, peakLevel;
|
||||
int numSamples;
|
||||
|
||||
unsigned int remainder = m_sampleFifo.remainder();
|
||||
|
||||
while ((remainder > 0) && (m_inputMessageQueue.size() == 0))
|
||||
{
|
||||
m_sampleFifo.write(remainder, ipart1begin, ipart1end, ipart2begin, ipart2end);
|
||||
|
||||
if (ipart1begin != ipart1end) { // first part of FIFO data
|
||||
processFifo(data, ipart1begin, ipart1end);
|
||||
}
|
||||
|
||||
if (ipart2begin != ipart2end) { // second part of FIFO data (used when block wraps around)
|
||||
processFifo(data, ipart2begin, ipart2end);
|
||||
}
|
||||
|
||||
remainder = m_sampleFifo.remainder();
|
||||
}
|
||||
|
||||
m_source.getLevels(rmsLevel, peakLevel, numSamples);
|
||||
emit levelChanged(rmsLevel, peakLevel, numSamples);
|
||||
}
|
||||
|
||||
void RttyModBaseband::processFifo(SampleVector& data, unsigned int iBegin, unsigned int iEnd)
|
||||
{
|
||||
m_channelizer->prefetch(iEnd - iBegin);
|
||||
m_channelizer->pull(data.begin() + iBegin, iEnd - iBegin);
|
||||
}
|
||||
|
||||
void RttyModBaseband::handleInputMessages()
|
||||
{
|
||||
Message* message;
|
||||
|
||||
while ((message = m_inputMessageQueue.pop()) != nullptr)
|
||||
{
|
||||
if (handleMessage(*message)) {
|
||||
delete message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RttyModBaseband::handleMessage(const Message& cmd)
|
||||
{
|
||||
if (MsgConfigureRttyModBaseband::match(cmd))
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
MsgConfigureRttyModBaseband& cfg = (MsgConfigureRttyModBaseband&) cmd;
|
||||
qDebug() << "RttyModBaseband::handleMessage: MsgConfigureRttyModBaseband";
|
||||
|
||||
applySettings(cfg.getSettings(), cfg.getForce());
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (RttyMod::MsgTx::match(cmd))
|
||||
{
|
||||
qDebug() << "RttyModBaseband::handleMessage: MsgTx";
|
||||
m_source.addTXText(m_settings.m_text);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (RttyMod::MsgTXText::match(cmd))
|
||||
{
|
||||
RttyMod::MsgTXText& tx = (RttyMod::MsgTXText&) cmd;
|
||||
m_source.addTXText(tx.m_text);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (DSPSignalNotification::match(cmd))
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
|
||||
qDebug() << "RttyModBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " << notif.getSampleRate();
|
||||
m_sampleFifo.resize(SampleSourceFifo::getSizePolicy(notif.getSampleRate()));
|
||||
m_channelizer->setBasebandSampleRate(notif.getSampleRate());
|
||||
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "RttyModBaseband - Baseband got unknown message";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModBaseband::applySettings(const RttyModSettings& settings, bool force)
|
||||
{
|
||||
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force)
|
||||
{
|
||||
m_channelizer->setChannelization(m_channelizer->getChannelSampleRate(), settings.m_inputFrequencyOffset);
|
||||
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
|
||||
}
|
||||
|
||||
m_source.applySettings(settings, force);
|
||||
|
||||
m_settings = settings;
|
||||
}
|
||||
|
||||
int RttyModBaseband::getChannelSampleRate() const
|
||||
{
|
||||
return m_channelizer->getChannelSampleRate();
|
||||
}
|
100
plugins/channeltx/modrtty/rttymodbaseband.h
Normal file
100
plugins/channeltx/modrtty/rttymodbaseband.h
Normal file
@ -0,0 +1,100 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_RTTYMODBASEBAND_H
|
||||
#define INCLUDE_RTTYMODBASEBAND_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QRecursiveMutex>
|
||||
|
||||
#include "dsp/samplesourcefifo.h"
|
||||
#include "util/message.h"
|
||||
#include "util/messagequeue.h"
|
||||
|
||||
#include "rttymodsource.h"
|
||||
|
||||
class UpChannelizer;
|
||||
class ChannelAPI;
|
||||
|
||||
class RttyModBaseband : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
class MsgConfigureRttyModBaseband : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const RttyModSettings& getSettings() const { return m_settings; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigureRttyModBaseband* create(const RttyModSettings& settings, bool force)
|
||||
{
|
||||
return new MsgConfigureRttyModBaseband(settings, force);
|
||||
}
|
||||
|
||||
private:
|
||||
RttyModSettings m_settings;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigureRttyModBaseband(const RttyModSettings& settings, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
|
||||
RttyModBaseband();
|
||||
~RttyModBaseband();
|
||||
void reset();
|
||||
void pull(const SampleVector::iterator& begin, unsigned int nbSamples);
|
||||
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
|
||||
void setMessageQueueToGUI(MessageQueue* messageQueue) { m_source.setMessageQueueToGUI(messageQueue); }
|
||||
double getMagSq() const { return m_source.getMagSq(); }
|
||||
int getChannelSampleRate() const;
|
||||
void setSpectrumSampleSink(BasebandSampleSink* sampleSink) { m_source.setSpectrumSink(sampleSink); }
|
||||
void setChannel(ChannelAPI *channel);
|
||||
int getSourceChannelSampleRate() const { return m_source.getChannelSampleRate(); }
|
||||
|
||||
signals:
|
||||
/**
|
||||
* Level changed
|
||||
* \param rmsLevel RMS level in range 0.0 - 1.0
|
||||
* \param peakLevel Peak level in range 0.0 - 1.0
|
||||
* \param numSamples Number of audio samples analyzed
|
||||
*/
|
||||
void levelChanged(qreal rmsLevel, qreal peakLevel, int numSamples);
|
||||
|
||||
private:
|
||||
SampleSourceFifo m_sampleFifo;
|
||||
UpChannelizer *m_channelizer;
|
||||
RttyModSource m_source;
|
||||
MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
|
||||
RttyModSettings m_settings;
|
||||
QRecursiveMutex m_mutex;
|
||||
|
||||
void processFifo(SampleVector& data, unsigned int iBegin, unsigned int iEnd);
|
||||
bool handleMessage(const Message& cmd);
|
||||
void applySettings(const RttyModSettings& settings, bool force = false);
|
||||
|
||||
private slots:
|
||||
void handleInputMessages();
|
||||
void handleData(); //!< Handle data when samples have to be processed
|
||||
};
|
||||
|
||||
|
||||
#endif // INCLUDE_RTTYMODBASEBAND_H
|
651
plugins/channeltx/modrtty/rttymodgui.cpp
Normal file
651
plugins/channeltx/modrtty/rttymodgui.cpp
Normal file
@ -0,0 +1,651 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QMainWindow>
|
||||
#include <QFileDialog>
|
||||
#include <QTime>
|
||||
#include <QScrollBar>
|
||||
#include <QDebug>
|
||||
|
||||
#include "dsp/spectrumvis.h"
|
||||
#include "dsp/dspengine.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "device/deviceuiset.h"
|
||||
#include "plugin/pluginapi.h"
|
||||
#include "plugin/pluginapi.h"
|
||||
#include "util/simpleserializer.h"
|
||||
#include "util/db.h"
|
||||
#include "util/rtty.h"
|
||||
#include "util/maidenhead.h"
|
||||
#include "gui/glspectrum.h"
|
||||
#include "gui/crightclickenabler.h"
|
||||
#include "gui/basicchannelsettingsdialog.h"
|
||||
#include "gui/devicestreamselectiondialog.h"
|
||||
#include "gui/fmpreemphasisdialog.h"
|
||||
#include "gui/dialpopup.h"
|
||||
#include "gui/dialogpositioner.h"
|
||||
#include "maincore.h"
|
||||
|
||||
#include "ui_rttymodgui.h"
|
||||
#include "rttymodgui.h"
|
||||
#include "rttymodrepeatdialog.h"
|
||||
#include "rttymodtxsettingsdialog.h"
|
||||
|
||||
RttyModGUI* RttyModGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx)
|
||||
{
|
||||
RttyModGUI* gui = new RttyModGUI(pluginAPI, deviceUISet, channelTx);
|
||||
return gui;
|
||||
}
|
||||
|
||||
void RttyModGUI::destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void RttyModGUI::resetToDefaults()
|
||||
{
|
||||
m_settings.resetToDefaults();
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
}
|
||||
|
||||
QByteArray RttyModGUI::serialize() const
|
||||
{
|
||||
return m_settings.serialize();
|
||||
}
|
||||
|
||||
bool RttyModGUI::deserialize(const QByteArray& data)
|
||||
{
|
||||
if (m_settings.deserialize(data)) {
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
return true;
|
||||
} else {
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool RttyModGUI::handleMessage(const Message& message)
|
||||
{
|
||||
if (RttyMod::MsgConfigureRttyMod::match(message))
|
||||
{
|
||||
const RttyMod::MsgConfigureRttyMod& cfg = (RttyMod::MsgConfigureRttyMod&) message;
|
||||
m_settings = cfg.getSettings();
|
||||
blockApplySettings(true);
|
||||
m_channelMarker.updateSettings(static_cast<const ChannelMarker*>(m_settings.m_channelMarker));
|
||||
displaySettings();
|
||||
blockApplySettings(false);
|
||||
return true;
|
||||
}
|
||||
else if (RttyMod::MsgReportTx::match(message))
|
||||
{
|
||||
const RttyMod::MsgReportTx& report = (RttyMod::MsgReportTx&)message;
|
||||
QString s = report.getText();
|
||||
int bufferedCharacters = report.getBufferedCharacters();
|
||||
|
||||
// Turn TX button green when transmitting
|
||||
QString tooltip = m_initialToolTip;
|
||||
if (bufferedCharacters == 0)
|
||||
{
|
||||
ui->txButton->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->txButton->setStyleSheet("QToolButton { background-color : green; }");
|
||||
tooltip.append(QString("\n\n%1 characters in buffer").arg(bufferedCharacters));
|
||||
}
|
||||
ui->txButton->setToolTip(tooltip);
|
||||
|
||||
s = s.replace(">", ""); // Don't display LTRS
|
||||
s = s.replace("\r", ""); // Don't display carriage returns
|
||||
|
||||
if (!s.isEmpty())
|
||||
{
|
||||
// Is the scroll bar at the bottom?
|
||||
int scrollPos = ui->transmittedText->verticalScrollBar()->value();
|
||||
bool atBottom = scrollPos >= ui->transmittedText->verticalScrollBar()->maximum();
|
||||
|
||||
// Move cursor to end where we want to append new text
|
||||
// (user may have moved it by clicking / highlighting text)
|
||||
ui->transmittedText->moveCursor(QTextCursor::End);
|
||||
|
||||
// Restore scroll position
|
||||
ui->transmittedText->verticalScrollBar()->setValue(scrollPos);
|
||||
|
||||
// Insert text
|
||||
ui->transmittedText->insertPlainText(s);
|
||||
|
||||
// Scroll to bottom, if we we're previously at the bottom
|
||||
if (atBottom) {
|
||||
ui->transmittedText->verticalScrollBar()->setValue(ui->transmittedText->verticalScrollBar()->maximum());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (DSPSignalNotification::match(message))
|
||||
{
|
||||
const DSPSignalNotification& notif = (const DSPSignalNotification&) message;
|
||||
m_deviceCenterFrequency = notif.getCenterFrequency();
|
||||
m_basebandSampleRate = notif.getSampleRate();
|
||||
ui->deltaFrequency->setValueRange(false, 7, -m_basebandSampleRate/2, m_basebandSampleRate/2);
|
||||
ui->deltaFrequencyLabel->setToolTip(tr("Range %1 %L2 Hz").arg(QChar(0xB1)).arg(m_basebandSampleRate/2));
|
||||
updateAbsoluteCenterFrequency();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModGUI::channelMarkerChangedByCursor()
|
||||
{
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::handleSourceMessages()
|
||||
{
|
||||
Message* message;
|
||||
|
||||
while ((message = getInputMessageQueue()->pop()) != 0)
|
||||
{
|
||||
if (handleMessage(*message))
|
||||
{
|
||||
delete message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModGUI::on_deltaFrequency_changed(qint64 value)
|
||||
{
|
||||
m_channelMarker.setCenterFrequency(value);
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
updateAbsoluteCenterFrequency();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_mode_currentIndexChanged(int index)
|
||||
{
|
||||
(void)index;
|
||||
|
||||
QString mode = ui->mode->currentText();
|
||||
|
||||
bool custom = mode == "Custom";
|
||||
if (!custom)
|
||||
{
|
||||
QStringList settings = mode.split("/");
|
||||
int baudRate = settings[0].toInt();
|
||||
int frequencyShift = settings[1].toInt();
|
||||
int bandwidth = frequencyShift * 2 + baudRate;
|
||||
ui->baudRate->setCurrentText(settings[0]);
|
||||
ui->frequencyShift->setValue(frequencyShift);
|
||||
ui->rfBW->setValue(bandwidth);
|
||||
}
|
||||
|
||||
ui->baudRateLabel->setEnabled(custom);
|
||||
ui->baudRate->setEnabled(custom);
|
||||
ui->frequencyShiftLabel->setEnabled(custom);
|
||||
ui->frequencyShift->setEnabled(custom);
|
||||
ui->frequencyShiftText->setEnabled(custom);
|
||||
ui->rfBWLabel->setEnabled(custom);
|
||||
ui->rfBW->setEnabled(custom);
|
||||
ui->rfBWText->setEnabled(custom);
|
||||
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_rfBW_valueChanged(int value)
|
||||
{
|
||||
int bw = value;
|
||||
ui->rfBWText->setText(formatFrequency(bw));
|
||||
m_channelMarker.setBandwidth(bw);
|
||||
m_settings.m_rfBandwidth = bw;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_baudRate_currentIndexChanged(int index)
|
||||
{
|
||||
(void)index;
|
||||
m_settings.m_baud = ui->baudRate->currentText().toFloat();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_frequencyShift_valueChanged(int value)
|
||||
{
|
||||
m_settings.m_frequencyShift = value;
|
||||
ui->frequencyShiftText->setText(formatFrequency(m_settings.m_frequencyShift));
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_characterSet_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_characterSet = (Baudot::CharacterSet)index;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_endian_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_msbFirst = checked;
|
||||
if (checked) {
|
||||
ui->endian->setText("MSB");
|
||||
} else {
|
||||
ui->endian->setText("LSB");
|
||||
}
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_spaceHigh_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_spaceHigh = checked;
|
||||
if (checked) {
|
||||
ui->spaceHigh->setText("M-S");
|
||||
} else {
|
||||
ui->spaceHigh->setText("S-M");
|
||||
}
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_clearTransmittedText_clicked()
|
||||
{
|
||||
ui->transmittedText->clear();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_gain_valueChanged(int value)
|
||||
{
|
||||
ui->gainText->setText(QString("%1dB").arg(value));
|
||||
m_settings.m_gain = value;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_channelMute_toggled(bool checked)
|
||||
{
|
||||
m_settings.m_channelMute = checked;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_txButton_clicked()
|
||||
{
|
||||
transmit(ui->text->currentText());
|
||||
}
|
||||
|
||||
void RttyModGUI::on_text_returnPressed()
|
||||
{
|
||||
transmit(ui->text->currentText());
|
||||
ui->text->setCurrentText("");
|
||||
}
|
||||
|
||||
void RttyModGUI::on_text_editingFinished()
|
||||
{
|
||||
m_settings.m_text = ui->text->currentText();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_repeat_toggled(bool checked)
|
||||
{
|
||||
m_settings.m_repeat = checked;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::repeatSelect(const QPoint& p)
|
||||
{
|
||||
RttyModRepeatDialog dialog(m_settings.m_repeatCount);
|
||||
dialog.move(p);
|
||||
new DialogPositioner(&dialog, false);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
m_settings.m_repeatCount = dialog.m_repeatCount;
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModGUI::txSettingsSelect(const QPoint& p)
|
||||
{
|
||||
RttyModTXSettingsDialog dialog(&m_settings);
|
||||
dialog.move(p);
|
||||
new DialogPositioner(&dialog, false);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
displaySettings();
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModGUI::on_udpEnabled_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_udpEnabled = checked;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_udpAddress_editingFinished()
|
||||
{
|
||||
m_settings.m_udpAddress = ui->udpAddress->text();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::on_udpPort_editingFinished()
|
||||
{
|
||||
m_settings.m_udpPort = ui->udpPort->text().toInt();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::onWidgetRolled(QWidget* widget, bool rollDown)
|
||||
{
|
||||
(void) widget;
|
||||
(void) rollDown;
|
||||
|
||||
getRollupContents()->saveState(m_rollupState);
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RttyModGUI::onMenuDialogCalled(const QPoint &p)
|
||||
{
|
||||
if (m_contextMenuType == ContextMenuChannelSettings)
|
||||
{
|
||||
BasicChannelSettingsDialog dialog(&m_channelMarker, this);
|
||||
dialog.setUseReverseAPI(m_settings.m_useReverseAPI);
|
||||
dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress);
|
||||
dialog.setReverseAPIPort(m_settings.m_reverseAPIPort);
|
||||
dialog.setReverseAPIDeviceIndex(m_settings.m_reverseAPIDeviceIndex);
|
||||
dialog.setReverseAPIChannelIndex(m_settings.m_reverseAPIChannelIndex);
|
||||
dialog.setDefaultTitle(m_displayedName);
|
||||
|
||||
if (m_deviceUISet->m_deviceMIMOEngine)
|
||||
{
|
||||
dialog.setNumberOfStreams(m_rttyMod->getNumberOfDeviceStreams());
|
||||
dialog.setStreamIndex(m_settings.m_streamIndex);
|
||||
}
|
||||
|
||||
dialog.move(p);
|
||||
new DialogPositioner(&dialog, false);
|
||||
dialog.exec();
|
||||
|
||||
m_settings.m_rgbColor = m_channelMarker.getColor().rgb();
|
||||
m_settings.m_title = m_channelMarker.getTitle();
|
||||
m_settings.m_useReverseAPI = dialog.useReverseAPI();
|
||||
m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress();
|
||||
m_settings.m_reverseAPIPort = dialog.getReverseAPIPort();
|
||||
m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex();
|
||||
m_settings.m_reverseAPIChannelIndex = dialog.getReverseAPIChannelIndex();
|
||||
|
||||
setWindowTitle(m_settings.m_title);
|
||||
setTitle(m_channelMarker.getTitle());
|
||||
setTitleColor(m_settings.m_rgbColor);
|
||||
|
||||
if (m_deviceUISet->m_deviceMIMOEngine)
|
||||
{
|
||||
m_settings.m_streamIndex = dialog.getSelectedStreamIndex();
|
||||
m_channelMarker.clearStreamIndexes();
|
||||
m_channelMarker.addStreamIndex(m_settings.m_streamIndex);
|
||||
updateIndexLabel();
|
||||
}
|
||||
|
||||
applySettings();
|
||||
}
|
||||
|
||||
resetContextMenuType();
|
||||
}
|
||||
|
||||
RttyModGUI::RttyModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget* parent) :
|
||||
ChannelGUI(parent),
|
||||
ui(new Ui::RttyModGUI),
|
||||
m_pluginAPI(pluginAPI),
|
||||
m_deviceUISet(deviceUISet),
|
||||
m_channelMarker(this),
|
||||
m_deviceCenterFrequency(0),
|
||||
m_basebandSampleRate(1),
|
||||
m_doApplySettings(true)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
m_helpURL = "plugins/channeltx/modrtty/readme.md";
|
||||
RollupContents *rollupContents = getRollupContents();
|
||||
ui->setupUi(rollupContents);
|
||||
setSizePolicy(rollupContents->sizePolicy());
|
||||
rollupContents->arrangeRollups();
|
||||
connect(rollupContents, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
|
||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
|
||||
|
||||
m_rttyMod = (RttyMod*) channelTx;
|
||||
m_rttyMod->setMessageQueueToGUI(getInputMessageQueue());
|
||||
|
||||
connect(&MainCore::instance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
|
||||
|
||||
m_spectrumVis = m_rttyMod->getSpectrumVis();
|
||||
m_spectrumVis->setGLSpectrum(ui->glSpectrum);
|
||||
|
||||
ui->spectrumGUI->setBuddies(m_spectrumVis, ui->glSpectrum);
|
||||
|
||||
ui->glSpectrum->setCenterFrequency(0);
|
||||
ui->glSpectrum->setSampleRate(2000);
|
||||
ui->glSpectrum->setLsbDisplay(false);
|
||||
|
||||
SpectrumSettings spectrumSettings = m_spectrumVis->getSettings();
|
||||
spectrumSettings.m_ssb = false;
|
||||
spectrumSettings.m_displayCurrent = true;
|
||||
spectrumSettings.m_displayWaterfall = false;
|
||||
spectrumSettings.m_displayMaxHold = false;
|
||||
spectrumSettings.m_displayHistogram = false;
|
||||
SpectrumVis::MsgConfigureSpectrumVis *msg = SpectrumVis::MsgConfigureSpectrumVis::create(spectrumSettings, false);
|
||||
m_spectrumVis->getInputMessageQueue()->push(msg);
|
||||
|
||||
CRightClickEnabler *repeatRightClickEnabler = new CRightClickEnabler(ui->repeat);
|
||||
connect(repeatRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(repeatSelect(const QPoint &)));
|
||||
|
||||
CRightClickEnabler *txRightClickEnabler = new CRightClickEnabler(ui->txButton);
|
||||
connect(txRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(txSettingsSelect(const QPoint &)));
|
||||
|
||||
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
|
||||
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
||||
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
||||
|
||||
m_channelMarker.blockSignals(true);
|
||||
m_channelMarker.setColor(Qt::red);
|
||||
m_channelMarker.setBandwidth(12500);
|
||||
m_channelMarker.setCenterFrequency(0);
|
||||
m_channelMarker.setTitle("RTTY Modulator");
|
||||
m_channelMarker.setSourceOrSinkStream(false);
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.setVisible(true); // activate signal on the last setting only
|
||||
|
||||
m_deviceUISet->addChannelMarker(&m_channelMarker);
|
||||
|
||||
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
|
||||
|
||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
|
||||
m_rttyMod->setLevelMeter(ui->volumeMeter);
|
||||
|
||||
m_settings.setChannelMarker(&m_channelMarker);
|
||||
m_settings.setRollupState(&m_rollupState);
|
||||
|
||||
ui->transmittedText->addAcronyms(Rtty::m_acronyms);
|
||||
|
||||
ui->spectrumContainer->setVisible(false);
|
||||
|
||||
displaySettings();
|
||||
makeUIConnections();
|
||||
applySettings();
|
||||
DialPopup::addPopupsToChildDials(this);
|
||||
|
||||
m_initialToolTip = ui->txButton->toolTip();
|
||||
}
|
||||
|
||||
RttyModGUI::~RttyModGUI()
|
||||
{
|
||||
// If we don't disconnect, we can get this signal after this has been deleted!
|
||||
QObject::disconnect(ui->text->lineEdit(), &QLineEdit::editingFinished, this, &RttyModGUI::on_text_editingFinished);
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void RttyModGUI::transmit(const QString& text)
|
||||
{
|
||||
RttyMod::MsgTXText*msg = RttyMod::MsgTXText::create(text);
|
||||
m_rttyMod->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
void RttyModGUI::blockApplySettings(bool block)
|
||||
{
|
||||
m_doApplySettings = !block;
|
||||
}
|
||||
|
||||
void RttyModGUI::applySettings(bool force)
|
||||
{
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
RttyMod::MsgConfigureRttyMod *msg = RttyMod::MsgConfigureRttyMod::create(m_settings, force);
|
||||
m_rttyMod->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
QString RttyModGUI::formatFrequency(int frequency) const
|
||||
{
|
||||
QString suffix = "";
|
||||
if (width() > 450) {
|
||||
suffix = " Hz";
|
||||
}
|
||||
return QString("%1%2").arg(frequency).arg(suffix);
|
||||
}
|
||||
|
||||
QString RttyModGUI::substitute(const QString& text)
|
||||
{
|
||||
const MainSettings& mainSettings = MainCore::instance()->getSettings();
|
||||
QString location = Maidenhead::toMaidenhead(mainSettings.getLatitude(), mainSettings.getLongitude());
|
||||
QString s = text;
|
||||
|
||||
s = s.replace("${callsign}", mainSettings.getStationName().toUpper());
|
||||
s = s.replace("${location}", location);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void RttyModGUI::displaySettings()
|
||||
{
|
||||
m_channelMarker.blockSignals(true);
|
||||
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
|
||||
m_channelMarker.setTitle(m_settings.m_title);
|
||||
m_channelMarker.setBandwidth(m_settings.m_rfBandwidth);
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.setColor(m_settings.m_rgbColor); // activate signal on the last setting only
|
||||
|
||||
setTitleColor(m_settings.m_rgbColor);
|
||||
setWindowTitle(m_channelMarker.getTitle());
|
||||
setTitle(m_channelMarker.getTitle());
|
||||
updateIndexLabel();
|
||||
|
||||
blockApplySettings(true);
|
||||
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
|
||||
ui->mode->setCurrentText("Custom");
|
||||
ui->rfBWText->setText(formatFrequency(m_settings.m_rfBandwidth));
|
||||
ui->rfBW->setValue(m_settings.m_rfBandwidth);
|
||||
QString baudRate;
|
||||
if (m_settings.m_baud < 46.0f && m_settings.m_baud > 45.0f) {
|
||||
baudRate = "45.45";
|
||||
} else {
|
||||
baudRate = QString("%1").arg(m_settings.m_baud);
|
||||
}
|
||||
ui->baudRate->setCurrentIndex(ui->baudRate->findText(baudRate));
|
||||
ui->frequencyShiftText->setText(formatFrequency(m_settings.m_frequencyShift));
|
||||
ui->frequencyShift->setValue(m_settings.m_frequencyShift);
|
||||
ui->frequencyShift->setValue(m_settings.m_frequencyShift);
|
||||
|
||||
ui->characterSet->setCurrentIndex((int)m_settings.m_characterSet);
|
||||
ui->endian->setChecked(m_settings.m_msbFirst);
|
||||
if (m_settings.m_msbFirst) {
|
||||
ui->endian->setText("MSB");
|
||||
} else {
|
||||
ui->endian->setText("LSB");
|
||||
}
|
||||
ui->spaceHigh->setChecked(m_settings.m_spaceHigh);
|
||||
if (m_settings.m_spaceHigh) {
|
||||
ui->spaceHigh->setText("M-S");
|
||||
} else {
|
||||
ui->spaceHigh->setText("S-M");
|
||||
}
|
||||
|
||||
ui->udpEnabled->setChecked(m_settings.m_udpEnabled);
|
||||
ui->udpAddress->setText(m_settings.m_udpAddress);
|
||||
ui->udpPort->setText(QString::number(m_settings.m_udpPort));
|
||||
|
||||
ui->gainText->setText(QString("%1").arg((double)m_settings.m_gain, 0, 'f', 1));
|
||||
ui->gain->setValue(m_settings.m_gain);
|
||||
|
||||
ui->channelMute->setChecked(m_settings.m_channelMute);
|
||||
ui->repeat->setChecked(m_settings.m_repeat);
|
||||
|
||||
ui->text->clear();
|
||||
for (const auto& text : m_settings.m_predefinedTexts) {
|
||||
ui->text->addItem(substitute(text));
|
||||
}
|
||||
ui->text->setCurrentText(m_settings.m_text);
|
||||
|
||||
getRollupContents()->restoreState(m_rollupState);
|
||||
updateAbsoluteCenterFrequency();
|
||||
blockApplySettings(false);
|
||||
}
|
||||
|
||||
void RttyModGUI::leaveEvent(QEvent* event)
|
||||
{
|
||||
m_channelMarker.setHighlighted(false);
|
||||
ChannelGUI::leaveEvent(event);
|
||||
}
|
||||
|
||||
void RttyModGUI::enterEvent(EnterEventType* event)
|
||||
{
|
||||
m_channelMarker.setHighlighted(true);
|
||||
ChannelGUI::enterEvent(event);
|
||||
}
|
||||
|
||||
void RttyModGUI::tick()
|
||||
{
|
||||
double powDb = CalcDb::dbPower(m_rttyMod->getMagSq());
|
||||
m_channelPowerDbAvg(powDb);
|
||||
ui->channelPower->setText(tr("%1 dB").arg(m_channelPowerDbAvg.asDouble(), 0, 'f', 1));
|
||||
}
|
||||
|
||||
void RttyModGUI::makeUIConnections()
|
||||
{
|
||||
QObject::connect(ui->deltaFrequency, &ValueDialZ::changed, this, &RttyModGUI::on_deltaFrequency_changed);
|
||||
QObject::connect(ui->mode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &RttyModGUI::on_mode_currentIndexChanged);
|
||||
QObject::connect(ui->rfBW, &QSlider::valueChanged, this, &RttyModGUI::on_rfBW_valueChanged);
|
||||
QObject::connect(ui->baudRate, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &RttyModGUI::on_baudRate_currentIndexChanged);
|
||||
QObject::connect(ui->frequencyShift, &QSlider::valueChanged, this, &RttyModGUI::on_frequencyShift_valueChanged);
|
||||
QObject::connect(ui->characterSet, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &RttyModGUI::on_characterSet_currentIndexChanged);
|
||||
QObject::connect(ui->endian, &QCheckBox::clicked, this, &RttyModGUI::on_endian_clicked);
|
||||
QObject::connect(ui->spaceHigh, &QCheckBox::clicked, this, &RttyModGUI::on_spaceHigh_clicked);
|
||||
QObject::connect(ui->clearTransmittedText, &QToolButton::clicked, this, &RttyModGUI::on_clearTransmittedText_clicked);
|
||||
QObject::connect(ui->gain, &QDial::valueChanged, this, &RttyModGUI::on_gain_valueChanged);
|
||||
QObject::connect(ui->channelMute, &QToolButton::toggled, this, &RttyModGUI::on_channelMute_toggled);
|
||||
QObject::connect(ui->txButton, &QToolButton::clicked, this, &RttyModGUI::on_txButton_clicked);
|
||||
QObject::connect(ui->text->lineEdit(), &QLineEdit::editingFinished, this, &RttyModGUI::on_text_editingFinished);
|
||||
QObject::connect(ui->text->lineEdit(), &QLineEdit::returnPressed, this, &RttyModGUI::on_text_returnPressed);
|
||||
QObject::connect(ui->repeat, &ButtonSwitch::toggled, this, &RttyModGUI::on_repeat_toggled);
|
||||
QObject::connect(ui->udpEnabled, &QCheckBox::clicked, this, &RttyModGUI::on_udpEnabled_clicked);
|
||||
QObject::connect(ui->udpAddress, &QLineEdit::editingFinished, this, &RttyModGUI::on_udpAddress_editingFinished);
|
||||
QObject::connect(ui->udpPort, &QLineEdit::editingFinished, this, &RttyModGUI::on_udpPort_editingFinished);
|
||||
}
|
||||
|
||||
void RttyModGUI::updateAbsoluteCenterFrequency()
|
||||
{
|
||||
setStatusFrequency(m_deviceCenterFrequency + m_settings.m_inputFrequencyOffset);
|
||||
}
|
130
plugins/channeltx/modrtty/rttymodgui.h
Normal file
130
plugins/channeltx/modrtty/rttymodgui.h
Normal file
@ -0,0 +1,130 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PLUGINS_CHANNELTX_MODRTTY_RTTYMODGUI_H_
|
||||
#define PLUGINS_CHANNELTX_MODRTTY_RTTYMODGUI_H_
|
||||
|
||||
#include "channel/channelgui.h"
|
||||
#include "dsp/channelmarker.h"
|
||||
#include "util/movingaverage.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "settings/rollupstate.h"
|
||||
|
||||
#include "rttymod.h"
|
||||
#include "rttymodsettings.h"
|
||||
|
||||
class PluginAPI;
|
||||
class DeviceUISet;
|
||||
class BasebandSampleSource;
|
||||
class SpectrumVis;
|
||||
|
||||
namespace Ui {
|
||||
class RttyModGUI;
|
||||
}
|
||||
|
||||
class RttyModGUI : public ChannelGUI {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static RttyModGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx);
|
||||
virtual void destroy();
|
||||
|
||||
void resetToDefaults();
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
|
||||
virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; };
|
||||
virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; };
|
||||
virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; };
|
||||
virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; };
|
||||
virtual QString getTitle() const { return m_settings.m_title; };
|
||||
virtual QColor getTitleColor() const { return m_settings.m_rgbColor; };
|
||||
virtual void zetHidden(bool hidden) { m_settings.m_hidden = hidden; }
|
||||
virtual bool getHidden() const { return m_settings.m_hidden; }
|
||||
virtual ChannelMarker& getChannelMarker() { return m_channelMarker; }
|
||||
virtual int getStreamIndex() const { return m_settings.m_streamIndex; }
|
||||
virtual void setStreamIndex(int streamIndex) { m_settings.m_streamIndex = streamIndex; }
|
||||
|
||||
public slots:
|
||||
void channelMarkerChangedByCursor();
|
||||
|
||||
private:
|
||||
Ui::RttyModGUI* ui;
|
||||
PluginAPI* m_pluginAPI;
|
||||
DeviceUISet* m_deviceUISet;
|
||||
ChannelMarker m_channelMarker;
|
||||
RollupState m_rollupState;
|
||||
RttyModSettings m_settings;
|
||||
qint64 m_deviceCenterFrequency;
|
||||
int m_basebandSampleRate;
|
||||
bool m_doApplySettings;
|
||||
SpectrumVis* m_spectrumVis;
|
||||
QString m_initialToolTip;
|
||||
|
||||
RttyMod* m_rttyMod;
|
||||
MovingAverageUtil<double, double, 2> m_channelPowerDbAvg; // Less than other mods, as packets are short
|
||||
|
||||
MessageQueue m_inputMessageQueue;
|
||||
|
||||
explicit RttyModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget* parent = 0);
|
||||
virtual ~RttyModGUI();
|
||||
|
||||
void transmit(const QString& str);
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings(bool force = false);
|
||||
void displaySettings();
|
||||
QString formatFrequency(int frequency) const;
|
||||
bool handleMessage(const Message& message);
|
||||
void makeUIConnections();
|
||||
void updateAbsoluteCenterFrequency();
|
||||
QString substitute(const QString& text);
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(EnterEventType*);
|
||||
|
||||
private slots:
|
||||
void handleSourceMessages();
|
||||
|
||||
void on_deltaFrequency_changed(qint64 value);
|
||||
void on_mode_currentIndexChanged(int value);
|
||||
void on_rfBW_valueChanged(int index);
|
||||
void on_baudRate_currentIndexChanged(int index);
|
||||
void on_frequencyShift_valueChanged(int value);
|
||||
void on_gain_valueChanged(int value);
|
||||
void on_channelMute_toggled(bool checked);
|
||||
void on_characterSet_currentIndexChanged(int index);
|
||||
void on_endian_clicked(bool checked);
|
||||
void on_spaceHigh_clicked(bool checked);
|
||||
void on_clearTransmittedText_clicked();
|
||||
void on_txButton_clicked();
|
||||
void on_text_editingFinished();
|
||||
void on_text_returnPressed();
|
||||
void on_repeat_toggled(bool checked);
|
||||
void repeatSelect(const QPoint& p);
|
||||
void txSettingsSelect(const QPoint& p);
|
||||
void on_udpEnabled_clicked(bool checked);
|
||||
void on_udpAddress_editingFinished();
|
||||
void on_udpPort_editingFinished();
|
||||
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void onMenuDialogCalled(const QPoint& p);
|
||||
|
||||
void tick();
|
||||
};
|
||||
|
||||
#endif /* PLUGINS_CHANNELTX_MODRTTY_RTTYMODGUI_H_ */
|
977
plugins/channeltx/modrtty/rttymodgui.ui
Normal file
977
plugins/channeltx/modrtty/rttymodgui.ui
Normal file
@ -0,0 +1,977 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RttyModGUI</class>
|
||||
<widget class="RollupContents" name="RttyModGUI">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>396</width>
|
||||
<height>702</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>390</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Sans</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>RTTY Modulator</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="settingsContainer" native="true">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>2</x>
|
||||
<y>2</y>
|
||||
<width>391</width>
|
||||
<height>211</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>280</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="settingsLayout">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="deltaFreqPowLayout">
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="deltaFrequencyLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="deltaFrequencyLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Df</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ValueDialZ" name="deltaFrequency" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Mono</family>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Demod shift frequency from center in Hz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="deltaUnits">
|
||||
<property name="text">
|
||||
<string>Hz </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="channelPower">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Channel power</string>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-100.0 dB</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="channelMute">
|
||||
<property name="toolTip">
|
||||
<string>Mute/Unmute channel</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/txon.png</normaloff>
|
||||
<normalon>:/txoff.png</normalon>:/txon.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="rfBandwidthLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="mode">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>86</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>RTTY baud rate and frequency shift</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>45.45/170</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>50/170</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>50/450</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>75/170</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>75/850</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Custom</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="baudRateLabel">
|
||||
<property name="text">
|
||||
<string>Baud</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="baudRate">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Baud rate in symbols per second</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>45</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>45.45</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>50</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>75</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>100</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>110</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>150</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>200</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="frequencyShiftLabel">
|
||||
<property name="text">
|
||||
<string>Shift</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="frequencyShift">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Frequency shift in Hertz</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>170</number>
|
||||
</property>
|
||||
<property name="sliderPosition">
|
||||
<number>170</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="frequencyShiftText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>850</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="rfBWLabel">
|
||||
<property name="text">
|
||||
<string>BW</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="rfBW">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>RF bandwidth</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>340</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="rfBWText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1700</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="volumeLayout">
|
||||
<item>
|
||||
<widget class="QDial" name="gain">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Gain</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-60</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="gainLabel">
|
||||
<property name="text">
|
||||
<string>Gain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="gainText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Audio input gain value</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-80.0dB</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LevelMeterVU" name="volumeMeter" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Mono</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Level (% full range) top trace: average, bottom trace: instantaneous peak, tip: peak hold</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="udpLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="udpEnabled">
|
||||
<property name="toolTip">
|
||||
<string>Forward text received via UDP</string>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>UDP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="udpAddress">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>UDP address to listen for text to forward on</string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>000.000.000.000</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>127.0.0.1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="udpSeparator">
|
||||
<property name="text">
|
||||
<string>:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="udpPort">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>UDP port to listen for text to forward on</string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>00000</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>9997</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="callsignLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="characterSetLabel">
|
||||
<property name="text">
|
||||
<string>Baudot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="characterSet">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Baudot character set</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ITA 2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>UK</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>European</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>US</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Russian</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Murray</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="endian">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Whether LSB (Least significant bit) or MSB (Most significant bit) is transmitted first</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>LSB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="spaceHigh">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Whether mark is high RF frequency (unchecked) or low RF frequency (checked)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>S-M</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="unshiftOnSpace">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Unshift on space - Set character set to letter when a space character is transmitted</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>US</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacerSettings">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="repeat">
|
||||
<property name="toolTip">
|
||||
<string>Repeatedly transmit the text. Right click for additional settings.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/playloop.png</normaloff>:/playloop.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="clearTransmittedText">
|
||||
<property name="toolTip">
|
||||
<string>Clear transmitted text</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/bin.png</normaloff>:/bin.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="packetDataLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="text">
|
||||
<property name="toolTip">
|
||||
<string>Text to send</string>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="txButton">
|
||||
<property name="toolTip">
|
||||
<string>Press to transmit the text. Right click for additional settings.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TX</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="logContainer" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>220</y>
|
||||
<width>391</width>
|
||||
<height>141</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Transmitted Text</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="transmittedLayout">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="AcronymView" name="transmittedText"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="spectrumContainer" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>370</y>
|
||||
<width>381</width>
|
||||
<height>284</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Baseband Spectrum</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="spectrumLayout">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="GLSpectrum" name="glSpectrum" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>250</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Mono</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="GLSpectrumGUI" name="spectrumGUI" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>RollupContents</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/rollupcontents.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GLSpectrum</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/glspectrum.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GLSpectrumGUI</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/glspectrumgui.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ValueDialZ</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/valuedialz.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ButtonSwitch</class>
|
||||
<extends>QToolButton</extends>
|
||||
<header>gui/buttonswitch.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LevelMeterVU</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/levelmeter.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>AcronymView</class>
|
||||
<extends>QTextEdit</extends>
|
||||
<header>gui/acronymview.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>deltaFrequency</tabstop>
|
||||
<tabstop>channelMute</tabstop>
|
||||
<tabstop>rfBW</tabstop>
|
||||
<tabstop>txButton</tabstop>
|
||||
<tabstop>transmittedText</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../../sdrgui/resources/res.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
92
plugins/channeltx/modrtty/rttymodplugin.cpp
Normal file
92
plugins/channeltx/modrtty/rttymodplugin.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QtPlugin>
|
||||
#include "plugin/pluginapi.h"
|
||||
|
||||
#ifndef SERVER_MODE
|
||||
#include "rttymodgui.h"
|
||||
#endif
|
||||
#include "rttymod.h"
|
||||
#include "rttymodwebapiadapter.h"
|
||||
#include "rttymodplugin.h"
|
||||
|
||||
const PluginDescriptor RttyModPlugin::m_pluginDescriptor = {
|
||||
RttyMod::m_channelId,
|
||||
QStringLiteral("RTTY Modulator"),
|
||||
QStringLiteral("7.16.0"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel")
|
||||
};
|
||||
|
||||
RttyModPlugin::RttyModPlugin(QObject* parent) :
|
||||
QObject(parent),
|
||||
m_pluginAPI(0)
|
||||
{
|
||||
}
|
||||
|
||||
const PluginDescriptor& RttyModPlugin::getPluginDescriptor() const
|
||||
{
|
||||
return m_pluginDescriptor;
|
||||
}
|
||||
|
||||
void RttyModPlugin::initPlugin(PluginAPI* pluginAPI)
|
||||
{
|
||||
m_pluginAPI = pluginAPI;
|
||||
|
||||
m_pluginAPI->registerTxChannel(RttyMod::m_channelIdURI, RttyMod::m_channelId, this);
|
||||
}
|
||||
|
||||
void RttyModPlugin::createTxChannel(DeviceAPI *deviceAPI, BasebandSampleSource **bs, ChannelAPI **cs) const
|
||||
{
|
||||
if (bs || cs)
|
||||
{
|
||||
RttyMod *instance = new RttyMod(deviceAPI);
|
||||
|
||||
if (bs) {
|
||||
*bs = instance;
|
||||
}
|
||||
|
||||
if (cs) {
|
||||
*cs = instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SERVER_MODE
|
||||
ChannelGUI* RttyModPlugin::createTxChannelGUI(
|
||||
DeviceUISet *deviceUISet,
|
||||
BasebandSampleSource *txChannel) const
|
||||
{
|
||||
(void) deviceUISet;
|
||||
(void) txChannel;
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
ChannelGUI* RttyModPlugin::createTxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSource *txChannel) const
|
||||
{
|
||||
return RttyModGUI::create(m_pluginAPI, deviceUISet, txChannel);
|
||||
}
|
||||
#endif
|
||||
|
||||
ChannelWebAPIAdapter* RttyModPlugin::createChannelWebAPIAdapter() const
|
||||
{
|
||||
return new RttyModWebAPIAdapter();
|
||||
}
|
49
plugins/channeltx/modrtty/rttymodplugin.h
Normal file
49
plugins/channeltx/modrtty/rttymodplugin.h
Normal file
@ -0,0 +1,49 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_RTTYMODPLUGIN_H
|
||||
#define INCLUDE_RTTYMODPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#include "plugin/plugininterface.h"
|
||||
|
||||
class DeviceUISet;
|
||||
class BasebandSampleSource;
|
||||
|
||||
class RttyModPlugin : public QObject, PluginInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(PluginInterface)
|
||||
Q_PLUGIN_METADATA(IID "sdrangel.channeltx.rttymod")
|
||||
|
||||
public:
|
||||
explicit RttyModPlugin(QObject* parent = 0);
|
||||
|
||||
const PluginDescriptor& getPluginDescriptor() const;
|
||||
void initPlugin(PluginAPI* pluginAPI);
|
||||
|
||||
virtual void createTxChannel(DeviceAPI *deviceAPI, BasebandSampleSource **bs, ChannelAPI **cs) const;
|
||||
virtual ChannelGUI* createTxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSource *rxChannel) const;
|
||||
virtual ChannelWebAPIAdapter* createChannelWebAPIAdapter() const;
|
||||
|
||||
private:
|
||||
static const PluginDescriptor m_pluginDescriptor;
|
||||
|
||||
PluginAPI* m_pluginAPI;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_RTTYMODPLUGIN_H
|
43
plugins/channeltx/modrtty/rttymodrepeatdialog.cpp
Normal file
43
plugins/channeltx/modrtty/rttymodrepeatdialog.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "rttymodrepeatdialog.h"
|
||||
#include "rttymodsettings.h"
|
||||
#include <QLineEdit>
|
||||
|
||||
RttyModRepeatDialog::RttyModRepeatDialog(int repeatCount, QWidget* parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::RttyModRepeatDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
QLineEdit *edit = ui->repeatCount->lineEdit();
|
||||
if (edit) {
|
||||
edit->setText(QString("%1").arg(repeatCount));
|
||||
}
|
||||
}
|
||||
|
||||
RttyModRepeatDialog::~RttyModRepeatDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void RttyModRepeatDialog::accept()
|
||||
{
|
||||
QString text = ui->repeatCount->currentText();
|
||||
m_repeatCount = text.toUInt();
|
||||
QDialog::accept();
|
||||
}
|
39
plugins/channeltx/modrtty/rttymodrepeatdialog.h
Normal file
39
plugins/channeltx/modrtty/rttymodrepeatdialog.h
Normal file
@ -0,0 +1,39 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_RTTYMODREPEATDIALOG_H
|
||||
#define INCLUDE_RTTYMODREPEATDIALOG_H
|
||||
|
||||
#include "ui_rttymodrepeatdialog.h"
|
||||
|
||||
class RttyModRepeatDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RttyModRepeatDialog(int repeatCount, QWidget* parent = 0);
|
||||
~RttyModRepeatDialog();
|
||||
|
||||
int m_repeatCount; // Number of times to transmit
|
||||
|
||||
private slots:
|
||||
void accept();
|
||||
|
||||
private:
|
||||
Ui::RttyModRepeatDialog* ui;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_RTTYMODREPEATDIALOG_H
|
116
plugins/channeltx/modrtty/rttymodrepeatdialog.ui
Normal file
116
plugins/channeltx/modrtty/rttymodrepeatdialog.ui
Normal file
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RttyModRepeatDialog</class>
|
||||
<widget class="QDialog" name="RttyModRepeatDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>351</width>
|
||||
<height>91</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Sans</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Packet Repeat Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="repeatCountLabel">
|
||||
<property name="text">
|
||||
<string>Times to transmit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="repeatCount">
|
||||
<property name="toolTip">
|
||||
<string>Number of times to transmit</string>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>10</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>100</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1000</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>repeatCount</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>RttyModRepeatDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>RttyModRepeatDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
233
plugins/channeltx/modrtty/rttymodsettings.cpp
Normal file
233
plugins/channeltx/modrtty/rttymodsettings.cpp
Normal file
@ -0,0 +1,233 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2017 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QColor>
|
||||
#include <QDebug>
|
||||
|
||||
#include "dsp/dspengine.h"
|
||||
#include "util/baudot.h"
|
||||
#include "util/simpleserializer.h"
|
||||
#include "settings/serializable.h"
|
||||
#include "rttymodsettings.h"
|
||||
|
||||
RttyModSettings::RttyModSettings() :
|
||||
m_channelMarker(nullptr),
|
||||
m_rollupState(nullptr)
|
||||
{
|
||||
resetToDefaults();
|
||||
}
|
||||
|
||||
void RttyModSettings::resetToDefaults()
|
||||
{
|
||||
m_inputFrequencyOffset = 0;
|
||||
m_baud = 45.45;
|
||||
m_rfBandwidth = 340;
|
||||
m_frequencyShift = 170;
|
||||
m_gain = 0.0f;
|
||||
m_channelMute = false;
|
||||
m_repeat = false;
|
||||
m_repeatCount = 10;
|
||||
m_lpfTaps = 301;
|
||||
m_rfNoise = false;
|
||||
m_writeToFile = false;
|
||||
m_text = "CQ CQ CQ DE SDRangel CQ";
|
||||
m_characterSet = Baudot::ITA2;
|
||||
m_msbFirst = false;
|
||||
m_spaceHigh = false;
|
||||
m_prefixCRLF = true;
|
||||
m_postfixCRLF = true;
|
||||
m_predefinedTexts = QStringList({
|
||||
"CQ CQ CQ DE ${callsign} ${callsign} CQ",
|
||||
"DE ${callsign} ${callsign} ${callsign}",
|
||||
"UR 599 QTH IS ${location}",
|
||||
"TU DE ${callsign} CQ"
|
||||
});
|
||||
m_rgbColor = QColor(180, 205, 130).rgb();
|
||||
m_title = "RTTY Modulator";
|
||||
m_streamIndex = 0;
|
||||
m_useReverseAPI = false;
|
||||
m_reverseAPIAddress = "127.0.0.1";
|
||||
m_reverseAPIPort = 8888;
|
||||
m_reverseAPIDeviceIndex = 0;
|
||||
m_reverseAPIChannelIndex = 0;
|
||||
m_pulseShaping = false;
|
||||
m_beta = 1.0f;
|
||||
m_symbolSpan = 6;
|
||||
m_udpEnabled = false;
|
||||
m_udpAddress = "127.0.0.1";
|
||||
m_udpPort = 9998;
|
||||
m_workspaceIndex = 0;
|
||||
m_hidden = false;
|
||||
}
|
||||
|
||||
QString RttyModSettings::getMode() const
|
||||
{
|
||||
return QString("%1/%2").arg(m_baud).arg(m_frequencyShift);
|
||||
}
|
||||
|
||||
QByteArray RttyModSettings::serialize() const
|
||||
{
|
||||
SimpleSerializer s(1);
|
||||
|
||||
s.writeS32(1, m_inputFrequencyOffset);
|
||||
s.writeReal(2, m_baud);
|
||||
s.writeS32(3, m_rfBandwidth);
|
||||
s.writeS32(4, m_frequencyShift);
|
||||
s.writeReal(5, m_gain);
|
||||
s.writeBool(6, m_channelMute);
|
||||
s.writeBool(7, m_repeat);
|
||||
s.writeS32(9, m_repeatCount);
|
||||
s.writeS32(23, m_lpfTaps);
|
||||
s.writeBool(25, m_rfNoise);
|
||||
s.writeBool(26, m_writeToFile);
|
||||
s.writeString(30, m_text);
|
||||
|
||||
s.writeS32(60, (int)m_characterSet);
|
||||
s.writeBool(61, m_unshiftOnSpace);
|
||||
s.writeBool(62, m_msbFirst);
|
||||
s.writeBool(63, m_spaceHigh);
|
||||
s.writeBool(64, m_prefixCRLF);
|
||||
s.writeBool(65, m_postfixCRLF);
|
||||
s.writeList(66, m_predefinedTexts);
|
||||
|
||||
s.writeU32(31, m_rgbColor);
|
||||
s.writeString(32, m_title);
|
||||
|
||||
if (m_channelMarker) {
|
||||
s.writeBlob(33, m_channelMarker->serialize());
|
||||
}
|
||||
|
||||
s.writeS32(34, m_streamIndex);
|
||||
s.writeBool(35, m_useReverseAPI);
|
||||
s.writeString(36, m_reverseAPIAddress);
|
||||
s.writeU32(37, m_reverseAPIPort);
|
||||
s.writeU32(38, m_reverseAPIDeviceIndex);
|
||||
s.writeU32(39, m_reverseAPIChannelIndex);
|
||||
s.writeBool(46, m_pulseShaping);
|
||||
s.writeReal(47, m_beta);
|
||||
s.writeS32(48, m_symbolSpan);
|
||||
s.writeBool(51, m_udpEnabled);
|
||||
s.writeString(52, m_udpAddress);
|
||||
s.writeU32(53, m_udpPort);
|
||||
|
||||
if (m_rollupState) {
|
||||
s.writeBlob(54, m_rollupState->serialize());
|
||||
}
|
||||
|
||||
s.writeS32(55, m_workspaceIndex);
|
||||
s.writeBlob(56, m_geometryBytes);
|
||||
s.writeBool(57, m_hidden);
|
||||
|
||||
|
||||
return s.final();
|
||||
}
|
||||
|
||||
bool RttyModSettings::deserialize(const QByteArray& data)
|
||||
{
|
||||
SimpleDeserializer d(data);
|
||||
|
||||
if(!d.isValid())
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(d.getVersion() == 1)
|
||||
{
|
||||
QByteArray bytetmp;
|
||||
qint32 tmp;
|
||||
uint32_t utmp;
|
||||
|
||||
d.readS32(1, &tmp, 0);
|
||||
m_inputFrequencyOffset = tmp;
|
||||
d.readReal(2, &m_baud, 45.45f);
|
||||
d.readS32(3, &m_rfBandwidth, 340);
|
||||
d.readS32(4, &m_frequencyShift, 170);
|
||||
d.readReal(5, &m_gain, 0.0f);
|
||||
d.readBool(6, &m_channelMute, false);
|
||||
d.readBool(7, &m_repeat, false);
|
||||
d.readS32(9, &m_repeatCount, -1);
|
||||
d.readS32(23, &m_lpfTaps, 301);
|
||||
d.readBool(25, &m_rfNoise, false);
|
||||
d.readBool(26, &m_writeToFile, false);
|
||||
d.readString(30, &m_text, "CQ CQ CQ anyone using SDRangel");
|
||||
|
||||
d.readS32(60, (int*)&m_characterSet, (int)Baudot::ITA2);
|
||||
d.readBool(61, &m_unshiftOnSpace, false);
|
||||
d.readBool(62, &m_msbFirst, false);
|
||||
d.readBool(63, &m_spaceHigh, false);
|
||||
d.readBool(64, &m_prefixCRLF, true);
|
||||
d.readBool(65, &m_postfixCRLF, true);
|
||||
d.readList(66, &m_predefinedTexts);
|
||||
|
||||
d.readU32(31, &m_rgbColor);
|
||||
d.readString(32, &m_title, "RTTY Modulator");
|
||||
|
||||
if (m_channelMarker)
|
||||
{
|
||||
d.readBlob(33, &bytetmp);
|
||||
m_channelMarker->deserialize(bytetmp);
|
||||
}
|
||||
|
||||
d.readS32(34, &m_streamIndex, 0);
|
||||
d.readBool(35, &m_useReverseAPI, false);
|
||||
d.readString(36, &m_reverseAPIAddress, "127.0.0.1");
|
||||
d.readU32(37, &utmp, 0);
|
||||
|
||||
if ((utmp > 1023) && (utmp < 65535)) {
|
||||
m_reverseAPIPort = utmp;
|
||||
} else {
|
||||
m_reverseAPIPort = 8888;
|
||||
}
|
||||
|
||||
d.readU32(38, &utmp, 0);
|
||||
m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp;
|
||||
d.readU32(39, &utmp, 0);
|
||||
m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp;
|
||||
d.readBool(46, &m_pulseShaping, false);
|
||||
d.readReal(47, &m_beta, 1.0f);
|
||||
d.readS32(48, &m_symbolSpan, 6);
|
||||
d.readBool(51, &m_udpEnabled);
|
||||
d.readString(52, &m_udpAddress, "127.0.0.1");
|
||||
d.readU32(53, &utmp);
|
||||
|
||||
if ((utmp > 1023) && (utmp < 65535)) {
|
||||
m_udpPort = utmp;
|
||||
} else {
|
||||
m_udpPort = 9998;
|
||||
}
|
||||
|
||||
if (m_rollupState)
|
||||
{
|
||||
d.readBlob(54, &bytetmp);
|
||||
m_rollupState->deserialize(bytetmp);
|
||||
}
|
||||
|
||||
d.readS32(55, &m_workspaceIndex, 0);
|
||||
d.readBlob(56, &m_geometryBytes);
|
||||
d.readBool(57, &m_hidden, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "RttyModSettings::deserialize: ERROR";
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
80
plugins/channeltx/modrtty/rttymodsettings.h
Normal file
80
plugins/channeltx/modrtty/rttymodsettings.h
Normal file
@ -0,0 +1,80 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2017 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PLUGINS_CHANNELTX_MODRTTY_RTTYMODSETTINGS_H
|
||||
#define PLUGINS_CHANNELTX_MODRTTY_RTTYMODSETTINGS_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <stdint.h>
|
||||
#include "dsp/dsptypes.h"
|
||||
#include "util/baudot.h"
|
||||
|
||||
class Serializable;
|
||||
|
||||
struct RttyModSettings
|
||||
{
|
||||
qint64 m_inputFrequencyOffset;
|
||||
float m_baud;
|
||||
int m_rfBandwidth;
|
||||
int m_frequencyShift;
|
||||
Real m_gain;
|
||||
bool m_channelMute;
|
||||
bool m_repeat;
|
||||
int m_repeatCount;
|
||||
int m_lpfTaps;
|
||||
bool m_rfNoise;
|
||||
bool m_writeToFile;
|
||||
QString m_text; // Text to send
|
||||
bool m_pulseShaping;
|
||||
float m_beta;
|
||||
int m_symbolSpan;
|
||||
Baudot::CharacterSet m_characterSet;
|
||||
bool m_unshiftOnSpace;
|
||||
bool m_msbFirst; // false = LSB first, true = MSB first
|
||||
bool m_spaceHigh; // false = mark high frequency, true = space high frequency
|
||||
bool m_prefixCRLF;
|
||||
bool m_postfixCRLF;
|
||||
QStringList m_predefinedTexts;
|
||||
|
||||
quint32 m_rgbColor;
|
||||
QString m_title;
|
||||
Serializable *m_channelMarker;
|
||||
int m_streamIndex;
|
||||
bool m_useReverseAPI;
|
||||
QString m_reverseAPIAddress;
|
||||
uint16_t m_reverseAPIPort;
|
||||
uint16_t m_reverseAPIDeviceIndex;
|
||||
uint16_t m_reverseAPIChannelIndex;
|
||||
bool m_udpEnabled;
|
||||
QString m_udpAddress;
|
||||
uint16_t m_udpPort;
|
||||
Serializable *m_rollupState;
|
||||
int m_workspaceIndex;
|
||||
QByteArray m_geometryBytes;
|
||||
bool m_hidden;
|
||||
|
||||
RttyModSettings();
|
||||
void resetToDefaults();
|
||||
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
||||
void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; }
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
QString getMode() const;
|
||||
};
|
||||
|
||||
#endif /* PLUGINS_CHANNELTX_MODRTTY_RTTYMODSETTINGS_H */
|
437
plugins/channeltx/modrtty/rttymodsource.cpp
Normal file
437
plugins/channeltx/modrtty/rttymodsource.cpp
Normal file
@ -0,0 +1,437 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cctype>
|
||||
#include <QDebug>
|
||||
|
||||
#include "dsp/basebandsamplesink.h"
|
||||
#include "dsp/datafifo.h"
|
||||
#include "rttymod.h"
|
||||
#include "rttymodsource.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "maincore.h"
|
||||
|
||||
RttyModSource::RttyModSource() :
|
||||
m_channelSampleRate(48000),
|
||||
m_channelFrequencyOffset(0),
|
||||
m_spectrumRate(2000),
|
||||
m_fmPhase(0.0),
|
||||
m_spectrumSink(nullptr),
|
||||
m_specSampleBufferIndex(0),
|
||||
m_magsq(0.0),
|
||||
m_levelCalcCount(0),
|
||||
m_peakLevel(0.0f),
|
||||
m_levelSum(0.0f),
|
||||
m_byteIdx(0),
|
||||
m_bitIdx(0),
|
||||
m_bitCount(0)
|
||||
{
|
||||
m_bits.append(0);
|
||||
m_lowpass.create(301, m_channelSampleRate, 400.0 / 2.0);
|
||||
m_pulseShape.create(0.5, 6, m_channelSampleRate / 45.45, true);
|
||||
|
||||
m_demodBuffer.resize(1<<12);
|
||||
m_demodBufferFill = 0;
|
||||
|
||||
m_specSampleBuffer.resize(m_specSampleBufferSize);
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorConsumed = false;
|
||||
m_interpolatorDistance = (Real)m_channelSampleRate / (Real)m_spectrumRate;
|
||||
m_interpolator.create(48, m_spectrumRate, m_spectrumRate / 2.2, 3.0);
|
||||
|
||||
applySettings(m_settings, true);
|
||||
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
|
||||
}
|
||||
|
||||
RttyModSource::~RttyModSource()
|
||||
{
|
||||
}
|
||||
|
||||
void RttyModSource::pull(SampleVector::iterator begin, unsigned int nbSamples)
|
||||
{
|
||||
std::for_each(
|
||||
begin,
|
||||
begin + nbSamples,
|
||||
[this](Sample& s) {
|
||||
pullOne(s);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void RttyModSource::pullOne(Sample& sample)
|
||||
{
|
||||
if (m_settings.m_channelMute)
|
||||
{
|
||||
sample.m_real = 0.0f;
|
||||
sample.m_imag = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate next sample
|
||||
modulateSample();
|
||||
|
||||
// Shift to carrier frequency
|
||||
Complex ci = m_modSample;
|
||||
ci *= m_carrierNco.nextIQ();
|
||||
|
||||
// Calculate power
|
||||
double magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
|
||||
m_movingAverage(magsq);
|
||||
m_magsq = m_movingAverage.asDouble();
|
||||
|
||||
// Convert from float to fixed point
|
||||
sample.m_real = (FixReal) (ci.real() * SDR_TX_SCALEF);
|
||||
sample.m_imag = (FixReal) (ci.imag() * SDR_TX_SCALEF);
|
||||
}
|
||||
|
||||
void RttyModSource::sampleToSpectrum(Complex sample)
|
||||
{
|
||||
if (m_spectrumSink)
|
||||
{
|
||||
Complex out;
|
||||
if (m_interpolator.decimate(&m_interpolatorDistanceRemain, sample, &out))
|
||||
{
|
||||
m_interpolatorDistanceRemain += m_interpolatorDistance;
|
||||
Real r = std::real(out) * SDR_TX_SCALEF;
|
||||
Real i = std::imag(out) * SDR_TX_SCALEF;
|
||||
m_specSampleBuffer[m_specSampleBufferIndex++] = Sample(r, i);
|
||||
if (m_specSampleBufferIndex == m_specSampleBufferSize)
|
||||
{
|
||||
m_spectrumSink->feed(m_specSampleBuffer.begin(), m_specSampleBuffer.end(), false);
|
||||
m_specSampleBufferIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModSource::modulateSample()
|
||||
{
|
||||
Real mod;
|
||||
|
||||
if (m_sampleIdx == 0)
|
||||
{
|
||||
if (m_bitCount == 0)
|
||||
{
|
||||
if (!m_textToTransmit.isEmpty())
|
||||
{
|
||||
// Encode a character at a time, so we get a TxReport after each character
|
||||
QString s = m_textToTransmit.left(1);
|
||||
m_textToTransmit = m_textToTransmit.mid(1);
|
||||
encodeText(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transmit "diddle"
|
||||
encodeText(">");
|
||||
}
|
||||
initTX();
|
||||
}
|
||||
|
||||
m_bit = getBit();
|
||||
}
|
||||
|
||||
m_sampleIdx++;
|
||||
if (m_sampleIdx >= m_samplesPerSymbol) {
|
||||
m_sampleIdx = 0;
|
||||
}
|
||||
|
||||
// FSK
|
||||
if (m_settings.m_pulseShaping)
|
||||
{
|
||||
if (m_sampleIdx == 1) {
|
||||
mod = m_pulseShape.filter(m_bit ? 1.0f : -1.0f);
|
||||
} else {
|
||||
mod = m_pulseShape.filter(0.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mod = m_bit ? 1.0f : -1.0f;
|
||||
}
|
||||
|
||||
// FM
|
||||
m_fmPhase += m_phaseSensitivity * mod * (m_settings.m_spaceHigh ? -1.0f : 1.0f);
|
||||
// Keep phase in range -pi,pi
|
||||
if (m_fmPhase > M_PI) {
|
||||
m_fmPhase -= 2.0f * M_PI;
|
||||
} else if (m_fmPhase < -M_PI) {
|
||||
m_fmPhase += 2.0f * M_PI;
|
||||
}
|
||||
|
||||
if (!m_settings.m_rfNoise)
|
||||
{
|
||||
m_modSample.real(m_linearGain * cos(m_fmPhase));
|
||||
m_modSample.imag(m_linearGain * sin(m_fmPhase));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Noise to test filter frequency response
|
||||
m_modSample.real(m_linearGain * ((Real)rand()/((Real)RAND_MAX)-0.5f));
|
||||
m_modSample.imag(m_linearGain * ((Real)rand()/((Real)RAND_MAX)-0.5f));
|
||||
}
|
||||
|
||||
// Apply low pass filter to limit RF BW
|
||||
m_modSample = m_lowpass.filter(m_modSample);
|
||||
|
||||
// Display in spectrum analyser
|
||||
sampleToSpectrum(m_modSample);
|
||||
|
||||
Real s = std::real(m_modSample);
|
||||
calculateLevel(s);
|
||||
|
||||
// Send to demod analyser
|
||||
m_demodBuffer[m_demodBufferFill] = mod * std::numeric_limits<int16_t>::max();
|
||||
++m_demodBufferFill;
|
||||
|
||||
if (m_demodBufferFill >= m_demodBuffer.size())
|
||||
{
|
||||
QList<ObjectPipe*> dataPipes;
|
||||
MainCore::instance()->getDataPipes().getDataPipes(m_channel, "demod", dataPipes);
|
||||
|
||||
if (dataPipes.size() > 0)
|
||||
{
|
||||
QList<ObjectPipe*>::iterator it = dataPipes.begin();
|
||||
|
||||
for (; it != dataPipes.end(); ++it)
|
||||
{
|
||||
DataFifo *fifo = qobject_cast<DataFifo*>((*it)->m_element);
|
||||
|
||||
if (fifo) {
|
||||
fifo->write((quint8*) &m_demodBuffer[0], m_demodBuffer.size() * sizeof(qint16), DataFifo::DataTypeI16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_demodBufferFill = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModSource::calculateLevel(Real& sample)
|
||||
{
|
||||
if (m_levelCalcCount < m_levelNbSamples)
|
||||
{
|
||||
m_peakLevel = std::max(std::fabs(m_peakLevel), sample);
|
||||
m_levelSum += sample * sample;
|
||||
m_levelCalcCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rmsLevel = sqrt(m_levelSum / m_levelNbSamples);
|
||||
m_peakLevelOut = m_peakLevel;
|
||||
m_peakLevel = 0.0f;
|
||||
m_levelSum = 0.0f;
|
||||
m_levelCalcCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModSource::applySettings(const RttyModSettings& settings, bool force)
|
||||
{
|
||||
if ((settings.m_baud != m_settings.m_baud) || force)
|
||||
{
|
||||
m_samplesPerSymbol = m_channelSampleRate / settings.m_baud;
|
||||
qDebug() << "m_samplesPerSymbol: " << m_samplesPerSymbol << " (" << m_channelSampleRate << "/" << settings.m_baud << ")";
|
||||
}
|
||||
|
||||
if ((settings.m_lpfTaps != m_settings.m_lpfTaps) || (settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force)
|
||||
{
|
||||
qDebug() << "RttyModSource::applySettings: Creating new lpf with taps " << settings.m_lpfTaps << " rfBW " << settings.m_rfBandwidth;
|
||||
m_lowpass.create(settings.m_lpfTaps, m_channelSampleRate, settings.m_rfBandwidth / 2.0);
|
||||
}
|
||||
if ((settings.m_beta != m_settings.m_beta) || (settings.m_symbolSpan != m_settings.m_symbolSpan) || (settings.m_baud != m_settings.m_baud) || force)
|
||||
{
|
||||
qDebug() << "RttyModSource::applySettings: Recreating pulse shaping filter: "
|
||||
<< " beta: " << settings.m_beta
|
||||
<< " symbolSpan: " << settings.m_symbolSpan
|
||||
<< " channelSampleRate:" << m_channelSampleRate
|
||||
<< " baud:" << settings.m_baud;
|
||||
m_pulseShape.create(settings.m_beta, settings.m_symbolSpan, m_channelSampleRate/settings.m_baud, true);
|
||||
}
|
||||
|
||||
if ((settings.m_characterSet != m_settings.m_characterSet) || force) {
|
||||
m_rttyEncoder.setCharacterSet(settings.m_characterSet);
|
||||
}
|
||||
if ((settings.m_unshiftOnSpace != m_settings.m_unshiftOnSpace) || force) {
|
||||
m_rttyEncoder.setUnshiftOnSpace(settings.m_unshiftOnSpace);
|
||||
}
|
||||
if ((settings.m_msbFirst != m_settings.m_msbFirst) || force) {
|
||||
m_rttyEncoder.setMsbFirst(settings.m_msbFirst);
|
||||
}
|
||||
|
||||
m_settings = settings;
|
||||
|
||||
// Precalculate FM sensensity and linear gain to save doing it in the loop
|
||||
m_phaseSensitivity = 2.0f * M_PI * (m_settings.m_frequencyShift/2.0f) / (double)m_channelSampleRate;
|
||||
m_linearGain = powf(10.0f, m_settings.m_gain/20.0f);
|
||||
}
|
||||
|
||||
void RttyModSource::applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force)
|
||||
{
|
||||
qDebug() << "RttyModSource::applyChannelSettings:"
|
||||
<< " channelSampleRate: " << channelSampleRate
|
||||
<< " channelFrequencyOffset: " << channelFrequencyOffset
|
||||
<< " rfBandwidth: " << m_settings.m_rfBandwidth;
|
||||
|
||||
if ((channelFrequencyOffset != m_channelFrequencyOffset)
|
||||
|| (channelSampleRate != m_channelSampleRate) || force)
|
||||
{
|
||||
m_carrierNco.setFreq(channelFrequencyOffset, channelSampleRate);
|
||||
}
|
||||
|
||||
if ((m_channelSampleRate != channelSampleRate) || force)
|
||||
{
|
||||
qDebug() << "RttyModSource::applyChannelSettings: Recreating filters";
|
||||
m_lowpass.create(m_settings.m_lpfTaps, channelSampleRate, m_settings.m_rfBandwidth / 2.0);
|
||||
qDebug() << "RttyModSource::applyChannelSettings: Recreating bandpass filter: "
|
||||
<< " channelSampleRate:" << channelSampleRate;
|
||||
qDebug() << "RttyModSource::applyChannelSettings: Recreating pulse shaping filter: "
|
||||
<< " beta: " << m_settings.m_beta
|
||||
<< " symbolSpan: " << m_settings.m_symbolSpan
|
||||
<< " channelSampleRate:" << m_channelSampleRate
|
||||
<< " baud:" << m_settings.m_baud;
|
||||
m_pulseShape.create(m_settings.m_beta, m_settings.m_symbolSpan, channelSampleRate/m_settings.m_baud, true);
|
||||
}
|
||||
|
||||
if ((m_channelSampleRate != channelSampleRate) || force)
|
||||
{
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorConsumed = false;
|
||||
m_interpolatorDistance = (Real) channelSampleRate / (Real) m_spectrumRate;
|
||||
m_interpolator.create(48, m_spectrumRate, m_spectrumRate / 2.2, 3.0);
|
||||
}
|
||||
|
||||
m_channelSampleRate = channelSampleRate;
|
||||
m_channelFrequencyOffset = channelFrequencyOffset;
|
||||
m_samplesPerSymbol = m_channelSampleRate / m_settings.m_baud;
|
||||
qDebug() << "m_samplesPerSymbol: " << m_samplesPerSymbol << " (" << m_channelSampleRate << "/" << m_settings.m_baud << ")";
|
||||
|
||||
// Precalculate FM sensensity to save doing it in the loop
|
||||
m_phaseSensitivity = 2.0f * M_PI * (m_settings.m_frequencyShift/2.0f) / (double)m_channelSampleRate;
|
||||
|
||||
QList<ObjectPipe*> pipes;
|
||||
MainCore::instance()->getMessagePipes().getMessagePipes(m_channel, "reportdemod", pipes);
|
||||
|
||||
if (pipes.size() > 0)
|
||||
{
|
||||
for (const auto& pipe : pipes)
|
||||
{
|
||||
MessageQueue* messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(m_channel, m_channelSampleRate);
|
||||
messageQueue->push(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int RttyModSource::getBit()
|
||||
{
|
||||
int bit;
|
||||
|
||||
if (m_bitCount > 0)
|
||||
{
|
||||
bit = (m_bits[m_byteIdx] >> m_bitIdx) & 1;
|
||||
m_bitIdx++;
|
||||
m_bitCount--;
|
||||
if (m_bitIdx == 8)
|
||||
{
|
||||
m_byteIdx++;
|
||||
m_bitIdx = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "RttyModSource::getBit: Called when empty";
|
||||
bit = 1;
|
||||
}
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
void RttyModSource::addBit(int bit)
|
||||
{
|
||||
m_bits[m_byteIdx] |= bit << m_bitIdx;
|
||||
m_bitIdx++;
|
||||
m_bitCount++;
|
||||
m_bitCountTotal++;
|
||||
if (m_bitIdx == 8)
|
||||
{
|
||||
m_byteIdx++;
|
||||
if (m_bits.size() <= m_byteIdx) {
|
||||
m_bits.append(0);
|
||||
}
|
||||
m_bitIdx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModSource::initTX()
|
||||
{
|
||||
m_byteIdx = 0;
|
||||
m_bitIdx = 0;
|
||||
m_bitCount = m_bitCountTotal; // Reset to allow retransmission
|
||||
m_bit = 0;
|
||||
}
|
||||
|
||||
void RttyModSource::addTXText(QString text)
|
||||
{
|
||||
int count = m_settings.m_repeat ? m_settings.m_repeatCount : 1;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
||||
QString s = text;
|
||||
|
||||
if (m_settings.m_prefixCRLF) {
|
||||
s.prepend("\r\r\n>"); // '>' switches to letters
|
||||
}
|
||||
if (m_settings.m_postfixCRLF) {
|
||||
s.append("\r\r\n");
|
||||
}
|
||||
|
||||
m_textToTransmit.append(s);
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModSource::encodeText(const QString& text)
|
||||
{
|
||||
// RTTY encoding
|
||||
m_byteIdx = 0;
|
||||
m_bitIdx = 0;
|
||||
m_bitCount = 0;
|
||||
m_bitCountTotal = 0;
|
||||
for (int i = 0; i < m_bits.size(); i++) {
|
||||
m_bits[i] = 0;
|
||||
}
|
||||
|
||||
QString s = text.toUpper(); // RTTY only supports upper case
|
||||
|
||||
for (int i = 0; i < s.size(); i++)
|
||||
{
|
||||
unsigned bits;
|
||||
unsigned bitCount;
|
||||
|
||||
m_rttyEncoder.encode(s[i], bits, bitCount);
|
||||
for (unsigned int j = 0; j < bitCount; j++)
|
||||
{
|
||||
int txBit = (bits >> j) & 1;
|
||||
addBit(txBit);
|
||||
}
|
||||
}
|
||||
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
RttyMod::MsgReportTx* msg = RttyMod::MsgReportTx::create(s, m_textToTransmit.size());
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
}
|
133
plugins/channeltx/modrtty/rttymodsource.h
Normal file
133
plugins/channeltx/modrtty/rttymodsource.h
Normal file
@ -0,0 +1,133 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_RTTYMODSOURCE_H
|
||||
#define INCLUDE_RTTYMODSOURCE_H
|
||||
|
||||
#include <QMutex>
|
||||
#include <QDebug>
|
||||
#include <QVector>
|
||||
|
||||
#include "dsp/channelsamplesource.h"
|
||||
#include "dsp/nco.h"
|
||||
#include "dsp/ncof.h"
|
||||
#include "dsp/interpolator.h"
|
||||
#include "dsp/firfilter.h"
|
||||
#include "dsp/raisedcosine.h"
|
||||
#include "util/movingaverage.h"
|
||||
#include "util/baudot.h"
|
||||
|
||||
#include "rttymodsettings.h"
|
||||
|
||||
class BasebandSampleSink;
|
||||
class ChannelAPI;
|
||||
|
||||
class RttyModSource : public ChannelSampleSource
|
||||
{
|
||||
public:
|
||||
RttyModSource();
|
||||
virtual ~RttyModSource();
|
||||
|
||||
virtual void pull(SampleVector::iterator begin, unsigned int nbSamples);
|
||||
virtual void pullOne(Sample& sample);
|
||||
virtual void prefetch(unsigned int nbSamples) { (void) nbSamples; }
|
||||
|
||||
double getMagSq() const { return m_magsq; }
|
||||
void getLevels(qreal& rmsLevel, qreal& peakLevel, int& numSamples) const
|
||||
{
|
||||
rmsLevel = m_rmsLevel;
|
||||
peakLevel = m_peakLevelOut;
|
||||
numSamples = m_levelNbSamples;
|
||||
}
|
||||
void setMessageQueueToGUI(MessageQueue* messageQueue) { m_messageQueueToGUI = messageQueue; }
|
||||
void setSpectrumSink(BasebandSampleSink *sampleSink) { m_spectrumSink = sampleSink; }
|
||||
void applySettings(const RttyModSettings& settings, bool force = false);
|
||||
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false);
|
||||
void addTXText(QString data);
|
||||
void setChannel(ChannelAPI *channel) { m_channel = channel; }
|
||||
int getChannelSampleRate() const { return m_channelSampleRate; }
|
||||
|
||||
private:
|
||||
int m_channelSampleRate;
|
||||
int m_channelFrequencyOffset;
|
||||
int m_spectrumRate;
|
||||
RttyModSettings m_settings;
|
||||
ChannelAPI *m_channel;
|
||||
|
||||
NCO m_carrierNco;
|
||||
double m_fmPhase; // Double gives cleaner spectrum than Real
|
||||
double m_phaseSensitivity;
|
||||
Real m_linearGain;
|
||||
Complex m_modSample;
|
||||
|
||||
int m_bit; // Current bit
|
||||
RaisedCosine<Real> m_pulseShape; // Pulse shaping filter
|
||||
Lowpass<Complex> m_lowpass; // Low pass filter to limit RF bandwidth
|
||||
|
||||
BasebandSampleSink* m_spectrumSink; // Spectrum GUI to display baseband waveform
|
||||
SampleVector m_specSampleBuffer;
|
||||
static const int m_specSampleBufferSize = 256;
|
||||
int m_specSampleBufferIndex;
|
||||
Interpolator m_interpolator; // Interpolator to downsample to spectrum
|
||||
Real m_interpolatorDistance;
|
||||
Real m_interpolatorDistanceRemain;
|
||||
bool m_interpolatorConsumed;
|
||||
|
||||
double m_magsq;
|
||||
MovingAverageUtil<double, double, 16> m_movingAverage;
|
||||
|
||||
quint32 m_levelCalcCount;
|
||||
qreal m_rmsLevel;
|
||||
qreal m_peakLevelOut;
|
||||
Real m_peakLevel;
|
||||
Real m_levelSum;
|
||||
|
||||
static const int m_levelNbSamples = 480; // every 10ms assuming 48k Sa/s
|
||||
|
||||
int m_sampleIdx; // Sample index in to symbol
|
||||
int m_samplesPerSymbol; // Number of samples per symbol
|
||||
|
||||
QString m_textToTransmit; // Transmit buffer (before RTTY encoding)
|
||||
|
||||
BaudotEncoder m_rttyEncoder;
|
||||
|
||||
QList<uint8_t> m_bits; // Bits to transmit
|
||||
int m_byteIdx; // Index in to m_bits
|
||||
int m_bitIdx; // Index in to current byte of m_bits
|
||||
int m_bitCount; // Count of number of valid bits in m_bits
|
||||
int m_bitCountTotal;
|
||||
|
||||
QVector<qint16> m_demodBuffer;
|
||||
int m_demodBufferFill;
|
||||
|
||||
MessageQueue* m_messageQueueToGUI;
|
||||
|
||||
MessageQueue* getMessageQueueToGUI() { return m_messageQueueToGUI; }
|
||||
|
||||
void encodeText(const QString& data);
|
||||
int getBit(); // Get bit from m_bits
|
||||
void addBit(int bit); // Add bit to m_bits, with zero stuffing
|
||||
void initTX();
|
||||
|
||||
void calculateLevel(Real& sample);
|
||||
void modulateSample();
|
||||
void sampleToSpectrum(Complex sample);
|
||||
|
||||
};
|
||||
|
||||
#endif // INCLUDE_RTTYMODSOURCE_H
|
110
plugins/channeltx/modrtty/rttymodtxsettingsdialog.cpp
Normal file
110
plugins/channeltx/modrtty/rttymodtxsettingsdialog.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "rttymodtxsettingsdialog.h"
|
||||
|
||||
static QListWidgetItem* newItem(const QString& text)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(text);
|
||||
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
||||
return item;
|
||||
}
|
||||
|
||||
RttyModTXSettingsDialog::RttyModTXSettingsDialog(RttyModSettings* settings, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_settings(settings),
|
||||
ui(new Ui::RttyModTXSettingsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->prefixCRLF->setChecked(m_settings->m_prefixCRLF);
|
||||
ui->postfixCRLF->setChecked(m_settings->m_postfixCRLF);
|
||||
for (const auto& text : m_settings->m_predefinedTexts) {
|
||||
ui->predefinedText->addItem(newItem(text));
|
||||
}
|
||||
ui->pulseShaping->setChecked(m_settings->m_pulseShaping);
|
||||
ui->beta->setValue(m_settings->m_beta);
|
||||
ui->symbolSpan->setValue(m_settings->m_symbolSpan);
|
||||
ui->lpfTaps->setValue(m_settings->m_lpfTaps);
|
||||
ui->rfNoise->setChecked(m_settings->m_rfNoise);
|
||||
}
|
||||
|
||||
RttyModTXSettingsDialog::~RttyModTXSettingsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void RttyModTXSettingsDialog::accept()
|
||||
{
|
||||
m_settings->m_prefixCRLF = ui->prefixCRLF->isChecked();
|
||||
m_settings->m_postfixCRLF = ui->postfixCRLF->isChecked();
|
||||
m_settings->m_predefinedTexts.clear();
|
||||
for (int i = 0; i < ui->predefinedText->count(); i++) {
|
||||
m_settings->m_predefinedTexts.append(ui->predefinedText->item(i)->text());
|
||||
}
|
||||
m_settings->m_pulseShaping = ui->pulseShaping->isChecked();
|
||||
m_settings->m_beta = ui->beta->value();
|
||||
m_settings->m_symbolSpan = ui->symbolSpan->value();
|
||||
m_settings->m_lpfTaps = ui->lpfTaps->value();
|
||||
m_settings->m_rfNoise = ui->rfNoise->isChecked();
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void RttyModTXSettingsDialog::on_add_clicked()
|
||||
{
|
||||
QListWidgetItem* item = newItem("...");
|
||||
ui->predefinedText->addItem(item);
|
||||
ui->predefinedText->setCurrentItem(item);
|
||||
}
|
||||
|
||||
void RttyModTXSettingsDialog::on_remove_clicked()
|
||||
{
|
||||
QList<QListWidgetItem*> items = ui->predefinedText->selectedItems();
|
||||
for (auto item : items) {
|
||||
delete ui->predefinedText->takeItem(ui->predefinedText->row(item));
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModTXSettingsDialog::on_up_clicked()
|
||||
{
|
||||
QList<QListWidgetItem*> items = ui->predefinedText->selectedItems();
|
||||
for (auto item : items)
|
||||
{
|
||||
int row = ui->predefinedText->row(item);
|
||||
if (row > 0)
|
||||
{
|
||||
QListWidgetItem* item = ui->predefinedText->takeItem(row);
|
||||
ui->predefinedText->insertItem(row - 1, item);
|
||||
ui->predefinedText->setCurrentItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RttyModTXSettingsDialog::on_down_clicked()
|
||||
{
|
||||
QList<QListWidgetItem*> items = ui->predefinedText->selectedItems();
|
||||
for (auto item : items)
|
||||
{
|
||||
int row = ui->predefinedText->row(item);
|
||||
if (row < ui->predefinedText->count() - 1)
|
||||
{
|
||||
QListWidgetItem* item = ui->predefinedText->takeItem(row);
|
||||
ui->predefinedText->insertItem(row + 1, item);
|
||||
ui->predefinedText->setCurrentItem(item);
|
||||
}
|
||||
}
|
||||
}
|
44
plugins/channeltx/modrtty/rttymodtxsettingsdialog.h
Normal file
44
plugins/channeltx/modrtty/rttymodtxsettingsdialog.h
Normal file
@ -0,0 +1,44 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_RTTYMODTXSETTINGSDIALOG_H
|
||||
#define INCLUDE_RTTYMODTXSETTINGSDIALOG_H
|
||||
|
||||
#include "ui_rttymodtxsettingsdialog.h"
|
||||
#include "rttymodsettings.h"
|
||||
|
||||
class RttyModTXSettingsDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RttyModTXSettingsDialog(RttyModSettings *settings, QWidget *parent = nullptr);
|
||||
~RttyModTXSettingsDialog();
|
||||
|
||||
RttyModSettings *m_settings;
|
||||
|
||||
private slots:
|
||||
void accept();
|
||||
void on_add_clicked();
|
||||
void on_remove_clicked();
|
||||
void on_up_clicked();
|
||||
void on_down_clicked();
|
||||
|
||||
private:
|
||||
Ui::RttyModTXSettingsDialog* ui;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_RTTYMODTXSETTINGSDIALOG_H
|
284
plugins/channeltx/modrtty/rttymodtxsettingsdialog.ui
Normal file
284
plugins/channeltx/modrtty/rttymodtxsettingsdialog.ui
Normal file
@ -0,0 +1,284 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RttyModTXSettingsDialog</class>
|
||||
<widget class="QDialog" name="RttyModTXSettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>351</width>
|
||||
<height>554</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Sans</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Transmit Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="listControls">
|
||||
<property name="title">
|
||||
<string>Text</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="prefixCRLF">
|
||||
<property name="toolTip">
|
||||
<string>Prefix text with carriage returns, line feed and switch to letters</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Prefix CR+CR+LF+LTRS</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Predefined text</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="add">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Add item to list</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>+</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="remove">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Remove selected items from list</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="up">
|
||||
<property name="toolTip">
|
||||
<string>Move selected item up</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Up</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/arrow_up.png</normaloff>:/arrow_up.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="down">
|
||||
<property name="toolTip">
|
||||
<string>Move selected item down</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/arrow_down.png</normaloff>:/arrow_down.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="postfixCRLF">
|
||||
<property name="toolTip">
|
||||
<string>Postfix text with carriage returns and line feeds</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Postfix CR+CR+LF</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QListWidget" name="predefinedText">
|
||||
<property name="toolTip">
|
||||
<string>Predefined text messages
|
||||
|
||||
Substitutions:
|
||||
${callsign}
|
||||
${location}</string>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="fskGroup">
|
||||
<property name="title">
|
||||
<string>Modulation</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lpfTapsLabel">
|
||||
<property name="text">
|
||||
<string>RF BW limit LPF taps</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="lpfTaps">
|
||||
<property name="toolTip">
|
||||
<string>Number of taps in LPF for RF BW filter.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="pulseShaping">
|
||||
<property name="toolTip">
|
||||
<string>Enable raised cosine pulse shaping filter</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Raised cosine pulse shaping</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="betaLabel">
|
||||
<property name="text">
|
||||
<string>Filter rolloff (beta)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="beta">
|
||||
<property name="toolTip">
|
||||
<string>Roll-off of the filter</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.250000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="symbolSpanLabel">
|
||||
<property name="text">
|
||||
<string>Filter symbol span</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="symbolSpan">
|
||||
<property name="toolTip">
|
||||
<string>Number of symbols over which filter is applied</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="debugGroup">
|
||||
<property name="title">
|
||||
<string>Debug</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="rfNoise">
|
||||
<property name="toolTip">
|
||||
<string>Generate white noise as RF signal.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Generate RF noise</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../../sdrgui/resources/res.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>RttyModTXSettingsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>RttyModTXSettingsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
53
plugins/channeltx/modrtty/rttymodwebapiadapter.cpp
Normal file
53
plugins/channeltx/modrtty/rttymodwebapiadapter.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB. //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SWGChannelSettings.h"
|
||||
#include "rttymod.h"
|
||||
#include "rttymodwebapiadapter.h"
|
||||
|
||||
RttyModWebAPIAdapter::RttyModWebAPIAdapter()
|
||||
{}
|
||||
|
||||
RttyModWebAPIAdapter::~RttyModWebAPIAdapter()
|
||||
{}
|
||||
|
||||
int RttyModWebAPIAdapter::webapiSettingsGet(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
response.setRttyModSettings(new SWGSDRangel::SWGRTTYModSettings());
|
||||
response.getRttyModSettings()->init();
|
||||
RttyMod::webapiFormatChannelSettings(response, m_settings);
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
int RttyModWebAPIAdapter::webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) force; // no action
|
||||
(void) errorMessage;
|
||||
RttyMod::webapiUpdateChannelSettings(m_settings, channelSettingsKeys, response);
|
||||
|
||||
RttyMod::webapiFormatChannelSettings(response, m_settings);
|
||||
return 200;
|
||||
}
|
50
plugins/channeltx/modrtty/rttymodwebapiadapter.h
Normal file
50
plugins/channeltx/modrtty/rttymodwebapiadapter.h
Normal file
@ -0,0 +1,50 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB. //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_RTTYMOD_WEBAPIADAPTER_H
|
||||
#define INCLUDE_RTTYMOD_WEBAPIADAPTER_H
|
||||
|
||||
#include "channel/channelwebapiadapter.h"
|
||||
#include "rttymodsettings.h"
|
||||
|
||||
/**
|
||||
* Standalone API adapter only for the settings
|
||||
*/
|
||||
class RttyModWebAPIAdapter : public ChannelWebAPIAdapter {
|
||||
public:
|
||||
RttyModWebAPIAdapter();
|
||||
virtual ~RttyModWebAPIAdapter();
|
||||
|
||||
virtual QByteArray serialize() const { return m_settings.serialize(); }
|
||||
virtual bool deserialize(const QByteArray& data) { return m_settings.deserialize(data); }
|
||||
|
||||
virtual int webapiSettingsGet(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
private:
|
||||
RttyModSettings m_settings;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_RTTYMOD_WEBAPIADAPTER_H
|
@ -38,6 +38,7 @@ const QStringList DemodAnalyzerSettings::m_channelTypes = {
|
||||
QStringLiteral("PacketDemod"),
|
||||
QStringLiteral("PacketMod"),
|
||||
QStringLiteral("RadiosondeDemod"),
|
||||
QStringLiteral("RTTYMod"),
|
||||
QStringLiteral("SSBDemod"),
|
||||
QStringLiteral("SSBMod"),
|
||||
QStringLiteral("WFMDemod"),
|
||||
@ -60,6 +61,7 @@ const QStringList DemodAnalyzerSettings::m_channelURIs = {
|
||||
QStringLiteral("sdrangel.channel.packetdemod"),
|
||||
QStringLiteral("sdrangel.channeltx.modpacket"),
|
||||
QStringLiteral("sdrangel.channel.radiosondedemod"),
|
||||
QStringLiteral("sdrangel.channeltx.modrtty"),
|
||||
QStringLiteral("sdrangel.channel.ssbdemod"),
|
||||
QStringLiteral("sdrangel.channeltx.modssb"),
|
||||
QStringLiteral("sdrangel.channel.wfmdemod"),
|
||||
|
@ -259,6 +259,7 @@ set(sdrbase_SOURCES
|
||||
util/simpleserializer.cpp
|
||||
util/serialutil.cpp
|
||||
#util/spinlock.cpp
|
||||
util/rtty.cpp
|
||||
util/uid.cpp
|
||||
util/units.cpp
|
||||
util/timeutil.cpp
|
||||
@ -491,6 +492,7 @@ set(sdrbase_HEADERS
|
||||
util/profiler.h
|
||||
util/radiosonde.h
|
||||
util/rtpsink.h
|
||||
util/rtty.h
|
||||
util/syncmessenger.h
|
||||
util/samplesourceserializer.h
|
||||
util/simpleserializer.h
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
void create(double beta, int symbolSpan, int samplesPerSymbol, bool normaliseUpsampledAmplitude = false)
|
||||
{
|
||||
int nTaps = symbolSpan * samplesPerSymbol + 1;
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
// check constraints
|
||||
if(!(nTaps & 1)) {
|
||||
@ -89,18 +89,38 @@ public:
|
||||
else
|
||||
{
|
||||
// Calculate maximum output of filter, assuming upsampled bipolar input E.g. [1 0 0 -1 0 0..]
|
||||
// This doesn't necessarily include the centre tap, so we try each offset
|
||||
double maxGain = 0.0;
|
||||
for (i = 0; i < samplesPerSymbol; i++)
|
||||
// This doesn't necessarily include the centre tap, as ISI there should be zero,
|
||||
// it's often at the midpoint between two symbols. However, depending on beta,
|
||||
// the input that produces the worst case can vary, so we currently try them all
|
||||
double maxGain = 0;
|
||||
for (int input = 0; input < (1 << symbolSpan); input++)
|
||||
{
|
||||
double g = 0.0;
|
||||
for (j = 0; j < (int)m_taps.size() - 1; j += samplesPerSymbol)
|
||||
g += std::fabs(2.0 * m_taps[j]);
|
||||
if ((i & 1) == 0)
|
||||
g += std::fabs(m_taps[j]);
|
||||
if (g > maxGain)
|
||||
maxGain = g;
|
||||
double maxV = 0;
|
||||
for(int i = 0; i < nTaps; i++) {
|
||||
m_samples[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < symbolSpan; i++)
|
||||
{
|
||||
Type sym = (input >> i) & 1 ? 1 : -1;
|
||||
for (int j = 0; j < samplesPerSymbol; j++)
|
||||
{
|
||||
Type out;
|
||||
if (j == 1) {
|
||||
out = filter(sym);
|
||||
} else {
|
||||
out = filter(0);
|
||||
}
|
||||
double outAbs = abs(out);
|
||||
if (outAbs > maxV) {
|
||||
maxV = outAbs;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (maxV > maxGain) {
|
||||
maxGain = maxV;
|
||||
}
|
||||
}
|
||||
|
||||
// Scale up so maximum out is 1
|
||||
for(i = 0; i < (int)m_taps.size(); i++)
|
||||
m_taps[i] /= maxGain;
|
||||
|
@ -23,84 +23,84 @@
|
||||
// We use < for FIGS and > for LTRS and ^ for Cyrillic
|
||||
// Unicode used for source file encoding
|
||||
|
||||
const QString Baudot::m_ita2Letter[] = {
|
||||
const QStringList Baudot::m_ita2Letter = {
|
||||
"\0", "E", "\n", "A", " ", "S", "I", "U",
|
||||
"\r", "D", "R", "J", "N", "F", "C", "K",
|
||||
"T", "Z", "L", "W", "H", "Y", "P", "Q",
|
||||
"O", "B", "G", "<", "M", "X", "V", ">"
|
||||
};
|
||||
|
||||
const QString Baudot::m_ita2Figure[] = {
|
||||
const QStringList Baudot::m_ita2Figure = {
|
||||
"\0", "3", "\n", "-", " ", "\'", "8", "7",
|
||||
"\r", "\x5", "4", "\a", ",", "!", ":", "(",
|
||||
"5", "+", ")", "2", "£", "6", "0", "1",
|
||||
"9", "?", "&", "<", ".", "/", "=", ">"
|
||||
};
|
||||
|
||||
const QString Baudot::m_ukLetter[] = {
|
||||
const QStringList Baudot::m_ukLetter = {
|
||||
"\0", "A", "E", "/", "Y", "U", "I", "O",
|
||||
"<", "J", "G", "H", "B", "C", "F", "D",
|
||||
" ", "-", "X", "Z", "S", "T", "W", "V",
|
||||
"\b", "K", "M", "L", "R", "Q", "N", "P"
|
||||
};
|
||||
|
||||
const QString Baudot::m_ukFigure[] = {
|
||||
const QStringList Baudot::m_ukFigure = {
|
||||
"\0", "1", "2", "⅟", "3", "4", "³⁄", "5",
|
||||
" ", "6", "7", "¹", "8", "9", "⁵⁄", "0",
|
||||
">", ".", "⁹⁄", ":", "⁷⁄", "²", "?", "\'",
|
||||
"\b", "(", ")", "=", "-", "/", "£", "+"
|
||||
};
|
||||
|
||||
const QString Baudot::m_europeanLetter[] = {
|
||||
const QStringList Baudot::m_europeanLetter = {
|
||||
"\0", "A", "E", "É", "Y", "U", "I", "O",
|
||||
"<", "J", "G", "H", "B", "C", "F", "D",
|
||||
" ", "t", "X", "Z", "S", "T", "W", "V",
|
||||
"\b", "K", "M", "L", "R", "Q", "N", "P"
|
||||
};
|
||||
|
||||
const QString Baudot::m_europeanFigure[] = {
|
||||
const QStringList Baudot::m_europeanFigure = {
|
||||
"\0", "1", "2", "&", "3", "4", "º", "5",
|
||||
" ", "6", "7", "H̱", "8", "9", "F̱", "0",
|
||||
">", ".", ",", ":", ";", "!", "?", "\'",
|
||||
"\b", "(", ")", "=", "-", "/", "№", "%"
|
||||
};
|
||||
|
||||
const QString Baudot::m_usLetter[] = {
|
||||
const QStringList Baudot::m_usLetter = {
|
||||
"\0", "E", "\n", "A", " ", "S", "I", "U",
|
||||
"\r", "D", "R", "J", "N", "F", "C", "K",
|
||||
"T", "Z", "L", "W", "H", "Y", "P", "Q",
|
||||
"O", "B", "G", "<", "M", "X", "V", ">"
|
||||
};
|
||||
|
||||
const QString Baudot::m_usFigure[] = {
|
||||
const QStringList Baudot::m_usFigure = {
|
||||
"\0", "3", "\n", "-", " ", "\a", "8", "7",
|
||||
"\r", "\x5", "4", "\'", ",", "!", ":", "(",
|
||||
"5", "\"", ")", "2", "#", "6", "0", "1",
|
||||
"9", "?", "&", "<", ".", "/", ";", ">"
|
||||
};
|
||||
|
||||
const QString Baudot::m_russianLetter[] = {
|
||||
const QStringList Baudot::m_russianLetter = {
|
||||
"\0", "Е", "\n", "А", " ", "С", "И", "У",
|
||||
"\r", "Д", "П", "Й", "Н", "Ф", "Ц", "К",
|
||||
"Т", "З", "Л", "В", "Х", "Ы", "P", "Я",
|
||||
"\r", "Д", "Р", "Й", "Ч", "Ф", "Ц", "К",
|
||||
"Т", "З", "Л", "В", "Х", "Ы", "П", "Я",
|
||||
"О", "Б", "Г", "<", "М", "Ь", "Ж", ">"
|
||||
};
|
||||
|
||||
const QString Baudot::m_russianFigure[] = {
|
||||
const QStringList Baudot::m_russianFigure = {
|
||||
"\0", "3", "\n", "-", " ", "\'", "8", "7",
|
||||
"\r", "Ч", "4", "Ю", ",", "Э", ":", "(",
|
||||
"5", "+", ")", "2", "Щ", "6", "0", "1",
|
||||
"9", "?", "Ш", "<", ".", "/", ";", ">"
|
||||
};
|
||||
|
||||
const QString Baudot::m_murrayLetter[] = {
|
||||
const QStringList Baudot::m_murrayLetter = {
|
||||
" ", "E", "?", "A", ">", "S", "I", "U",
|
||||
"\n", "D", "R", "J", "N", "F", "C", "K",
|
||||
"T", "Z", "L", "W", "H", "Y", "P", "Q",
|
||||
"O", "B", "G", "<", "M", "X", "V", "\b"
|
||||
};
|
||||
|
||||
const QString Baudot::m_murrayFigure[] = {
|
||||
const QStringList Baudot::m_murrayFigure = {
|
||||
" ", "3", "?", " ", ">", "'", "8", "7",
|
||||
"\n", "²", "4", "⁷⁄", "-", "⅟", "(", "⁹⁄",
|
||||
"5", ".", "/", "2", "⁵⁄", "6", "0", "1",
|
||||
@ -190,3 +190,183 @@ QString BaudotDecoder::decode(char bits)
|
||||
return c;
|
||||
}
|
||||
|
||||
BaudotEncoder::BaudotEncoder()
|
||||
{
|
||||
setCharacterSet(Baudot::ITA2);
|
||||
setUnshiftOnSpace(false);
|
||||
setMsbFirst(false);
|
||||
setStartBits(1);
|
||||
setStopBits(1);
|
||||
init();
|
||||
}
|
||||
|
||||
void BaudotEncoder::setCharacterSet(Baudot::CharacterSet characterSet)
|
||||
{
|
||||
m_characterSet = characterSet;
|
||||
switch (m_characterSet)
|
||||
{
|
||||
case Baudot::ITA2:
|
||||
m_chars[LETTERS] = Baudot::m_ita2Letter;
|
||||
m_chars[FIGURES] = Baudot::m_ita2Figure;
|
||||
break;
|
||||
case Baudot::UK:
|
||||
m_chars[LETTERS] = Baudot::m_ukLetter;
|
||||
m_chars[FIGURES] = Baudot::m_ukFigure;
|
||||
break;
|
||||
case Baudot::EUROPEAN:
|
||||
m_chars[LETTERS] = Baudot::m_europeanLetter;
|
||||
m_chars[FIGURES] = Baudot::m_europeanFigure;
|
||||
break;
|
||||
case Baudot::US:
|
||||
m_chars[LETTERS] = Baudot::m_usLetter;
|
||||
m_chars[FIGURES] = Baudot::m_usFigure;
|
||||
break;
|
||||
case Baudot::RUSSIAN:
|
||||
m_chars[LETTERS] = Baudot::m_ita2Letter;
|
||||
m_chars[FIGURES] = Baudot::m_russianFigure;
|
||||
break;
|
||||
case Baudot::MURRAY:
|
||||
m_chars[LETTERS] = Baudot::m_murrayLetter;
|
||||
m_chars[FIGURES] = Baudot::m_murrayFigure;
|
||||
break;
|
||||
default:
|
||||
qDebug() << "BaudotEncoder::BaudotEncoder: Unsupported character set " << m_characterSet;
|
||||
m_chars[LETTERS] = Baudot::m_ita2Letter;
|
||||
m_chars[FIGURES] = Baudot::m_ita2Figure;
|
||||
m_characterSet = Baudot::ITA2;
|
||||
break;
|
||||
}
|
||||
m_chars[(int)CYRILLIC] = Baudot::m_russianLetter;
|
||||
}
|
||||
|
||||
void BaudotEncoder::setUnshiftOnSpace(bool unshiftOnSpace)
|
||||
{
|
||||
m_unshiftOnSpace = unshiftOnSpace;
|
||||
}
|
||||
|
||||
void BaudotEncoder::setMsbFirst(bool msbFirst)
|
||||
{
|
||||
m_msbFirst = msbFirst;
|
||||
}
|
||||
|
||||
// startBits should be 0 or 1
|
||||
void BaudotEncoder::setStartBits(int startBits)
|
||||
{
|
||||
m_startBits = startBits;
|
||||
}
|
||||
|
||||
// stopBits should be 0, 1 or 2
|
||||
void BaudotEncoder::setStopBits(int stopBits)
|
||||
{
|
||||
m_stopBits = stopBits;
|
||||
}
|
||||
|
||||
void BaudotEncoder::init()
|
||||
{
|
||||
m_page = LETTERS;
|
||||
}
|
||||
|
||||
bool BaudotEncoder::encode(QChar c, unsigned &bits, unsigned int &bitCount)
|
||||
{
|
||||
bits = 0;
|
||||
bitCount = 0;
|
||||
|
||||
// Only upper case is supported
|
||||
c = c.toUpper();
|
||||
QString s(c);
|
||||
|
||||
if (s == '>')
|
||||
{
|
||||
addCode(bits, bitCount, m_chars[m_page].indexOf(s));
|
||||
m_page = LETTERS;
|
||||
return true;
|
||||
}
|
||||
else if (s == '<')
|
||||
{
|
||||
addCode(bits, bitCount, m_chars[m_page].indexOf(s));
|
||||
m_page = FIGURES;
|
||||
return true;
|
||||
}
|
||||
else if ((m_characterSet == Baudot::RUSSIAN) && (s == '\0'))
|
||||
{
|
||||
addCode(bits, bitCount, m_chars[m_page].indexOf(s));
|
||||
m_page = CYRILLIC;
|
||||
return true;
|
||||
}
|
||||
|
||||
// We could create reverse look-up tables to speed this up, but it's only 200 baud...
|
||||
|
||||
// Is character in current page? If so, use that, as it avoids switching
|
||||
if (m_chars[m_page].contains(s))
|
||||
{
|
||||
addCode(bits, bitCount, m_chars[m_page].indexOf(s));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Look for character in other pages
|
||||
const QString switchPage[] = { ">", "<", "\0" };
|
||||
|
||||
for (int page = m_page == LETTERS ? 1 : 0; page < ((m_characterSet == Baudot::RUSSIAN) ? 3 : 2); page++)
|
||||
{
|
||||
if (m_chars[page].contains(s))
|
||||
{
|
||||
// Switch to page
|
||||
addCode(bits, bitCount, m_chars[m_page].indexOf(switchPage[page]));
|
||||
m_page = (BaudotEncoder::Page)page;
|
||||
|
||||
addCode(bits, bitCount, m_chars[m_page].indexOf(s));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void BaudotEncoder::addCode(unsigned& bits, unsigned int& bitCount, unsigned int code) const
|
||||
{
|
||||
const unsigned int codeLen = 5;
|
||||
|
||||
addStartBits(bits, bitCount);
|
||||
code = reverseBits(code, codeLen);
|
||||
addBits(bits, bitCount, code, codeLen);
|
||||
addStopBits(bits, bitCount);
|
||||
}
|
||||
|
||||
void BaudotEncoder::addStartBits(unsigned& bits, unsigned int& bitCount) const
|
||||
{
|
||||
// Start bit is 0
|
||||
addBits(bits, bitCount, 0, m_startBits);
|
||||
}
|
||||
|
||||
void BaudotEncoder::addStopBits(unsigned& bits, unsigned int& bitCount) const
|
||||
{
|
||||
// Stop bit is 1
|
||||
addBits(bits, bitCount, ((1 << m_stopBits)) - 1, m_stopBits);
|
||||
}
|
||||
|
||||
void BaudotEncoder::addBits(unsigned& bits, unsigned int& bitCount, int data, int count) const
|
||||
{
|
||||
bits |= data << bitCount;
|
||||
bitCount += count;
|
||||
}
|
||||
|
||||
unsigned BaudotEncoder::reverseBits(unsigned bits, unsigned int count) const
|
||||
{
|
||||
if (m_msbFirst) {
|
||||
return BaudotEncoder::reverse(bits) >> (sizeof(unsigned int) * 8 - count);
|
||||
} else {
|
||||
return bits;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int BaudotEncoder::reverse(unsigned int x)
|
||||
{
|
||||
x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
|
||||
x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
|
||||
x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
|
||||
x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
|
||||
|
||||
return((x >> 16) | (x << 16));
|
||||
}
|
||||
|
@ -38,18 +38,18 @@ public:
|
||||
};
|
||||
|
||||
// QString used for fractions in figure set
|
||||
static const QString m_ita2Letter[];
|
||||
static const QString m_ita2Figure[];
|
||||
static const QString m_ukLetter[];
|
||||
static const QString m_ukFigure[];
|
||||
static const QString m_europeanLetter[];
|
||||
static const QString m_europeanFigure[];
|
||||
static const QString m_usLetter[];
|
||||
static const QString m_usFigure[];
|
||||
static const QString m_russianLetter[];
|
||||
static const QString m_russianFigure[];
|
||||
static const QString m_murrayLetter[];
|
||||
static const QString m_murrayFigure[];
|
||||
static const QStringList m_ita2Letter;
|
||||
static const QStringList m_ita2Figure;
|
||||
static const QStringList m_ukLetter;
|
||||
static const QStringList m_ukFigure;
|
||||
static const QStringList m_europeanLetter;
|
||||
static const QStringList m_europeanFigure;
|
||||
static const QStringList m_usLetter;
|
||||
static const QStringList m_usFigure;
|
||||
static const QStringList m_russianLetter;
|
||||
static const QStringList m_russianFigure;
|
||||
static const QStringList m_murrayLetter;
|
||||
static const QStringList m_murrayFigure;
|
||||
|
||||
};
|
||||
|
||||
@ -58,7 +58,7 @@ class SDRBASE_API BaudotDecoder {
|
||||
public:
|
||||
|
||||
BaudotDecoder();
|
||||
void setCharacterSet(Baudot::CharacterSet characterSet=Baudot::ITA2);
|
||||
void setCharacterSet(Baudot::CharacterSet characterSet = Baudot::ITA2);
|
||||
void setUnshiftOnSpace(bool unshiftOnSpace);
|
||||
void init();
|
||||
QString decode(char bits);
|
||||
@ -67,11 +67,47 @@ private:
|
||||
|
||||
Baudot::CharacterSet m_characterSet;
|
||||
bool m_unshiftOnSpace;
|
||||
const QString *m_letters;
|
||||
const QString *m_figures;
|
||||
QStringList m_letters;
|
||||
QStringList m_figures;
|
||||
bool m_figure;
|
||||
|
||||
};
|
||||
|
||||
class SDRBASE_API BaudotEncoder {
|
||||
|
||||
public:
|
||||
|
||||
BaudotEncoder();
|
||||
void setCharacterSet(Baudot::CharacterSet characterSet = Baudot::ITA2);
|
||||
void setUnshiftOnSpace(bool unshiftOnSpace);
|
||||
void setMsbFirst(bool msbFirst);
|
||||
void setStartBits(int startBits);
|
||||
void setStopBits(int stopBits);
|
||||
void init();
|
||||
bool encode(QChar c, unsigned& bits, unsigned int &bitCount);
|
||||
|
||||
private:
|
||||
|
||||
void addCode(unsigned& bits, unsigned int& bitCount, unsigned int code) const;
|
||||
void addStartBits(unsigned int& bits, unsigned int& bitCount) const;
|
||||
void addStopBits(unsigned int& bits, unsigned int& bitCount) const;
|
||||
void addBits(unsigned int& bits, unsigned int& bitCount, int data, int count) const;
|
||||
unsigned reverseBits(unsigned int bits, unsigned int count) const;
|
||||
static unsigned reverse(unsigned int bits);
|
||||
|
||||
Baudot::CharacterSet m_characterSet;
|
||||
bool m_unshiftOnSpace;
|
||||
QStringList m_chars[3];
|
||||
enum Page {
|
||||
LETTERS,
|
||||
FIGURES,
|
||||
CYRILLIC
|
||||
} m_page;
|
||||
bool m_msbFirst;
|
||||
int m_startBits;
|
||||
int m_stopBits;
|
||||
|
||||
};
|
||||
|
||||
#endif // INCLUDE_UTIL_BAUDOT_H
|
||||
|
||||
|
290
sdrbase/util/rtty.cpp
Normal file
290
sdrbase/util/rtty.cpp
Normal file
@ -0,0 +1,290 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "util/rtty.h"
|
||||
|
||||
// From http://www.ct2fzi.net/abreviations/abreviations.html
|
||||
const QHash<QString, QString> Rtty::m_acronyms = {
|
||||
{"AA", "After All"},
|
||||
{"AB", "All Before"},
|
||||
{"ABT", "About"},
|
||||
{"ACK", "Acknowledgement"},
|
||||
{"ADEE", "Addressee"},
|
||||
{"ADR", "Address"},
|
||||
{"AF", "Audio Frequency"},
|
||||
{"AGN", "Again"},
|
||||
{"AM", "Amplitude Modulation"},
|
||||
{"AMU", "Antenna Matching Unit"},
|
||||
{"ANS", "Answer"},
|
||||
{"ANT", "Antenna"},
|
||||
{"ARQ", "Automatic Repeat Request"},
|
||||
{"ATU", "Antenna Tuning Unit"},
|
||||
{"B4", "Before"},
|
||||
{"BCN", "Beacon"},
|
||||
{"BCNU", "Be Seeing You"},
|
||||
{"BD", "Bad"},
|
||||
{"BK", "Break"},
|
||||
{"BN", "Been"},
|
||||
{"BTH", "Both"},
|
||||
{"BTR", "Better"},
|
||||
{"BTW", "By The Way"},
|
||||
{"BTU", "Back To You"},
|
||||
{"C", "Correct"},
|
||||
{"CBA", "Callbook Address"},
|
||||
{"CFM", "Confirm"},
|
||||
{"CK", "Check"},
|
||||
{"CKT", "Circuit"},
|
||||
{"CL", "Closing Down"},
|
||||
{"CLBK", "Callbook"},
|
||||
{"CLD", "Called"},
|
||||
{"CLG", "Calling"},
|
||||
{"CMG", "Coming"},
|
||||
{"CNT", "Can't"},
|
||||
{"COMP", "Computer"},
|
||||
{"CONDX", "Conditions"},
|
||||
{"COZ", "Because"},
|
||||
{"CPI", "Copy"},
|
||||
{"CQ", "General Call"},
|
||||
{"CRD", "Card"},
|
||||
{"CS", "Callsign"},
|
||||
{"CTCSS", "Continuous Tone Coded Squelch System"},
|
||||
{"CU", "See You"},
|
||||
{"CUAGN", "See You Again"},
|
||||
{"CUD", "Could"},
|
||||
{"CUL", "See You Later"},
|
||||
{"CUM", "Come"},
|
||||
{"CUZ", "Because"},
|
||||
{"CW", "Continuous Wave / Morse"},
|
||||
{"DA", "Day"},
|
||||
{"DE", "From"},
|
||||
{"DF", "Direction Finding"},
|
||||
{"DIFF", "Difference"},
|
||||
{"DLD", "Delivered"},
|
||||
{"DLVD", "Delivered"},
|
||||
{"DN", "Down"},
|
||||
{"DR", "Dear"},
|
||||
{"DSB", "Double Side Band"},
|
||||
{"DSP", "Digital Signal Processing"},
|
||||
{"DSW", "Goodbye (Russian)"},
|
||||
{"DWN", "Down"},
|
||||
{"DX", "Distance"},
|
||||
{"EL", "Element"},
|
||||
{"EME", "Earth-Moon-Earth"},
|
||||
{"ENUF", "Enough"},
|
||||
{"ES", "And"},
|
||||
{"EU", "Europe"},
|
||||
{"EVE", "Evening"},
|
||||
{"FB", "Fine Business"},
|
||||
{"FER", "For"},
|
||||
{"FIO", "For Information Only"},
|
||||
{"FM", "Frequency Modulation"},
|
||||
{"FQ", "Frequency"},
|
||||
{"FREQ", "Frequency"},
|
||||
{"FSD", "Full Scale Deflection"},
|
||||
{"FSK", "Frequency Shift Keying"},
|
||||
{"FWD", "Forward"},
|
||||
{"FWIW", "For What It's Worth"},
|
||||
{"FYI", "For Your Information"},
|
||||
{"GA", "Good Afternoon"},
|
||||
{"GB", "Good Bye"},
|
||||
{"GD", "Good Day"},
|
||||
{"GE", "Good Evening"},
|
||||
{"GESS", "Guess"},
|
||||
{"GG", "Going"},
|
||||
{"GLD", "Glad"},
|
||||
{"GM", "Good Morning"},
|
||||
{"GMT", "Greenwich Mean Time"},
|
||||
{"GN", "Good Night"},
|
||||
{"GND", "Ground"},
|
||||
{"GP", "Ground Plane"},
|
||||
{"GPS", "Global Positioning System"},
|
||||
{"GS", "Green Stamp"},
|
||||
{"GUD", "Good"},
|
||||
{"GV", "Give"},
|
||||
{"GVG", "Giving"},
|
||||
{"HAGD", "Have A Good Day"},
|
||||
{"HAGWE", "Have A Good Weekend"},
|
||||
{"HF", "High Frequency"},
|
||||
{"HI", "High"},
|
||||
{"HPE", "Hope"},
|
||||
{"HQ", "Headquarters"},
|
||||
{"HR", "Here / Hour"},
|
||||
{"HRD", "Heard"},
|
||||
{"HV", "Have"},
|
||||
{"HVG", "Having"},
|
||||
{"HVY", "Heavy"},
|
||||
{"HW", "How"},
|
||||
{"IMHO", "In My Humble Opinion"},
|
||||
{"IMI", "Say again"},
|
||||
{"K", "Over"},
|
||||
{"KN", "Over"},
|
||||
{"LF", "Low Frequency"},
|
||||
{"LNG", "Long"},
|
||||
{"LP", "Long Path"},
|
||||
{"LSB", "Lower Sideband"},
|
||||
{"LSN", "Listen"},
|
||||
{"LTR", "Later"},
|
||||
{"LV", "Leave"},
|
||||
{"LVG", "Leaving"},
|
||||
{"LW", "Long Wire"},
|
||||
{"MGR", "Manager"},
|
||||
{"MI", "My"},
|
||||
{"MNI", "Many"},
|
||||
{"MOM", "Moment"},
|
||||
{"MS", "Meteor Scatter"},
|
||||
{"MSG", "Message"},
|
||||
{"N", "No"},
|
||||
{"NCS", "Net Control Station"},
|
||||
{"ND", "Nothing Doing"},
|
||||
{"NM", "No More"},
|
||||
{"NR", "Near / Number"},
|
||||
{"NW", "Now"},
|
||||
{"OB", "Old Boy"},
|
||||
{"OC", "Old Chap"},
|
||||
{"OM", "Old Man"},
|
||||
{"OP", "Operator"},
|
||||
{"OPR", "Operator"},
|
||||
{"OT", "Old Timer"},
|
||||
{"OW", "Old Woman"},
|
||||
{"PA", "Power Amplifier"},
|
||||
{"PBL", "Preamble"},
|
||||
{"PKG", "Package"},
|
||||
{"POV", "Point Of View"},
|
||||
{"PSE", "Please"},
|
||||
{"PSK", "Phase Shift Keying"},
|
||||
{"PT", "Point"},
|
||||
{"PTT", "Push To Talk"},
|
||||
{"PWR", "Power"},
|
||||
{"PX", "Prefix"},
|
||||
{"QRA", "Address"},
|
||||
{"QRG", "Frequency"},
|
||||
{"QRK", "Readability"},
|
||||
{"QRL", "Busy"},
|
||||
{"QRM", "Interference"},
|
||||
{"QRN", "Noise"},
|
||||
{"QRO", "High Power"},
|
||||
{"QRP", "Low Power"},
|
||||
{"QRQ", "Send Faster"},
|
||||
{"QRS", "Send Slower"},
|
||||
{"QRSS", "Send Very Slowly"},
|
||||
{"QRT", "Stop Sending"},
|
||||
{"QRU", "Nothing Further To Say"},
|
||||
{"QRV", "Ready"},
|
||||
{"QRX", "Wait"},
|
||||
{"QRZ", "Who Is Calling Me"},
|
||||
{"QSA", "Signal Strength"},
|
||||
{"QSB", "Fading"},
|
||||
{"QSK", "Break-in"},
|
||||
{"QSL", "All Received OK"},
|
||||
{"QSLL", "I Will Send A QSL Card"},
|
||||
{"QSO", "Contact"},
|
||||
{"QSP", "Relay A Message"},
|
||||
{"QSX", "Listening On Frequency"},
|
||||
{"QSY", "Change Frequency"},
|
||||
{"QTH", "Location"},
|
||||
{"R", "Received OK"},
|
||||
{"RC", "Ragchew"},
|
||||
{"RCD", "Recieved"},
|
||||
{"RCVR", "Receiver"},
|
||||
{"RE", "Regarding"},
|
||||
{"REF", "Reference"},
|
||||
{"RF", "Radio Frequency"},
|
||||
{"RFI", "Radio Frequency Interference"},
|
||||
{"RPT", "Repeat / Report"},
|
||||
{"RST", "Signal Report"},
|
||||
{"RTTY", "Radio Teletype"},
|
||||
{"RX", "Receive"},
|
||||
{"SA", "Say"},
|
||||
{"SDR", "Software Defined Radio"},
|
||||
{"SEZ", "Says"},
|
||||
{"SGD", "Signed"},
|
||||
{"SHUD", "Should"},
|
||||
{"SIG", "Signal"},
|
||||
{"SK", "End Of Work"},
|
||||
{"SKED", "Schedule"},
|
||||
{"SN", "Soon"},
|
||||
{"SP", "Short Path"},
|
||||
{"SRI", "Sorry"},
|
||||
{"SSB", "Single Sideband"},
|
||||
{"STN", "Station"},
|
||||
{"SUM", "Some"},
|
||||
{"SVC", "Service"},
|
||||
{"SWR", "Standing Wave Ratio"},
|
||||
{"TFC", "Traffic"},
|
||||
{"TIA", "Thanks In Advance"},
|
||||
{"TKS", "Thanks"},
|
||||
{"TMW", "Tomorrow"},
|
||||
{"TNC", "Terminal Node Controller"},
|
||||
{"TNX", "Thanks"},
|
||||
{"TR", "Transmit"},
|
||||
{"T/R", "Transmit/Receive"},
|
||||
{"TRBL", "Trouble"},
|
||||
{"TRF", "Tuned Radio Frequency"},
|
||||
{"TRIX", "Tricks"},
|
||||
{"TRX", "Transceiver"},
|
||||
{"TT", "That"},
|
||||
{"TTS", "That Is"},
|
||||
{"TU", "Thank You"},
|
||||
{"TVI", "Television Interference"},
|
||||
{"TX", "Transmit"},
|
||||
{"TXT", "Text"},
|
||||
{"U", "You"},
|
||||
{"UHF", "Ultra High Frequency"},
|
||||
{"UNLIS", "Unlicensed"},
|
||||
{"UR", "Your"},
|
||||
{"URS", "Yours"},
|
||||
{"UTC", "Coordinated Universal Time"},
|
||||
{"V", "Volts"},
|
||||
{"VHF", "Very High Frequency"},
|
||||
{"VE", "Understood"},
|
||||
{"VERT", "Vertical"},
|
||||
{"VFB", "Very Fine Business"},
|
||||
{"VFO", "Variable Frequency Oscillator"},
|
||||
{"VLF", "Very Low Frequency"},
|
||||
{"VOX", "Voice Operated"},
|
||||
{"VSB", "Vestigial Sideband"},
|
||||
{"VSWR", "Voltage Standing Wave Ratio"},
|
||||
{"VY", "Very"},
|
||||
{"W", "Watts"},
|
||||
{"WA", "Word After"},
|
||||
{"WAT", "What"},
|
||||
{"WATSA", "What Say"},
|
||||
{"WB", "Word Before"},
|
||||
{"WD", "Word"},
|
||||
{"WDS", "Words"},
|
||||
{"WID", "With"},
|
||||
{"WKD", "Worked"},
|
||||
{"WKG", "Working"},
|
||||
{"WL", "Will"},
|
||||
{"WPM", "Words Per Minute"},
|
||||
{"WRD", "Word"},
|
||||
{"WRK", "Work"},
|
||||
{"WUD", "Would"},
|
||||
{"WX", "Weather"},
|
||||
{"XCVR", "Transceiver"},
|
||||
{"XMTR", "Transmitter"},
|
||||
{"XTAL", "Crystal"},
|
||||
{"YF", "Wife"},
|
||||
{"YL", "Young Lady"},
|
||||
{"YR", "Year"},
|
||||
{"Z", "Zulu Time"},
|
||||
{"30", "I Have Nothing More to Send"},
|
||||
{"33", "Fondest Regards"},
|
||||
{"55", "Best Success"},
|
||||
{"73", "Best Wishes"},
|
||||
{"88", "Love And Kisses"},
|
||||
};
|
31
sdrbase/util/rtty.h
Normal file
31
sdrbase/util/rtty.h
Normal file
@ -0,0 +1,31 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_UTIL_RTTY_H
|
||||
#define INCLUDE_UTIL_RTTY_H
|
||||
|
||||
#include <QHash>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
class SDRBASE_API Rtty
|
||||
{
|
||||
public:
|
||||
static const QHash<QString, QString> m_acronyms;
|
||||
};
|
||||
|
||||
#endif /* INCLUDE_UTIL_RTTY_H */
|
@ -4643,7 +4643,12 @@ bool WebAPIRequestMapper::getChannelSettings(
|
||||
{
|
||||
channelSettings->setRttyDemodSettings(new SWGSDRangel::SWGRTTYDemodSettings());
|
||||
channelSettings->getRttyDemodSettings()->fromJsonObject(settingsJsonObject);
|
||||
}
|
||||
}
|
||||
else if (channelSettingsKey == "RTTYModSettings")
|
||||
{
|
||||
channelSettings->setRttyModSettings(new SWGSDRangel::SWGRTTYModSettings());
|
||||
channelSettings->getRttyModSettings()->fromJsonObject(settingsJsonObject);
|
||||
}
|
||||
else if (channelSettingsKey == "SigMFFileSinkSettings")
|
||||
{
|
||||
channelSettings->setSigMfFileSinkSettings(new SWGSDRangel::SWGSigMFFileSinkSettings());
|
||||
@ -4751,6 +4756,11 @@ bool WebAPIRequestMapper::getChannelActions(
|
||||
channelActions->setPacketModActions(new SWGSDRangel::SWGPacketModActions());
|
||||
channelActions->getPacketModActions()->fromJsonObject(actionsJsonObject);
|
||||
}
|
||||
else if (channelActionsKey == "RTTYModActions")
|
||||
{
|
||||
channelActions->setRttyModActions(new SWGSDRangel::SWGRTTYModActions());
|
||||
channelActions->getRttyModActions()->fromJsonObject(actionsJsonObject);
|
||||
}
|
||||
else if (channelActionsKey == "SigMFFileSinkActions")
|
||||
{
|
||||
channelActions->setSigMfFileSinkActions(new SWGSDRangel::SWGSigMFFileSinkActions());
|
||||
@ -5432,6 +5442,7 @@ void WebAPIRequestMapper::resetChannelSettings(SWGSDRangel::SWGChannelSettings&
|
||||
channelSettings.setRemoteSourceSettings(nullptr);
|
||||
channelSettings.setRemoteTcpSinkSettings(nullptr);
|
||||
channelSettings.setRttyDemodSettings(nullptr);
|
||||
channelSettings.setRttyModSettings(nullptr);
|
||||
channelSettings.setSsbDemodSettings(nullptr);
|
||||
channelSettings.setSsbModSettings(nullptr);
|
||||
channelSettings.setUdpSourceSettings(nullptr);
|
||||
@ -5468,6 +5479,7 @@ void WebAPIRequestMapper::resetChannelReport(SWGSDRangel::SWGChannelReport& chan
|
||||
channelReport.setRadiosondeDemodReport(nullptr);
|
||||
channelReport.setRemoteSourceReport(nullptr);
|
||||
channelReport.setRttyDemodReport(nullptr);
|
||||
channelReport.setRttyModReport(nullptr);
|
||||
channelReport.setSsbDemodReport(nullptr);
|
||||
channelReport.setSsbModReport(nullptr);
|
||||
channelReport.setUdpSourceReport(nullptr);
|
||||
@ -5488,6 +5500,7 @@ void WebAPIRequestMapper::resetChannelActions(SWGSDRangel::SWGChannelActions& ch
|
||||
channelActions.setIeee802154ModActions(nullptr);
|
||||
channelActions.setRadioAstronomyActions(nullptr);
|
||||
channelActions.setPacketModActions(nullptr);
|
||||
channelActions.setRttyModActions(nullptr);
|
||||
}
|
||||
|
||||
void WebAPIRequestMapper::resetAudioInputDevice(SWGSDRangel::SWGAudioInputDevice& audioInputDevice)
|
||||
|
@ -70,6 +70,7 @@ const QMap<QString, QString> WebAPIUtils::m_channelURIToSettingsKey = {
|
||||
{"sdrangel.demod.remotetcpsink", "RemoteTCPSinkSettings"},
|
||||
{"sdrangel.channeltx.remotesource", "RemoteSourceSettings"},
|
||||
{"sdrangel.channel.rttydemod", "RTTYDemodSettings"},
|
||||
{"sdrangel.channel.rttymod", "RTTYModSettings"},
|
||||
{"sdrangel.channeltx.modssb", "SSBModSettings"},
|
||||
{"sdrangel.channel.ssbdemod", "SSBDemodSettings"},
|
||||
{"sdrangel.channel.ft8demod", "FT8DemodSettings"},
|
||||
@ -185,7 +186,8 @@ const QMap<QString, QString> WebAPIUtils::m_channelTypeToSettingsKey = {
|
||||
{"RemoteSink", "RemoteSinkSettings"},
|
||||
{"RemoteSource", "RemoteSourceSettings"},
|
||||
{"RemoteTCPSink", "RemoteTCPSinkSettings"},
|
||||
{"RTTYDemodSettings", "RTTYDemodSettings"},
|
||||
{"RTTYDemod", "RTTYDemodSettings"},
|
||||
{"RTTYMod", "RTTYModSettings"},
|
||||
{"SSBMod", "SSBModSettings"},
|
||||
{"SSBDemod", "SSBDemodSettings"},
|
||||
{"FT8Demod", "FT8DemodSettings"},
|
||||
@ -208,7 +210,8 @@ const QMap<QString, QString> WebAPIUtils::m_channelTypeToActionsKey = {
|
||||
{"SigMFFileSink", "SigMFFileSinkActions"},
|
||||
{"IEEE_802_15_4_Mod", "IEEE_802_15_4_ModActions"},
|
||||
{"RadioAstronomy", "RadioAstronomyActions"},
|
||||
{"PacketMod", "PacketModActions"}
|
||||
{"PacketMod", "PacketModActions"},
|
||||
{"RTTYMod", "RTTYModActions"}
|
||||
};
|
||||
|
||||
const QMap<QString, QString> WebAPIUtils::m_sourceDeviceHwIdToSettingsKey = {
|
||||
|
@ -7,6 +7,7 @@ set(CMAKE_AUTOUIC OFF)
|
||||
set(sdrgui_SOURCES
|
||||
mainwindow.cpp
|
||||
gui/aboutdialog.cpp
|
||||
gui/acronymview.cpp
|
||||
gui/addpresetdialog.cpp
|
||||
gui/audiodialog.cpp
|
||||
gui/audioselectdialog.cpp
|
||||
@ -127,6 +128,7 @@ set(sdrgui_HEADERS
|
||||
gui/aboutdialog.h
|
||||
gui/accessiblevaluedial.h
|
||||
gui/accessiblevaluedialz.h
|
||||
gui/acronymview.h
|
||||
gui/addpresetdialog.h
|
||||
gui/audiodialog.h
|
||||
gui/audioselectdialog.h
|
||||
|
68
sdrgui/gui/acronymview.cpp
Normal file
68
sdrgui/gui/acronymview.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QEvent>
|
||||
#include <QHelpEvent>
|
||||
#include <QToolTip>
|
||||
#include <QDebug>
|
||||
|
||||
#include "acronymview.h"
|
||||
|
||||
AcronymView::AcronymView(QWidget* parent) :
|
||||
QPlainTextEdit(parent)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
setReadOnly(true);
|
||||
}
|
||||
|
||||
bool AcronymView::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::ToolTip)
|
||||
{
|
||||
QHelpEvent* helpEvent = static_cast<QHelpEvent*>(event);
|
||||
QTextCursor cursor = cursorForPosition(helpEvent->pos());
|
||||
cursor.select(QTextCursor::WordUnderCursor);
|
||||
QString text = cursor.selectedText();
|
||||
// Remove trailing digits from METAR
|
||||
while (text.size() > 0 && text.right(1)[0].isDigit()) {
|
||||
text = text.left(text.size() - 1);
|
||||
}
|
||||
if (!text.isEmpty() && m_acronym.contains(text))
|
||||
{
|
||||
QToolTip::showText(helpEvent->globalPos(), QString("%1 - %2").arg(text).arg(m_acronym.value(text)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!text.isEmpty()) {
|
||||
qDebug() << "AcronymView::event: No tooltip for " << text;
|
||||
}
|
||||
QToolTip::hideText();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return QPlainTextEdit::event(event);
|
||||
}
|
||||
|
||||
void AcronymView::addAcronym(const QString& acronym, const QString& explanation)
|
||||
{
|
||||
m_acronym.insert(acronym, explanation);
|
||||
}
|
||||
|
||||
void AcronymView::addAcronyms(const QHash<QString, QString>& acronyms)
|
||||
{
|
||||
m_acronym.insert(acronyms);
|
||||
}
|
41
sdrgui/gui/acronymview.h
Normal file
41
sdrgui/gui/acronymview.h
Normal file
@ -0,0 +1,41 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_GUI_ACRONYMVIEW_H
|
||||
#define INCLUDE_GUI_ACRONYMVIEW_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
// Displays text like a QPlainTextEdit, but adds tooltips for acronyms in the text
|
||||
class SDRGUI_API AcronymView : public QPlainTextEdit {
|
||||
Q_OBJECT
|
||||
|
||||
QHash<QString, QString> m_acronym;
|
||||
|
||||
public:
|
||||
|
||||
AcronymView(QWidget* parent = nullptr);
|
||||
bool event(QEvent* event);
|
||||
void addAcronym(const QString& acronym, const QString& explanation);
|
||||
void addAcronyms(const QHash<QString, QString>& acronyms);
|
||||
|
||||
};
|
||||
|
||||
#endif // INCLUDE_GUI_ACRONYMVIEW_H
|
@ -31,5 +31,7 @@ ChannelActions:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/PacketMod.yaml#/PacketModActions"
|
||||
RadioAstronomyActions:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RadioAstronomy.yaml#/RadioAstronomyActions"
|
||||
RTTYModActions:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RTTYMod.yaml#/RTTYModActions"
|
||||
SigMFFileSinkActions:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/SigMFFileSink.yaml#/SigMFFileSinkActions"
|
||||
|
@ -81,6 +81,8 @@ ChannelReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RadiosondeDemod.yaml#/RadiosondeDemodReport"
|
||||
RemoteSourceReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RemoteSource.yaml#/RemoteSourceReport"
|
||||
RTTYModReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RTTYMod.yaml#/RTTYModReport"
|
||||
PacketDemodReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/PacketDemod.yaml#/PacketDemodReport"
|
||||
PacketModReport:
|
||||
|
@ -69,6 +69,8 @@ ChannelSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/FT8Demod.yaml#/FT8DemodSettings"
|
||||
RTTYDemodSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RTTYDemod.yaml#/RTTYDemodSettings"
|
||||
RTTYModSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RTTYMod.yaml#/RTTYModSettings"
|
||||
HeatMapSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/HeatMap.yaml#/HeatMapSettings"
|
||||
ILSDemodSettings:
|
||||
|
113
swagger/sdrangel/api/swagger/include/RTTYMod.yaml
Normal file
113
swagger/sdrangel/api/swagger/include/RTTYMod.yaml
Normal file
@ -0,0 +1,113 @@
|
||||
RTTYModSettings:
|
||||
description: RTTYMod
|
||||
properties:
|
||||
inputFrequencyOffset:
|
||||
type: integer
|
||||
format: int64
|
||||
baud:
|
||||
type: number
|
||||
format: float
|
||||
description: Baud rate
|
||||
rfBandwidth:
|
||||
type: integer
|
||||
frequencyShift:
|
||||
type: integer
|
||||
gain:
|
||||
type: number
|
||||
format: float
|
||||
channelMute:
|
||||
type: integer
|
||||
repeat:
|
||||
type: integer
|
||||
repeatCount:
|
||||
type: integer
|
||||
lpfTaps:
|
||||
type: integer
|
||||
rfNoise:
|
||||
type: integer
|
||||
description: >
|
||||
Boolean
|
||||
* 0 - off
|
||||
* 1 - on
|
||||
text:
|
||||
type: string
|
||||
description: Text to transmit
|
||||
pulseShaping:
|
||||
type: integer
|
||||
description: >
|
||||
Boolean
|
||||
* 0 - off
|
||||
* 1 - on
|
||||
beta:
|
||||
type: number
|
||||
format: float
|
||||
symbolSpan:
|
||||
type: integer
|
||||
characterSet:
|
||||
type: integer
|
||||
unshiftOnSpace:
|
||||
type: integer
|
||||
msbFirst:
|
||||
type: integer
|
||||
spaceHigh:
|
||||
type: integer
|
||||
prefixCRLF:
|
||||
type: integer
|
||||
postfixCRLF:
|
||||
type: integer
|
||||
udpEnabled:
|
||||
description: "Whether to receive text to transmit on specified UDP port"
|
||||
type: integer
|
||||
udpAddress:
|
||||
description: "UDP address to receive text to transmit via"
|
||||
type: string
|
||||
udpPort:
|
||||
description: "UDP port to receive text to transmit via"
|
||||
type: integer
|
||||
rgbColor:
|
||||
type: integer
|
||||
title:
|
||||
type: string
|
||||
streamIndex:
|
||||
description: MIMO channel. Not relevant when connected to SI (single Rx).
|
||||
type: integer
|
||||
useReverseAPI:
|
||||
description: Synchronize with reverse API (1 for yes, 0 for no)
|
||||
type: integer
|
||||
reverseAPIAddress:
|
||||
type: string
|
||||
reverseAPIPort:
|
||||
type: integer
|
||||
reverseAPIDeviceIndex:
|
||||
type: integer
|
||||
reverseAPIChannelIndex:
|
||||
type: integer
|
||||
channelMarker:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/ChannelMarker.yaml#/ChannelMarker"
|
||||
rollupState:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RollupState.yaml#/RollupState"
|
||||
|
||||
RTTYModReport:
|
||||
description: RTTYMod
|
||||
properties:
|
||||
channelPowerDB:
|
||||
description: power transmitted in channel (dB)
|
||||
type: number
|
||||
format: float
|
||||
channelSampleRate:
|
||||
type: integer
|
||||
|
||||
RTTYModActions:
|
||||
description: RTTYMod
|
||||
properties:
|
||||
tx:
|
||||
type: integer
|
||||
description: >
|
||||
Transmit current text
|
||||
* 0 - Do nothing
|
||||
* 1 - Transmit
|
||||
payload:
|
||||
type: object
|
||||
properties:
|
||||
text:
|
||||
type: string
|
@ -3484,6 +3484,9 @@ margin-bottom: 20px;
|
||||
"RadioAstronomyActions" : {
|
||||
"$ref" : "#/definitions/RadioAstronomyActions"
|
||||
},
|
||||
"RTTYModActions" : {
|
||||
"$ref" : "#/definitions/RTTYModActions"
|
||||
},
|
||||
"SigMFFileSinkActions" : {
|
||||
"$ref" : "#/definitions/SigMFFileSinkActions"
|
||||
}
|
||||
@ -3773,6 +3776,9 @@ margin-bottom: 20px;
|
||||
"RemoteSourceReport" : {
|
||||
"$ref" : "#/definitions/RemoteSourceReport"
|
||||
},
|
||||
"RTTYModReport" : {
|
||||
"$ref" : "#/definitions/RTTYModReport"
|
||||
},
|
||||
"PacketDemodReport" : {
|
||||
"$ref" : "#/definitions/PacketDemodReport"
|
||||
},
|
||||
@ -3904,6 +3910,9 @@ margin-bottom: 20px;
|
||||
"RTTYDemodSettings" : {
|
||||
"$ref" : "#/definitions/RTTYDemodSettings"
|
||||
},
|
||||
"RTTYModSettings" : {
|
||||
"$ref" : "#/definitions/RTTYModSettings"
|
||||
},
|
||||
"HeatMapSettings" : {
|
||||
"$ref" : "#/definitions/HeatMapSettings"
|
||||
},
|
||||
@ -5895,7 +5904,8 @@ margin-bottom: 20px;
|
||||
},
|
||||
"bandwidth" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "bandwidth ratio [0.0, 1.0]"
|
||||
}
|
||||
},
|
||||
"description" : "FFT filter band definition"
|
||||
@ -7269,11 +7279,13 @@ margin-bottom: 20px;
|
||||
"description" : "Identifier of the channel or feature plugin providing azimuth and elevation (E.g. R0:0 ADSBDemod)"
|
||||
},
|
||||
"azimuthOffset" : {
|
||||
"type" : "integer",
|
||||
"type" : "number",
|
||||
"format" : "float",
|
||||
"description" : "Azimuth offset in degrees"
|
||||
},
|
||||
"elevationOffset" : {
|
||||
"type" : "integer",
|
||||
"type" : "number",
|
||||
"format" : "float",
|
||||
"description" : "Elevation offset in degrees"
|
||||
},
|
||||
"azimuthMin" : {
|
||||
@ -8960,7 +8972,7 @@ margin-bottom: 20px;
|
||||
},
|
||||
"fftOn" : {
|
||||
"type" : "integer",
|
||||
"description" : "Activate FFT multiband filter\n * 0 - do not run flter\n * 1 - run filter\n"
|
||||
"description" : "Activate FFT multiband filter\n * 0 - do not run filter\n * 1 - run filter\n"
|
||||
},
|
||||
"log2FFT" : {
|
||||
"type" : "integer",
|
||||
@ -8977,7 +8989,8 @@ margin-bottom: 20px;
|
||||
}
|
||||
},
|
||||
"reverseFilter" : {
|
||||
"type" : "integer"
|
||||
"type" : "integer",
|
||||
"description" : "* 0 - band definitions are bandpass * 1 - band definitions are band reject\n"
|
||||
},
|
||||
"streamIndex" : {
|
||||
"type" : "integer",
|
||||
@ -9446,7 +9459,8 @@ margin-bottom: 20px;
|
||||
"description" : "Angle to rotate the image by"
|
||||
},
|
||||
"text" : {
|
||||
"type" : "string"
|
||||
"type" : "string",
|
||||
"description" : "Text to draw on the map when item is selected"
|
||||
},
|
||||
"latitude" : {
|
||||
"type" : "number",
|
||||
@ -9519,7 +9533,7 @@ margin-bottom: 20px;
|
||||
"labelAltitudeOffset" : {
|
||||
"type" : "number",
|
||||
"format" : "float",
|
||||
"description" : "Veritical offset to position label at"
|
||||
"description" : "Vertical offset to position label at"
|
||||
},
|
||||
"modelAltitudeOffset" : {
|
||||
"type" : "number",
|
||||
@ -9605,7 +9619,8 @@ margin-bottom: 20px;
|
||||
"description" : "Angle to rotate the image by"
|
||||
},
|
||||
"text" : {
|
||||
"type" : "string"
|
||||
"type" : "string",
|
||||
"description" : "Text to draw on the map when item is selected"
|
||||
},
|
||||
"latitude" : {
|
||||
"type" : "number",
|
||||
@ -9678,7 +9693,7 @@ margin-bottom: 20px;
|
||||
"labelAltitudeOffset" : {
|
||||
"type" : "number",
|
||||
"format" : "float",
|
||||
"description" : "Veritical offset to position label at"
|
||||
"description" : "Vertical offset to position label at"
|
||||
},
|
||||
"modelAltitudeOffset" : {
|
||||
"type" : "number",
|
||||
@ -11747,6 +11762,155 @@ margin-bottom: 20px;
|
||||
}
|
||||
},
|
||||
"description" : "ACARSDemod"
|
||||
};
|
||||
defs.RTTYModActions = {
|
||||
"properties" : {
|
||||
"tx" : {
|
||||
"type" : "integer",
|
||||
"description" : "Transmit current text\n * 0 - Do nothing\n * 1 - Transmit\n"
|
||||
},
|
||||
"payload" : {
|
||||
"$ref" : "#/definitions/RTTYModActions_payload"
|
||||
}
|
||||
},
|
||||
"description" : "RTTYMod"
|
||||
};
|
||||
defs.RTTYModActions_payload = {
|
||||
"properties" : {
|
||||
"text" : {
|
||||
"type" : "string"
|
||||
}
|
||||
}
|
||||
};
|
||||
defs.RTTYModReport = {
|
||||
"properties" : {
|
||||
"channelPowerDB" : {
|
||||
"type" : "number",
|
||||
"format" : "float",
|
||||
"description" : "power transmitted in channel (dB)"
|
||||
},
|
||||
"channelSampleRate" : {
|
||||
"type" : "integer"
|
||||
}
|
||||
},
|
||||
"description" : "RTTYMod"
|
||||
};
|
||||
defs.RTTYModSettings = {
|
||||
"properties" : {
|
||||
"inputFrequencyOffset" : {
|
||||
"type" : "integer",
|
||||
"format" : "int64"
|
||||
},
|
||||
"baud" : {
|
||||
"type" : "number",
|
||||
"format" : "float",
|
||||
"description" : "Baud rate"
|
||||
},
|
||||
"rfBandwidth" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"frequencyShift" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"gain" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
},
|
||||
"channelMute" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"repeat" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"repeatCount" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"lpfTaps" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"rfNoise" : {
|
||||
"type" : "integer",
|
||||
"description" : "Boolean\n * 0 - off\n * 1 - on\n"
|
||||
},
|
||||
"text" : {
|
||||
"type" : "string",
|
||||
"description" : "Text to transmit"
|
||||
},
|
||||
"pulseShaping" : {
|
||||
"type" : "integer",
|
||||
"description" : "Boolean\n * 0 - off\n * 1 - on\n"
|
||||
},
|
||||
"beta" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
},
|
||||
"symbolSpan" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"characterSet" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"unshiftOnSpace" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"msbFirst" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"spaceHigh" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"prefixCRLF" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"postfixCRLF" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"udpEnabled" : {
|
||||
"type" : "integer",
|
||||
"description" : "Whether to receive text to transmit on specified UDP port"
|
||||
},
|
||||
"udpAddress" : {
|
||||
"type" : "string",
|
||||
"description" : "UDP address to receive text to transmit via"
|
||||
},
|
||||
"udpPort" : {
|
||||
"type" : "integer",
|
||||
"description" : "UDP port to receive text to transmit via"
|
||||
},
|
||||
"rgbColor" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"title" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"streamIndex" : {
|
||||
"type" : "integer",
|
||||
"description" : "MIMO channel. Not relevant when connected to SI (single Rx)."
|
||||
},
|
||||
"useReverseAPI" : {
|
||||
"type" : "integer",
|
||||
"description" : "Synchronize with reverse API (1 for yes, 0 for no)"
|
||||
},
|
||||
"reverseAPIAddress" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"reverseAPIPort" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"reverseAPIDeviceIndex" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"reverseAPIChannelIndex" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"channelMarker" : {
|
||||
"$ref" : "#/definitions/ChannelMarker"
|
||||
},
|
||||
"rollupState" : {
|
||||
"$ref" : "#/definitions/RollupState"
|
||||
}
|
||||
},
|
||||
"description" : "RTTYMod"
|
||||
};
|
||||
defs.RadioAstronomyActions = {
|
||||
"properties" : {
|
||||
@ -14449,15 +14613,18 @@ margin-bottom: 20px;
|
||||
},
|
||||
"b" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "Galactic latitude in degrees"
|
||||
},
|
||||
"l" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "Galactic longitude in degrees"
|
||||
},
|
||||
"d" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "Distance to object from Sun in kpc"
|
||||
}
|
||||
},
|
||||
"description" : "Details of object to display in Star Tracker line-of-sight view. Can be sent by other plugins to startracker.display message queue"
|
||||
@ -14469,15 +14636,18 @@ margin-bottom: 20px;
|
||||
},
|
||||
"b" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "Galactic latitude in degrees"
|
||||
},
|
||||
"l" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "Galactic longitude in degrees"
|
||||
},
|
||||
"d" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "Distance to object from Sun in kpc"
|
||||
}
|
||||
},
|
||||
"description" : "Details of object to display in Star Tracker line-of-sight view. Can be sent by other plugins to startracker.display message queue"
|
||||
@ -14490,11 +14660,13 @@ margin-bottom: 20px;
|
||||
},
|
||||
"azimuth" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "The azimuth angle in degrees to the target"
|
||||
},
|
||||
"elevation" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "The elevation angle in degrees to the target"
|
||||
}
|
||||
},
|
||||
"description" : "Settings to display in Star Tracker. Can be sent by other plugins to startracker.display message queue."
|
||||
@ -14507,11 +14679,13 @@ margin-bottom: 20px;
|
||||
},
|
||||
"azimuth" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "The azimuth angle in degrees to the target"
|
||||
},
|
||||
"elevation" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "The elevation angle in degrees to the target"
|
||||
}
|
||||
},
|
||||
"description" : "Settings to display in Star Tracker. Can be sent by other plugins to startracker.display message queue."
|
||||
@ -14595,7 +14769,7 @@ margin-bottom: 20px;
|
||||
"temperature" : {
|
||||
"type" : "number",
|
||||
"format" : "float",
|
||||
"description" : "Air temperature in Celsuis, for refraction"
|
||||
"description" : "Air temperature in Celsius, for refraction"
|
||||
},
|
||||
"humidity" : {
|
||||
"type" : "number",
|
||||
@ -14618,7 +14792,8 @@ margin-bottom: 20px;
|
||||
"description" : "Frequency of radio waves being observed in MHz"
|
||||
},
|
||||
"stellariumServerEnabled" : {
|
||||
"type" : "integer"
|
||||
"type" : "integer",
|
||||
"description" : "Enable Stellarium server (1 for yes, 0 for no)"
|
||||
},
|
||||
"stellariumPort" : {
|
||||
"type" : "integer",
|
||||
@ -14676,15 +14851,18 @@ margin-bottom: 20px;
|
||||
defs.StarTrackerTarget = {
|
||||
"properties" : {
|
||||
"name" : {
|
||||
"type" : "string"
|
||||
"type" : "string",
|
||||
"description" : "The name of the target"
|
||||
},
|
||||
"azimuth" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "The azimuth angle in degrees to the target"
|
||||
},
|
||||
"elevation" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "The elevation angle in degrees to the target"
|
||||
},
|
||||
"ra" : {
|
||||
"type" : "number",
|
||||
@ -14698,11 +14876,13 @@ margin-bottom: 20px;
|
||||
},
|
||||
"b" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "Galactic latitude in degrees"
|
||||
},
|
||||
"l" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "Galactic longitude in degrees"
|
||||
},
|
||||
"earthRotationVelocity" : {
|
||||
"type" : "number",
|
||||
@ -14745,15 +14925,18 @@ margin-bottom: 20px;
|
||||
defs.StarTrackerTarget_2 = {
|
||||
"properties" : {
|
||||
"name" : {
|
||||
"type" : "string"
|
||||
"type" : "string",
|
||||
"description" : "The name of the target"
|
||||
},
|
||||
"azimuth" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "The azimuth angle in degrees to the target"
|
||||
},
|
||||
"elevation" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "The elevation angle in degrees to the target"
|
||||
},
|
||||
"ra" : {
|
||||
"type" : "number",
|
||||
@ -14767,11 +14950,13 @@ margin-bottom: 20px;
|
||||
},
|
||||
"b" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "Galactic latitude in degrees"
|
||||
},
|
||||
"l" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "Galactic longitude in degrees"
|
||||
},
|
||||
"earthRotationVelocity" : {
|
||||
"type" : "number",
|
||||
@ -14822,15 +15007,18 @@ margin-bottom: 20px;
|
||||
defs.TargetAzimuthElevation = {
|
||||
"properties" : {
|
||||
"name" : {
|
||||
"type" : "string"
|
||||
"type" : "string",
|
||||
"description" : "The name of the target"
|
||||
},
|
||||
"azimuth" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "The azimuth angle in degrees to the target"
|
||||
},
|
||||
"elevation" : {
|
||||
"type" : "number",
|
||||
"format" : "float"
|
||||
"format" : "float",
|
||||
"description" : "The elevation angle in degrees to the target"
|
||||
}
|
||||
},
|
||||
"description" : "A target azimuth and elevation"
|
||||
@ -22563,7 +22751,7 @@ $(document).ready(function() {
|
||||
|
||||
|
||||
<h2>Responses</h2>
|
||||
<h3> Status: 202 - On successful semding of the message it returns the details of the device being set </h3>
|
||||
<h3> Status: 202 - On successful sending of the message it returns the details of the device being set </h3>
|
||||
|
||||
<ul class="nav nav-tabs nav-tabs-examples" >
|
||||
<li class="active">
|
||||
@ -22578,7 +22766,7 @@ $(document).ready(function() {
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var schemaWrapper = {
|
||||
"description" : "On successful semding of the message it returns the details of the device being set",
|
||||
"description" : "On successful sending of the message it returns the details of the device being set",
|
||||
"schema" : {
|
||||
"$ref" : "#/definitions/DeviceListItem"
|
||||
}
|
||||
@ -31220,7 +31408,7 @@ $(document).ready(function() {
|
||||
<div class="pull-right"></div>
|
||||
<div class="clearfix"></div>
|
||||
<p></p>
|
||||
<p class="marked">Apply main spectrum settings unconditionnaly (force)</p>
|
||||
<p class="marked">Apply main spectrum settings unconditionally (force)</p>
|
||||
<p></p>
|
||||
<br />
|
||||
<pre class="prettyprint language-html prettyprinted" data-type="put"><code><span class="pln">/sdrangel/deviceset/{deviceSetIndex}/spectrum/settings</span></code></pre>
|
||||
@ -41339,7 +41527,7 @@ except ApiException as e:
|
||||
<div class="pull-right"></div>
|
||||
<div class="clearfix"></div>
|
||||
<p></p>
|
||||
<p class="marked">Delete audio input device paramaters and return to defaults</p>
|
||||
<p class="marked">Delete audio input device parameters and return to defaults</p>
|
||||
<p></p>
|
||||
<br />
|
||||
<pre class="prettyprint language-html prettyprinted" data-type="delete"><code><span class="pln">/sdrangel/audio/input/parameters</span></code></pre>
|
||||
@ -41769,7 +41957,7 @@ $(document).ready(function() {
|
||||
<div class="pull-right"></div>
|
||||
<div class="clearfix"></div>
|
||||
<p></p>
|
||||
<p class="marked">Set audio input device paramaters</p>
|
||||
<p class="marked">Set audio input device parameters</p>
|
||||
<p></p>
|
||||
<br />
|
||||
<pre class="prettyprint language-html prettyprinted" data-type="patch"><code><span class="pln">/sdrangel/audio/input/parameters</span></code></pre>
|
||||
@ -42534,7 +42722,7 @@ except ApiException as e:
|
||||
<div class="pull-right"></div>
|
||||
<div class="clearfix"></div>
|
||||
<p></p>
|
||||
<p class="marked">Delete audio output device paramaters and return to defaults</p>
|
||||
<p class="marked">Delete audio output device parameters and return to defaults</p>
|
||||
<p></p>
|
||||
<br />
|
||||
<pre class="prettyprint language-html prettyprinted" data-type="delete"><code><span class="pln">/sdrangel/audio/output/parameters</span></code></pre>
|
||||
@ -52246,7 +52434,7 @@ except ApiException as e:
|
||||
<div class="pull-right"></div>
|
||||
<div class="clearfix"></div>
|
||||
<p></p>
|
||||
<p class="marked">Change logging parmeters for this instance</p>
|
||||
<p class="marked">Change logging parameters for this instance</p>
|
||||
<p></p>
|
||||
<br />
|
||||
<pre class="prettyprint language-html prettyprinted" data-type="put"><code><span class="pln">/sdrangel/logging</span></code></pre>
|
||||
@ -57806,7 +57994,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2023-07-09T18:31:34.285+02:00
|
||||
Generated 2023-09-01T21:10:19.928+02:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -50,6 +50,8 @@ SWGChannelActions::SWGChannelActions() {
|
||||
m_packet_mod_actions_isSet = false;
|
||||
radio_astronomy_actions = nullptr;
|
||||
m_radio_astronomy_actions_isSet = false;
|
||||
rtty_mod_actions = nullptr;
|
||||
m_rtty_mod_actions_isSet = false;
|
||||
sig_mf_file_sink_actions = nullptr;
|
||||
m_sig_mf_file_sink_actions_isSet = false;
|
||||
}
|
||||
@ -82,6 +84,8 @@ SWGChannelActions::init() {
|
||||
m_packet_mod_actions_isSet = false;
|
||||
radio_astronomy_actions = new SWGRadioAstronomyActions();
|
||||
m_radio_astronomy_actions_isSet = false;
|
||||
rtty_mod_actions = new SWGRTTYModActions();
|
||||
m_rtty_mod_actions_isSet = false;
|
||||
sig_mf_file_sink_actions = new SWGSigMFFileSinkActions();
|
||||
m_sig_mf_file_sink_actions_isSet = false;
|
||||
}
|
||||
@ -115,6 +119,9 @@ SWGChannelActions::cleanup() {
|
||||
if(radio_astronomy_actions != nullptr) {
|
||||
delete radio_astronomy_actions;
|
||||
}
|
||||
if(rtty_mod_actions != nullptr) {
|
||||
delete rtty_mod_actions;
|
||||
}
|
||||
if(sig_mf_file_sink_actions != nullptr) {
|
||||
delete sig_mf_file_sink_actions;
|
||||
}
|
||||
@ -153,6 +160,8 @@ SWGChannelActions::fromJsonObject(QJsonObject &pJson) {
|
||||
|
||||
::SWGSDRangel::setValue(&radio_astronomy_actions, pJson["RadioAstronomyActions"], "SWGRadioAstronomyActions", "SWGRadioAstronomyActions");
|
||||
|
||||
::SWGSDRangel::setValue(&rtty_mod_actions, pJson["RTTYModActions"], "SWGRTTYModActions", "SWGRTTYModActions");
|
||||
|
||||
::SWGSDRangel::setValue(&sig_mf_file_sink_actions, pJson["SigMFFileSinkActions"], "SWGSigMFFileSinkActions", "SWGSigMFFileSinkActions");
|
||||
|
||||
}
|
||||
@ -204,6 +213,9 @@ SWGChannelActions::asJsonObject() {
|
||||
if((radio_astronomy_actions != nullptr) && (radio_astronomy_actions->isSet())){
|
||||
toJsonValue(QString("RadioAstronomyActions"), radio_astronomy_actions, obj, QString("SWGRadioAstronomyActions"));
|
||||
}
|
||||
if((rtty_mod_actions != nullptr) && (rtty_mod_actions->isSet())){
|
||||
toJsonValue(QString("RTTYModActions"), rtty_mod_actions, obj, QString("SWGRTTYModActions"));
|
||||
}
|
||||
if((sig_mf_file_sink_actions != nullptr) && (sig_mf_file_sink_actions->isSet())){
|
||||
toJsonValue(QString("SigMFFileSinkActions"), sig_mf_file_sink_actions, obj, QString("SWGSigMFFileSinkActions"));
|
||||
}
|
||||
@ -321,6 +333,16 @@ SWGChannelActions::setRadioAstronomyActions(SWGRadioAstronomyActions* radio_astr
|
||||
this->m_radio_astronomy_actions_isSet = true;
|
||||
}
|
||||
|
||||
SWGRTTYModActions*
|
||||
SWGChannelActions::getRttyModActions() {
|
||||
return rtty_mod_actions;
|
||||
}
|
||||
void
|
||||
SWGChannelActions::setRttyModActions(SWGRTTYModActions* rtty_mod_actions) {
|
||||
this->rtty_mod_actions = rtty_mod_actions;
|
||||
this->m_rtty_mod_actions_isSet = true;
|
||||
}
|
||||
|
||||
SWGSigMFFileSinkActions*
|
||||
SWGChannelActions::getSigMfFileSinkActions() {
|
||||
return sig_mf_file_sink_actions;
|
||||
@ -369,6 +391,9 @@ SWGChannelActions::isSet(){
|
||||
if(radio_astronomy_actions && radio_astronomy_actions->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(rtty_mod_actions && rtty_mod_actions->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(sig_mf_file_sink_actions && sig_mf_file_sink_actions->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "SWGFileSourceActions.h"
|
||||
#include "SWGIEEE_802_15_4_ModActions.h"
|
||||
#include "SWGPacketModActions.h"
|
||||
#include "SWGRTTYModActions.h"
|
||||
#include "SWGRadioAstronomyActions.h"
|
||||
#include "SWGSigMFFileSinkActions.h"
|
||||
#include <QString>
|
||||
@ -83,6 +84,9 @@ public:
|
||||
SWGRadioAstronomyActions* getRadioAstronomyActions();
|
||||
void setRadioAstronomyActions(SWGRadioAstronomyActions* radio_astronomy_actions);
|
||||
|
||||
SWGRTTYModActions* getRttyModActions();
|
||||
void setRttyModActions(SWGRTTYModActions* rtty_mod_actions);
|
||||
|
||||
SWGSigMFFileSinkActions* getSigMfFileSinkActions();
|
||||
void setSigMfFileSinkActions(SWGSigMFFileSinkActions* sig_mf_file_sink_actions);
|
||||
|
||||
@ -123,6 +127,9 @@ private:
|
||||
SWGRadioAstronomyActions* radio_astronomy_actions;
|
||||
bool m_radio_astronomy_actions_isSet;
|
||||
|
||||
SWGRTTYModActions* rtty_mod_actions;
|
||||
bool m_rtty_mod_actions_isSet;
|
||||
|
||||
SWGSigMFFileSinkActions* sig_mf_file_sink_actions;
|
||||
bool m_sig_mf_file_sink_actions_isSet;
|
||||
|
||||
|
@ -102,6 +102,8 @@ SWGChannelReport::SWGChannelReport() {
|
||||
m_radiosonde_demod_report_isSet = false;
|
||||
remote_source_report = nullptr;
|
||||
m_remote_source_report_isSet = false;
|
||||
rtty_mod_report = nullptr;
|
||||
m_rtty_mod_report_isSet = false;
|
||||
packet_demod_report = nullptr;
|
||||
m_packet_demod_report_isSet = false;
|
||||
packet_mod_report = nullptr;
|
||||
@ -204,6 +206,8 @@ SWGChannelReport::init() {
|
||||
m_radiosonde_demod_report_isSet = false;
|
||||
remote_source_report = new SWGRemoteSourceReport();
|
||||
m_remote_source_report_isSet = false;
|
||||
rtty_mod_report = new SWGRTTYModReport();
|
||||
m_rtty_mod_report_isSet = false;
|
||||
packet_demod_report = new SWGPacketDemodReport();
|
||||
m_packet_demod_report_isSet = false;
|
||||
packet_mod_report = new SWGPacketModReport();
|
||||
@ -337,6 +341,9 @@ SWGChannelReport::cleanup() {
|
||||
if(remote_source_report != nullptr) {
|
||||
delete remote_source_report;
|
||||
}
|
||||
if(rtty_mod_report != nullptr) {
|
||||
delete rtty_mod_report;
|
||||
}
|
||||
if(packet_demod_report != nullptr) {
|
||||
delete packet_demod_report;
|
||||
}
|
||||
@ -454,6 +461,8 @@ SWGChannelReport::fromJsonObject(QJsonObject &pJson) {
|
||||
|
||||
::SWGSDRangel::setValue(&remote_source_report, pJson["RemoteSourceReport"], "SWGRemoteSourceReport", "SWGRemoteSourceReport");
|
||||
|
||||
::SWGSDRangel::setValue(&rtty_mod_report, pJson["RTTYModReport"], "SWGRTTYModReport", "SWGRTTYModReport");
|
||||
|
||||
::SWGSDRangel::setValue(&packet_demod_report, pJson["PacketDemodReport"], "SWGPacketDemodReport", "SWGPacketDemodReport");
|
||||
|
||||
::SWGSDRangel::setValue(&packet_mod_report, pJson["PacketModReport"], "SWGPacketModReport", "SWGPacketModReport");
|
||||
@ -601,6 +610,9 @@ SWGChannelReport::asJsonObject() {
|
||||
if((remote_source_report != nullptr) && (remote_source_report->isSet())){
|
||||
toJsonValue(QString("RemoteSourceReport"), remote_source_report, obj, QString("SWGRemoteSourceReport"));
|
||||
}
|
||||
if((rtty_mod_report != nullptr) && (rtty_mod_report->isSet())){
|
||||
toJsonValue(QString("RTTYModReport"), rtty_mod_report, obj, QString("SWGRTTYModReport"));
|
||||
}
|
||||
if((packet_demod_report != nullptr) && (packet_demod_report->isSet())){
|
||||
toJsonValue(QString("PacketDemodReport"), packet_demod_report, obj, QString("SWGPacketDemodReport"));
|
||||
}
|
||||
@ -1005,6 +1017,16 @@ SWGChannelReport::setRemoteSourceReport(SWGRemoteSourceReport* remote_source_rep
|
||||
this->m_remote_source_report_isSet = true;
|
||||
}
|
||||
|
||||
SWGRTTYModReport*
|
||||
SWGChannelReport::getRttyModReport() {
|
||||
return rtty_mod_report;
|
||||
}
|
||||
void
|
||||
SWGChannelReport::setRttyModReport(SWGRTTYModReport* rtty_mod_report) {
|
||||
this->rtty_mod_report = rtty_mod_report;
|
||||
this->m_rtty_mod_report_isSet = true;
|
||||
}
|
||||
|
||||
SWGPacketDemodReport*
|
||||
SWGChannelReport::getPacketDemodReport() {
|
||||
return packet_demod_report;
|
||||
@ -1221,6 +1243,9 @@ SWGChannelReport::isSet(){
|
||||
if(remote_source_report && remote_source_report->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(rtty_mod_report && rtty_mod_report->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(packet_demod_report && packet_demod_report->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "SWGPacketModReport.h"
|
||||
#include "SWGPagerDemodReport.h"
|
||||
#include "SWGRTTYDemodReport.h"
|
||||
#include "SWGRTTYModReport.h"
|
||||
#include "SWGRadioAstronomyReport.h"
|
||||
#include "SWGRadioClockReport.h"
|
||||
#include "SWGRadiosondeDemodReport.h"
|
||||
@ -198,6 +199,9 @@ public:
|
||||
SWGRemoteSourceReport* getRemoteSourceReport();
|
||||
void setRemoteSourceReport(SWGRemoteSourceReport* remote_source_report);
|
||||
|
||||
SWGRTTYModReport* getRttyModReport();
|
||||
void setRttyModReport(SWGRTTYModReport* rtty_mod_report);
|
||||
|
||||
SWGPacketDemodReport* getPacketDemodReport();
|
||||
void setPacketDemodReport(SWGPacketDemodReport* packet_demod_report);
|
||||
|
||||
@ -343,6 +347,9 @@ private:
|
||||
SWGRemoteSourceReport* remote_source_report;
|
||||
bool m_remote_source_report_isSet;
|
||||
|
||||
SWGRTTYModReport* rtty_mod_report;
|
||||
bool m_rtty_mod_report_isSet;
|
||||
|
||||
SWGPacketDemodReport* packet_demod_report;
|
||||
bool m_packet_demod_report_isSet;
|
||||
|
||||
|
@ -88,6 +88,8 @@ SWGChannelSettings::SWGChannelSettings() {
|
||||
m_ft8_demod_settings_isSet = false;
|
||||
rtty_demod_settings = nullptr;
|
||||
m_rtty_demod_settings_isSet = false;
|
||||
rtty_mod_settings = nullptr;
|
||||
m_rtty_mod_settings_isSet = false;
|
||||
heat_map_settings = nullptr;
|
||||
m_heat_map_settings_isSet = false;
|
||||
ils_demod_settings = nullptr;
|
||||
@ -214,6 +216,8 @@ SWGChannelSettings::init() {
|
||||
m_ft8_demod_settings_isSet = false;
|
||||
rtty_demod_settings = new SWGRTTYDemodSettings();
|
||||
m_rtty_demod_settings_isSet = false;
|
||||
rtty_mod_settings = new SWGRTTYModSettings();
|
||||
m_rtty_mod_settings_isSet = false;
|
||||
heat_map_settings = new SWGHeatMapSettings();
|
||||
m_heat_map_settings_isSet = false;
|
||||
ils_demod_settings = new SWGILSDemodSettings();
|
||||
@ -360,6 +364,9 @@ SWGChannelSettings::cleanup() {
|
||||
if(rtty_demod_settings != nullptr) {
|
||||
delete rtty_demod_settings;
|
||||
}
|
||||
if(rtty_mod_settings != nullptr) {
|
||||
delete rtty_mod_settings;
|
||||
}
|
||||
if(heat_map_settings != nullptr) {
|
||||
delete heat_map_settings;
|
||||
}
|
||||
@ -520,6 +527,8 @@ SWGChannelSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
|
||||
::SWGSDRangel::setValue(&rtty_demod_settings, pJson["RTTYDemodSettings"], "SWGRTTYDemodSettings", "SWGRTTYDemodSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&rtty_mod_settings, pJson["RTTYModSettings"], "SWGRTTYModSettings", "SWGRTTYModSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&heat_map_settings, pJson["HeatMapSettings"], "SWGHeatMapSettings", "SWGHeatMapSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&ils_demod_settings, pJson["ILSDemodSettings"], "SWGILSDemodSettings", "SWGILSDemodSettings");
|
||||
@ -684,6 +693,9 @@ SWGChannelSettings::asJsonObject() {
|
||||
if((rtty_demod_settings != nullptr) && (rtty_demod_settings->isSet())){
|
||||
toJsonValue(QString("RTTYDemodSettings"), rtty_demod_settings, obj, QString("SWGRTTYDemodSettings"));
|
||||
}
|
||||
if((rtty_mod_settings != nullptr) && (rtty_mod_settings->isSet())){
|
||||
toJsonValue(QString("RTTYModSettings"), rtty_mod_settings, obj, QString("SWGRTTYModSettings"));
|
||||
}
|
||||
if((heat_map_settings != nullptr) && (heat_map_settings->isSet())){
|
||||
toJsonValue(QString("HeatMapSettings"), heat_map_settings, obj, QString("SWGHeatMapSettings"));
|
||||
}
|
||||
@ -1075,6 +1087,16 @@ SWGChannelSettings::setRttyDemodSettings(SWGRTTYDemodSettings* rtty_demod_settin
|
||||
this->m_rtty_demod_settings_isSet = true;
|
||||
}
|
||||
|
||||
SWGRTTYModSettings*
|
||||
SWGChannelSettings::getRttyModSettings() {
|
||||
return rtty_mod_settings;
|
||||
}
|
||||
void
|
||||
SWGChannelSettings::setRttyModSettings(SWGRTTYModSettings* rtty_mod_settings) {
|
||||
this->rtty_mod_settings = rtty_mod_settings;
|
||||
this->m_rtty_mod_settings_isSet = true;
|
||||
}
|
||||
|
||||
SWGHeatMapSettings*
|
||||
SWGChannelSettings::getHeatMapSettings() {
|
||||
return heat_map_settings;
|
||||
@ -1460,6 +1482,9 @@ SWGChannelSettings::isSet(){
|
||||
if(rtty_demod_settings && rtty_demod_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(rtty_mod_settings && rtty_mod_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(heat_map_settings && heat_map_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "SWGPacketModSettings.h"
|
||||
#include "SWGPagerDemodSettings.h"
|
||||
#include "SWGRTTYDemodSettings.h"
|
||||
#include "SWGRTTYModSettings.h"
|
||||
#include "SWGRadioAstronomySettings.h"
|
||||
#include "SWGRadioClockSettings.h"
|
||||
#include "SWGRadiosondeDemodSettings.h"
|
||||
@ -187,6 +188,9 @@ public:
|
||||
SWGRTTYDemodSettings* getRttyDemodSettings();
|
||||
void setRttyDemodSettings(SWGRTTYDemodSettings* rtty_demod_settings);
|
||||
|
||||
SWGRTTYModSettings* getRttyModSettings();
|
||||
void setRttyModSettings(SWGRTTYModSettings* rtty_mod_settings);
|
||||
|
||||
SWGHeatMapSettings* getHeatMapSettings();
|
||||
void setHeatMapSettings(SWGHeatMapSettings* heat_map_settings);
|
||||
|
||||
@ -368,6 +372,9 @@ private:
|
||||
SWGRTTYDemodSettings* rtty_demod_settings;
|
||||
bool m_rtty_demod_settings_isSet;
|
||||
|
||||
SWGRTTYModSettings* rtty_mod_settings;
|
||||
bool m_rtty_mod_settings_isSet;
|
||||
|
||||
SWGHeatMapSettings* heat_map_settings;
|
||||
bool m_heat_map_settings_isSet;
|
||||
|
||||
|
@ -251,6 +251,10 @@
|
||||
#include "SWGRDSReport_altFrequencies.h"
|
||||
#include "SWGRTTYDemodReport.h"
|
||||
#include "SWGRTTYDemodSettings.h"
|
||||
#include "SWGRTTYModActions.h"
|
||||
#include "SWGRTTYModActions_payload.h"
|
||||
#include "SWGRTTYModReport.h"
|
||||
#include "SWGRTTYModSettings.h"
|
||||
#include "SWGRadioAstronomyActions.h"
|
||||
#include "SWGRadioAstronomyReport.h"
|
||||
#include "SWGRadioAstronomySettings.h"
|
||||
@ -1545,6 +1549,26 @@ namespace SWGSDRangel {
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGRTTYModActions").compare(type) == 0) {
|
||||
SWGRTTYModActions *obj = new SWGRTTYModActions();
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGRTTYModActions_payload").compare(type) == 0) {
|
||||
SWGRTTYModActions_payload *obj = new SWGRTTYModActions_payload();
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGRTTYModReport").compare(type) == 0) {
|
||||
SWGRTTYModReport *obj = new SWGRTTYModReport();
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGRTTYModSettings").compare(type) == 0) {
|
||||
SWGRTTYModSettings *obj = new SWGRTTYModSettings();
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGRadioAstronomyActions").compare(type) == 0) {
|
||||
SWGRadioAstronomyActions *obj = new SWGRadioAstronomyActions();
|
||||
obj->init();
|
||||
|
133
swagger/sdrangel/code/qt5/client/SWGRTTYModActions.cpp
Normal file
133
swagger/sdrangel/code/qt5/client/SWGRTTYModActions.cpp
Normal file
@ -0,0 +1,133 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
#include "SWGRTTYModActions.h"
|
||||
|
||||
#include "SWGHelpers.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
SWGRTTYModActions::SWGRTTYModActions(QString* json) {
|
||||
init();
|
||||
this->fromJson(*json);
|
||||
}
|
||||
|
||||
SWGRTTYModActions::SWGRTTYModActions() {
|
||||
tx = 0;
|
||||
m_tx_isSet = false;
|
||||
payload = nullptr;
|
||||
m_payload_isSet = false;
|
||||
}
|
||||
|
||||
SWGRTTYModActions::~SWGRTTYModActions() {
|
||||
this->cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModActions::init() {
|
||||
tx = 0;
|
||||
m_tx_isSet = false;
|
||||
payload = new SWGRTTYModActions_payload();
|
||||
m_payload_isSet = false;
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModActions::cleanup() {
|
||||
|
||||
if(payload != nullptr) {
|
||||
delete payload;
|
||||
}
|
||||
}
|
||||
|
||||
SWGRTTYModActions*
|
||||
SWGRTTYModActions::fromJson(QString &json) {
|
||||
QByteArray array (json.toStdString().c_str());
|
||||
QJsonDocument doc = QJsonDocument::fromJson(array);
|
||||
QJsonObject jsonObject = doc.object();
|
||||
this->fromJsonObject(jsonObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModActions::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&tx, pJson["tx"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&payload, pJson["payload"], "SWGRTTYModActions_payload", "SWGRTTYModActions_payload");
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
SWGRTTYModActions::asJson ()
|
||||
{
|
||||
QJsonObject* obj = this->asJsonObject();
|
||||
|
||||
QJsonDocument doc(*obj);
|
||||
QByteArray bytes = doc.toJson();
|
||||
delete obj;
|
||||
return QString(bytes);
|
||||
}
|
||||
|
||||
QJsonObject*
|
||||
SWGRTTYModActions::asJsonObject() {
|
||||
QJsonObject* obj = new QJsonObject();
|
||||
if(m_tx_isSet){
|
||||
obj->insert("tx", QJsonValue(tx));
|
||||
}
|
||||
if((payload != nullptr) && (payload->isSet())){
|
||||
toJsonValue(QString("payload"), payload, obj, QString("SWGRTTYModActions_payload"));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModActions::getTx() {
|
||||
return tx;
|
||||
}
|
||||
void
|
||||
SWGRTTYModActions::setTx(qint32 tx) {
|
||||
this->tx = tx;
|
||||
this->m_tx_isSet = true;
|
||||
}
|
||||
|
||||
SWGRTTYModActions_payload*
|
||||
SWGRTTYModActions::getPayload() {
|
||||
return payload;
|
||||
}
|
||||
void
|
||||
SWGRTTYModActions::setPayload(SWGRTTYModActions_payload* payload) {
|
||||
this->payload = payload;
|
||||
this->m_payload_isSet = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SWGRTTYModActions::isSet(){
|
||||
bool isObjectUpdated = false;
|
||||
do{
|
||||
if(m_tx_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(payload && payload->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
}
|
||||
|
65
swagger/sdrangel/code/qt5/client/SWGRTTYModActions.h
Normal file
65
swagger/sdrangel/code/qt5/client/SWGRTTYModActions.h
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWGRTTYModActions.h
|
||||
*
|
||||
* RTTYMod
|
||||
*/
|
||||
|
||||
#ifndef SWGRTTYModActions_H_
|
||||
#define SWGRTTYModActions_H_
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
|
||||
#include "SWGRTTYModActions_payload.h"
|
||||
|
||||
#include "SWGObject.h"
|
||||
#include "export.h"
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
class SWG_API SWGRTTYModActions: public SWGObject {
|
||||
public:
|
||||
SWGRTTYModActions();
|
||||
SWGRTTYModActions(QString* json);
|
||||
virtual ~SWGRTTYModActions();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
virtual QString asJson () override;
|
||||
virtual QJsonObject* asJsonObject() override;
|
||||
virtual void fromJsonObject(QJsonObject &json) override;
|
||||
virtual SWGRTTYModActions* fromJson(QString &jsonString) override;
|
||||
|
||||
qint32 getTx();
|
||||
void setTx(qint32 tx);
|
||||
|
||||
SWGRTTYModActions_payload* getPayload();
|
||||
void setPayload(SWGRTTYModActions_payload* payload);
|
||||
|
||||
|
||||
virtual bool isSet() override;
|
||||
|
||||
private:
|
||||
qint32 tx;
|
||||
bool m_tx_isSet;
|
||||
|
||||
SWGRTTYModActions_payload* payload;
|
||||
bool m_payload_isSet;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SWGRTTYModActions_H_ */
|
110
swagger/sdrangel/code/qt5/client/SWGRTTYModActions_payload.cpp
Normal file
110
swagger/sdrangel/code/qt5/client/SWGRTTYModActions_payload.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
#include "SWGRTTYModActions_payload.h"
|
||||
|
||||
#include "SWGHelpers.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
SWGRTTYModActions_payload::SWGRTTYModActions_payload(QString* json) {
|
||||
init();
|
||||
this->fromJson(*json);
|
||||
}
|
||||
|
||||
SWGRTTYModActions_payload::SWGRTTYModActions_payload() {
|
||||
text = nullptr;
|
||||
m_text_isSet = false;
|
||||
}
|
||||
|
||||
SWGRTTYModActions_payload::~SWGRTTYModActions_payload() {
|
||||
this->cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModActions_payload::init() {
|
||||
text = new QString("");
|
||||
m_text_isSet = false;
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModActions_payload::cleanup() {
|
||||
if(text != nullptr) {
|
||||
delete text;
|
||||
}
|
||||
}
|
||||
|
||||
SWGRTTYModActions_payload*
|
||||
SWGRTTYModActions_payload::fromJson(QString &json) {
|
||||
QByteArray array (json.toStdString().c_str());
|
||||
QJsonDocument doc = QJsonDocument::fromJson(array);
|
||||
QJsonObject jsonObject = doc.object();
|
||||
this->fromJsonObject(jsonObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModActions_payload::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&text, pJson["text"], "QString", "QString");
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
SWGRTTYModActions_payload::asJson ()
|
||||
{
|
||||
QJsonObject* obj = this->asJsonObject();
|
||||
|
||||
QJsonDocument doc(*obj);
|
||||
QByteArray bytes = doc.toJson();
|
||||
delete obj;
|
||||
return QString(bytes);
|
||||
}
|
||||
|
||||
QJsonObject*
|
||||
SWGRTTYModActions_payload::asJsonObject() {
|
||||
QJsonObject* obj = new QJsonObject();
|
||||
if(text != nullptr && *text != QString("")){
|
||||
toJsonValue(QString("text"), text, obj, QString("QString"));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGRTTYModActions_payload::getText() {
|
||||
return text;
|
||||
}
|
||||
void
|
||||
SWGRTTYModActions_payload::setText(QString* text) {
|
||||
this->text = text;
|
||||
this->m_text_isSet = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SWGRTTYModActions_payload::isSet(){
|
||||
bool isObjectUpdated = false;
|
||||
do{
|
||||
if(text && *text != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
}
|
||||
|
59
swagger/sdrangel/code/qt5/client/SWGRTTYModActions_payload.h
Normal file
59
swagger/sdrangel/code/qt5/client/SWGRTTYModActions_payload.h
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWGRTTYModActions_payload.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SWGRTTYModActions_payload_H_
|
||||
#define SWGRTTYModActions_payload_H_
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "SWGObject.h"
|
||||
#include "export.h"
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
class SWG_API SWGRTTYModActions_payload: public SWGObject {
|
||||
public:
|
||||
SWGRTTYModActions_payload();
|
||||
SWGRTTYModActions_payload(QString* json);
|
||||
virtual ~SWGRTTYModActions_payload();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
virtual QString asJson () override;
|
||||
virtual QJsonObject* asJsonObject() override;
|
||||
virtual void fromJsonObject(QJsonObject &json) override;
|
||||
virtual SWGRTTYModActions_payload* fromJson(QString &jsonString) override;
|
||||
|
||||
QString* getText();
|
||||
void setText(QString* text);
|
||||
|
||||
|
||||
virtual bool isSet() override;
|
||||
|
||||
private:
|
||||
QString* text;
|
||||
bool m_text_isSet;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SWGRTTYModActions_payload_H_ */
|
131
swagger/sdrangel/code/qt5/client/SWGRTTYModReport.cpp
Normal file
131
swagger/sdrangel/code/qt5/client/SWGRTTYModReport.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
#include "SWGRTTYModReport.h"
|
||||
|
||||
#include "SWGHelpers.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
SWGRTTYModReport::SWGRTTYModReport(QString* json) {
|
||||
init();
|
||||
this->fromJson(*json);
|
||||
}
|
||||
|
||||
SWGRTTYModReport::SWGRTTYModReport() {
|
||||
channel_power_db = 0.0f;
|
||||
m_channel_power_db_isSet = false;
|
||||
channel_sample_rate = 0;
|
||||
m_channel_sample_rate_isSet = false;
|
||||
}
|
||||
|
||||
SWGRTTYModReport::~SWGRTTYModReport() {
|
||||
this->cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModReport::init() {
|
||||
channel_power_db = 0.0f;
|
||||
m_channel_power_db_isSet = false;
|
||||
channel_sample_rate = 0;
|
||||
m_channel_sample_rate_isSet = false;
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModReport::cleanup() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
SWGRTTYModReport*
|
||||
SWGRTTYModReport::fromJson(QString &json) {
|
||||
QByteArray array (json.toStdString().c_str());
|
||||
QJsonDocument doc = QJsonDocument::fromJson(array);
|
||||
QJsonObject jsonObject = doc.object();
|
||||
this->fromJsonObject(jsonObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModReport::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&channel_power_db, pJson["channelPowerDB"], "float", "");
|
||||
|
||||
::SWGSDRangel::setValue(&channel_sample_rate, pJson["channelSampleRate"], "qint32", "");
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
SWGRTTYModReport::asJson ()
|
||||
{
|
||||
QJsonObject* obj = this->asJsonObject();
|
||||
|
||||
QJsonDocument doc(*obj);
|
||||
QByteArray bytes = doc.toJson();
|
||||
delete obj;
|
||||
return QString(bytes);
|
||||
}
|
||||
|
||||
QJsonObject*
|
||||
SWGRTTYModReport::asJsonObject() {
|
||||
QJsonObject* obj = new QJsonObject();
|
||||
if(m_channel_power_db_isSet){
|
||||
obj->insert("channelPowerDB", QJsonValue(channel_power_db));
|
||||
}
|
||||
if(m_channel_sample_rate_isSet){
|
||||
obj->insert("channelSampleRate", QJsonValue(channel_sample_rate));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
float
|
||||
SWGRTTYModReport::getChannelPowerDb() {
|
||||
return channel_power_db;
|
||||
}
|
||||
void
|
||||
SWGRTTYModReport::setChannelPowerDb(float channel_power_db) {
|
||||
this->channel_power_db = channel_power_db;
|
||||
this->m_channel_power_db_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModReport::getChannelSampleRate() {
|
||||
return channel_sample_rate;
|
||||
}
|
||||
void
|
||||
SWGRTTYModReport::setChannelSampleRate(qint32 channel_sample_rate) {
|
||||
this->channel_sample_rate = channel_sample_rate;
|
||||
this->m_channel_sample_rate_isSet = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SWGRTTYModReport::isSet(){
|
||||
bool isObjectUpdated = false;
|
||||
do{
|
||||
if(m_channel_power_db_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_channel_sample_rate_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
}
|
||||
|
64
swagger/sdrangel/code/qt5/client/SWGRTTYModReport.h
Normal file
64
swagger/sdrangel/code/qt5/client/SWGRTTYModReport.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWGRTTYModReport.h
|
||||
*
|
||||
* RTTYMod
|
||||
*/
|
||||
|
||||
#ifndef SWGRTTYModReport_H_
|
||||
#define SWGRTTYModReport_H_
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
|
||||
|
||||
#include "SWGObject.h"
|
||||
#include "export.h"
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
class SWG_API SWGRTTYModReport: public SWGObject {
|
||||
public:
|
||||
SWGRTTYModReport();
|
||||
SWGRTTYModReport(QString* json);
|
||||
virtual ~SWGRTTYModReport();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
virtual QString asJson () override;
|
||||
virtual QJsonObject* asJsonObject() override;
|
||||
virtual void fromJsonObject(QJsonObject &json) override;
|
||||
virtual SWGRTTYModReport* fromJson(QString &jsonString) override;
|
||||
|
||||
float getChannelPowerDb();
|
||||
void setChannelPowerDb(float channel_power_db);
|
||||
|
||||
qint32 getChannelSampleRate();
|
||||
void setChannelSampleRate(qint32 channel_sample_rate);
|
||||
|
||||
|
||||
virtual bool isSet() override;
|
||||
|
||||
private:
|
||||
float channel_power_db;
|
||||
bool m_channel_power_db_isSet;
|
||||
|
||||
qint32 channel_sample_rate;
|
||||
bool m_channel_sample_rate_isSet;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SWGRTTYModReport_H_ */
|
856
swagger/sdrangel/code/qt5/client/SWGRTTYModSettings.cpp
Normal file
856
swagger/sdrangel/code/qt5/client/SWGRTTYModSettings.cpp
Normal file
@ -0,0 +1,856 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
#include "SWGRTTYModSettings.h"
|
||||
|
||||
#include "SWGHelpers.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
SWGRTTYModSettings::SWGRTTYModSettings(QString* json) {
|
||||
init();
|
||||
this->fromJson(*json);
|
||||
}
|
||||
|
||||
SWGRTTYModSettings::SWGRTTYModSettings() {
|
||||
input_frequency_offset = 0L;
|
||||
m_input_frequency_offset_isSet = false;
|
||||
baud = 0.0f;
|
||||
m_baud_isSet = false;
|
||||
rf_bandwidth = 0;
|
||||
m_rf_bandwidth_isSet = false;
|
||||
frequency_shift = 0;
|
||||
m_frequency_shift_isSet = false;
|
||||
gain = 0.0f;
|
||||
m_gain_isSet = false;
|
||||
channel_mute = 0;
|
||||
m_channel_mute_isSet = false;
|
||||
repeat = 0;
|
||||
m_repeat_isSet = false;
|
||||
repeat_count = 0;
|
||||
m_repeat_count_isSet = false;
|
||||
lpf_taps = 0;
|
||||
m_lpf_taps_isSet = false;
|
||||
rf_noise = 0;
|
||||
m_rf_noise_isSet = false;
|
||||
text = nullptr;
|
||||
m_text_isSet = false;
|
||||
pulse_shaping = 0;
|
||||
m_pulse_shaping_isSet = false;
|
||||
beta = 0.0f;
|
||||
m_beta_isSet = false;
|
||||
symbol_span = 0;
|
||||
m_symbol_span_isSet = false;
|
||||
character_set = 0;
|
||||
m_character_set_isSet = false;
|
||||
unshift_on_space = 0;
|
||||
m_unshift_on_space_isSet = false;
|
||||
msb_first = 0;
|
||||
m_msb_first_isSet = false;
|
||||
space_high = 0;
|
||||
m_space_high_isSet = false;
|
||||
prefix_crlf = 0;
|
||||
m_prefix_crlf_isSet = false;
|
||||
postfix_crlf = 0;
|
||||
m_postfix_crlf_isSet = false;
|
||||
udp_enabled = 0;
|
||||
m_udp_enabled_isSet = false;
|
||||
udp_address = nullptr;
|
||||
m_udp_address_isSet = false;
|
||||
udp_port = 0;
|
||||
m_udp_port_isSet = false;
|
||||
rgb_color = 0;
|
||||
m_rgb_color_isSet = false;
|
||||
title = nullptr;
|
||||
m_title_isSet = false;
|
||||
stream_index = 0;
|
||||
m_stream_index_isSet = false;
|
||||
use_reverse_api = 0;
|
||||
m_use_reverse_api_isSet = false;
|
||||
reverse_api_address = nullptr;
|
||||
m_reverse_api_address_isSet = false;
|
||||
reverse_api_port = 0;
|
||||
m_reverse_api_port_isSet = false;
|
||||
reverse_api_device_index = 0;
|
||||
m_reverse_api_device_index_isSet = false;
|
||||
reverse_api_channel_index = 0;
|
||||
m_reverse_api_channel_index_isSet = false;
|
||||
channel_marker = nullptr;
|
||||
m_channel_marker_isSet = false;
|
||||
rollup_state = nullptr;
|
||||
m_rollup_state_isSet = false;
|
||||
}
|
||||
|
||||
SWGRTTYModSettings::~SWGRTTYModSettings() {
|
||||
this->cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModSettings::init() {
|
||||
input_frequency_offset = 0L;
|
||||
m_input_frequency_offset_isSet = false;
|
||||
baud = 0.0f;
|
||||
m_baud_isSet = false;
|
||||
rf_bandwidth = 0;
|
||||
m_rf_bandwidth_isSet = false;
|
||||
frequency_shift = 0;
|
||||
m_frequency_shift_isSet = false;
|
||||
gain = 0.0f;
|
||||
m_gain_isSet = false;
|
||||
channel_mute = 0;
|
||||
m_channel_mute_isSet = false;
|
||||
repeat = 0;
|
||||
m_repeat_isSet = false;
|
||||
repeat_count = 0;
|
||||
m_repeat_count_isSet = false;
|
||||
lpf_taps = 0;
|
||||
m_lpf_taps_isSet = false;
|
||||
rf_noise = 0;
|
||||
m_rf_noise_isSet = false;
|
||||
text = new QString("");
|
||||
m_text_isSet = false;
|
||||
pulse_shaping = 0;
|
||||
m_pulse_shaping_isSet = false;
|
||||
beta = 0.0f;
|
||||
m_beta_isSet = false;
|
||||
symbol_span = 0;
|
||||
m_symbol_span_isSet = false;
|
||||
character_set = 0;
|
||||
m_character_set_isSet = false;
|
||||
unshift_on_space = 0;
|
||||
m_unshift_on_space_isSet = false;
|
||||
msb_first = 0;
|
||||
m_msb_first_isSet = false;
|
||||
space_high = 0;
|
||||
m_space_high_isSet = false;
|
||||
prefix_crlf = 0;
|
||||
m_prefix_crlf_isSet = false;
|
||||
postfix_crlf = 0;
|
||||
m_postfix_crlf_isSet = false;
|
||||
udp_enabled = 0;
|
||||
m_udp_enabled_isSet = false;
|
||||
udp_address = new QString("");
|
||||
m_udp_address_isSet = false;
|
||||
udp_port = 0;
|
||||
m_udp_port_isSet = false;
|
||||
rgb_color = 0;
|
||||
m_rgb_color_isSet = false;
|
||||
title = new QString("");
|
||||
m_title_isSet = false;
|
||||
stream_index = 0;
|
||||
m_stream_index_isSet = false;
|
||||
use_reverse_api = 0;
|
||||
m_use_reverse_api_isSet = false;
|
||||
reverse_api_address = new QString("");
|
||||
m_reverse_api_address_isSet = false;
|
||||
reverse_api_port = 0;
|
||||
m_reverse_api_port_isSet = false;
|
||||
reverse_api_device_index = 0;
|
||||
m_reverse_api_device_index_isSet = false;
|
||||
reverse_api_channel_index = 0;
|
||||
m_reverse_api_channel_index_isSet = false;
|
||||
channel_marker = new SWGChannelMarker();
|
||||
m_channel_marker_isSet = false;
|
||||
rollup_state = new SWGRollupState();
|
||||
m_rollup_state_isSet = false;
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModSettings::cleanup() {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(text != nullptr) {
|
||||
delete text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(udp_address != nullptr) {
|
||||
delete udp_address;
|
||||
}
|
||||
|
||||
|
||||
if(title != nullptr) {
|
||||
delete title;
|
||||
}
|
||||
|
||||
|
||||
if(reverse_api_address != nullptr) {
|
||||
delete reverse_api_address;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(channel_marker != nullptr) {
|
||||
delete channel_marker;
|
||||
}
|
||||
if(rollup_state != nullptr) {
|
||||
delete rollup_state;
|
||||
}
|
||||
}
|
||||
|
||||
SWGRTTYModSettings*
|
||||
SWGRTTYModSettings::fromJson(QString &json) {
|
||||
QByteArray array (json.toStdString().c_str());
|
||||
QJsonDocument doc = QJsonDocument::fromJson(array);
|
||||
QJsonObject jsonObject = doc.object();
|
||||
this->fromJsonObject(jsonObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYModSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&input_frequency_offset, pJson["inputFrequencyOffset"], "qint64", "");
|
||||
|
||||
::SWGSDRangel::setValue(&baud, pJson["baud"], "float", "");
|
||||
|
||||
::SWGSDRangel::setValue(&rf_bandwidth, pJson["rfBandwidth"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&frequency_shift, pJson["frequencyShift"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&gain, pJson["gain"], "float", "");
|
||||
|
||||
::SWGSDRangel::setValue(&channel_mute, pJson["channelMute"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&repeat, pJson["repeat"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&repeat_count, pJson["repeatCount"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&lpf_taps, pJson["lpfTaps"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&rf_noise, pJson["rfNoise"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&text, pJson["text"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&pulse_shaping, pJson["pulseShaping"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&beta, pJson["beta"], "float", "");
|
||||
|
||||
::SWGSDRangel::setValue(&symbol_span, pJson["symbolSpan"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&character_set, pJson["characterSet"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&unshift_on_space, pJson["unshiftOnSpace"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&msb_first, pJson["msbFirst"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&space_high, pJson["spaceHigh"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&prefix_crlf, pJson["prefixCRLF"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&postfix_crlf, pJson["postfixCRLF"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&udp_enabled, pJson["udpEnabled"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&udp_address, pJson["udpAddress"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&udp_port, pJson["udpPort"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&stream_index, pJson["streamIndex"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_port, pJson["reverseAPIPort"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_device_index, pJson["reverseAPIDeviceIndex"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_channel_index, pJson["reverseAPIChannelIndex"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&channel_marker, pJson["channelMarker"], "SWGChannelMarker", "SWGChannelMarker");
|
||||
|
||||
::SWGSDRangel::setValue(&rollup_state, pJson["rollupState"], "SWGRollupState", "SWGRollupState");
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
SWGRTTYModSettings::asJson ()
|
||||
{
|
||||
QJsonObject* obj = this->asJsonObject();
|
||||
|
||||
QJsonDocument doc(*obj);
|
||||
QByteArray bytes = doc.toJson();
|
||||
delete obj;
|
||||
return QString(bytes);
|
||||
}
|
||||
|
||||
QJsonObject*
|
||||
SWGRTTYModSettings::asJsonObject() {
|
||||
QJsonObject* obj = new QJsonObject();
|
||||
if(m_input_frequency_offset_isSet){
|
||||
obj->insert("inputFrequencyOffset", QJsonValue(input_frequency_offset));
|
||||
}
|
||||
if(m_baud_isSet){
|
||||
obj->insert("baud", QJsonValue(baud));
|
||||
}
|
||||
if(m_rf_bandwidth_isSet){
|
||||
obj->insert("rfBandwidth", QJsonValue(rf_bandwidth));
|
||||
}
|
||||
if(m_frequency_shift_isSet){
|
||||
obj->insert("frequencyShift", QJsonValue(frequency_shift));
|
||||
}
|
||||
if(m_gain_isSet){
|
||||
obj->insert("gain", QJsonValue(gain));
|
||||
}
|
||||
if(m_channel_mute_isSet){
|
||||
obj->insert("channelMute", QJsonValue(channel_mute));
|
||||
}
|
||||
if(m_repeat_isSet){
|
||||
obj->insert("repeat", QJsonValue(repeat));
|
||||
}
|
||||
if(m_repeat_count_isSet){
|
||||
obj->insert("repeatCount", QJsonValue(repeat_count));
|
||||
}
|
||||
if(m_lpf_taps_isSet){
|
||||
obj->insert("lpfTaps", QJsonValue(lpf_taps));
|
||||
}
|
||||
if(m_rf_noise_isSet){
|
||||
obj->insert("rfNoise", QJsonValue(rf_noise));
|
||||
}
|
||||
if(text != nullptr && *text != QString("")){
|
||||
toJsonValue(QString("text"), text, obj, QString("QString"));
|
||||
}
|
||||
if(m_pulse_shaping_isSet){
|
||||
obj->insert("pulseShaping", QJsonValue(pulse_shaping));
|
||||
}
|
||||
if(m_beta_isSet){
|
||||
obj->insert("beta", QJsonValue(beta));
|
||||
}
|
||||
if(m_symbol_span_isSet){
|
||||
obj->insert("symbolSpan", QJsonValue(symbol_span));
|
||||
}
|
||||
if(m_character_set_isSet){
|
||||
obj->insert("characterSet", QJsonValue(character_set));
|
||||
}
|
||||
if(m_unshift_on_space_isSet){
|
||||
obj->insert("unshiftOnSpace", QJsonValue(unshift_on_space));
|
||||
}
|
||||
if(m_msb_first_isSet){
|
||||
obj->insert("msbFirst", QJsonValue(msb_first));
|
||||
}
|
||||
if(m_space_high_isSet){
|
||||
obj->insert("spaceHigh", QJsonValue(space_high));
|
||||
}
|
||||
if(m_prefix_crlf_isSet){
|
||||
obj->insert("prefixCRLF", QJsonValue(prefix_crlf));
|
||||
}
|
||||
if(m_postfix_crlf_isSet){
|
||||
obj->insert("postfixCRLF", QJsonValue(postfix_crlf));
|
||||
}
|
||||
if(m_udp_enabled_isSet){
|
||||
obj->insert("udpEnabled", QJsonValue(udp_enabled));
|
||||
}
|
||||
if(udp_address != nullptr && *udp_address != QString("")){
|
||||
toJsonValue(QString("udpAddress"), udp_address, obj, QString("QString"));
|
||||
}
|
||||
if(m_udp_port_isSet){
|
||||
obj->insert("udpPort", QJsonValue(udp_port));
|
||||
}
|
||||
if(m_rgb_color_isSet){
|
||||
obj->insert("rgbColor", QJsonValue(rgb_color));
|
||||
}
|
||||
if(title != nullptr && *title != QString("")){
|
||||
toJsonValue(QString("title"), title, obj, QString("QString"));
|
||||
}
|
||||
if(m_stream_index_isSet){
|
||||
obj->insert("streamIndex", QJsonValue(stream_index));
|
||||
}
|
||||
if(m_use_reverse_api_isSet){
|
||||
obj->insert("useReverseAPI", QJsonValue(use_reverse_api));
|
||||
}
|
||||
if(reverse_api_address != nullptr && *reverse_api_address != QString("")){
|
||||
toJsonValue(QString("reverseAPIAddress"), reverse_api_address, obj, QString("QString"));
|
||||
}
|
||||
if(m_reverse_api_port_isSet){
|
||||
obj->insert("reverseAPIPort", QJsonValue(reverse_api_port));
|
||||
}
|
||||
if(m_reverse_api_device_index_isSet){
|
||||
obj->insert("reverseAPIDeviceIndex", QJsonValue(reverse_api_device_index));
|
||||
}
|
||||
if(m_reverse_api_channel_index_isSet){
|
||||
obj->insert("reverseAPIChannelIndex", QJsonValue(reverse_api_channel_index));
|
||||
}
|
||||
if((channel_marker != nullptr) && (channel_marker->isSet())){
|
||||
toJsonValue(QString("channelMarker"), channel_marker, obj, QString("SWGChannelMarker"));
|
||||
}
|
||||
if((rollup_state != nullptr) && (rollup_state->isSet())){
|
||||
toJsonValue(QString("rollupState"), rollup_state, obj, QString("SWGRollupState"));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
qint64
|
||||
SWGRTTYModSettings::getInputFrequencyOffset() {
|
||||
return input_frequency_offset;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setInputFrequencyOffset(qint64 input_frequency_offset) {
|
||||
this->input_frequency_offset = input_frequency_offset;
|
||||
this->m_input_frequency_offset_isSet = true;
|
||||
}
|
||||
|
||||
float
|
||||
SWGRTTYModSettings::getBaud() {
|
||||
return baud;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setBaud(float baud) {
|
||||
this->baud = baud;
|
||||
this->m_baud_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getRfBandwidth() {
|
||||
return rf_bandwidth;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setRfBandwidth(qint32 rf_bandwidth) {
|
||||
this->rf_bandwidth = rf_bandwidth;
|
||||
this->m_rf_bandwidth_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getFrequencyShift() {
|
||||
return frequency_shift;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setFrequencyShift(qint32 frequency_shift) {
|
||||
this->frequency_shift = frequency_shift;
|
||||
this->m_frequency_shift_isSet = true;
|
||||
}
|
||||
|
||||
float
|
||||
SWGRTTYModSettings::getGain() {
|
||||
return gain;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setGain(float gain) {
|
||||
this->gain = gain;
|
||||
this->m_gain_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getChannelMute() {
|
||||
return channel_mute;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setChannelMute(qint32 channel_mute) {
|
||||
this->channel_mute = channel_mute;
|
||||
this->m_channel_mute_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getRepeat() {
|
||||
return repeat;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setRepeat(qint32 repeat) {
|
||||
this->repeat = repeat;
|
||||
this->m_repeat_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getRepeatCount() {
|
||||
return repeat_count;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setRepeatCount(qint32 repeat_count) {
|
||||
this->repeat_count = repeat_count;
|
||||
this->m_repeat_count_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getLpfTaps() {
|
||||
return lpf_taps;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setLpfTaps(qint32 lpf_taps) {
|
||||
this->lpf_taps = lpf_taps;
|
||||
this->m_lpf_taps_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getRfNoise() {
|
||||
return rf_noise;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setRfNoise(qint32 rf_noise) {
|
||||
this->rf_noise = rf_noise;
|
||||
this->m_rf_noise_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGRTTYModSettings::getText() {
|
||||
return text;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setText(QString* text) {
|
||||
this->text = text;
|
||||
this->m_text_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getPulseShaping() {
|
||||
return pulse_shaping;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setPulseShaping(qint32 pulse_shaping) {
|
||||
this->pulse_shaping = pulse_shaping;
|
||||
this->m_pulse_shaping_isSet = true;
|
||||
}
|
||||
|
||||
float
|
||||
SWGRTTYModSettings::getBeta() {
|
||||
return beta;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setBeta(float beta) {
|
||||
this->beta = beta;
|
||||
this->m_beta_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getSymbolSpan() {
|
||||
return symbol_span;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setSymbolSpan(qint32 symbol_span) {
|
||||
this->symbol_span = symbol_span;
|
||||
this->m_symbol_span_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getCharacterSet() {
|
||||
return character_set;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setCharacterSet(qint32 character_set) {
|
||||
this->character_set = character_set;
|
||||
this->m_character_set_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getUnshiftOnSpace() {
|
||||
return unshift_on_space;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setUnshiftOnSpace(qint32 unshift_on_space) {
|
||||
this->unshift_on_space = unshift_on_space;
|
||||
this->m_unshift_on_space_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getMsbFirst() {
|
||||
return msb_first;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setMsbFirst(qint32 msb_first) {
|
||||
this->msb_first = msb_first;
|
||||
this->m_msb_first_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getSpaceHigh() {
|
||||
return space_high;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setSpaceHigh(qint32 space_high) {
|
||||
this->space_high = space_high;
|
||||
this->m_space_high_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getPrefixCrlf() {
|
||||
return prefix_crlf;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setPrefixCrlf(qint32 prefix_crlf) {
|
||||
this->prefix_crlf = prefix_crlf;
|
||||
this->m_prefix_crlf_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getPostfixCrlf() {
|
||||
return postfix_crlf;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setPostfixCrlf(qint32 postfix_crlf) {
|
||||
this->postfix_crlf = postfix_crlf;
|
||||
this->m_postfix_crlf_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getUdpEnabled() {
|
||||
return udp_enabled;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setUdpEnabled(qint32 udp_enabled) {
|
||||
this->udp_enabled = udp_enabled;
|
||||
this->m_udp_enabled_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGRTTYModSettings::getUdpAddress() {
|
||||
return udp_address;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setUdpAddress(QString* udp_address) {
|
||||
this->udp_address = udp_address;
|
||||
this->m_udp_address_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getUdpPort() {
|
||||
return udp_port;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setUdpPort(qint32 udp_port) {
|
||||
this->udp_port = udp_port;
|
||||
this->m_udp_port_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getRgbColor() {
|
||||
return rgb_color;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setRgbColor(qint32 rgb_color) {
|
||||
this->rgb_color = rgb_color;
|
||||
this->m_rgb_color_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGRTTYModSettings::getTitle() {
|
||||
return title;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setTitle(QString* title) {
|
||||
this->title = title;
|
||||
this->m_title_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getStreamIndex() {
|
||||
return stream_index;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setStreamIndex(qint32 stream_index) {
|
||||
this->stream_index = stream_index;
|
||||
this->m_stream_index_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getUseReverseApi() {
|
||||
return use_reverse_api;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setUseReverseApi(qint32 use_reverse_api) {
|
||||
this->use_reverse_api = use_reverse_api;
|
||||
this->m_use_reverse_api_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGRTTYModSettings::getReverseApiAddress() {
|
||||
return reverse_api_address;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setReverseApiAddress(QString* reverse_api_address) {
|
||||
this->reverse_api_address = reverse_api_address;
|
||||
this->m_reverse_api_address_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getReverseApiPort() {
|
||||
return reverse_api_port;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setReverseApiPort(qint32 reverse_api_port) {
|
||||
this->reverse_api_port = reverse_api_port;
|
||||
this->m_reverse_api_port_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getReverseApiDeviceIndex() {
|
||||
return reverse_api_device_index;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setReverseApiDeviceIndex(qint32 reverse_api_device_index) {
|
||||
this->reverse_api_device_index = reverse_api_device_index;
|
||||
this->m_reverse_api_device_index_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYModSettings::getReverseApiChannelIndex() {
|
||||
return reverse_api_channel_index;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setReverseApiChannelIndex(qint32 reverse_api_channel_index) {
|
||||
this->reverse_api_channel_index = reverse_api_channel_index;
|
||||
this->m_reverse_api_channel_index_isSet = true;
|
||||
}
|
||||
|
||||
SWGChannelMarker*
|
||||
SWGRTTYModSettings::getChannelMarker() {
|
||||
return channel_marker;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setChannelMarker(SWGChannelMarker* channel_marker) {
|
||||
this->channel_marker = channel_marker;
|
||||
this->m_channel_marker_isSet = true;
|
||||
}
|
||||
|
||||
SWGRollupState*
|
||||
SWGRTTYModSettings::getRollupState() {
|
||||
return rollup_state;
|
||||
}
|
||||
void
|
||||
SWGRTTYModSettings::setRollupState(SWGRollupState* rollup_state) {
|
||||
this->rollup_state = rollup_state;
|
||||
this->m_rollup_state_isSet = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SWGRTTYModSettings::isSet(){
|
||||
bool isObjectUpdated = false;
|
||||
do{
|
||||
if(m_input_frequency_offset_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_baud_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_rf_bandwidth_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_frequency_shift_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_gain_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_channel_mute_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_repeat_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_repeat_count_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_lpf_taps_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_rf_noise_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(text && *text != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_pulse_shaping_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_beta_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_symbol_span_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_character_set_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_unshift_on_space_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_msb_first_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_space_high_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_prefix_crlf_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_postfix_crlf_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_udp_enabled_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(udp_address && *udp_address != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_udp_port_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_rgb_color_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(title && *title != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_stream_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_use_reverse_api_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(reverse_api_address && *reverse_api_address != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_port_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_device_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_channel_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(channel_marker && channel_marker->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(rollup_state && rollup_state->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
}
|
||||
|
253
swagger/sdrangel/code/qt5/client/SWGRTTYModSettings.h
Normal file
253
swagger/sdrangel/code/qt5/client/SWGRTTYModSettings.h
Normal file
@ -0,0 +1,253 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWGRTTYModSettings.h
|
||||
*
|
||||
* RTTYMod
|
||||
*/
|
||||
|
||||
#ifndef SWGRTTYModSettings_H_
|
||||
#define SWGRTTYModSettings_H_
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
|
||||
#include "SWGChannelMarker.h"
|
||||
#include "SWGRollupState.h"
|
||||
#include <QString>
|
||||
|
||||
#include "SWGObject.h"
|
||||
#include "export.h"
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
class SWG_API SWGRTTYModSettings: public SWGObject {
|
||||
public:
|
||||
SWGRTTYModSettings();
|
||||
SWGRTTYModSettings(QString* json);
|
||||
virtual ~SWGRTTYModSettings();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
virtual QString asJson () override;
|
||||
virtual QJsonObject* asJsonObject() override;
|
||||
virtual void fromJsonObject(QJsonObject &json) override;
|
||||
virtual SWGRTTYModSettings* fromJson(QString &jsonString) override;
|
||||
|
||||
qint64 getInputFrequencyOffset();
|
||||
void setInputFrequencyOffset(qint64 input_frequency_offset);
|
||||
|
||||
float getBaud();
|
||||
void setBaud(float baud);
|
||||
|
||||
qint32 getRfBandwidth();
|
||||
void setRfBandwidth(qint32 rf_bandwidth);
|
||||
|
||||
qint32 getFrequencyShift();
|
||||
void setFrequencyShift(qint32 frequency_shift);
|
||||
|
||||
float getGain();
|
||||
void setGain(float gain);
|
||||
|
||||
qint32 getChannelMute();
|
||||
void setChannelMute(qint32 channel_mute);
|
||||
|
||||
qint32 getRepeat();
|
||||
void setRepeat(qint32 repeat);
|
||||
|
||||
qint32 getRepeatCount();
|
||||
void setRepeatCount(qint32 repeat_count);
|
||||
|
||||
qint32 getLpfTaps();
|
||||
void setLpfTaps(qint32 lpf_taps);
|
||||
|
||||
qint32 getRfNoise();
|
||||
void setRfNoise(qint32 rf_noise);
|
||||
|
||||
QString* getText();
|
||||
void setText(QString* text);
|
||||
|
||||
qint32 getPulseShaping();
|
||||
void setPulseShaping(qint32 pulse_shaping);
|
||||
|
||||
float getBeta();
|
||||
void setBeta(float beta);
|
||||
|
||||
qint32 getSymbolSpan();
|
||||
void setSymbolSpan(qint32 symbol_span);
|
||||
|
||||
qint32 getCharacterSet();
|
||||
void setCharacterSet(qint32 character_set);
|
||||
|
||||
qint32 getUnshiftOnSpace();
|
||||
void setUnshiftOnSpace(qint32 unshift_on_space);
|
||||
|
||||
qint32 getMsbFirst();
|
||||
void setMsbFirst(qint32 msb_first);
|
||||
|
||||
qint32 getSpaceHigh();
|
||||
void setSpaceHigh(qint32 space_high);
|
||||
|
||||
qint32 getPrefixCrlf();
|
||||
void setPrefixCrlf(qint32 prefix_crlf);
|
||||
|
||||
qint32 getPostfixCrlf();
|
||||
void setPostfixCrlf(qint32 postfix_crlf);
|
||||
|
||||
qint32 getUdpEnabled();
|
||||
void setUdpEnabled(qint32 udp_enabled);
|
||||
|
||||
QString* getUdpAddress();
|
||||
void setUdpAddress(QString* udp_address);
|
||||
|
||||
qint32 getUdpPort();
|
||||
void setUdpPort(qint32 udp_port);
|
||||
|
||||
qint32 getRgbColor();
|
||||
void setRgbColor(qint32 rgb_color);
|
||||
|
||||
QString* getTitle();
|
||||
void setTitle(QString* title);
|
||||
|
||||
qint32 getStreamIndex();
|
||||
void setStreamIndex(qint32 stream_index);
|
||||
|
||||
qint32 getUseReverseApi();
|
||||
void setUseReverseApi(qint32 use_reverse_api);
|
||||
|
||||
QString* getReverseApiAddress();
|
||||
void setReverseApiAddress(QString* reverse_api_address);
|
||||
|
||||
qint32 getReverseApiPort();
|
||||
void setReverseApiPort(qint32 reverse_api_port);
|
||||
|
||||
qint32 getReverseApiDeviceIndex();
|
||||
void setReverseApiDeviceIndex(qint32 reverse_api_device_index);
|
||||
|
||||
qint32 getReverseApiChannelIndex();
|
||||
void setReverseApiChannelIndex(qint32 reverse_api_channel_index);
|
||||
|
||||
SWGChannelMarker* getChannelMarker();
|
||||
void setChannelMarker(SWGChannelMarker* channel_marker);
|
||||
|
||||
SWGRollupState* getRollupState();
|
||||
void setRollupState(SWGRollupState* rollup_state);
|
||||
|
||||
|
||||
virtual bool isSet() override;
|
||||
|
||||
private:
|
||||
qint64 input_frequency_offset;
|
||||
bool m_input_frequency_offset_isSet;
|
||||
|
||||
float baud;
|
||||
bool m_baud_isSet;
|
||||
|
||||
qint32 rf_bandwidth;
|
||||
bool m_rf_bandwidth_isSet;
|
||||
|
||||
qint32 frequency_shift;
|
||||
bool m_frequency_shift_isSet;
|
||||
|
||||
float gain;
|
||||
bool m_gain_isSet;
|
||||
|
||||
qint32 channel_mute;
|
||||
bool m_channel_mute_isSet;
|
||||
|
||||
qint32 repeat;
|
||||
bool m_repeat_isSet;
|
||||
|
||||
qint32 repeat_count;
|
||||
bool m_repeat_count_isSet;
|
||||
|
||||
qint32 lpf_taps;
|
||||
bool m_lpf_taps_isSet;
|
||||
|
||||
qint32 rf_noise;
|
||||
bool m_rf_noise_isSet;
|
||||
|
||||
QString* text;
|
||||
bool m_text_isSet;
|
||||
|
||||
qint32 pulse_shaping;
|
||||
bool m_pulse_shaping_isSet;
|
||||
|
||||
float beta;
|
||||
bool m_beta_isSet;
|
||||
|
||||
qint32 symbol_span;
|
||||
bool m_symbol_span_isSet;
|
||||
|
||||
qint32 character_set;
|
||||
bool m_character_set_isSet;
|
||||
|
||||
qint32 unshift_on_space;
|
||||
bool m_unshift_on_space_isSet;
|
||||
|
||||
qint32 msb_first;
|
||||
bool m_msb_first_isSet;
|
||||
|
||||
qint32 space_high;
|
||||
bool m_space_high_isSet;
|
||||
|
||||
qint32 prefix_crlf;
|
||||
bool m_prefix_crlf_isSet;
|
||||
|
||||
qint32 postfix_crlf;
|
||||
bool m_postfix_crlf_isSet;
|
||||
|
||||
qint32 udp_enabled;
|
||||
bool m_udp_enabled_isSet;
|
||||
|
||||
QString* udp_address;
|
||||
bool m_udp_address_isSet;
|
||||
|
||||
qint32 udp_port;
|
||||
bool m_udp_port_isSet;
|
||||
|
||||
qint32 rgb_color;
|
||||
bool m_rgb_color_isSet;
|
||||
|
||||
QString* title;
|
||||
bool m_title_isSet;
|
||||
|
||||
qint32 stream_index;
|
||||
bool m_stream_index_isSet;
|
||||
|
||||
qint32 use_reverse_api;
|
||||
bool m_use_reverse_api_isSet;
|
||||
|
||||
QString* reverse_api_address;
|
||||
bool m_reverse_api_address_isSet;
|
||||
|
||||
qint32 reverse_api_port;
|
||||
bool m_reverse_api_port_isSet;
|
||||
|
||||
qint32 reverse_api_device_index;
|
||||
bool m_reverse_api_device_index_isSet;
|
||||
|
||||
qint32 reverse_api_channel_index;
|
||||
bool m_reverse_api_channel_index_isSet;
|
||||
|
||||
SWGChannelMarker* channel_marker;
|
||||
bool m_channel_marker_isSet;
|
||||
|
||||
SWGRollupState* rollup_state;
|
||||
bool m_rollup_state_isSet;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SWGRTTYModSettings_H_ */
|
Loading…
Reference in New Issue
Block a user