33 Commits

Author SHA1 Message Date
d83da38d79 Added windows build script 2020-12-24 14:43:14 +01:00
b21f8abbd6 fixed missing module 2020-12-24 00:11:33 +01:00
e9aade4d0d fixed debian build again again 2020-12-23 23:39:34 +01:00
2bf2fff3d6 fixed debian build again 2020-12-23 23:34:56 +01:00
463a22fdfb fixed debian build 2 2020-12-23 23:20:28 +01:00
3175022b31 fixed debian build 2020-12-23 23:18:44 +01:00
504d910226 removed automated debian package build 2020-12-23 22:21:46 +01:00
c2769e1a72 fixed CI 2 2020-12-23 21:59:05 +01:00
7577253dbf fixed CI 2020-12-23 21:19:02 +01:00
e4c5b2dbd1 fixed directories 2020-12-23 21:10:24 +01:00
fafd76ff94 Added debian package build 2020-12-23 20:58:02 +01:00
e354d11820 Added debian package build 2020-12-23 20:57:41 +01:00
a3374c7eca fixed airspyhf module missing function 2020-12-23 20:22:20 +01:00
552b886cea fixed volk version in CI 2020-12-23 20:10:55 +01:00
ff9a19381b switch to more recent ubuntu version for CI 2020-12-23 20:09:08 +01:00
77aacc2e5d Fixed compiler version 2020-12-23 19:50:54 +01:00
6a1fa2c13b added more recent GCC version to CI 2020-12-23 19:44:34 +01:00
c3bb64bf6e Update cmake.yml 2020-12-23 19:39:14 +01:00
da68ab4ed0 Create cmake.yml 2020-12-23 19:36:12 +01:00
1aedf92bcd fixes to the rtl-tcp source 2020-12-23 19:23:47 +01:00
abcf484506 removed un-necessary directory 2020-12-23 00:12:52 +01:00
a93681a980 New system for band plans 2020-12-23 00:11:12 +01:00
a08758ea54 fixed directory bug on linux 2 2020-12-22 23:10:49 +01:00
0a0f5b8e8c fixed directory bug on linux 2020-12-22 23:04:46 +01:00
84f67a3ac1 updated readme about new directory system 2020-12-22 22:45:27 +01:00
22d18a9e58 new directory system on linux 2020-12-22 22:39:24 +01:00
d1a8425d43 Create FUNDING.yml 2020-12-22 21:42:16 +01:00
65d94f03e4 Fixed compile bugs 2020-12-22 21:23:49 +01:00
3a49041f27 other fix 2020-12-22 21:09:49 +01:00
eec2f7c4a0 fixed bug in spyserevr source 2020-12-22 20:44:49 +01:00
720df5ce89 Fixed build issues 2 2020-12-22 20:37:10 +01:00
d7cea16d4a Fixed build issues 2020-12-22 20:35:31 +01:00
d5c0fdd525 fixed linux build bug 2020-12-22 20:00:51 +01:00
48 changed files with 415 additions and 119 deletions

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
# These are supported funding model platforms
patreon: ryzerth

42
.github/workflows/cmake.yml vendored Normal file
View File

@ -0,0 +1,42 @@
name: CMake
on: [push]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: sudo apt install libfftw3-dev libglfw3-dev libglew-dev libvolk2-dev libsoapysdr-dev libairspyhf-dev libiio-dev libad9361-dev portaudio19-dev
- name: Create Build Environment
# Some projects don't allow in-source building, so create a separate build directory
# We'll use this as our working directory for all subsequent commands
run: cmake -E make_directory ${{runner.workspace}}/build
- name: Configure CMake
# Use a bash shell so we can use the same syntax for environment variable
# access regardless of the host operating system
shell: bash
working-directory: ${{runner.workspace}}/build
# Note the current convention is to use the -S and -B options here to specify source
# and build directories, but this is only available with CMake 3.13 and higher.
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
- name: Build
working-directory: ${{runner.workspace}}/build
shell: bash
# Execute the build. You can specify a specific target with "--target <NAME>"
run: cmake --build . --config $BUILD_TYPE

View File

@ -23,9 +23,9 @@ if (MSVC)
else (MSVC) else (MSVC)
find_package(PkgConfig) find_package(PkgConfig)
pkg_check_modules(SOAPY REQUIRED airspyhf) pkg_check_modules(LIBAIRSPYHF REQUIRED libairspyhf)
target_include_directories(airspyhf_source PUBLIC ${AIRSPYHF_INCLUDE_DIRS}) target_include_directories(airspyhf_source PUBLIC ${LIBAIRSPYHF_INCLUDE_DIRS})
target_link_directories(airspyhf_source PUBLIC ${AIRSPYHF_LIBRARY_DIRS}) target_link_directories(airspyhf_source PUBLIC ${LIBAIRSPYHF_LIBRARY_DIRS})
target_link_libraries(airspyhf_source PUBLIC ${AIRSPYHF_LIBRARIES}) target_link_libraries(airspyhf_source PUBLIC ${LIBAIRSPYHF_LIBRARIES})
endif (MSVC) endif (MSVC)

View File

@ -1,6 +1,6 @@
#include <imgui.h> #include <imgui.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <new_module.h> #include <module.h>
#include <gui/gui.h> #include <gui/gui.h>
#include <signal_path/signal_path.h> #include <signal_path/signal_path.h>
#include <core.h> #include <core.h>
@ -40,6 +40,8 @@ public:
refresh(); refresh();
selectFirst();
// config.aquire(); // config.aquire();
// std::string serString = config.conf["device"]; // std::string serString = config.conf["device"];
// config.release(); // config.release();
@ -129,9 +131,6 @@ public:
sampleRateListTxt += '\0'; sampleRateListTxt += '\0';
} }
blockSize = airspyhf_get_output_size(dev);
spdlog::info("AirspyHF block size {0}", blockSize);
srId = 0; srId = 0;
airspyhf_close(dev); airspyhf_close(dev);
@ -274,7 +273,6 @@ private:
std::string name; std::string name;
airspyhf_device_t* openDev; airspyhf_device_t* openDev;
bool enabled = true; bool enabled = true;
int blockSize = 0;
dsp::stream<dsp::complex_t> stream; dsp::stream<dsp::complex_t> stream;
double sampleRate; double sampleRate;
SourceManager::SourceHandler handler; SourceManager::SourceHandler handler;

View File

