From 88c5554970133a37e9959ff0251d65e9982a7750 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Thu, 5 Dec 2024 09:08:02 +0000 Subject: [PATCH 01/25] Update mac_x64 build to macos-13, as github no longer supports 12. --- .github/workflows/mac.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 598bde0b2..36a28c304 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -9,7 +9,7 @@ on: jobs: build_mac_x64: - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v4 with: From 405073d198f40bfb0c9b03524d1991718e5dd768 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Thu, 5 Dec 2024 10:15:18 +0000 Subject: [PATCH 02/25] Install svn needed to build lame --- .github/workflows/mac.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 36a28c304..9f9114931 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -15,6 +15,10 @@ jobs: with: submodules: true fetch-depth: 0 + - name: Update brew + run: brew update + - name: Install brew packages + run: brew install nasm subversion - name: Install SDRplay API run: | wget https://www.sdrplay.com/software/SDRplayAPI-macos-installer-universal-3.15.0.pkg From ec0ffa005a78cdec5da8cb2c9c7f7dabeb6b56b8 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Thu, 5 Dec 2024 13:11:08 +0000 Subject: [PATCH 03/25] Try macos-14, as 13 fails due to https://github.com/actions/runner-images/issues/7522 --- .github/workflows/mac.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 9f9114931..f09acb1b6 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -9,7 +9,7 @@ on: jobs: build_mac_x64: - runs-on: macos-13 + runs-on: macos-14 steps: - uses: actions/checkout@v4 with: From a9385cb91c49b17550d1ee68283f39535ade1504 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Thu, 5 Dec 2024 14:40:08 +0000 Subject: [PATCH 04/25] macos-14 is arm only --- .github/workflows/mac.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index f09acb1b6..9f9114931 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -9,7 +9,7 @@ on: jobs: build_mac_x64: - runs-on: macos-14 + runs-on: macos-13 steps: - uses: actions/checkout@v4 with: From a3692309c072197435efd3560d07edf3e85fb789 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 19 Jan 2025 13:09:16 +0000 Subject: [PATCH 05/25] Radiosonde: Rate limit position updates to SondeHub. Fixes #2378. --- plugins/feature/radiosonde/radiosondegui.cpp | 47 ++++++++++++++------ plugins/feature/radiosonde/radiosondegui.h | 4 ++ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/plugins/feature/radiosonde/radiosondegui.cpp b/plugins/feature/radiosonde/radiosondegui.cpp index 066448855..ecf023eb5 100644 --- a/plugins/feature/radiosonde/radiosondegui.cpp +++ b/plugins/feature/radiosonde/radiosondegui.cpp @@ -190,6 +190,8 @@ RadiosondeGUI::RadiosondeGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, F // Get updated when position changes connect(&MainCore::instance()->getSettings(), &MainSettings::preferenceChanged, this, &RadiosondeGUI::preferenceChanged); + connect(&m_positionUpdateTimer, &QTimer::timeout, this, &RadiosondeGUI::updatePosition); + m_positionUpdateTimer.setSingleShot(true); ui->radiosondes->setItemDelegateForColumn(RADIOSONDE_COL_LATITUDE, new DecimalDelegate(5, ui->radiosondes)); ui->radiosondes->setItemDelegateForColumn(RADIOSONDE_COL_LONGITUDE, new DecimalDelegate(5, ui->radiosondes)); @@ -979,22 +981,41 @@ QStringList RadiosondeGUI::getRadios() void RadiosondeGUI::updatePosition() { + // Limit number of position updates sent to SondeHub + const int updateTime = m_settings.m_mobile ? m_minMobilePositionUpdateTime : m_minFixedPositionUpdateTime; + if (m_sondeHub && m_settings.m_displayPosition) { - float stationLatitude = MainCore::instance()->getSettings().getLatitude(); - float stationLongitude = MainCore::instance()->getSettings().getLongitude(); - float stationAltitude = MainCore::instance()->getSettings().getAltitude(); + if (!m_lastPositionUpdate.isValid() || (m_lastPositionUpdate.secsTo(QDateTime::currentDateTime()) >= updateTime)) + { + float stationLatitude = MainCore::instance()->getSettings().getLatitude(); + float stationLongitude = MainCore::instance()->getSettings().getLongitude(); + float stationAltitude = MainCore::instance()->getSettings().getAltitude(); - m_sondeHub->updatePosition( - m_settings.m_callsign, - stationLatitude, - stationLongitude, - stationAltitude, - getRadios().join(" "), - m_settings.m_antenna, - m_settings.m_email, - m_settings.m_mobile - ); + m_sondeHub->updatePosition( + m_settings.m_callsign, + stationLatitude, + stationLongitude, + stationAltitude, + getRadios().join(" "), + m_settings.m_antenna, + m_settings.m_email, + m_settings.m_mobile + ); + + m_positionUpdateTimer.stop(); + m_lastPositionUpdate = QDateTime::currentDateTime(); + } + else + { + qint64 msecs = (updateTime * 1000) - m_lastPositionUpdate.msecsTo(QDateTime::currentDateTime()); + + if (msecs < 0) { + msecs = 0; + } + m_positionUpdateTimer.setInterval(msecs); + m_positionUpdateTimer.start(); + } } } diff --git a/plugins/feature/radiosonde/radiosondegui.h b/plugins/feature/radiosonde/radiosondegui.h index 124a189ea..9afb619cd 100644 --- a/plugins/feature/radiosonde/radiosondegui.h +++ b/plugins/feature/radiosonde/radiosondegui.h @@ -103,6 +103,10 @@ private: QMenu *radiosondesMenu; // Column select context menu SondeHub *m_sondeHub; + QDateTime m_lastPositionUpdate; + QTimer m_positionUpdateTimer; + static const int m_minMobilePositionUpdateTime = 30; // In seconds + static const int m_minFixedPositionUpdateTime = 5 * 60; explicit RadiosondeGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr); virtual ~RadiosondeGUI(); From 9c64424cec0fd84b3b5247aba90c15d277b17479 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 19 Jan 2025 13:09:55 +0000 Subject: [PATCH 06/25] Display errors from SondeHub as warnings rather than debug. --- sdrbase/util/sondehub.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/sdrbase/util/sondehub.cpp b/sdrbase/util/sondehub.cpp index 75c00c76f..9cb76158c 100644 --- a/sdrbase/util/sondehub.cpp +++ b/sdrbase/util/sondehub.cpp @@ -126,6 +126,7 @@ void SondeHub::upload( obj.insert("subtype", subframe->getType()); } + //obj.insert("dev", true); //qDebug() << obj; QJsonArray payloads { obj @@ -189,7 +190,43 @@ void SondeHub::handleReply(QNetworkReply* reply) if (!reply->error()) { QByteArray bytes = reply->readAll(); - //qDebug() << bytes; + QJsonDocument document = QJsonDocument::fromJson(bytes); + if (document.isObject()) + { + QJsonObject obj = document.object(); + if (obj.contains(QStringLiteral("message"))) + { + QString message = obj.value(QStringLiteral("message")).toString(); + qWarning() << "SondeHub message:" << message; + } + if (obj.contains(QStringLiteral("errors"))) + { + QJsonArray errors = obj.value(QStringLiteral("errors")).toArray(); + for (auto errorObjRef : errors) + { + QJsonObject errorObj = errorObjRef.toObject(); + if (errorObj.contains(QStringLiteral("error_message"))) + { + QString errorMessage = errorObj.value(QStringLiteral("error_message")).toString(); + qWarning() << "SondeHub error:" << errorMessage; + if (errorObj.contains(QStringLiteral("payload"))) + { + QJsonObject payload = errorObj.value(QStringLiteral("payload")).toObject(); + qWarning() << "SondeHub error:" << QJsonDocument(payload); + } + } + else + { + qWarning() << "SondeHub error:" << QJsonDocument(errorObj); + } + } + } + //qDebug() << "SondeHub::handleReply: obj" << QJsonDocument(obj); + } + else + { + qDebug() << "SondeHub::handleReply:" << bytes; + } } else { From b2a1dc356979b614fddc898d3d9271efb212f6f7 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Mon, 20 Jan 2025 09:25:33 +0000 Subject: [PATCH 07/25] Fix SSB Mod Morse keyer --- plugins/channeltx/modssb/ssbmod.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp index 411bf7d71..54485d601 100644 --- a/plugins/channeltx/modssb/ssbmod.cpp +++ b/plugins/channeltx/modssb/ssbmod.cpp @@ -68,6 +68,7 @@ SSBMod::SSBMod(DeviceAPI *deviceAPI) : m_basebandSource->setSpectrumSink(&m_spectrumVis); m_basebandSource->setInputFileStream(&m_ifstream); m_basebandSource->setChannel(this); + m_basebandSource->setCWKeyer(&m_cwKeyer); m_basebandSource->moveToThread(m_thread); applySettings(m_settings, true); From f841eecab927218feed93cb24fb168bd179e81ca Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Mon, 20 Jan 2025 10:54:21 +0000 Subject: [PATCH 08/25] Add --start option to start all devices and features. For #2359. --- sdrbase/feature/featurewebapiutils.cpp | 30 ++++++++++++++++++++++++++ sdrbase/feature/featurewebapiutils.h | 1 + sdrbase/mainparser.cpp | 9 +++++++- sdrbase/mainparser.h | 3 +++ sdrgui/mainwindow.cpp | 28 ++++++++++++++++++++++++ sdrgui/mainwindow.h | 2 ++ 6 files changed, 72 insertions(+), 1 deletion(-) diff --git a/sdrbase/feature/featurewebapiutils.cpp b/sdrbase/feature/featurewebapiutils.cpp index 45832bb96..84303acda 100644 --- a/sdrbase/feature/featurewebapiutils.cpp +++ b/sdrbase/feature/featurewebapiutils.cpp @@ -20,12 +20,42 @@ #include "SWGFeatureActions.h" #include "SWGMapActions.h" #include "SWGPERTesterActions.h" +#include "SWGDeviceState.h" #include "maincore.h" #include "feature/featureset.h" #include "feature/feature.h" #include "featurewebapiutils.h" +// Start feature +bool FeatureWebAPIUtils::run(int featureSetIndex, int featureIndex) +{ + Feature *feature = FeatureWebAPIUtils::getFeature(featureSetIndex, featureIndex, ""); + if (feature != nullptr) + { + SWGSDRangel::SWGDeviceState runResponse; + QString errorResponse; + int httpRC; + + runResponse.setState(new QString()); + httpRC = feature->webapiRun(true, runResponse, errorResponse); + + if (httpRC/100 != 2) + { + qWarning("FeatureWebAPIUtils::run: run error %d: %s", + httpRC, qPrintable(errorResponse)); + return false; + } + + return true; + } + else + { + qWarning("FeatureWebAPIUtils::run: no feature F%d:%d", featureSetIndex, featureIndex); + return false; + } +} + // Find the specified target on the map bool FeatureWebAPIUtils::mapFind(const QString& target, int featureSetIndex, int featureIndex) { diff --git a/sdrbase/feature/featurewebapiutils.h b/sdrbase/feature/featurewebapiutils.h index d0448892c..ddad1ae82 100644 --- a/sdrbase/feature/featurewebapiutils.h +++ b/sdrbase/feature/featurewebapiutils.h @@ -47,6 +47,7 @@ private slots: class SDRBASE_API FeatureWebAPIUtils { public: + static bool run(int featureSetIndex, int featureIndex); static bool mapFind(const QString& target, int featureSetIndex=-1, int featureIndex=-1); static bool mapSetDateTime(const QDateTime& dateTime, int featureSetIndex=-1, int featureIndex=-1); static bool skyMapFind(const QString& target, int featureSetIndex=-1, int featureIndex=-1); diff --git a/sdrbase/mainparser.cpp b/sdrbase/mainparser.cpp index 3735a5103..1456b8f25 100644 --- a/sdrbase/mainparser.cpp +++ b/sdrbase/mainparser.cpp @@ -42,7 +42,8 @@ MainParser::MainParser() : m_remoteTCPSinkPortOption("remote-tcp-port", "Remote TCP Sink port (Default 1234).", "port", "1234"), m_remoteTCPSinkHWTypeOption("remote-tcp-hwtype", "Remote TCP Sink device hardware type (Optional. E.g. RTLSDR/SDRplayV3/AirspyHF).", "hwtype"), m_remoteTCPSinkSerialOption("remote-tcp-serial", "Remote TCP Sink device serial (Optional).", "serial"), - m_listDevicesOption("list-devices", "List available physical devices.") + m_listDevicesOption("list-devices", "List available physical devices."), + m_startOption("start", "Start all devices and features") { m_serverAddress = ""; // Bind to any address @@ -56,6 +57,7 @@ MainParser::MainParser() : m_remoteTCPSinkHWType = ""; m_remoteTCPSinkSerial = ""; m_listDevices = false; + m_start = false; m_parser.setApplicationDescription("Software Defined Radio application"); m_parser.addHelpOption(); @@ -72,6 +74,7 @@ MainParser::MainParser() : m_parser.addOption(m_remoteTCPSinkHWTypeOption); m_parser.addOption(m_remoteTCPSinkSerialOption); m_parser.addOption(m_listDevicesOption); + m_parser.addOption(m_startOption); } MainParser::~MainParser() @@ -154,4 +157,8 @@ void MainParser::parse(const QCoreApplication& app) qCritical() << "You must specify a device with either --remote-tcp-hwtype or --remote-tcp-serial"; exit (EXIT_FAILURE); } + + // Start devices and features + m_start = m_parser.isSet(m_startOption); + } diff --git a/sdrbase/mainparser.h b/sdrbase/mainparser.h index d38be74ba..220db95bb 100644 --- a/sdrbase/mainparser.h +++ b/sdrbase/mainparser.h @@ -45,6 +45,7 @@ public: const QString& getRemoteTCPSinkHWType() const { return m_remoteTCPSinkHWType; } const QString& getRemoteTCPSinkSerial() const { return m_remoteTCPSinkSerial; } bool getListDevices() const { return m_listDevices; } + bool getStart() const { return m_start; } private: QString m_serverAddress; @@ -58,6 +59,7 @@ private: QString m_remoteTCPSinkHWType; QString m_remoteTCPSinkSerial; bool m_listDevices; + bool m_start; QCommandLineParser m_parser; QCommandLineOption m_serverAddressOption; @@ -71,6 +73,7 @@ private: QCommandLineOption m_remoteTCPSinkHWTypeOption; QCommandLineOption m_remoteTCPSinkSerialOption; QCommandLineOption m_listDevicesOption; + QCommandLineOption m_startOption; }; diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index a3c5e9fe9..0fad8ba78 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -61,6 +61,7 @@ #include "feature/featureset.h" #include "feature/feature.h" #include "feature/featuregui.h" +#include "feature/featurewebapiutils.h" #include "mainspectrum/mainspectrumgui.h" #include "commands/commandkeyreceiver.h" #include "gui/presetitem.h" @@ -275,6 +276,9 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse InitFSM *fsm = new InitFSM(this, splash, !parser.getScratch()); connect(fsm, &InitFSM::finished, fsm, &InitFSM::deleteLater); connect(fsm, &InitFSM::finished, splash, &SDRangelSplash::deleteLater); + if (parser.getStart()) { + connect(fsm, &InitFSM::finished, this, &MainWindow::startAllAfterDelay); + } fsm->start(); qDebug() << "MainWindow::MainWindow: end"; @@ -3382,6 +3386,30 @@ void MainWindow::showAllChannels(int deviceSetIndex) } } +void MainWindow::startAllAfterDelay() +{ + // Wait a little bit before starting all devices and features, + // as some devices, such as FileSinks, can fail to start if run before initialised + // Is there a better way than this arbitrary time? + QTimer::singleShot(1000, this, &MainWindow::startAll); +} + +// Start all devices and features in all workspaces +void MainWindow::startAll() +{ + // Start all devices + for (const auto& workspace : m_workspaces) { + startAllDevices(workspace); + } + // Start all features + for (int featureSetIndex = 0; featureSetIndex < m_featureUIs.size(); featureSetIndex++) + { + for (int featureIndex = 0; featureIndex < m_featureUIs[featureSetIndex]->getNumberOfFeatures(); featureIndex++) { + FeatureWebAPIUtils::run(featureSetIndex, featureIndex); + } + } +} + // Start all devices in the workspace void MainWindow::startAllDevices(const Workspace *workspace) const { diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h index 6b7baf77b..d14228fad 100644 --- a/sdrgui/mainwindow.h +++ b/sdrgui/mainwindow.h @@ -458,6 +458,8 @@ private slots: void featureMove(FeatureGUI *gui, int wsIndexDestnation); void deviceStateChanged(DeviceAPI *deviceAPI); void openFeaturePresetsDialog(QPoint p, Workspace *workspace); + void startAllAfterDelay(); + void startAll(); void startAllDevices(const Workspace *workspace) const; void stopAllDevices(const Workspace *workspace) const; void deviceMove(DeviceGUI *gui, int wsIndexDestnation); From 2f280ec06ad61f31d6503f734f8ae66bbc25b908 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 21 Jan 2025 10:41:01 +0000 Subject: [PATCH 09/25] Radiosonde: Fix radio type sent to SondeHub --- plugins/feature/radiosonde/radiosondegui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/feature/radiosonde/radiosondegui.cpp b/plugins/feature/radiosonde/radiosondegui.cpp index ecf023eb5..9c2e4ac6b 100644 --- a/plugins/feature/radiosonde/radiosondegui.cpp +++ b/plugins/feature/radiosonde/radiosondegui.cpp @@ -965,7 +965,7 @@ QStringList RadiosondeGUI::getRadios() for (const auto& channel : channels) { - DeviceAPI *device = mainCore->getDevice(channel.m_index); + DeviceAPI *device = mainCore->getDevice(channel.m_superIndex); if (device) { QString name = device->getHardwareId(); From 52d59b8609ab880bad06546779adee4ea7b855a9 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 21 Jan 2025 13:33:11 +0000 Subject: [PATCH 10/25] Radiosonde: Add option to display predicted paths. --- plugins/feature/radiosonde/radiosondegui.cpp | 133 +++++++++++++++++- plugins/feature/radiosonde/radiosondegui.h | 9 ++ plugins/feature/radiosonde/radiosondegui.ui | 27 +++- .../feature/radiosonde/radiosondesettings.cpp | 9 ++ .../feature/radiosonde/radiosondesettings.h | 1 + plugins/feature/radiosonde/readme.md | 3 +- sdrbase/util/sondehub.cpp | 59 +++++++- sdrbase/util/sondehub.h | 11 ++ 8 files changed, 240 insertions(+), 12 deletions(-) diff --git a/plugins/feature/radiosonde/radiosondegui.cpp b/plugins/feature/radiosonde/radiosondegui.cpp index 9c2e4ac6b..ec381a9c7 100644 --- a/plugins/feature/radiosonde/radiosondegui.cpp +++ b/plugins/feature/radiosonde/radiosondegui.cpp @@ -157,6 +157,13 @@ RadiosondeGUI::RadiosondeGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, F connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); m_sondeHub = SondeHub::create(); + if (m_sondeHub) + { + connect(m_sondeHub, &SondeHub::prediction, this, &RadiosondeGUI::handlePrediction); + connect(&m_predicitionTimer, &QTimer::timeout, this, &RadiosondeGUI::requestPredictions); + m_predicitionTimer.setInterval(60 * 1000); + m_predicitionTimer.setSingleShot(false); + } // Initialise chart ui->chart->setRenderHint(QPainter::Antialiasing); @@ -257,12 +264,14 @@ void RadiosondeGUI::displaySettings() ui->y2->setCurrentIndex((int)m_settings.m_y2); ui->feed->setChecked(m_settings.m_feedEnabled); + ui->showPredictedPaths->setChecked(m_settings.m_showPredictedPaths); getRollupContents()->restoreState(m_rollupState); blockApplySettings(false); getRollupContents()->arrangeRollups(); updatePosition(); + applyShowPredictedPaths(); } void RadiosondeGUI::onMenuDialogCalled(const QPoint &p) @@ -673,6 +682,10 @@ void RadiosondeGUI::updateRadiosondes(RS41Frame *message, QDateTime dateTime) MainCore::instance()->getSettings().getAltitude() ); } + + if (!found) { + requestPredictions(); + } } void RadiosondeGUI::on_radiosondes_itemSelectionChanged() @@ -908,16 +921,38 @@ void RadiosondeGUI::on_deleteAll_clicked() { QString serial = ui->radiosondes->item(row, RADIOSONDE_COL_SERIAL)->text(); // Remove from map - sendToMap(serial, "", - "", "", - "", 0.0f, - 0.0f, 0.0f, 0.0f, QDateTime(), - 0.0f); + clearFromMapFeature(serial, 0); // Remove from table ui->radiosondes->removeRow(row); // Remove from hash and free memory delete m_radiosondes.take(serial); } + deletePredictedPaths(); +} + +void RadiosondeGUI::deletePredictedPaths() +{ + for (const auto& prediction : m_predictions) { + clearFromMapFeature(prediction, 3); + } + m_predictions.clear(); +} + +void RadiosondeGUI::clearFromMapFeature(const QString& name, int type) +{ + QList mapPipes; + MainCore::instance()->getMessagePipes().getMessagePipes(m_radiosonde, "mapitems", mapPipes); + + for (const auto& pipe : mapPipes) + { + MessageQueue *messageQueue = qobject_cast(pipe->m_element); + SWGSDRangel::SWGMapItem *swgMapItem = new SWGSDRangel::SWGMapItem(); + swgMapItem->setName(new QString(name)); + swgMapItem->setImage(new QString("")); + swgMapItem->setType(type); + MainCore::MsgMapItem *msg = MainCore::MsgMapItem::create(m_radiosonde, swgMapItem); + messageQueue->push(msg); + } } void RadiosondeGUI::makeUIConnections() @@ -928,6 +963,7 @@ void RadiosondeGUI::makeUIConnections() QObject::connect(ui->y2, qOverload(&QComboBox::currentIndexChanged), this, &RadiosondeGUI::on_y2_currentIndexChanged); QObject::connect(ui->deleteAll, &QPushButton::clicked, this, &RadiosondeGUI::on_deleteAll_clicked); QObject::connect(ui->feed, &ButtonSwitch::clicked, this, &RadiosondeGUI::on_feed_clicked); + QObject::connect(ui->showPredictedPaths, &ButtonSwitch::clicked, this, &RadiosondeGUI::on_showPredictedPaths_clicked); } void RadiosondeGUI::on_feed_clicked(bool checked) @@ -956,6 +992,28 @@ void RadiosondeGUI::feedSelect(const QPoint& p) } } +void RadiosondeGUI::on_showPredictedPaths_clicked(bool checked) +{ + m_settings.m_showPredictedPaths = checked; + m_settingsKeys.append("showPredictedPaths"); + applySettings(); + applyShowPredictedPaths(); +} + +void RadiosondeGUI::applyShowPredictedPaths() +{ + if (m_settings.m_showPredictedPaths) + { + requestPredictions(); + m_predicitionTimer.start(); + } + else + { + m_predicitionTimer.stop(); + deletePredictedPaths(); + } +} + // Get names of devices with radiosonde demods, for SondeHub Radio string QStringList RadiosondeGUI::getRadios() { @@ -1019,6 +1077,71 @@ void RadiosondeGUI::updatePosition() } } +void RadiosondeGUI::requestPredictions() +{ + if (m_sondeHub && m_settings.m_showPredictedPaths) + { + for (int row = 0; row < ui->radiosondes->rowCount(); row++) + { + QString serial = ui->radiosondes->item(row, RADIOSONDE_COL_SERIAL)->text(); + m_sondeHub->getPrediction(serial); + } + } +} + +void RadiosondeGUI::handlePrediction(const QString& serial, const QList& positions) +{ + if (positions.size() < 2) { + return; + } + + // Send to Map feature + QList mapPipes; + MainCore::instance()->getMessagePipes().getMessagePipes(m_radiosonde, "mapitems", mapPipes); + + if (mapPipes.size() > 0) + { + QString name = QString("%1_prediction").arg(serial); + + for (const auto& pipe : mapPipes) + { + MessageQueue *messageQueue = qobject_cast(pipe->m_element); + SWGSDRangel::SWGMapItem *swgMapItem = new SWGSDRangel::SWGMapItem(); + + swgMapItem->setName(new QString(name)); + swgMapItem->setLatitude(positions[0].m_latitude); + swgMapItem->setLongitude(positions[0].m_longitude); + swgMapItem->setAltitude(positions[0].m_altitude); + QString image = QString("none"); + swgMapItem->setImage(new QString(image)); + swgMapItem->setImageRotation(0); + swgMapItem->setFixedPosition(true); + swgMapItem->setLabel(new QString(serial)); + swgMapItem->setAltitudeReference(0); + QList *coords = new QList(); + + for (const auto& position : positions) + { + SWGSDRangel::SWGMapCoordinate* c = new SWGSDRangel::SWGMapCoordinate(); + c->setLatitude(position.m_latitude); + c->setLongitude(position.m_longitude); + c->setAltitude(position.m_altitude); + coords->append(c); + } + + swgMapItem->setCoordinates(coords); + swgMapItem->setType(3); + + MainCore::MsgMapItem *msg = MainCore::MsgMapItem::create(m_radiosonde, swgMapItem); + messageQueue->push(msg); + + if (!m_predictions.contains(name)) { + m_predictions.append(name); + } + } + } +} + void RadiosondeGUI::preferenceChanged(int elementType) { Preferences::ElementType pref = (Preferences::ElementType)elementType; diff --git a/plugins/feature/radiosonde/radiosondegui.h b/plugins/feature/radiosonde/radiosondegui.h index 9afb619cd..fd6c31d47 100644 --- a/plugins/feature/radiosonde/radiosondegui.h +++ b/plugins/feature/radiosonde/radiosondegui.h @@ -108,6 +108,9 @@ private: static const int m_minMobilePositionUpdateTime = 30; // In seconds static const int m_minFixedPositionUpdateTime = 5 * 60; + QTimer m_predicitionTimer; + QStringList m_predictions; + explicit RadiosondeGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr); virtual ~RadiosondeGUI(); @@ -130,6 +133,9 @@ private: float getData(RadiosondeSettings::ChartData dataType, RadiosondeData *radiosonde, RS41Frame *message); void updatePosition(); QStringList getRadios(); + void applyShowPredictedPaths(); + void deletePredictedPaths(); + void clearFromMapFeature(const QString& name, int type); enum RadiosondeCol { RADIOSONDE_COL_SERIAL, @@ -168,6 +174,9 @@ private slots: void on_deleteAll_clicked(); void on_feed_clicked(bool checked); void feedSelect(const QPoint& p); + void on_showPredictedPaths_clicked(bool checked); + void requestPredictions(); + void handlePrediction(const QString& serial, const QList& positions); void preferenceChanged(int elementType); }; diff --git a/plugins/feature/radiosonde/radiosondegui.ui b/plugins/feature/radiosonde/radiosondegui.ui index eee177b19..106c74341 100644 --- a/plugins/feature/radiosonde/radiosondegui.ui +++ b/plugins/feature/radiosonde/radiosondegui.ui @@ -31,7 +31,7 @@ Radiosonde - Qt::LeftToRight + Qt::LayoutDirection::LeftToRight @@ -76,20 +76,20 @@ - Qt::Vertical + Qt::Orientation::Vertical Radiosondes - QAbstractItemView::NoEditTriggers + QAbstractItemView::EditTrigger::NoEditTriggers - QAbstractItemView::SingleSelection + QAbstractItemView::SelectionMode::SingleSelection - QAbstractItemView::SelectRows + QAbstractItemView::SelectionBehavior::SelectRows @@ -416,6 +416,23 @@ + + + + Show predicted paths on map + + + ... + + + + :/logarithmic.png:/logarithmic.png + + + true + + + diff --git a/plugins/feature/radiosonde/radiosondesettings.cpp b/plugins/feature/radiosonde/radiosondesettings.cpp index c45c27b90..35140dcd2 100644 --- a/plugins/feature/radiosonde/radiosondesettings.cpp +++ b/plugins/feature/radiosonde/radiosondesettings.cpp @@ -60,6 +60,7 @@ void RadiosondeSettings::resetToDefaults() m_displayPosition = false; m_mobile = false; m_email = ""; + m_showPredictedPaths = false; for (int i = 0; i < RADIOSONDES_COLUMNS; i++) { @@ -95,6 +96,7 @@ QByteArray RadiosondeSettings::serialize() const s.writeBool(17, m_displayPosition); s.writeBool(18, m_mobile); s.writeString(19, m_email); + s.writeBool(20, m_showPredictedPaths); for (int i = 0; i < RADIOSONDES_COLUMNS; i++) { @@ -159,6 +161,7 @@ bool RadiosondeSettings::deserialize(const QByteArray& data) d.readBool(17, &m_displayPosition, false); d.readBool(18, &m_mobile, false); d.readString(19, &m_email, ""); + d.readBool(20, &m_showPredictedPaths, false); for (int i = 0; i < RADIOSONDES_COLUMNS; i++) { d.readS32(300 + i, &m_radiosondesColumnIndexes[i], i); @@ -224,6 +227,9 @@ void RadiosondeSettings::applySettings(const QStringList& settingsKeys, const Ra if (settingsKeys.contains("email")) { m_email = settings.m_email; } + if (settingsKeys.contains("showPredictedPaths")) { + m_showPredictedPaths = settings.m_showPredictedPaths; + } if (settingsKeys.contains("workspaceIndex")) { m_workspaceIndex = settings.m_workspaceIndex; } @@ -292,6 +298,9 @@ QString RadiosondeSettings::getDebugString(const QStringList& settingsKeys, bool if (settingsKeys.contains("email") || force) { ostr << " m_email: " << m_email.toStdString(); } + if (settingsKeys.contains("showPredictedPaths") || force) { + ostr << " m_showPredictedPaths: " << m_showPredictedPaths; + } if (settingsKeys.contains("workspaceIndex") || force) { ostr << " m_workspaceIndex: " << m_workspaceIndex; } diff --git a/plugins/feature/radiosonde/radiosondesettings.h b/plugins/feature/radiosonde/radiosondesettings.h index 1f7071027..2112f26fa 100644 --- a/plugins/feature/radiosonde/radiosondesettings.h +++ b/plugins/feature/radiosonde/radiosondesettings.h @@ -62,6 +62,7 @@ struct RadiosondeSettings bool m_displayPosition; bool m_mobile; QString m_email; + bool m_showPredictedPaths; int m_radiosondesColumnIndexes[RADIOSONDES_COLUMNS]; int m_radiosondesColumnSizes[RADIOSONDES_COLUMNS]; diff --git a/plugins/feature/radiosonde/readme.md b/plugins/feature/radiosonde/readme.md index 6fd8e850a..55cad6f4d 100644 --- a/plugins/feature/radiosonde/readme.md +++ b/plugins/feature/radiosonde/readme.md @@ -7,7 +7,7 @@ based on data received via [Radiosonde Demodulators](../../channelrx/demodradios The chart can plot two data series vs time for the radiosonde selected in the table. -The Radiosonde feature can draw balloons objects on the [Map](../../feature/map/readme.md) feature in 2D and 3D. +The Radiosonde feature can draw balloons objects and predicted paths on the [Map](../../feature/map/readme.md) feature in 2D and 3D. Received data can be forwarded to [SondeHub](https://sondehub.org/). Your location can be displayed on the SondeHub map, as either a stationary receiver or chase car. @@ -48,6 +48,7 @@ The Radiosonde feature can plot balloons (during ascent) and parachutes (during To use, simply open a Map feature and the Radiosonde plugin will display objects based upon the data it receives from that point. Selecting a radiosonde item on the map will display a text bubble containing information from the above table. To centre the map on an item in the table, double click in the Lat or Lon columns. +Predicted paths can be displayed by checking the Show Predicted Paths button. The path is predicted by SondeHub. ![Radiosonde on map](../../../doc/img/Radiosonde_plugin_map.png) diff --git a/sdrbase/util/sondehub.cpp b/sdrbase/util/sondehub.cpp index 9cb76158c..d15e665f7 100644 --- a/sdrbase/util/sondehub.cpp +++ b/sdrbase/util/sondehub.cpp @@ -183,6 +183,17 @@ void SondeHub::updatePosition( m_networkManager->put(request, data); } +void SondeHub::getPrediction(const QString& serial) +{ + QUrl url(QString("https://api.v2.sondehub.org/predictions?vehicles=%1").arg(serial)); + + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + request.setHeader(QNetworkRequest::UserAgentHeader, "sdrangel"); + + m_networkManager->get(request); +} + void SondeHub::handleReply(QNetworkReply* reply) { if (reply) @@ -221,7 +232,53 @@ void SondeHub::handleReply(QNetworkReply* reply) } } } - //qDebug() << "SondeHub::handleReply: obj" << QJsonDocument(obj); + //qDebug() << "SondeHub::handleReply: obj" << QJsonDocument(obj); + } + else if (document.isArray()) + { + QJsonArray array = document.array(); + + for (auto arrayRef : array) + { + if (arrayRef.isObject()) + { + QJsonObject obj = arrayRef.toObject(); + + if (obj.contains(QStringLiteral("vehicle")) && obj.contains(QStringLiteral("data"))) + { + QJsonArray data; + // Perhaps a bug that data is a string rather than an array? + if (obj.value(QStringLiteral("data")).isString()) + { + QJsonDocument dataDocument = QJsonDocument::fromJson(obj.value(QStringLiteral("data")).toString().toUtf8()); + data = dataDocument.array(); + } + else + { + data = obj.value(QStringLiteral("data")).toArray(); + } + + QList positions; + for (auto dataObjRef : data) + { + QJsonObject positionObj = dataObjRef.toObject(); + Position position; + + position.m_dateTime = QDateTime::fromSecsSinceEpoch(positionObj.value(QStringLiteral("time")).toInt()); + position.m_latitude = positionObj.value(QStringLiteral("lat")).toDouble(); + position.m_longitude = positionObj.value(QStringLiteral("lon")).toDouble(); + position.m_altitude = positionObj.value(QStringLiteral("alt")).toDouble(); + positions.append(position); + } + + emit prediction(obj.value("vehicle").toString(), positions); + } + } + else + { + qDebug() << "SondeHub::handleReply:" << bytes; + } + } } else { diff --git a/sdrbase/util/sondehub.h b/sdrbase/util/sondehub.h index 6ad663a6f..8409ac94b 100644 --- a/sdrbase/util/sondehub.h +++ b/sdrbase/util/sondehub.h @@ -36,6 +36,13 @@ protected: public: + struct Position { + float m_latitude; + float m_longitude; + float m_altitude; + QDateTime m_dateTime; + }; + static SondeHub* create(); ~SondeHub(); @@ -61,10 +68,14 @@ public: bool mobile ); + void getPrediction(const QString& serial); private slots: void handleReply(QNetworkReply* reply); +signals: + void prediction(const QString& serial, const QList& path); + private: QNetworkAccessManager *m_networkManager; From 7af58538b672a565dd019e6efd58126d96ac6838 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 21 Jan 2025 13:47:47 +0000 Subject: [PATCH 11/25] FileSink: Add minimum width constraint so widgets don't move around as dials are changed. --- plugins/channelrx/filesink/filesinkgui.ui | 38 +++++++++++++++++------ 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/plugins/channelrx/filesink/filesinkgui.ui b/plugins/channelrx/filesink/filesinkgui.ui index e9fc5b051..31812990c 100644 --- a/plugins/channelrx/filesink/filesinkgui.ui +++ b/plugins/channelrx/filesink/filesinkgui.ui @@ -107,7 +107,7 @@ PointingHandCursor - Qt::StrongFocus + Qt::FocusPolicy::StrongFocus Demod shift frequency from center in Hz @@ -124,7 +124,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -186,7 +186,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -211,7 +211,7 @@ 0000k - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter @@ -230,7 +230,7 @@ #000 - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter @@ -265,7 +265,7 @@ 999.99M - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter @@ -298,7 +298,7 @@ 1 - Qt::Horizontal + Qt::Orientation::Horizontal @@ -317,14 +317,14 @@ 000 - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter - Qt::Vertical + Qt::Orientation::Vertical @@ -368,6 +368,12 @@ + + + 30 + 0 + + Spectrum squelch level (dB) @@ -397,6 +403,12 @@ + + + 16 + 0 + + Squelched recoding pre-recording time (s) @@ -426,6 +438,12 @@ + + + 16 + 0 + + Squelched recording post-recording time (s) @@ -506,7 +524,7 @@ ... - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter From 4519e512c6079521f9a61f161e54f5bdac12be94 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Wed, 22 Jan 2025 20:45:22 +0000 Subject: [PATCH 12/25] Retry make package in case hdituil fails --- .github/workflows/mac.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 9f9114931..28c2b0568 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -44,7 +44,17 @@ jobs: - name: Build SDRangel on Mac run: | cd build - make -j4 package + RETRIES=3 + COUNT=1 + while [ $COUNT -lt $RETRIES ]; do + make -j4 package + if [ $? -eq 0 ]; then + RETRIES=0 + break + fi + let COUNT=$COUNT+1 + done + shell: bash - name: Get version id: get_version run: | From c9c9febe4141fcdda13e4800fd86dd9a4bddffdf Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Wed, 22 Jan 2025 21:38:00 +0000 Subject: [PATCH 13/25] Use version 4.1 of x265 as master is broken on Mac. --- external/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index d84f58523..33d5948c7 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -420,6 +420,7 @@ if (NOT FFMPEG_FOUND AND NOT USE_PRECOMPILED_LIBS) if (NOT X265_FOUND OR X265_EXTERNAL) ExternalProject_Add(x265 GIT_REPOSITORY https://bitbucket.org/multicoreware/x265_git.git + GIT_TAG 4.1 PREFIX "${EXTERNAL_BUILD_LIBRARIES}/x265" SOURCE_SUBDIR "source" CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX= From 9ea7ade57f9919644a73cf5abb5c5b45c43f5213 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Wed, 22 Jan 2025 21:38:22 +0000 Subject: [PATCH 14/25] Try continue-on-error: true to allow make to be retried --- .github/workflows/mac.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 28c2b0568..4d64098de 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -55,6 +55,7 @@ jobs: let COUNT=$COUNT+1 done shell: bash + continue-on-error: true - name: Get version id: get_version run: | From 2ea5ef220b33024a306d6173a7c210875844cf40 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Thu, 23 Jan 2025 08:53:01 +0000 Subject: [PATCH 15/25] Add set +e to allow script to continue on error --- .github/workflows/mac.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 4d64098de..65a5014cd 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -46,6 +46,7 @@ jobs: cd build RETRIES=3 COUNT=1 + set +e while [ $COUNT -lt $RETRIES ]; do make -j4 package if [ $? -eq 0 ]; then From 6df8b94637663d6758f9bc54e0eaad687689ace5 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Thu, 23 Jan 2025 11:02:37 +0000 Subject: [PATCH 16/25] Try to fix arm build as well. --- .github/workflows/mac.yml | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 65a5014cd..a646a4821 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -44,11 +44,15 @@ jobs: - name: Build SDRangel on Mac run: | cd build - RETRIES=3 + make -j4 + - name: Create dmg + run: | + cd build + RETRIES=5 COUNT=1 set +e while [ $COUNT -lt $RETRIES ]; do - make -j4 package + make package if [ $? -eq 0 ]; then RETRIES=0 break @@ -115,7 +119,23 @@ jobs: - name: Build SDRangel on Mac run: | cd build - make -j3 package + make -j3 + - name: Create dmg + run: | + cd build + RETRIES=5 + COUNT=1 + set +e + while [ $COUNT -lt $RETRIES ]; do + make package + if [ $? -eq 0 ]; then + RETRIES=0 + break + fi + let COUNT=$COUNT+1 + done + shell: bash + continue-on-error: true - name: Get version id: get_version run: | From 23279d2f465fe67e6003c8ade25d4ad69927b95b Mon Sep 17 00:00:00 2001 From: srcejon Date: Thu, 23 Jan 2025 22:57:16 +0000 Subject: [PATCH 17/25] Fix gcc warnings about warning options --- cmake/Modules/CompilerOptions.cmake | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmake/Modules/CompilerOptions.cmake b/cmake/Modules/CompilerOptions.cmake index 75b698171..64f84c72a 100644 --- a/cmake/Modules/CompilerOptions.cmake +++ b/cmake/Modules/CompilerOptions.cmake @@ -19,7 +19,11 @@ if(WIN32) endif() if(NOT MSVC) - add_compile_options(-Wall -Wextra -Wvla -Woverloaded-virtual -Wno-inconsistent-missing-override -ffast-math -fno-finite-math-only -ftree-vectorize) + add_compile_options(-Wall -Wextra -Wvla -ffast-math -fno-finite-math-only -ftree-vectorize) + add_compile_options($<$:-Woverloaded-virtual>) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + add_compile_options(-Wno-inconsistent-missing-override) + endif() else() # Disable some warnings, so more useful warnings aren't hidden in the noise # 4996 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. From fc64424377203ec4fb29ab0ab10129df53d11661 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sat, 25 Jan 2025 15:57:43 +0000 Subject: [PATCH 18/25] Update snap to use UHD 4.7. --- snap/snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 0b753bfce..3cdf6f6a7 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -564,7 +564,7 @@ parts: plugin: cmake source: https://github.com/EttusResearch/uhd.git source-type: git - source-commit: v4.5.0.0 + source-commit: v4.7.0.0 source-subdir: host build-packages: - libusb-1.0-0-dev From e6b3e50fd2590639b2f16342e00a49ddc196a1c1 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 2 Feb 2025 19:09:22 +0100 Subject: [PATCH 19/25] Updated version and changelog --- CHANGELOG | 6 ++++++ CMakeLists.txt | 2 +- debian/changelog | 6 ++++++ gitdiff.sh | 3 ++- plugins/channelrx/demodadsb/adsbplugin.cpp | 2 +- plugins/channelrx/demoddsc/dscdemodplugin.cpp | 2 +- plugins/channelrx/filesink/filesinkplugin.cpp | 2 +- plugins/channelrx/remotetcpsink/remotetcpsinkplugin.cpp | 2 +- plugins/channeltx/modam/ammodplugin.cpp | 2 +- plugins/channeltx/modnfm/nfmmodplugin.cpp | 2 +- plugins/channeltx/modssb/ssbmodplugin.cpp | 2 +- plugins/channeltx/modwfm/wfmmodplugin.cpp | 2 +- plugins/feature/radiosonde/radiosondeplugin.cpp | 2 +- plugins/feature/sid/sidplugin.cpp | 2 +- plugins/samplesink/usrpoutput/usrpoutputplugin.cpp | 2 +- plugins/samplesource/usrpinput/usrpinputplugin.cpp | 2 +- 16 files changed, 27 insertions(+), 14 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a451c89e1..684d21059 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +sdrangel (7.22.6-1) unstable; urgency=medium + + * See Github release + + -- Edouard Griffiths, F4EXB Sun, 02 Feb 2025 18:08:11 +0100 + sdrangel (7.22.5-1) unstable; urgency=medium * Windows: upload signed releases rather than unsigned releases to Github releases page. PR #2347 diff --git a/CMakeLists.txt b/CMakeLists.txt index 7944dd8e0..9ab7abda1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # configure version set(sdrangel_VERSION_MAJOR "7") set(sdrangel_VERSION_MINOR "22") -set(sdrangel_VERSION_PATCH "5") +set(sdrangel_VERSION_PATCH "6") set(sdrangel_VERSION_SUFFIX "") # SDRAngel cmake options diff --git a/debian/changelog b/debian/changelog index cbcb73a4d..f83d75ef6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +sdrangel (7.22.6-1) unstable; urgency=medium + + * See Github release + + -- Edouard Griffiths, F4EXB Sun, 02 Feb 2025 18:08:11 +0100 + sdrangel (7.22.5-1) unstable; urgency=medium * Windows: upload signed releases rather than unsigned releases to Github releases page. PR #2347 diff --git a/gitdiff.sh b/gitdiff.sh index 6af69efba..e6deb2802 100755 --- a/gitdiff.sh +++ b/gitdiff.sh @@ -4,6 +4,7 @@ PLUGINS=$(git diff --name-only ${1}..${2} | grep plugins/ | cut -d'/' -f2,3 | so for plugin in $PLUGINS do FILE=$(find $BASEDIR/plugins/$plugin -name "*plugin.cpp") - sed -i -E "s/QStringLiteral\(\"7\.(.*)\"\)/QStringLiteral\(\"7\.22\.5\"\)/" $FILE + echo $FILE + sed -i -E "s/QStringLiteral\(\"7\.(.*)\"\)/QStringLiteral\(\"7\.22\.6\"\)/" $FILE done diff --git a/plugins/channelrx/demodadsb/adsbplugin.cpp b/plugins/channelrx/demodadsb/adsbplugin.cpp index 72650461c..b7b402315 100644 --- a/plugins/channelrx/demodadsb/adsbplugin.cpp +++ b/plugins/channelrx/demodadsb/adsbplugin.cpp @@ -30,7 +30,7 @@ const PluginDescriptor ADSBPlugin::m_pluginDescriptor = { ADSBDemod::m_channelId, QStringLiteral("ADS-B Demodulator"), - QStringLiteral("7.22.5"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Jon Beniston, M7RCE"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channelrx/demoddsc/dscdemodplugin.cpp b/plugins/channelrx/demoddsc/dscdemodplugin.cpp index 673437909..e3134aa4c 100644 --- a/plugins/channelrx/demoddsc/dscdemodplugin.cpp +++ b/plugins/channelrx/demoddsc/dscdemodplugin.cpp @@ -33,7 +33,7 @@ const PluginDescriptor DSCDemodPlugin::m_pluginDescriptor = { DSCDemod::m_channelId, QStringLiteral("DSC Demodulator"), - QStringLiteral("7.22.5"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Jon Beniston, M7RCE"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channelrx/filesink/filesinkplugin.cpp b/plugins/channelrx/filesink/filesinkplugin.cpp index 8c50fef86..0966cd9d1 100644 --- a/plugins/channelrx/filesink/filesinkplugin.cpp +++ b/plugins/channelrx/filesink/filesinkplugin.cpp @@ -33,7 +33,7 @@ const PluginDescriptor FileSinkPlugin::m_pluginDescriptor = { FileSink::m_channelId, QStringLiteral("File Sink"), - QStringLiteral("7.22.5"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channelrx/remotetcpsink/remotetcpsinkplugin.cpp b/plugins/channelrx/remotetcpsink/remotetcpsinkplugin.cpp index 54079dc35..1ee9de9a8 100644 --- a/plugins/channelrx/remotetcpsink/remotetcpsinkplugin.cpp +++ b/plugins/channelrx/remotetcpsink/remotetcpsinkplugin.cpp @@ -35,7 +35,7 @@ const PluginDescriptor RemoteTCPSinkPlugin::m_pluginDescriptor = { RemoteTCPSink::m_channelId, QStringLiteral("Remote TCP channel sink"), - QStringLiteral("7.22.5"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Jon Beniston, M7RCE"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channeltx/modam/ammodplugin.cpp b/plugins/channeltx/modam/ammodplugin.cpp index 1c7763847..f1899a28a 100644 --- a/plugins/channeltx/modam/ammodplugin.cpp +++ b/plugins/channeltx/modam/ammodplugin.cpp @@ -32,7 +32,7 @@ const PluginDescriptor AMModPlugin::m_pluginDescriptor = { AMMod::m_channelId, QStringLiteral("AM Modulator"), - QStringLiteral("7.22.5"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channeltx/modnfm/nfmmodplugin.cpp b/plugins/channeltx/modnfm/nfmmodplugin.cpp index 8219ee1a5..2b919d227 100644 --- a/plugins/channeltx/modnfm/nfmmodplugin.cpp +++ b/plugins/channeltx/modnfm/nfmmodplugin.cpp @@ -32,7 +32,7 @@ const PluginDescriptor NFMModPlugin::m_pluginDescriptor = { NFMMod::m_channelId, QStringLiteral("NFM Modulator"), - QStringLiteral("7.22.5"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channeltx/modssb/ssbmodplugin.cpp b/plugins/channeltx/modssb/ssbmodplugin.cpp index 7558a0b96..0e41cd5cb 100644 --- a/plugins/channeltx/modssb/ssbmodplugin.cpp +++ b/plugins/channeltx/modssb/ssbmodplugin.cpp @@ -32,7 +32,7 @@ const PluginDescriptor SSBModPlugin::m_pluginDescriptor = { SSBMod::m_channelId, QStringLiteral("SSB Modulator"), - QStringLiteral("7.22.5"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channeltx/modwfm/wfmmodplugin.cpp b/plugins/channeltx/modwfm/wfmmodplugin.cpp index bd6f6ebb4..d20076832 100644 --- a/plugins/channeltx/modwfm/wfmmodplugin.cpp +++ b/plugins/channeltx/modwfm/wfmmodplugin.cpp @@ -32,7 +32,7 @@ const PluginDescriptor WFMModPlugin::m_pluginDescriptor = { WFMMod::m_channelId, QStringLiteral("WFM Modulator"), - QStringLiteral("7.22.5"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/feature/radiosonde/radiosondeplugin.cpp b/plugins/feature/radiosonde/radiosondeplugin.cpp index 793fc6249..49cd0fdf2 100644 --- a/plugins/feature/radiosonde/radiosondeplugin.cpp +++ b/plugins/feature/radiosonde/radiosondeplugin.cpp @@ -33,7 +33,7 @@ const PluginDescriptor RadiosondePlugin::m_pluginDescriptor = { Radiosonde::m_featureId, QStringLiteral("Radiosonde"), - QStringLiteral("7.22.1"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Jon Beniston, M7RCE"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/feature/sid/sidplugin.cpp b/plugins/feature/sid/sidplugin.cpp index eb9acfa02..08c050f12 100644 --- a/plugins/feature/sid/sidplugin.cpp +++ b/plugins/feature/sid/sidplugin.cpp @@ -29,7 +29,7 @@ const PluginDescriptor SIDPlugin::m_pluginDescriptor = { SIDMain::m_featureId, QStringLiteral("SID"), - QStringLiteral("7.22.1"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Jon Beniston, M7RCE"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/samplesink/usrpoutput/usrpoutputplugin.cpp b/plugins/samplesink/usrpoutput/usrpoutputplugin.cpp index 1cdb3820a..b693d9274 100644 --- a/plugins/samplesink/usrpoutput/usrpoutputplugin.cpp +++ b/plugins/samplesink/usrpoutput/usrpoutputplugin.cpp @@ -36,7 +36,7 @@ const PluginDescriptor USRPOutputPlugin::m_pluginDescriptor = { QStringLiteral("USRP"), QStringLiteral("URSP Output"), - QStringLiteral("7.22.3"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Jon Beniston, M7RCE and Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/samplesource/usrpinput/usrpinputplugin.cpp b/plugins/samplesource/usrpinput/usrpinputplugin.cpp index db57b3957..4457623dc 100644 --- a/plugins/samplesource/usrpinput/usrpinputplugin.cpp +++ b/plugins/samplesource/usrpinput/usrpinputplugin.cpp @@ -36,7 +36,7 @@ const PluginDescriptor USRPInputPlugin::m_pluginDescriptor = { QStringLiteral("USRP"), QStringLiteral("USRP Input"), - QStringLiteral("7.22.1"), + QStringLiteral("7.22.6"), QStringLiteral("(c) Jon Beniston, M7RCE and Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, From a2f842835250c5ac3dced3a9df2551c5aa938ebe Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Mon, 3 Feb 2025 13:58:46 +0000 Subject: [PATCH 20/25] Radiosonde: Fix pressure calculation. #2242 --- sdrbase/util/radiosonde.cpp | 14 ++++++++++---- sdrbase/util/radiosonde.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/sdrbase/util/radiosonde.cpp b/sdrbase/util/radiosonde.cpp index 34c2b0124..e45da02ba 100644 --- a/sdrbase/util/radiosonde.cpp +++ b/sdrbase/util/radiosonde.cpp @@ -76,6 +76,12 @@ QString RS41Frame::toHex() return m_bytes.toHex(); } +int16_t RS41Frame::getInt16(const QByteArray ba, int offset) const +{ + return (ba[offset] & 0xff) + | ((ba[offset+1] & 0xff) << 8); +} + uint16_t RS41Frame::getUInt16(const QByteArray ba, int offset) const { return (ba[offset] & 0xff) @@ -130,7 +136,7 @@ void RS41Frame::decodeMeas(const QByteArray ba) m_pressureMain = getUInt24(ba, 0x1b); m_pressureRef1 = getUInt24(ba, 0x1e); m_pressureRef2 = getUInt24(ba, 0x21); - m_pressureTemp = getUInt16(ba, 0x26) / 100.0f; + m_pressureTemp = getInt16(ba, 0x26) / 100.0f; } void RS41Frame::decodeGPSInfo(const QByteArray ba) @@ -187,7 +193,7 @@ static float waterVapourSaturationPressure(float tCelsius) return p / 100.0f; } -static float calcT(int f, int f1, int f2, float r1, float r2, float *poly, float *cal) +static float calcT(int f, int f1, int f2, float r1, float r2, const float *poly, const float *cal) { /*float g = (float)(f2-f1) / (r2-r1); // gain float Rb = (f1*r2-f2*r1) / (float)(f2-f1); // offset @@ -219,7 +225,7 @@ static float calcT(int f, int f1, int f2, float r1, float r2, float *poly, float return tCal; } -static float calcU(int cInt, int cMin, int cMax, float c1, float c2, float T, float HT, float *capCal, float *matrixCal, float height, float *vectorPCal, float *matrixPCal) +static float calcU(int cInt, int cMin, int cMax, float c1, float c2, float T, float HT, float *capCal, float *matrixCal, float height, const float *vectorPCal, const float *matrixPCal) { //qDebug() << "cInt " << cInt << " cMin " << cMin << " cMax " << cMax << " c1 " << c1 << " c2 " << c2 << " T " << T << " HT " << HT << " capCal[0] " << capCal[0] << " capCal[1] " << capCal[1] << "height" << height; @@ -302,7 +308,7 @@ static float calcU(int cInt, int cMin, int cMax, float c1, float c2, float T, fl return uCal; } -static float calcP(int f, int f1, int f2, float pressureTemp, float *cal) +static float calcP(int f, int f1, int f2, float pressureTemp, const float *cal) { // Convert integer measurement to scale factor float s = (f-f1) / (float)(f2-f1); diff --git a/sdrbase/util/radiosonde.h b/sdrbase/util/radiosonde.h index 2136d4cd1..001af7fca 100644 --- a/sdrbase/util/radiosonde.h +++ b/sdrbase/util/radiosonde.h @@ -124,6 +124,7 @@ public: static int getFrameLength(int frameType); protected: + int16_t getInt16(const QByteArray ba, int offset) const; uint16_t getUInt16(const QByteArray ba, int offset) const; uint32_t getUInt24(const QByteArray ba, int offset) const; uint32_t getUInt32(const QByteArray ba, int offset) const; From b65311736064c0da733ebe60d43058af3490ddfa Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Mon, 3 Feb 2025 14:04:43 +0000 Subject: [PATCH 21/25] Fix lint warnings. --- sdrbase/util/radiosonde.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdrbase/util/radiosonde.cpp b/sdrbase/util/radiosonde.cpp index e45da02ba..124e1d4c2 100644 --- a/sdrbase/util/radiosonde.cpp +++ b/sdrbase/util/radiosonde.cpp @@ -225,7 +225,7 @@ static float calcT(int f, int f1, int f2, float r1, float r2, const float *poly, return tCal; } -static float calcU(int cInt, int cMin, int cMax, float c1, float c2, float T, float HT, float *capCal, float *matrixCal, float height, const float *vectorPCal, const float *matrixPCal) +static float calcU(int cInt, int cMin, int cMax, float c1, float c2, float T, float HT, const float *capCal, const float *matrixCal, float height, const float *vectorPCal, const float *matrixPCal) { //qDebug() << "cInt " << cInt << " cMin " << cMin << " cMax " << cMax << " c1 " << c1 << " c2 " << c2 << " T " << T << " HT " << HT << " capCal[0] " << capCal[0] << " capCal[1] " << capCal[1] << "height" << height; From 310df0046cd258473d212787f988591c3a0b05fe Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 4 Feb 2025 12:03:13 +0000 Subject: [PATCH 22/25] Try setting MACOSX_DEPLOYMENT_TARGET to see if it can run on older MacOSes. --- .github/workflows/mac.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index a646a4821..04ab1d723 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -10,6 +10,8 @@ on: jobs: build_mac_x64: runs-on: macos-13 + env: + MACOSX_DEPLOYMENT_TARGET: 12.0 steps: - uses: actions/checkout@v4 with: From 7f20ca0a6db05e888b3d6db6bd0595d78b1f35f9 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 4 Feb 2025 12:04:51 +0000 Subject: [PATCH 23/25] Fix indent --- .github/workflows/mac.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 04ab1d723..9b6585e6a 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -10,7 +10,7 @@ on: jobs: build_mac_x64: runs-on: macos-13 - env: + env: MACOSX_DEPLOYMENT_TARGET: 12.0 steps: - uses: actions/checkout@v4 From 082a07d39bac9dcaa459dbd99642fd22a6405b55 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 16 Feb 2025 18:11:37 +0000 Subject: [PATCH 24/25] Fix -DBUILD_SHARED_LIBS=ON for FLAC --- external/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 33d5948c7..91c4c3620 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -859,7 +859,7 @@ if(ENABLE_CHANNELRX_REMOTETCPSINK) ExternalProject_Add(flac GIT_REPOSITORY https://github.com/xiph/flac.git PREFIX "${EXTERNAL_BUILD_LIBRARIES}/flac" - CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DINSTALL_MANPAGES=OFF -D=BUILD_SHARED_LIBS=ON -DWITH_FORTIFY_SOURCE=OFF -DWITH_STACK_PROTECTOR=PFF -DBUILD_PROGRAMS=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DWITH_OGG=OFF -DBUILD_DOCS=OFF + CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DINSTALL_MANPAGES=OFF -DBUILD_SHARED_LIBS=ON -DWITH_FORTIFY_SOURCE=OFF -DWITH_STACK_PROTECTOR=PFF -DBUILD_PROGRAMS=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DWITH_OGG=OFF -DBUILD_DOCS=OFF BUILD_BYPRODUCTS "${FLAC_LIBRARIES}" INSTALL_COMMAND "" TEST_COMMAND "" From c40da37fafa4a3b34ea801fffefd28c7281d61c3 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Thu, 27 Feb 2025 13:20:44 +0000 Subject: [PATCH 25/25] wdsp: Remove redundant code that causes stack overflow on Mac. For #2324. --- wdsp/emnr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wdsp/emnr.cpp b/wdsp/emnr.cpp index 27c656710..6e6660e3a 100644 --- a/wdsp/emnr.cpp +++ b/wdsp/emnr.cpp @@ -444,6 +444,7 @@ EMNR::G::G( std::copy(Calculus::GG.begin(), Calculus::GG.end(), GG.begin()); std::copy(Calculus::GGS.begin(), Calculus::GGS.end(), GGS.begin()); + /* Removed as redundant and causes a stack overflow on Mac - see #2324 // We keep this pretty useless part just in case... if ((fileb = fopen("calculus", "rb"))) { @@ -462,7 +463,7 @@ EMNR::G::G( std::copy(ggs.begin(), ggs.end(), GGS.begin()); } fclose(fileb); - } + }*/ } void EMNR::G::calc_gamma0()