From b65da2fd49e41b9a05c8e08132fb8f166fc62fe4 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Wed, 28 Sep 2022 15:55:50 +0200 Subject: [PATCH 1/3] work --- CMakeLists.txt | 5 + core/src/signal_path/source.cpp | 14 ++- core/src/signal_path/source.h | 10 ++ misc_modules/rigctl_client/CMakeLists.txt | 24 ++++ misc_modules/rigctl_client/src/main.cpp | 104 ++++++++++++++++++ .../rigctl_client/src/rigctl_client.h | 10 ++ 6 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 misc_modules/rigctl_client/CMakeLists.txt create mode 100644 misc_modules/rigctl_client/src/main.cpp create mode 100644 misc_modules/rigctl_client/src/rigctl_client.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b0455f1..bd929da2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ option(OPT_BUILD_WEATHER_SAT_DECODER "Build the HRPT decoder module (no dependen option(OPT_BUILD_DISCORD_PRESENCE "Build the Discord Rich Presence module" ON) option(OPT_BUILD_FREQUENCY_MANAGER "Build the Frequency Manager module" ON) option(OPT_BUILD_RECORDER "Audio and baseband recorder" ON) +option(OPT_BUILD_RIGCTL_CLIENT "Rigctl client to make SDR++ act as a panadapter" ON) option(OPT_BUILD_RIGCTL_SERVER "Rigctl backend for controlling SDR++ with software like gpredict" ON) option(OPT_BUILD_SCANNER "Frequency scanner" ON) option(OPT_BUILD_SCHEDULER "Build the scheduler" OFF) @@ -189,6 +190,10 @@ if (OPT_BUILD_RECORDER) add_subdirectory("misc_modules/recorder") endif (OPT_BUILD_RECORDER) +if (OPT_BUILD_RIGCTL_CLIENT) +add_subdirectory("misc_modules/rigctl_client") +endif (OPT_BUILD_RIGCTL_CLIENT) + if (OPT_BUILD_RIGCTL_SERVER) add_subdirectory("misc_modules/rigctl_server") endif (OPT_BUILD_RIGCTL_SERVER) diff --git a/core/src/signal_path/source.cpp b/core/src/signal_path/source.cpp index 6b297022..6e69f62d 100644 --- a/core/src/signal_path/source.cpp +++ b/core/src/signal_path/source.cpp @@ -84,11 +84,23 @@ void SourceManager::tune(double freq) { if (selectedHandler == NULL) { return; } - selectedHandler->tuneHandler(freq + tuneOffset, selectedHandler->ctx); + // TODO: No need to always retune the hardware in panadpter mode + selectedHandler->tuneHandler((tuneMode == TuningMode::NORMAL) ? (freq + tuneOffset) : ifFreq, selectedHandler->ctx); + onRetune.emit(freq); currentFreq = freq; } void SourceManager::setTuningOffset(double offset) { tuneOffset = offset; tune(currentFreq); +} + +void SourceManager::setTuningMode(TuningMode mode) { + tuneMode = mode; + tune(currentFreq); +} + +void SourceManager::setPanadpterIF(double freq) { + ifFreq = freq; + tune(currentFreq); } \ No newline at end of file diff --git a/core/src/signal_path/source.h b/core/src/signal_path/source.h index 887a0f7d..d6183e19 100644 --- a/core/src/signal_path/source.h +++ b/core/src/signal_path/source.h @@ -21,6 +21,11 @@ public: void* ctx; }; + enum TuningMode { + NORMAL, + PANADAPTER + }; + void registerSource(std::string name, SourceHandler* handler); void unregisterSource(std::string name); void selectSource(std::string name); @@ -29,12 +34,15 @@ public: void stop(); void tune(double freq); void setTuningOffset(double offset); + void setTuningMode(TuningMode mode); + void setPanadpterIF(double freq); std::vector getSourceNames(); Event onSourceRegistered; Event onSourceUnregister; Event onSourceUnregistered; + Event onRetune; private: std::map sources; @@ -42,5 +50,7 @@ private: SourceHandler* selectedHandler = NULL; double tuneOffset; double currentFreq; + double ifFreq = 0.0; + TuningMode tuneMode; dsp::stream nullSource; }; \ No newline at end of file diff --git a/misc_modules/rigctl_client/CMakeLists.txt b/misc_modules/rigctl_client/CMakeLists.txt new file mode 100644 index 00000000..bf75a300 --- /dev/null +++ b/misc_modules/rigctl_client/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.13) +project(rigctl_client) + +file(GLOB SRC "src/*.cpp") + +add_library(rigctl_client SHARED ${SRC}) +target_link_libraries(rigctl_client PRIVATE sdrpp_core) +set_target_properties(rigctl_client PROPERTIES PREFIX "") + +target_include_directories(rigctl_client PRIVATE "src/") +target_include_directories(rigctl_client PRIVATE "../recorder/src") +target_include_directories(rigctl_client PRIVATE "../../decoder_modules/meteor_demodulator/src") +target_include_directories(rigctl_client PRIVATE "../../decoder_modules/radio/src") + +if (MSVC) + target_compile_options(rigctl_client PRIVATE /O2 /Ob2 /std:c++17 /EHsc) +elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_compile_options(rigctl_client PRIVATE -O3 -std=c++17 -Wno-unused-command-line-argument -undefined dynamic_lookup) +else () + target_compile_options(rigctl_client PRIVATE -O3 -std=c++17) +endif () + +# Install directives +install(TARGETS rigctl_client DESTINATION lib/sdrpp/plugins) diff --git a/misc_modules/rigctl_client/src/main.cpp b/misc_modules/rigctl_client/src/main.cpp new file mode 100644 index 00000000..1ad44df3 --- /dev/null +++ b/misc_modules/rigctl_client/src/main.cpp @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define CONCAT(a, b) ((std::string(a) + b).c_str()) + +#define MAX_COMMAND_LENGTH 8192 + +SDRPP_MOD_INFO{ + /* Name: */ "rigctl_client", + /* Description: */ "My fancy new module", + /* Author: */ "Ryzerth", + /* Version: */ 0, 1, 0, + /* Max instances */ 1 +}; + +enum { + RECORDER_TYPE_RECORDER, + RECORDER_TYPE_METEOR_DEMODULATOR +}; + +ConfigManager config; + +class SigctlServerModule : public ModuleManager::Instance { +public: + SigctlServerModule(std::string name) { + this->name = name; + + _retuneHandler.ctx = this; + _retuneHandler.handler = retuneHandler; + + sigpath::sourceManager.onRetune.bindHandler(&_retuneHandler); + gui::menu.registerEntry(name, menuHandler, this, NULL); + } + + ~SigctlServerModule() { + gui::menu.removeEntry(name); + sigpath::sourceManager.onRetune.unbindHandler(&_retuneHandler); + } + + void postInit() { + + } + + void enable() { + enabled = true; + } + + void disable() { + enabled = false; + } + + bool isEnabled() { + return enabled; + } + +private: + static void menuHandler(void* ctx) { + SigctlServerModule* _this = (SigctlServerModule*)ctx; + float menuWidth = ImGui::GetContentRegionAvail().x; + + if (ImGui::Checkbox("Panadapter Mode", &_this->panMode)) { + sigpath::sourceManager.setPanadpterIF(8830000.0); + sigpath::sourceManager.setTuningMode(_this->panMode ? SourceManager::TuningMode::PANADAPTER : SourceManager::TuningMode::NORMAL); + } + } + + static void retuneHandler(double freq, void* ctx) { + spdlog::warn("PAN RETUNE: {0}", freq); + } + + std::string name; + bool enabled = true; + bool panMode = false; + + EventHandler _retuneHandler; +}; + +MOD_EXPORT void _INIT_() { + config.setPath(core::args["root"].s() + "/rigctl_client_config.json"); + config.load(json::object()); + config.enableAutoSave(); +} + +MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) { + return new SigctlServerModule(name); +} + +MOD_EXPORT void _DELETE_INSTANCE_(void* instance) { + delete (SigctlServerModule*)instance; +} + +MOD_EXPORT void _END_() { + config.disableAutoSave(); + config.save(); +} diff --git a/misc_modules/rigctl_client/src/rigctl_client.h b/misc_modules/rigctl_client/src/rigctl_client.h new file mode 100644 index 00000000..5a426395 --- /dev/null +++ b/misc_modules/rigctl_client/src/rigctl_client.h @@ -0,0 +1,10 @@ +#pragma once +#include + +class RigCTLClient { +public: + + +private: + +}; \ No newline at end of file From 52a4143cf5b094473952b71a8316e1912eab3444 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Wed, 28 Sep 2022 17:15:38 +0200 Subject: [PATCH 2/3] code cleanup and fixes --- core/src/core.cpp | 4 ++ core/src/signal_path/source.cpp | 2 +- misc_modules/rigctl_client/src/main.cpp | 67 ++++++++++++++++++++++--- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/core/src/core.cpp b/core/src/core.cpp index 58fe0e62..cb0fd371 100644 --- a/core/src/core.cpp +++ b/core/src/core.cpp @@ -195,6 +195,10 @@ int sdrpp_main(int argc, char* argv[]) { defConfig["moduleInstances"]["Frequency Manager"] = "frequency_manager"; defConfig["moduleInstances"]["Recorder"] = "recorder"; defConfig["moduleInstances"]["Rigctl Server"] = "rigctl_server"; + // defConfig["moduleInstances"]["Rigctl Client"] = "rigctl_client"; + // TODO: Enable rigctl_client when ready + // defConfig["moduleInstances"]["Scanner"] = "scanner"; + // TODO: Enable scanner when ready // Themes diff --git a/core/src/signal_path/source.cpp b/core/src/signal_path/source.cpp index 6e69f62d..428f0e49 100644 --- a/core/src/signal_path/source.cpp +++ b/core/src/signal_path/source.cpp @@ -85,7 +85,7 @@ void SourceManager::tune(double freq) { return; } // TODO: No need to always retune the hardware in panadpter mode - selectedHandler->tuneHandler((tuneMode == TuningMode::NORMAL) ? (freq + tuneOffset) : ifFreq, selectedHandler->ctx); + selectedHandler->tuneHandler(((tuneMode == TuningMode::NORMAL) ? freq : ifFreq) + tuneOffset, selectedHandler->ctx); onRetune.emit(freq); currentFreq = freq; } diff --git a/misc_modules/rigctl_client/src/main.cpp b/misc_modules/rigctl_client/src/main.cpp index 1ad44df3..3cd7c32a 100644 --- a/misc_modules/rigctl_client/src/main.cpp +++ b/misc_modules/rigctl_client/src/main.cpp @@ -34,16 +34,17 @@ public: SigctlServerModule(std::string name) { this->name = name; + strcpy(host, "127.0.0.1"); + _retuneHandler.ctx = this; _retuneHandler.handler = retuneHandler; - sigpath::sourceManager.onRetune.bindHandler(&_retuneHandler); gui::menu.registerEntry(name, menuHandler, this, NULL); } ~SigctlServerModule() { + stop(); gui::menu.removeEntry(name); - sigpath::sourceManager.onRetune.unbindHandler(&_retuneHandler); } void postInit() { @@ -62,14 +63,62 @@ public: return enabled; } + void start() { + std::lock_guard lck(mtx); + if (running) { return; } + + sigpath::sourceManager.setPanadpterIF(ifFreq); + sigpath::sourceManager.setTuningMode(SourceManager::TuningMode::PANADAPTER); + sigpath::sourceManager.onRetune.bindHandler(&_retuneHandler); + running = true; + } + + void stop() { + std::lock_guard lck(mtx); + if (!running) { return; } + + sigpath::sourceManager.onRetune.unbindHandler(&_retuneHandler); + sigpath::sourceManager.setTuningMode(SourceManager::TuningMode::NORMAL); + running = false; + } + private: static void menuHandler(void* ctx) { SigctlServerModule* _this = (SigctlServerModule*)ctx; float menuWidth = ImGui::GetContentRegionAvail().x; - if (ImGui::Checkbox("Panadapter Mode", &_this->panMode)) { - sigpath::sourceManager.setPanadpterIF(8830000.0); - sigpath::sourceManager.setTuningMode(_this->panMode ? SourceManager::TuningMode::PANADAPTER : SourceManager::TuningMode::NORMAL); + if (_this->running) { style::beginDisabled(); } + if (ImGui::InputText(CONCAT("##_rigctl_cli_host_", _this->name), _this->host, 1023)) { + config.acquire(); + config.conf[_this->name]["host"] = std::string(_this->host); + config.release(true); + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX()); + if (ImGui::InputInt(CONCAT("##_rigctl_cli_port_", _this->name), &_this->port, 0, 0)) { + config.acquire(); + config.conf[_this->name]["port"] = _this->port; + config.release(true); + } + if (_this->running) { style::endDisabled(); } + + ImGui::LeftLabel("IF Frequency"); + ImGui::FillWidth(); + if (ImGui::InputDouble(CONCAT("##_rigctl_if_freq_", _this->name), &_this->ifFreq, 100.0, 100000.0, "%.0f")) { + if (_this->running) { + sigpath::sourceManager.setPanadpterIF(_this->ifFreq); + } + config.acquire(); + config.conf[_this->name]["ifFreq"] = _this->ifFreq; + config.release(true); + } + + ImGui::FillWidth(); + if (_this->running && ImGui::Button(CONCAT("Stop##_rigctl_cli_stop_", _this->name), ImVec2(menuWidth, 0))) { + _this->stop(); + } + else if (!_this->running && ImGui::Button(CONCAT("Start##_rigctl_cli_stop_", _this->name), ImVec2(menuWidth, 0))) { + _this->start(); } } @@ -79,7 +128,13 @@ private: std::string name; bool enabled = true; - bool panMode = false; + bool running = false; + std::recursive_mutex mtx; + + char host[1024]; + int port = 4532; + + double ifFreq = 8830000.0; EventHandler _retuneHandler; }; From a85bae95274831d5117b3c911079102ebfde3ba7 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Tue, 11 Oct 2022 17:43:20 +0200 Subject: [PATCH 3/3] Update CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bd929da2..4cf394af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,7 @@ option(OPT_BUILD_WEATHER_SAT_DECODER "Build the HRPT decoder module (no dependen option(OPT_BUILD_DISCORD_PRESENCE "Build the Discord Rich Presence module" ON) option(OPT_BUILD_FREQUENCY_MANAGER "Build the Frequency Manager module" ON) option(OPT_BUILD_RECORDER "Audio and baseband recorder" ON) -option(OPT_BUILD_RIGCTL_CLIENT "Rigctl client to make SDR++ act as a panadapter" ON) +option(OPT_BUILD_RIGCTL_CLIENT "Rigctl client to make SDR++ act as a panadapter" OFF) option(OPT_BUILD_RIGCTL_SERVER "Rigctl backend for controlling SDR++ with software like gpredict" ON) option(OPT_BUILD_SCANNER "Frequency scanner" ON) option(OPT_BUILD_SCHEDULER "Build the scheduler" OFF)