@ -14,3 +14,19 @@ include_directories("src/")
add_library(audio_sink SHARED ${SRC}) add_library(audio_sink SHARED ${SRC})
target_link_libraries(audio_sink PRIVATE sdrpp_core) target_link_libraries(audio_sink PRIVATE sdrpp_core)
set_target_properties(audio_sink PROPERTIES PREFIX "") set_target_properties(audio_sink PROPERTIES PREFIX "")
if (MSVC)
find_package(portaudio CONFIG REQUIRED)
target_link_libraries(sdrpp_core PUBLIC portaudio)
else (MSVC)
find_package(PkgConfig)
pkg_check_modules(PORTAUDIO REQUIRED portaudio-2.0)
target_include_directories(sdrpp_core PUBLIC ${PORTAUDIO_INCLUDE_DIRS})
target_link_directories(sdrpp_core PUBLIC ${PORTAUDIO_LIBRARY_DIRS})
target_link_libraries(sdrpp_core PUBLIC ${PORTAUDIO_LIBRARIES})
endif (MSVC)

View File

@ -1,5 +1,5 @@
#include <imgui.h> #include <imgui.h>
#include <new_module.h> #include <module.h>
#include <gui/gui.h> #include <gui/gui.h>
#include <signal_path/signal_path.h> #include <signal_path/signal_path.h>
#include <signal_path/sink.h> #include <signal_path/sink.h>

View File

@ -31,9 +31,6 @@ if (MSVC)
# Volk # Volk
target_link_libraries(sdrpp_core PUBLIC volk) target_link_libraries(sdrpp_core PUBLIC volk)
# SoapySDR
target_link_libraries(sdrpp_core PUBLIC SoapySDR)
# Glew # Glew
find_package(GLEW REQUIRED) find_package(GLEW REQUIRED)
target_link_libraries(sdrpp_core PUBLIC GLEW::GLEW) target_link_libraries(sdrpp_core PUBLIC GLEW::GLEW)
@ -46,12 +43,6 @@ if (MSVC)
find_package(FFTW3f CONFIG REQUIRED) find_package(FFTW3f CONFIG REQUIRED)
target_link_libraries(sdrpp_core PUBLIC FFTW3::fftw3f) target_link_libraries(sdrpp_core PUBLIC FFTW3::fftw3f)
# PortAudio
find_package(portaudio CONFIG REQUIRED)
target_link_libraries(sdrpp_core PUBLIC portaudio portaudio_static)
target_link_libraries(sdrpp_core PUBLIC volk)
else() else()
find_package(PkgConfig) find_package(PkgConfig)
find_package(OpenGL REQUIRED) find_package(OpenGL REQUIRED)
@ -60,14 +51,12 @@ else()
pkg_check_modules(FFTW3 REQUIRED fftw3f) pkg_check_modules(FFTW3 REQUIRED fftw3f)
pkg_check_modules(VOLK REQUIRED volk) pkg_check_modules(VOLK REQUIRED volk)
pkg_check_modules(GLFW3 REQUIRED glfw3) pkg_check_modules(GLFW3 REQUIRED glfw3)
pkg_check_modules(PORTAUDIO REQUIRED portaudio-2.0)
target_include_directories(sdrpp_core PUBLIC target_include_directories(sdrpp_core PUBLIC
${GLEW_INCLUDE_DIRS} ${GLEW_INCLUDE_DIRS}
${FFTW3_INCLUDE_DIRS} ${FFTW3_INCLUDE_DIRS}
${GLFW3_INCLUDE_DIRS} ${GLFW3_INCLUDE_DIRS}
${VOLK_INCLUDE_DIRS} ${VOLK_INCLUDE_DIRS}
${PORTAUDIO_INCLUDE_DIRS}
) )
target_link_directories(sdrpp_core PUBLIC target_link_directories(sdrpp_core PUBLIC
@ -75,16 +64,14 @@ else()
${FFTW3_LIBRARY_DIRS} ${FFTW3_LIBRARY_DIRS}
${GLFW3_LIBRARY_DIRS} ${GLFW3_LIBRARY_DIRS}
${VOLK_LIBRARY_DIRS} ${VOLK_LIBRARY_DIRS}
${PORTAUDIO_LIBRARY_DIRS}
) )
target_link_libraries(sdrpp_core PUBLIC target_link_libraries(sdrpp_core PUBLIC
${OPENGL_LIBRARIES} ${OPENGL_LIBRARIES}
${GLEW_STATIC_LIBRARIES} ${GLEW_LIBRARIES}
${FFTW3_STATIC_LIBRARIES} ${FFTW3_LIBRARIES}
${GLFW3_STATIC_LIBRARIES} ${GLFW3_LIBRARIES}
${VOLK_STATIC_LIBRARIES} ${VOLK_LIBRARIES}
${PORTAUDIO_STATIC_LIBRARIES}
) )
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")

View File

@ -17,6 +17,7 @@
#include <options.h> #include <options.h>
#include <duktape/duktape.h> #include <duktape/duktape.h>
#include <duktape/duk_console.h> #include <duktape/duk_console.h>
#include <filesystem>
#define STB_IMAGE_RESIZE_IMPLEMENTATION #define STB_IMAGE_RESIZE_IMPLEMENTATION
#include <stb_image_resize.h> #include <stb_image_resize.h>
@ -77,6 +78,20 @@ int sdrpp_main(int argc, char *argv[]) {
options::loadDefaults(); options::loadDefaults();
if (!options::parse(argc, argv)) { return -1; } if (!options::parse(argc, argv)) { return -1; }
// Check root directory
if (!std::filesystem::exists(options::opts.root)) {
spdlog::warn("Root directory {0} does not exist, creating it", options::opts.root);
if (!std::filesystem::create_directory(options::opts.root)) {
spdlog::error("Could not create root directory {0}", options::opts.root);
return -1;
}
}
if (!std::filesystem::is_directory(options::opts.root)) {
spdlog::error("{0} is not a directory", options::opts.root);
return -1;
}
// ======== DEFAULT CONFIG ======== // ======== DEFAULT CONFIG ========
json defConfig; json defConfig;
defConfig["bandColors"]["amateur"] = "#FF0000FF"; defConfig["bandColors"]["amateur"] = "#FF0000FF";
@ -103,12 +118,15 @@ int sdrpp_main(int argc, char *argv[]) {
}; };
defConfig["menuWidth"] = 300; defConfig["menuWidth"] = 300;
defConfig["min"] = -70.0; defConfig["min"] = -70.0;
defConfig["moduleInstances"]["Audio Sink"] = "audio_sink";
defConfig["moduleInstances"]["PlutoSDR Source"] = "plutosdr_source";
defConfig["moduleInstances"]["RTL-TCP Source"] = "rtl_tcp_source";
defConfig["moduleInstances"]["Radio"] = "radio"; defConfig["moduleInstances"]["Radio"] = "radio";
defConfig["moduleInstances"]["Recorder"] = "recorder"; defConfig["moduleInstances"]["Recorder"] = "recorder";
defConfig["moduleInstances"]["SoapySDR Source"] = "soapy_source"; defConfig["moduleInstances"]["SoapySDR Source"] = "soapy_source";
defConfig["moduleInstances"]["PlutoSDR Source"] = "plutosdr_source";
defConfig["moduleInstances"]["RTL-TCP Source"] = "rtl_tcp_source";
defConfig["moduleInstances"]["AirspyHF+ Source"] = "airspyhf_source";
defConfig["moduleInstances"]["Audio Sink"] = "audio_sink";
defConfig["modules"] = json::array(); defConfig["modules"] = json::array();
defConfig["offset"] = 0.0; defConfig["offset"] = 0.0;
defConfig["showWaterfall"] = true; defConfig["showWaterfall"] = true;
@ -117,6 +135,20 @@ int sdrpp_main(int argc, char *argv[]) {
defConfig["windowSize"]["h"] = 720; defConfig["windowSize"]["h"] = 720;
defConfig["windowSize"]["w"] = 1280; defConfig["windowSize"]["w"] = 1280;
defConfig["bandColors"]["broadcast"] = "#0000FFFF";
defConfig["bandColors"]["amateur"] = "#FF0000FF";
defConfig["bandColors"]["aviation"] = "#00FF00FF";
defConfig["bandColors"]["marine"] = "#00FFFFFF";
defConfig["bandColors"]["military"] = "#FFFF00FF";
#ifdef _WIN32
defConfig["modulesDirectory"] = "./modules";
defConfig["resourcesDirectory"] = "./res";
#else
defConfig["modulesDirectory"] = "/usr/lib/sdrpp/plugins";
defConfig["resourcesDirectory"] = "/usr/share/sdrpp";
#endif
// Load config // Load config
spdlog::info("Loading config"); spdlog::info("Loading config");
core::configManager.setPath(options::opts.root + "/config.json"); core::configManager.setPath(options::opts.root + "/config.json");
@ -138,6 +170,8 @@ int sdrpp_main(int argc, char *argv[]) {
int winWidth = core::configManager.conf["windowSize"]["w"]; int winWidth = core::configManager.conf["windowSize"]["w"];
int winHeight = core::configManager.conf["windowSize"]["h"]; int winHeight = core::configManager.conf["windowSize"]["h"];
maximized = core::configManager.conf["maximized"]; maximized = core::configManager.conf["maximized"];
std::string resDir = core::configManager.conf["resourcesDirectory"];
json bandColors = core::configManager.conf["bandColors"];
core::configManager.release(); core::configManager.release();
// Create window with graphics context // Create window with graphics context
@ -157,7 +191,7 @@ int sdrpp_main(int argc, char *argv[]) {
// Load app icon // Load app icon
GLFWimage icons[10]; GLFWimage icons[10];
icons[0].pixels = stbi_load(((std::string)(options::opts.root + "/res/icons/sdrpp.png")).c_str(), &icons[0].width, &icons[0].height, 0, 4); icons[0].pixels = stbi_load(((std::string)(resDir + "/icons/sdrpp.png")).c_str(), &icons[0].width, &icons[0].height, 0, 4);
icons[1].pixels = (unsigned char*)malloc(16 * 16 * 4); icons[1].width = icons[1].height = 16; icons[1].pixels = (unsigned char*)malloc(16 * 16 * 4); icons[1].width = icons[1].height = 16;
icons[2].pixels = (unsigned char*)malloc(24 * 24 * 4); icons[2].width = icons[2].height = 24; icons[2].pixels = (unsigned char*)malloc(24 * 24 * 4); icons[2].width = icons[2].height = 24;
icons[3].pixels = (unsigned char*)malloc(32 * 32 * 4); icons[3].width = icons[3].height = 32; icons[3].pixels = (unsigned char*)malloc(32 * 32 * 4); icons[3].width = icons[3].height = 32;
@ -198,21 +232,21 @@ int sdrpp_main(int argc, char *argv[]) {
ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 150"); ImGui_ImplOpenGL3_Init("#version 150");
style::setDarkStyle(); if (!style::setDarkStyle(resDir)) { return -1; }
LoadingScreen::setWindow(window); LoadingScreen::setWindow(window);
LoadingScreen::show("Loading icons"); LoadingScreen::show("Loading icons");
spdlog::info("Loading icons"); spdlog::info("Loading icons");
icons::load(); if (!icons::load(resDir)) { return -1; }
LoadingScreen::show("Loading band plans"); LoadingScreen::show("Loading band plans");
spdlog::info("Loading band plans"); spdlog::info("Loading band plans");
bandplan::loadFromDir(options::opts.root + "/bandplans"); bandplan::loadFromDir(resDir + "/bandplans");
LoadingScreen::show("Loading band plan colors"); LoadingScreen::show("Loading band plan colors");
spdlog::info("Loading band plans color table"); spdlog::info("Loading band plans color table");
bandplan::loadColorTable(options::opts.root + "/band_colors.json"); bandplan::loadColorTable(bandColors);
windowInit(); windowInit();

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <config.h> #include <config.h>
#include <new_module.h> #include <module.h>
#include <scripting.h> #include <scripting.h>
#include <new_module.h> #include <module.h>
namespace core { namespace core {
SDRPP_EXPORT ConfigManager configManager; SDRPP_EXPORT ConfigManager configManager;

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
#include <new_module.h> #include <module.h>
namespace sdrpp_credits { namespace sdrpp_credits {
SDRPP_EXPORT const char* contributors[]; SDRPP_EXPORT const char* contributors[];

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <dsp/block.h> #include <dsp/block.h>
#include <string.h>
#define RING_BUF_SZ 1000000 #define RING_BUF_SZ 1000000

View File

@ -33,19 +33,19 @@ namespace credits {
ImGui::Text("Contributors"); ImGui::Text("Contributors");
for (int i = 0; i < sdrpp_credits::contributorCount; i++) { for (int i = 0; i < sdrpp_credits::contributorCount; i++) {
ImGui::BulletText(sdrpp_credits::contributors[i]); ImGui::BulletText("%s", sdrpp_credits::contributors[i]);
} }
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text("Libraries"); ImGui::Text("Libraries");
for (int i = 0; i < sdrpp_credits::libraryCount; i++) { for (int i = 0; i < sdrpp_credits::libraryCount; i++) {
ImGui::BulletText(sdrpp_credits::libraries[i]); ImGui::BulletText("%s", sdrpp_credits::libraries[i]);
} }
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text("Patrons"); ImGui::Text("Patrons");
for (int i = 0; i < sdrpp_credits::patronCount; i++) { for (int i = 0; i < sdrpp_credits::patronCount; i++) {
ImGui::BulletText(sdrpp_credits::patrons[i]); ImGui::BulletText("%s", sdrpp_credits::patrons[i]);
} }
ImGui::Columns(1, "CreditColumnsEnd", true); ImGui::Columns(1, "CreditColumnsEnd", true);

View File

@ -44,19 +44,19 @@ namespace LoadingScreen {
ImGui::Text("Contributors"); ImGui::Text("Contributors");
for (int i = 0; i < sdrpp_credits::contributorCount; i++) { for (int i = 0; i < sdrpp_credits::contributorCount; i++) {
ImGui::BulletText(sdrpp_credits::contributors[i]); ImGui::BulletText("%s", sdrpp_credits::contributors[i]);
} }
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text("Libraries"); ImGui::Text("Libraries");
for (int i = 0; i < sdrpp_credits::libraryCount; i++) { for (int i = 0; i < sdrpp_credits::libraryCount; i++) {
ImGui::BulletText(sdrpp_credits::libraries[i]); ImGui::BulletText("%s", sdrpp_credits::libraries[i]);
} }
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text("Patrons"); ImGui::Text("Patrons");
for (int i = 0; i < sdrpp_credits::patronCount; i++) { for (int i = 0; i < sdrpp_credits::patronCount; i++) {
ImGui::BulletText(sdrpp_credits::patrons[i]); ImGui::BulletText("%s", sdrpp_credits::patrons[i]);
} }
ImGui::Columns(1, "CreditColumnsEnd", true); ImGui::Columns(1, "CreditColumnsEnd", true);
@ -64,7 +64,7 @@ namespace LoadingScreen {
ImGui::Spacing(); ImGui::Spacing();
ImGui::Spacing(); ImGui::Spacing();
ImGui::Spacing(); ImGui::Spacing();
ImGui::Text(msg.c_str()); ImGui::Text("%s", msg.c_str());
ImGui::EndPopup(); ImGui::EndPopup();
ImGui::PopStyleVar(1); ImGui::PopStyleVar(1);

View File

@ -3,7 +3,7 @@
#include <gui/widgets/frequency_select.h> #include <gui/widgets/frequency_select.h>
#include <gui/widgets/menu.h> #include <gui/widgets/menu.h>
#include <gui/dialogs/loading_screen.h> #include <gui/dialogs/loading_screen.h>
#include <new_module.h> #include <module.h>
namespace gui { namespace gui {
SDRPP_EXPORT ImGui::WaterFall waterfall; SDRPP_EXPORT ImGui::WaterFall waterfall;

View File

@ -6,6 +6,8 @@
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include <imgui/stb_image.h> #include <imgui/stb_image.h>
#include <filesystem>
#include <spdlog/spdlog.h>
namespace icons { namespace icons {
ImTextureID LOGO; ImTextureID LOGO;
@ -31,14 +33,21 @@ namespace icons {
return texId; return texId;
} }
void load() { bool load(std::string resDir) {
LOGO = (ImTextureID)(uintptr_t)loadTexture(options::opts.root + "/res/icons/sdrpp.png"); if (!std::filesystem::is_directory(resDir)) {
PLAY = (ImTextureID)(uintptr_t)loadTexture(options::opts.root + "/res/icons/play.png"); spdlog::error("Inavlid resource directory: {0}", resDir);
STOP = (ImTextureID)(uintptr_t)loadTexture(options::opts.root + "/res/icons/stop.png"); return false;
MENU = (ImTextureID)(uintptr_t)loadTexture(options::opts.root + "/res/icons/menu.png"); }
MUTED = (ImTextureID)(uintptr_t)loadTexture(options::opts.root + "/res/icons/muted.png");
UNMUTED = (ImTextureID)(uintptr_t)loadTexture(options::opts.root + "/res/icons/unmuted.png"); LOGO = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/sdrpp.png");
NORMAL_TUNING = (ImTextureID)(uintptr_t)loadTexture(options::opts.root + "/res/icons/normal_tuning.png"); PLAY = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/play.png");
CENTER_TUNING = (ImTextureID)(uintptr_t)loadTexture(options::opts.root + "/res/icons/center_tuning.png"); STOP = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/stop.png");
MENU = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/menu.png");
MUTED = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/muted.png");
UNMUTED = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/unmuted.png");
NORMAL_TUNING = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/normal_tuning.png");
CENTER_TUNING = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/center_tuning.png");
return true;
} }
} }

View File

@ -14,5 +14,5 @@ namespace icons {
extern ImTextureID CENTER_TUNING; extern ImTextureID CENTER_TUNING;
GLuint loadTexture(std::string path); GLuint loadTexture(std::string path);
void load(); bool load(std::string resDir);
} }

View File

@ -120,6 +120,7 @@ void windowInit() {
core::configManager.aquire(); core::configManager.aquire();
gui::menu.order = core::configManager.conf["menuOrder"].get<std::vector<std::string>>(); gui::menu.order = core::configManager.conf["menuOrder"].get<std::vector<std::string>>();
std::string modulesDir = core::configManager.conf["modulesDirectory"];
core::configManager.release(); core::configManager.release();
gui::menu.registerEntry("Source", sourecmenu::draw, NULL); gui::menu.registerEntry("Source", sourecmenu::draw, NULL);
@ -144,8 +145,8 @@ void windowInit() {
spdlog::info("Loading modules"); spdlog::info("Loading modules");
// Load modules from /module directory // Load modules from /module directory
if (std::filesystem::is_directory(options::opts.root + "/modules")) { if (std::filesystem::is_directory(modulesDir)) {
for (const auto & file : std::filesystem::directory_iterator(options::opts.root + "/modules")) { for (const auto & file : std::filesystem::directory_iterator(modulesDir)) {
std::string path = file.path().generic_string(); std::string path = file.path().generic_string();
if (file.path().extension().generic_string() != SDRPP_MOD_EXTENTSION) { if (file.path().extension().generic_string() != SDRPP_MOD_EXTENTSION) {
continue; continue;
@ -157,7 +158,7 @@ void windowInit() {
} }
} }
else { else {
spdlog::warn("Module directory {0} does not exist, not loading modules from directory"); spdlog::warn("Module directory {0} does not exist, not loading modules from directory", modulesDir);
} }
// Read module config // Read module config
@ -610,3 +611,7 @@ void drawWindow() {
void setViewBandwidthSlider(float bandwidth) { void setViewBandwidthSlider(float bandwidth) {
bw = bandwidth; bw = bandwidth;
} }
bool sdrIsRunning() {
return playing;
}

View File

@ -6,3 +6,4 @@
void windowInit(); void windowInit();
void drawWindow(); void drawWindow();
void setViewBandwidthSlider(float bandwidth); void setViewBandwidthSlider(float bandwidth);
bool sdrIsRunning();

View File

@ -2,6 +2,8 @@
#include <imgui.h> #include <imgui.h>
#include <gui/gui.h> #include <gui/gui.h>
#include <core.h> #include <core.h>
#include <gui/main_window.h>
#include <gui/style.h>
#include <signal_path/signal_path.h> #include <signal_path/signal_path.h>
namespace sourecmenu { namespace sourecmenu {
@ -34,6 +36,8 @@ namespace sourecmenu {
} }
float itemWidth = ImGui::GetContentRegionAvailWidth(); float itemWidth = ImGui::GetContentRegionAvailWidth();
if (sdrIsRunning()) { style::beginDisabled(); }
ImGui::SetNextItemWidth(itemWidth); ImGui::SetNextItemWidth(itemWidth);
if (ImGui::Combo("##source", &sourceId, items.c_str())) { if (ImGui::Combo("##source", &sourceId, items.c_str())) {
sigpath::sourceManager.selectSource(sigpath::sourceManager.sourceNames[sourceId]); sigpath::sourceManager.selectSource(sigpath::sourceManager.sourceNames[sourceId]);
@ -42,7 +46,10 @@ namespace sourecmenu {
core::configManager.release(true); core::configManager.release(true);
} }
if (sdrIsRunning()) { style::endDisabled(); }
sigpath::sourceManager.showSelectedMenu(); sigpath::sourceManager.showSelectedMenu();
ImGui::SetNextItemWidth(itemWidth - ImGui::CalcTextSize("Offset (Hz)").x - 10); ImGui::SetNextItemWidth(itemWidth - ImGui::CalcTextSize("Offset (Hz)").x - 10);
if (ImGui::InputDouble("Offset (Hz)##freq_offset", &freqOffset, 1.0, 100.0)) { if (ImGui::InputDouble("Offset (Hz)##freq_offset", &freqOffset, 1.0, 100.0)) {
sigpath::sourceManager.setTuningOffset(freqOffset); sigpath::sourceManager.setTuningOffset(freqOffset);

View File

@ -3,13 +3,20 @@
#include <imgui_internal.h> #include <imgui_internal.h>
#include <config.h> #include <config.h>
#include <options.h> #include <options.h>
#include <spdlog/spdlog.h>
#include <filesystem>
namespace style { namespace style {
ImFont* baseFont; ImFont* baseFont;
ImFont* bigFont; ImFont* bigFont;
ImFont* hugeFont; ImFont* hugeFont;
void setDefaultStyle() { bool setDefaultStyle(std::string resDir) {
if (!std::filesystem::is_directory(resDir)) {
spdlog::error("Inavlid resource directory: {0}", resDir);
return false;
}
ImGui::GetStyle().WindowRounding = 0.0f; ImGui::GetStyle().WindowRounding = 0.0f;
ImGui::GetStyle().ChildRounding = 0.0f; ImGui::GetStyle().ChildRounding = 0.0f;
ImGui::GetStyle().FrameRounding = 0.0f; ImGui::GetStyle().FrameRounding = 0.0f;
@ -17,19 +24,26 @@ namespace style {
ImGui::GetStyle().PopupRounding = 0.0f; ImGui::GetStyle().PopupRounding = 0.0f;
ImGui::GetStyle().ScrollbarRounding = 0.0f; ImGui::GetStyle().ScrollbarRounding = 0.0f;
baseFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(options::opts.root + "/res/fonts/Roboto-Medium.ttf")).c_str(), 16.0f); baseFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 16.0f);
bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(options::opts.root + "/res/fonts/Roboto-Medium.ttf")).c_str(), 42.0f); bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 42.0f);
hugeFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(options::opts.root + "/res/fonts/Roboto-Medium.ttf")).c_str(), 128.0f); hugeFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 128.0f);
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
//ImGui::StyleColorsLight(); //ImGui::StyleColorsLight();
return true;
} }
void testtt() { void testtt() {
ImGui::StyleColorsLight(); ImGui::StyleColorsLight();
} }
void setDarkStyle() { bool setDarkStyle(std::string resDir) {
if (!std::filesystem::is_directory(resDir)) {
spdlog::error("Inavlid resource directory: {0}", resDir);
return false;
}
ImGui::GetStyle().WindowRounding = 0.0f; ImGui::GetStyle().WindowRounding = 0.0f;
ImGui::GetStyle().ChildRounding = 0.0f; ImGui::GetStyle().ChildRounding = 0.0f;
ImGui::GetStyle().FrameRounding = 0.0f; ImGui::GetStyle().FrameRounding = 0.0f;
@ -37,9 +51,9 @@ namespace style {
ImGui::GetStyle().PopupRounding = 0.0f; ImGui::GetStyle().PopupRounding = 0.0f;
ImGui::GetStyle().ScrollbarRounding = 0.0f; ImGui::GetStyle().ScrollbarRounding = 0.0f;
baseFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(options::opts.root + "/res/fonts/Roboto-Medium.ttf")).c_str(), 16.0f); baseFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 16.0f);
bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(options::opts.root + "/res/fonts/Roboto-Medium.ttf")).c_str(), 42.0f); bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 42.0f);
hugeFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(options::opts.root + "/res/fonts/Roboto-Medium.ttf")).c_str(), 128.0f); hugeFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 128.0f);
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@ -89,6 +103,8 @@ namespace style {
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_NavHighlight] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); colors[ImGuiCol_NavHighlight] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
return true;
} }
void beginDisabled() { void beginDisabled() {

View File

@ -1,13 +1,14 @@
#pragma once #pragma once
#include <imgui.h> #include <imgui.h>
#include <string>
namespace style { namespace style {
extern ImFont* baseFont; extern ImFont* baseFont;
extern ImFont* bigFont; extern ImFont* bigFont;
extern ImFont* hugeFont; extern ImFont* hugeFont;
void setDefaultStyle(); bool setDefaultStyle(std::string resDir);
void setDarkStyle(); bool setDarkStyle(std::string resDir);
void beginDisabled(); void beginDisabled();
void endDisabled(); void endDisabled();
void testtt(); void testtt();

View File

@ -108,20 +108,7 @@ namespace bandplan {
} }
} }
void loadColorTable(std::string path) { void loadColorTable(json table) {
if (!std::filesystem::exists(path)) { colorTable = table.get<std::map<std::string, BandPlanColor_t>>();
spdlog::error("Band Plan Color Table file does not exist");
return;
}
if (!std::filesystem::is_regular_file(path)) {
spdlog::error("Band Plan Color Table file isn't a file...");
return;
}
std::ifstream file(path.c_str());
json data;
file >> data;
file.close();
colorTable = data.get<std::map<std::string, BandPlanColor_t>>();
} }
}; };

View File

@ -38,7 +38,7 @@ namespace bandplan {
void loadBandPlan(std::string path); void loadBandPlan(std::string path);
void loadFromDir(std::string path); void loadFromDir(std::string path);
void loadColorTable(std::string path); void loadColorTable(json table);
extern std::map<std::string, BandPlan_t> bandplans; extern std::map<std::string, BandPlan_t> bandplans;
extern std::vector<std::string> bandplanNames; extern std::vector<std::string> bandplanNames;

View File

@ -2,7 +2,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#include <new_module.h> #include <module.h>
class Menu { class Menu {
public: public:

View File

@ -1,4 +1,4 @@
#include <new_module.h> #include <module.h>
#include <filesystem> #include <filesystem>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>

View File

@ -1,5 +1,6 @@
#include <options.h> #include <options.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <stdlib.h>
namespace options { namespace options {
CMDLineOptions opts; CMDLineOptions opts;
@ -8,7 +9,8 @@ namespace options {
#ifdef _WIN32 #ifdef _WIN32
opts.root = "."; opts.root = ".";
#else #else
opts.root = "~/.sdrpp/"; std::string homedir = getenv("HOME");
opts.root = homedir + "/.config/sdrpp";
#endif #endif
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <string> #include <string>
#include <new_module.h> #include <module.h>
namespace options { namespace options {
struct CMDLineOptions { struct CMDLineOptions {

View File

@ -3,7 +3,7 @@
#include <signal_path/vfo_manager.h> #include <signal_path/vfo_manager.h>
#include <signal_path/source.h> #include <signal_path/source.h>
#include <signal_path/sink.h> #include <signal_path/sink.h>
#include <new_module.h> #include <module.h>
namespace sigpath { namespace sigpath {
SDRPP_EXPORT SignalPath signalPath; SDRPP_EXPORT SignalPath signalPath;

View File

@ -1,3 +1,3 @@
#pragma once #pragma once
#define VERSION_STR "0.2.5_alpha" #define VERSION_STR "0.2.5_beta"

48
make_debian_package.sh Normal file
View File

@ -0,0 +1,48 @@
#!/bin/sh
# Create directory structure
echo Create directory structure
mkdir sdrpp_debian_amd64
mkdir sdrpp_debian_amd64/DEBIAN
mkdir sdrpp_debian_amd64/usr
mkdir sdrpp_debian_amd64/usr/bin
mkdir sdrpp_debian_amd64/usr/share
mkdir sdrpp_debian_amd64/usr/share/sdrpp
mkdir sdrpp_debian_amd64/usr/lib
mkdir sdrpp_debian_amd64/usr/lib/sdrpp
mkdir sdrpp_debian_amd64/usr/lib/sdrpp/plugins
# Create package info
echo Create package info
echo Package: sdrpp >> sdrpp_debian_amd64/DEBIAN/control
echo Version: 0.2.5 >> sdrpp_debian_amd64/DEBIAN/control
echo Maintainer: Ryzerth >> sdrpp_debian_amd64/DEBIAN/control
echo Architecture: all >> sdrpp_debian_amd64/DEBIAN/control
echo Description: Bloat-free SDR receiver software >> sdrpp_debian_amd64/DEBIAN/control
# Copy core files
echo Copy core files
cp $1/sdrpp sdrpp_debian_amd64/usr/bin/
cp $1/libsdrpp_core.so sdrpp_debian_amd64/usr/lib/
# Copy reasources
echo Copy reasources
cp -r root/res/* sdrpp_debian_amd64/usr/share/sdrpp/
# Copy module
echo Copy modules
cp $1/radio/radio.so sdrpp_debian_amd64/usr/lib/sdrpp/plugins/
cp $1/recorder/recorder.so sdrpp_debian_amd64/usr/lib/sdrpp/plugins/
cp $1/airspyhf_source/airspyhf_source.so sdrpp_debian_amd64/usr/lib/sdrpp/plugins/
cp $1/plutosdr_source/plutosdr_source.so sdrpp_debian_amd64/usr/lib/sdrpp/plugins/
cp $1/rtl_tcp_source/rtl_tcp_source.so sdrpp_debian_amd64/usr/lib/sdrpp/plugins/
cp $1/soapy_source/soapy_source.so sdrpp_debian_amd64/usr/lib/sdrpp/plugins/
cp $1/audio_sink/audio_sink.so sdrpp_debian_amd64/usr/lib/sdrpp/plugins/
# Create package
echo Create packagesudo
dpkg-deb --build sdrpp_debian_amd64
# Cleanup
echo Cleanup
rm -rf sdrpp_debian_amd64

31
make_windows_package.ps1 Normal file
View File

@ -0,0 +1,31 @@
mkdir sdrpp_windows_x64
# Copy root
cp -Recurse root/* sdrpp_windows_x64/
# Copy core
cp build/Release/* sdrpp_windows_x64/
cp 'C:/Program Files/PothosSDR/bin/volk.dll' sdrpp_windows_x64/
# Copy modules
cp build/radio/Release/radio.dll sdrpp_windows_x64/modules/
cp build/recorder/Release/recorder.dll sdrpp_windows_x64/modules/
cp build/airspyhf_source/Release/airspyhf_source.dll sdrpp_windows_x64/modules/
cp 'C:/Program Files/PothosSDR/bin/airspyhf.dll' sdrpp_windows_x64/
cp build/plutosdr_source/Release/plutosdr_source.dll sdrpp_windows_x64/modules/
cp 'C:/Program Files/PothosSDR/bin/libiio.dll' sdrpp_windows_x64/
cp 'C:/Program Files/PothosSDR/bin/libad9361.dll' sdrpp_windows_x64/
cp build/rtl_tcp_source/Release/rtl_tcp_source.dll sdrpp_windows_x64/modules/
cp build/soapy_source/Release/soapy_source.dll sdrpp_windows_x64/modules/
cp build/audio_sink/Release/audio_sink.dll sdrpp_windows_x64/modules/
cp build/audio_sink/Release/portaudio.dll sdrpp_windows_x64/
Compress-Archive -Path sdrpp_windows_x64/ -DestinationPath sdrpp_windows_x64.zip
rm -Force -Recurse sdrpp_windows_x64

View File

@ -25,8 +25,8 @@ if (MSVC)
else (MSVC) else (MSVC)
find_package(PkgConfig) find_package(PkgConfig)
pkg_check_modules(SOAPY REQUIRED libiio) pkg_check_modules(LIBIIO REQUIRED libiio)
pkg_check_modules(SOAPY REQUIRED libad9361) pkg_check_modules(LIBAD9361 REQUIRED libad9361)
target_include_directories(plutosdr_source PUBLIC ${LIBIIO_INCLUDE_DIRS}) target_include_directories(plutosdr_source PUBLIC ${LIBIIO_INCLUDE_DIRS})
target_link_directories(plutosdr_source PUBLIC ${LIBIIO_LIBRARY_DIRS}) target_link_directories(plutosdr_source PUBLIC ${LIBIIO_LIBRARY_DIRS})

View File

@ -1,6 +1,6 @@
#include <imgui.h> #include <imgui.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <new_module.h> #include <module.h>
#include <gui/gui.h> #include <gui/gui.h>
#include <signal_path/signal_path.h> #include <signal_path/signal_path.h>
#include <core.h> #include <core.h>

View File

@ -5,7 +5,7 @@
#include <gui/style.h> #include <gui/style.h>
#include <signal_path/signal_path.h> #include <signal_path/signal_path.h>
#include <radio_demod.h> #include <radio_demod.h>
#include <new_module.h> #include <module.h>
#include <wfm_demod.h> #include <wfm_demod.h>
#include <fm_demod.h> #include <fm_demod.h>
#include <am_demod.h> #include <am_demod.h>

View File

@ -3,6 +3,8 @@
![Screenshot](https://i.imgur.com/WejsiFN.png) ![Screenshot](https://i.imgur.com/WejsiFN.png)
SDR++ is a cross-platform and open source SDR software with the aim of being bloat free and simple to use. SDR++ is a cross-platform and open source SDR software with the aim of being bloat free and simple to use.
![CMake](https://github.com/AlexandreRouma/SDRPlusPlus/workflows/CMake/badge.svg)
* [Patreon](https://patreon.com/ryzerth) * [Patreon](https://patreon.com/ryzerth)
* [Discord Server](https://discord.gg/aFgWjyD) * [Discord Server](https://discord.gg/aFgWjyD)
@ -79,6 +81,15 @@ You will first need to edit the `root_dev/config` file to point to the modules t
... ...
``` ```
You also need to change the location of the resource and module directories, for development, I recommend:
```json
...
"modulesDirectory": "../root_dev/modules",
...
"resourcesDirectory": "../root_dev/res",
...
```
Remember that these paths will be relative to the run directory. Remember that these paths will be relative to the run directory.
Off cours, remember to add entries for all modules that were built and that you wish to use. Off cours, remember to add entries for all modules that were built and that you wish to use.
@ -127,6 +138,8 @@ Next install dependencies based on the modules you wish to build:
* plutosdr_source: libiio, libad9361 * plutosdr_source: libiio, libad9361
* audio_sink: portaudio * audio_sink: portaudio
Note: make sure you're using GCC 8 or later as older versions do not have `std::filesystem` built-in.
## Building ## Building
replace `<N>` with the number of threads you wish to use to build replace `<N>` with the number of threads you wish to use to build
```sh ```sh
@ -144,7 +157,12 @@ sh ./create_root.sh
## Running for development ## Running for development
If you wish to install SDR++, skip to the next step If you wish to install SDR++, skip to the next step
You will first need to edit the `root_dev/config` file to point to the modules that were built. Here us a sample if what it would look like: First run SDR++ from the build directory to generate a default config file
```
./sdrpp -r ../root_dev/
```
Then, you need to edit the `root_dev/config` file to point to the modules that were built. Here us a sample if what it would look like:
```json ```json
... ...
@ -158,6 +176,15 @@ You will first need to edit the `root_dev/config` file to point to the modules t
... ...
``` ```
You also need to change the location of the resource and module directories, for development, I recommend:
```json
...
"modulesDirectory": "../root_dev/modules",
...
"resourcesDirectory": "../root_dev/res",
...
```
Remember that these paths will be relative to the run directory. Remember that these paths will be relative to the run directory.
Off cours, remember to add entries for all modules that were built and that you wish to use. Off cours, remember to add entries for all modules that were built and that you wish to use.

View File

@ -1,5 +1,5 @@
#include <imgui.h> #include <imgui.h>
#include <new_module.h> #include <module.h>
#include <watcher.h> #include <watcher.h>
#include <wav.h> #include <wav.h>
#include <dsp/types.h> #include <dsp/types.h>
@ -310,6 +310,14 @@ MOD_EXPORT void _INIT_() {
config.setPath(options::opts.root + "/recorder_config.json"); config.setPath(options::opts.root + "/recorder_config.json");
config.load(def); config.load(def);
config.enableAutoSave(); config.enableAutoSave();
// Create default recording directory
if (!std::filesystem::exists(options::opts.root + "/recordings")) {
spdlog::warn("Recordings directory does not exist, creating it");
if (!std::filesystem::create_directory(options::opts.root + "/recordings")) {
spdlog::error("Could not create recordings directory");
}
}
} }
MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) { MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) {

View File

@ -1,7 +0,0 @@
{
"broadcast": "#0000FFFF",
"amateur": "#FF0000FF",
"aviation": "#00FF00FF",
"marine": "#00FFFFFF",
"military": "#FFFF00FF"
}

View File

@ -1,10 +1,11 @@
#include <rtltcp_client.h> #include <rtltcp_client.h>
#include <imgui.h> #include <imgui.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <new_module.h> #include <module.h>
#include <gui/gui.h> #include <gui/gui.h>
#include <signal_path/signal_path.h> #include <signal_path/signal_path.h>
#include <core.h> #include <core.h>
#include <options.h>
#include <gui/style.h> #include <gui/style.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str()) #define CONCAT(a, b) ((std::string(a) + b).c_str())
@ -17,6 +18,34 @@ SDRPP_MOD_INFO {
/* Max instances */ 1 /* Max instances */ 1
}; };
ConfigManager config;
const double sampleRates[] = {
250000,
1024000,
1536000,
1792000,
1920000,
2048000,
2160000,
2560000,
2880000,
3200000
};
const char* sampleRatesTxt[] = {
"250KHz",
"1.024MHz",
"1.536MHz",
"1.792MHz",
"1.92MHz",
"2.048MHz",
"2.16MHz",
"2.56MHz",
"2.88MHz",
"3.2MHz"
};
class RTLTCPSourceModule : public ModuleManager::Instance { class RTLTCPSourceModule : public ModuleManager::Instance {
public: public:
RTLTCPSourceModule(std::string name) { RTLTCPSourceModule(std::string name) {
@ -24,6 +53,24 @@ public:
sampleRate = 2560000.0; sampleRate = 2560000.0;
int srCount = sizeof(sampleRatesTxt) / sizeof(char*);
for (int i = 0; i < srCount; i++) {
srTxt += sampleRatesTxt[i];
srTxt += '\0';
}
srId = 7;
config.aquire();
std::string hostStr = config.conf["host"];
port = config.conf["port"];
directSamplingMode = config.conf["directSamplingMode"];
rtlAGC = config.conf["rtlAGC"];
tunerAGC = config.conf["tunerAGC"];
gain = config.conf["gainIndex"];
hostStr = hostStr.substr(0, 1023);
strcpy(ip, hostStr.c_str());
config.release();
handler.ctx = this; handler.ctx = this;
handler.selectHandler = menuSelected; handler.selectHandler = menuSelected;
handler.deselectHandler = menuDeselected; handler.deselectHandler = menuDeselected;
@ -72,12 +119,13 @@ private:
spdlog::error("Could not connect to {0}:{1}", _this->ip, _this->port); spdlog::error("Could not connect to {0}:{1}", _this->ip, _this->port);
return; return;
} }
spdlog::warn("Setting sample rate to {0}", _this->sampleRate);
_this->client.setFrequency(_this->freq); _this->client.setFrequency(_this->freq);
_this->client.setSampleRate(_this->sampleRate); _this->client.setSampleRate(_this->sampleRate);
_this->client.setGainIndex(_this->gain);
_this->client.setGainMode(!_this->tunerAGC); _this->client.setGainMode(!_this->tunerAGC);
_this->client.setDirectSampling(_this->directSamplingMode); _this->client.setDirectSampling(_this->directSamplingMode);
_this->client.setAGCMode(_this->rtlAGC); _this->client.setAGCMode(_this->rtlAGC);
_this->client.setGainIndex(_this->gain);
_this->running = true; _this->running = true;
_this->workerThread = std::thread(worker, _this); _this->workerThread = std::thread(worker, _this);
spdlog::info("RTLTCPSourceModule '{0}': Start!", _this->name); spdlog::info("RTLTCPSourceModule '{0}': Start!", _this->name);
@ -110,22 +158,36 @@ private:
float menuWidth = ImGui::GetContentRegionAvailWidth(); float menuWidth = ImGui::GetContentRegionAvailWidth();
float portWidth = ImGui::CalcTextSize("00000").x + 20; float portWidth = ImGui::CalcTextSize("00000").x + 20;
if (_this->running) { style::beginDisabled(); }
ImGui::SetNextItemWidth(menuWidth - portWidth); ImGui::SetNextItemWidth(menuWidth - portWidth);
ImGui::InputText(CONCAT("##_ip_select_", _this->name), _this->ip, 1024); ImGui::InputText(CONCAT("##_ip_select_", _this->name), _this->ip, 1024);
ImGui::SameLine(); ImGui::SameLine();
ImGui::SetNextItemWidth(portWidth); ImGui::SetNextItemWidth(portWidth);
ImGui::InputInt(CONCAT("##_port_select_", _this->name), &_this->port, 0); ImGui::InputInt(CONCAT("##_port_select_", _this->name), &_this->port, 0);
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo(CONCAT("##_rtltcp_sr_", _this->name), &_this->srId, _this->srTxt.c_str())) {
_this->sampleRate = sampleRates[_this->srId];
core::setInputSampleRate(_this->sampleRate);
}
if (_this->running) { style::endDisabled(); }
ImGui::SetNextItemWidth(ImGui::CalcTextSize("OOOOOOOOOO").x); ImGui::SetNextItemWidth(ImGui::CalcTextSize("OOOOOOOOOO").x);
if (ImGui::Combo("Direct sampling", &_this->directSamplingMode, "Disabled\0I branch\0Q branch\0")) { if (ImGui::Combo(CONCAT("Direct Sampling##_rtltcp_ds_", _this->name), &_this->directSamplingMode, "Disabled\0I branch\0Q branch\0")) {
if (_this->running) { if (_this->running) {
_this->client.setDirectSampling(_this->directSamplingMode); _this->client.setDirectSampling(_this->directSamplingMode);
_this->client.setGainIndex(_this->gain);
} }
} }
if (ImGui::Checkbox("RTL AGC", &_this->rtlAGC)) { if (ImGui::Checkbox("RTL AGC", &_this->rtlAGC)) {
if (_this->running) { if (_this->running) {
_this->client.setAGCMode(_this->rtlAGC); _this->client.setAGCMode(_this->rtlAGC);
if (!_this->rtlAGC) {
_this->client.setGainIndex(_this->gain);
}
} }
} }
@ -182,10 +244,22 @@ private:
bool rtlAGC = false; bool rtlAGC = false;
bool tunerAGC = false; bool tunerAGC = false;
int directSamplingMode = 0; int directSamplingMode = 0;
int srId = 0;
std::string srTxt = "";
}; };
MOD_EXPORT void _INIT_() { MOD_EXPORT void _INIT_() {
// Do your one time init here config.setPath(options::opts.root + "/rtl_tcp_config.json");
json defConf;
defConf["host"] = "localhost";
defConf["port"] = 1234;
defConf["directSamplingMode"] = 0;
defConf["rtlAGC"] = false;
defConf["tunerAGC"] = false;
defConf["gainIndex"] = 0;
config.load(defConf);
config.enableAutoSave();
} }
MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) { MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) {
@ -197,5 +271,6 @@ MOD_EXPORT void _DELETE_INSTANCE_(ModuleManager::Instance* instance) {
} }
MOD_EXPORT void _END_() { MOD_EXPORT void _END_() {
// Do your one shutdown here config.disableAutoSave();
config.save();
} }

View File

@ -43,6 +43,9 @@ public:
struct addrinfo *ptr = NULL; struct addrinfo *ptr = NULL;
struct addrinfo hints; struct addrinfo hints;
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
ZeroMemory( &hints, sizeof(hints) ); ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
@ -54,7 +57,7 @@ public:
int iResult = getaddrinfo(host, buf, &hints, &result); int iResult = getaddrinfo(host, buf, &hints, &result);
if (iResult != 0) { if (iResult != 0) {
// TODO: log error // TODO: log error
printf("A"); printf("\n%s\n", gai_strerror(iResult));
WSACleanup(); WSACleanup();
return false; return false;
} }

View File

@ -19,6 +19,8 @@ if (MSVC)
# Misc headers # Misc headers
target_include_directories(sdrpp_core PUBLIC "C:/Program Files/PothosSDR/include/") target_include_directories(sdrpp_core PUBLIC "C:/Program Files/PothosSDR/include/")
target_link_libraries(sdrpp_core PUBLIC SoapySDR)
else (MSVC) else (MSVC)
find_package(PkgConfig) find_package(PkgConfig)

View File

@ -1,6 +1,6 @@
#include <imgui.h> #include <imgui.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <new_module.h> #include <module.h>
#include <gui/gui.h> #include <gui/gui.h>
#include <signal_path/signal_path.h> #include <signal_path/signal_path.h>
#include <SoapySDR/Device.hpp> #include <SoapySDR/Device.hpp>

View File

@ -1,7 +1,7 @@
#include <spyserver_client.h> #include <spyserver_client.h>
#include <imgui.h> #include <imgui.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <new_module.h> #include <module.h>
#include <gui/gui.h> #include <gui/gui.h>
#include <signal_path/signal_path.h> #include <signal_path/signal_path.h>
#include <core.h> #include <core.h>

View File

@ -74,7 +74,7 @@ bool SpyServerClient::connectToSpyserver(char* host, int port) {
unsigned long mode = 1; unsigned long mode = 1;
ioctlsocket(sock, FIONBIO, &mode); ioctlsocket(sock, FIONBIO, &mode);
#else #else
fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK) fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK);
#endif #endif
connected = true; connected = true;
@ -117,7 +117,7 @@ int SpyServerClient::receive(char* buf, int count) {
#ifdef _WIN32 #ifdef _WIN32
return checkError(recv(sock, (char*)buf, count, 0), count); return checkError(recv(sock, (char*)buf, count, 0), count);
#else #else
return checkError(read(sockfd, buf, count)); return checkError(read(sockfd, buf, count), count);
#endif #endif
} }