A lot of new stuff

This commit is contained in:
Ryzerth 2021-06-28 02:22:51 +02:00
parent 72a794df6f
commit da96ecaaba
14 changed files with 763 additions and 68 deletions

View File

@ -43,7 +43,7 @@ jobs:
- name: Prepare CMake - name: Prepare CMake
working-directory: ${{runner.workspace}}/build working-directory: ${{runner.workspace}}/build
run: cmake "$Env:GITHUB_WORKSPACE" "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" -DOPT_BUILD_SDRPLAY_SOURCE=ON run: cmake "$Env:GITHUB_WORKSPACE" "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON
- name: Build - name: Build
working-directory: ${{runner.workspace}}/build working-directory: ${{runner.workspace}}/build

View File

@ -7,82 +7,101 @@ else()
set(CMAKE_INSTALL_PREFIX "/usr") set(CMAKE_INSTALL_PREFIX "/usr")
endif() endif()
# Sources
option(OPT_BUILD_RTL_TCP_SOURCE "Build RTL-TCP Source Module (no dependencies required)" ON)
option(OPT_BUILD_SPYSERVER_SOURCE "Build SpyServer Source Module (no dependencies required)" OFF)
option(OPT_BUILD_SOAPY_SOURCE "Build SoapySDR Source Module (Depedencies: soapysdr)" ON)
option(OPT_BUILD_AIRSPYHF_SOURCE "Build Airspy HF+ Source Module (Depedencies: libairspyhf)" ON)
option(OPT_BUILD_AIRSPY_SOURCE "Build Airspy Source Module (Depedencies: libairspy)" ON) option(OPT_BUILD_AIRSPY_SOURCE "Build Airspy Source Module (Depedencies: libairspy)" ON)
option(OPT_BUILD_BLADERF_SOURCE "Build BladeRF Source Module (Depedencies: libbladeRF)" ON) option(OPT_BUILD_AIRSPYHF_SOURCE "Build Airspy HF+ Source Module (Depedencies: libairspyhf)" ON)
option(OPT_BUILD_SDRPLAY_SOURCE "Build SDRplay Source Module (Depedencies: libsdrplay)" OFF) option(OPT_BUILD_BLADERF_SOURCE "Build BladeRF Source Module (Depedencies: libbladeRF)" OFF)
option(OPT_BUILD_PLUTOSDR_SOURCE "Build PlutoSDR Source Module (Depedencies: libiio, libad9361)" ON) option(OPT_BUILD_FILE_SOURCE "Wav file source" ON)
option(OPT_BUILD_HACKRF_SOURCE "Build HackRF Source Module (Depedencies: libhackrf)" ON) option(OPT_BUILD_HACKRF_SOURCE "Build HackRF Source Module (Depedencies: libhackrf)" ON)
option(OPT_BUILD_RTL_SDR_SOURCE "Build RTL-SDR Source Module (Depedencies: librtlsdr)" ON) option(OPT_BUILD_LIMESDR_SOURCE "Build LimeSDR Source Module (Depedencies: liblimesuite)" OFF)
option(OPT_BUILD_SDDC_SOURCE "Build SDDC Source Module (Depedencies: libusb-1.0)" OFF) option(OPT_BUILD_SDDC_SOURCE "Build SDDC Source Module (Depedencies: libusb-1.0)" OFF)
option(OPT_BUILD_RTL_SDR_SOURCE "Build RTL-SDR Source Module (Depedencies: librtlsdr)" ON)
option(OPT_BUILD_RTL_TCP_SOURCE "Build RTL-TCP Source Module (no dependencies required)" ON)
option(OPT_BUILD_SDRPLAY_SOURCE "Build SDRplay Source Module (Depedencies: libsdrplay)" OFF)
option(OPT_BUILD_SOAPY_SOURCE "Build SoapySDR Source Module (Depedencies: soapysdr)" ON)
option(OPT_BUILD_SPYSERVER_SOURCE "Build SpyServer Source Module (no dependencies required)" OFF)
option(OPT_BUILD_PLUTOSDR_SOURCE "Build PlutoSDR Source Module (Depedencies: libiio, libad9361)" ON)
# Sinks
option(OPT_BUILD_AUDIO_SINK "Build Audio Sink Module (Depedencies: rtaudio)" ON) option(OPT_BUILD_AUDIO_SINK "Build Audio Sink Module (Depedencies: rtaudio)" ON)
# Decoders
option(OPT_BUILD_FALCON9_DECODER "Build the falcon9 live decoder (Dependencies: ffplay)" OFF) option(OPT_BUILD_FALCON9_DECODER "Build the falcon9 live decoder (Dependencies: ffplay)" OFF)
option(OPT_BUILD_METEOR_DEMODULATOR "Build the meteor demodulator module (no dependencies required)" ON) option(OPT_BUILD_METEOR_DEMODULATOR "Build the meteor demodulator module (no dependencies required)" ON)
option(OPT_BUILD_RADIO "Main audio modulation decoder (AM, FM, SSB, etc...)" ON)
option(OPT_BUILD_WEATHER_SAT_DECODER "Build the HRPT decoder module (no dependencies required)" ON) option(OPT_BUILD_WEATHER_SAT_DECODER "Build the HRPT decoder module (no dependencies required)" ON)
# Misc
option(OPT_BUILD_DISCORD_PRESENCE "Build the Discord Rich Presence module" ON) 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_FREQUENCY_MANAGER "Build the Frequency Manager module" OFF)
option(OPT_BUILD_RECORDER "Audio and baseband recorder" ON)
# Core of SDR++ # Core of SDR++
add_subdirectory("core") add_subdirectory("core")
# Base modules
add_subdirectory("radio")
add_subdirectory("recorder")
add_subdirectory("file_source")
# Source modules # Source modules
if (OPT_BUILD_RTL_TCP_SOURCE) if (OPT_BUILD_AIRSPY_SOURCE)
add_subdirectory("rtl_tcp_source") add_subdirectory("airspy_source")
endif (OPT_BUILD_RTL_TCP_SOURCE) endif (OPT_BUILD_AIRSPY_SOURCE)
if (OPT_BUILD_SPYSERVER_SOURCE)
add_subdirectory("spyserver_source")
endif (OPT_BUILD_SPYSERVER_SOURCE)
if (OPT_BUILD_SOAPY_SOURCE)
add_subdirectory("soapy_source")
endif (OPT_BUILD_SOAPY_SOURCE)
if (OPT_BUILD_AIRSPYHF_SOURCE) if (OPT_BUILD_AIRSPYHF_SOURCE)
add_subdirectory("airspyhf_source") add_subdirectory("airspyhf_source")
endif (OPT_BUILD_AIRSPYHF_SOURCE) endif (OPT_BUILD_AIRSPYHF_SOURCE)
if (OPT_BUILD_AIRSPY_SOURCE)
add_subdirectory("airspy_source")
endif (OPT_BUILD_AIRSPY_SOURCE)
if (OPT_BUILD_BLADERF_SOURCE) if (OPT_BUILD_BLADERF_SOURCE)
add_subdirectory("bladerf_source") add_subdirectory("bladerf_source")
endif(OPT_BUILD_BLADERF_SOURCE) endif (OPT_BUILD_BLADERF_SOURCE)
if (OPT_BUILD_SDRPLAY_SOURCE) if (OPT_BUILD_FILE_SOURCE)
add_subdirectory("sdrplay_source") add_subdirectory("file_source")
endif (OPT_BUILD_SDRPLAY_SOURCE) endif (OPT_BUILD_FILE_SOURCE)
if (OPT_BUILD_PLUTOSDR_SOURCE)
add_subdirectory("plutosdr_source")
endif (OPT_BUILD_PLUTOSDR_SOURCE)
if (OPT_BUILD_HACKRF_SOURCE) if (OPT_BUILD_HACKRF_SOURCE)
add_subdirectory("hackrf_source") add_subdirectory("hackrf_source")
endif (OPT_BUILD_HACKRF_SOURCE) endif (OPT_BUILD_HACKRF_SOURCE)
if (OPT_BUILD_RTL_SDR_SOURCE) if (OPT_BUILD_LIMESDR_SOURCE)
add_subdirectory("rtl_sdr_source") add_subdirectory("limesdr_source")
endif (OPT_BUILD_RTL_SDR_SOURCE) endif (OPT_BUILD_LIMESDR_SOURCE)
if (OPT_BUILD_SDDC_SOURCE) if (OPT_BUILD_SDDC_SOURCE)
add_subdirectory("sddc_source") add_subdirectory("sddc_source")
endif (OPT_BUILD_SDDC_SOURCE) endif (OPT_BUILD_SDDC_SOURCE)
if (OPT_BUILD_RTL_SDR_SOURCE)
add_subdirectory("rtl_sdr_source")
endif (OPT_BUILD_RTL_SDR_SOURCE)
if (OPT_BUILD_RTL_TCP_SOURCE)
add_subdirectory("rtl_tcp_source")
endif (OPT_BUILD_RTL_TCP_SOURCE)
if (OPT_BUILD_SDRPLAY_SOURCE)
add_subdirectory("sdrplay_source")
endif (OPT_BUILD_SDRPLAY_SOURCE)
if (OPT_BUILD_SOAPY_SOURCE)
add_subdirectory("soapy_source")
endif (OPT_BUILD_SOAPY_SOURCE)
if (OPT_BUILD_SPYSERVER_SOURCE)
add_subdirectory("spyserver_source")
endif (OPT_BUILD_SPYSERVER_SOURCE)
if (OPT_BUILD_PLUTOSDR_SOURCE)
add_subdirectory("plutosdr_source")
endif (OPT_BUILD_PLUTOSDR_SOURCE)
# Sink modules
if (OPT_BUILD_AUDIO_SINK) if (OPT_BUILD_AUDIO_SINK)
add_subdirectory("audio_sink") add_subdirectory("audio_sink")
endif (OPT_BUILD_AUDIO_SINK) endif (OPT_BUILD_AUDIO_SINK)
# Decoders
if (OPT_BUILD_FALCON9_DECODER) if (OPT_BUILD_FALCON9_DECODER)
add_subdirectory("falcon9_decoder") add_subdirectory("falcon9_decoder")
endif (OPT_BUILD_FALCON9_DECODER) endif (OPT_BUILD_FALCON9_DECODER)
@ -91,10 +110,16 @@ if (OPT_BUILD_METEOR_DEMODULATOR)
add_subdirectory("meteor_demodulator") add_subdirectory("meteor_demodulator")
endif (OPT_BUILD_METEOR_DEMODULATOR) endif (OPT_BUILD_METEOR_DEMODULATOR)
if (OPT_BUILD_RADIO)
add_subdirectory("radio")
endif (OPT_BUILD_RADIO)
if (OPT_BUILD_WEATHER_SAT_DECODER) if (OPT_BUILD_WEATHER_SAT_DECODER)
add_subdirectory("weather_sat_decoder") add_subdirectory("weather_sat_decoder")
endif (OPT_BUILD_WEATHER_SAT_DECODER) endif (OPT_BUILD_WEATHER_SAT_DECODER)
# Misc
if (OPT_BUILD_DISCORD_PRESENCE) if (OPT_BUILD_DISCORD_PRESENCE)
add_subdirectory("discord_integration") add_subdirectory("discord_integration")
endif (OPT_BUILD_DISCORD_PRESENCE) endif (OPT_BUILD_DISCORD_PRESENCE)
@ -103,6 +128,11 @@ if (OPT_BUILD_FREQUENCY_MANAGER)
add_subdirectory("frequency_manager") add_subdirectory("frequency_manager")
endif (OPT_BUILD_FREQUENCY_MANAGER) endif (OPT_BUILD_FREQUENCY_MANAGER)
if (OPT_BUILD_RECORDER)
add_subdirectory("recorder")
endif (OPT_BUILD_RECORDER)
if (MSVC) if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc") set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")

View File

@ -92,6 +92,7 @@ public:
void selectFirst() { void selectFirst() {
if (devCount > 0) { selectByInfo(&devInfoList[0]); } if (devCount > 0) { selectByInfo(&devInfoList[0]); }
else { selectedSerial = ""; }
} }
void selectBySerial(std::string serial, bool reloadChannelId = true) { void selectBySerial(std::string serial, bool reloadChannelId = true) {

View File

@ -154,20 +154,25 @@ int sdrpp_main(int argc, char *argv[]) {
defConfig["min"] = -120.0; defConfig["min"] = -120.0;
// Module instances // Module instances
defConfig["moduleInstances"]["Radio"] = "radio"; defConfig["moduleInstances"]["Airspy Source"] = "airspy_source";
defConfig["moduleInstances"]["Recorder"] = "recorder"; defConfig["moduleInstances"]["AirspyHF+ Source"] = "airspyhf_source";
defConfig["moduleInstances"]["BladeRF Source"] = "bladerf_source";
defConfig["moduleInstances"]["File Source"] = "file_source";
defConfig["moduleInstances"]["HackRF Source"] = "hackrf_source";
defConfig["moduleInstances"]["LimeSDR Source"] = "limesdr_source";
defConfig["moduleInstances"]["RTL-SDR Source"] = "rtl_sdr_source";
defConfig["moduleInstances"]["RTL-TCP Source"] = "rtl_tcp_source";
defConfig["moduleInstances"]["SDRplay Source"] = "sdrplay_source";
defConfig["moduleInstances"]["SoapySDR Source"] = "soapy_source"; defConfig["moduleInstances"]["SoapySDR Source"] = "soapy_source";
defConfig["moduleInstances"]["PlutoSDR Source"] = "plutosdr_source"; defConfig["moduleInstances"]["PlutoSDR Source"] = "plutosdr_source";
defConfig["moduleInstances"]["BladeRF Source"] = "bladerf_source";
defConfig["moduleInstances"]["HackRF Source"] = "hackrf_source";
defConfig["moduleInstances"]["RTL-TCP Source"] = "rtl_tcp_source";
defConfig["moduleInstances"]["RTL-SDR Source"] = "rtl_sdr_source";
defConfig["moduleInstances"]["AirspyHF+ Source"] = "airspyhf_source";
defConfig["moduleInstances"]["Airspy Source"] = "airspy_source";
defConfig["moduleInstances"]["File Source"] = "file_source";
defConfig["moduleInstances"]["SDRplay Source"] = "sdrplay_source";
defConfig["moduleInstances"]["Audio Sink"] = "audio_sink"; defConfig["moduleInstances"]["Audio Sink"] = "audio_sink";
defConfig["moduleInstances"]["Radio"] = "radio";
defConfig["moduleInstances"]["Recorder"] = "recorder";
// Themes // Themes
defConfig["theme"] = "Dark"; defConfig["theme"] = "Dark";

View File

@ -4,7 +4,7 @@ cd /root
# Install dependencies and tools # Install dependencies and tools
apt update apt update
apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk2-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev p7zip-full wget apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk2-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run
@ -18,7 +18,7 @@ git clone https://github.com/AlexandreRouma/SDRPlusPlus
cd SDRPlusPlus cd SDRPlusPlus
mkdir build mkdir build
cd build cd build
cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON
make -j2 make -j2
cd .. cd ..

View File

@ -4,7 +4,7 @@ cd /root
# Install dependencies and tools # Install dependencies and tools
apt update apt update
apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk1-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev p7zip-full wget apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk1-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run
@ -18,7 +18,7 @@ git clone https://github.com/AlexandreRouma/SDRPlusPlus
cd SDRPlusPlus cd SDRPlusPlus
mkdir build mkdir build
cd build cd build
cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=OFF cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=OFF -DOPT_BUILD_LIMESDR_SOURCE=ON
make -j2 make -j2
cd .. cd ..

View File

@ -4,7 +4,7 @@ cd /root
# Install dependencies and tools # Install dependencies and tools
apt update apt update
apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk2-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev p7zip-full wget apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk2-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run
@ -18,7 +18,7 @@ git clone https://github.com/AlexandreRouma/SDRPlusPlus
cd SDRPlusPlus cd SDRPlusPlus
mkdir build mkdir build
cd build cd build
cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON
make -j2 make -j2
cd .. cd ..

View File

@ -4,7 +4,7 @@ cd /root
# Install dependencies and tools # Install dependencies and tools
apt update apt update
apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk2-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev p7zip-full wget apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk2-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run
@ -18,7 +18,7 @@ git clone https://github.com/AlexandreRouma/SDRPlusPlus
cd SDRPlusPlus cd SDRPlusPlus
mkdir build mkdir build
cd build cd build
cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON
make -j2 make -j2
cd .. cd ..

View File

@ -4,7 +4,7 @@ cd /root
# Install dependencies and tools # Install dependencies and tools
apt update apt update
apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk2-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev p7zip-full wget apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk2-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run
@ -18,7 +18,7 @@ git clone https://github.com/AlexandreRouma/SDRPlusPlus
cd SDRPlusPlus cd SDRPlusPlus
mkdir build mkdir build
cd build cd build
cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON
make -j2 make -j2
cd .. cd ..

View File

@ -4,7 +4,7 @@ cd /root
# Install dependencies and tools # Install dependencies and tools
apt update apt update
apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk2-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev p7zip-full wget apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libglew-dev libvolk2-dev libsoapysdr-dev libairspyhf-dev libairspy-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuit-dev p7zip-full wget
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.07.1.run
@ -18,7 +18,7 @@ git clone https://github.com/AlexandreRouma/SDRPlusPlus
cd SDRPlusPlus cd SDRPlusPlus
mkdir build mkdir build
cd build cd build
cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON
make -j2 make -j2
cd .. cd ..

View File

@ -0,0 +1,38 @@
cmake_minimum_required(VERSION 3.13)
project(limesdr_source)
if (MSVC)
set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -Wno-unused-command-line-argument -undefined dynamic_lookup")
else ()
set(CMAKE_CXX_FLAGS "-O3 -std=c++17")
endif ()
include_directories("src/")
file(GLOB SRC "src/*.cpp")
add_library(limesdr_source SHARED ${SRC})
target_link_libraries(limesdr_source PRIVATE sdrpp_core)
set_target_properties(limesdr_source PROPERTIES PREFIX "")
if (MSVC)
# Lib path
target_link_directories(limesdr_source PUBLIC "C:/Program Files/PothosSDR/lib")
target_link_libraries(limesdr_source PUBLIC LimeSuite)
else (MSVC)
find_package(PkgConfig)
# Not in pkg-config
target_link_libraries(limesdr_source PUBLIC LimeSuite)
# Include it because for some reason pkgconfig doesn't look here?
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
target_include_directories(airspyhf_source PUBLIC "/usr/local/include")
endif()
endif ()
# Install directives
install(TARGETS limesdr_source DESTINATION lib/sdrpp/plugins)

538
limesdr_source/src/main.cpp Normal file
View File

@ -0,0 +1,538 @@
#include <imgui.h>
#include <spdlog/spdlog.h>
#include <module.h>
#include <gui/gui.h>
#include <signal_path/signal_path.h>
#include <core.h>
#include <gui/style.h>
#include <config.h>
#include <options.h>
#include <lime/LimeSuite.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
SDRPP_MOD_INFO {
/* Name: */ "limesdr_source",
/* Description: */ "LimeSDR source module for SDR++",
/* Author: */ "Ryzerth",
/* Version: */ 0, 1, 0,
/* Max instances */ 1
};
ConfigManager config;
class LimeSDRSourceModule : public ModuleManager::Instance {
public:
LimeSDRSourceModule(std::string name) {
this->name = name;
// Init limesuite if needed
sampleRate = 10000000.0;
handler.ctx = this;
handler.selectHandler = menuSelected;
handler.deselectHandler = menuDeselected;
handler.menuHandler = menuHandler;
handler.startHandler = start;
handler.stopHandler = stop;
handler.tuneHandler = tune;
handler.stream = &stream;
refresh();
// Select device from config
selectFirst();
core::setInputSampleRate(sampleRate);
sigpath::sourceManager.registerSource("LimeSDR", &handler);
}
~LimeSDRSourceModule() {
// Exit limesuite if needed
}
void enable() {
enabled = true;
}
void disable() {
enabled = false;
}
bool isEnabled() {
return enabled;
}
void refresh() {
devCount = LMS_GetDeviceList(devList);
char buf[256];
devListTxt = "";
for (int i = 0; i < devCount; i++) {
lms_device_t* dev = NULL;
LMS_Open(&dev, devList[i], NULL);
const lms_dev_info_t* info = LMS_GetDeviceInfo(dev);
sprintf(buf, "%s [%" PRIX64 "]", info->deviceName, info->boardSerialNumber);
LMS_Close(dev);
devNames.push_back(buf);
devListTxt += buf;
devListTxt += '\0';
}
}
void selectFirst() {
if (devCount > 0) {
selectByInfoStr(devList[0]);
return;
}
selectedDevName = "";
}
void selectByName(std::string name) {
for (int i = 0; i < devCount; i++) {
if (devNames[i] == name) {
selectByInfoStr(devList[i]);
break;
}
}
selectFirst();
}
void selectByInfoStr(lms_info_str_t info) {
if (devCount == 0) {
selectedDevName = "";
return;
}
// Set devId and selectedDevNames
for (int i = 0; i < devCount; i++) {
if (info == devList[i]) {
devId = i;
selectedDevName = devNames[i];
break;
}
}
lms_device_t* dev = NULL;
LMS_Open(&dev, info, NULL);
channelCount = LMS_GetNumChannels(dev, false);
char buf[32];
for (int i = 0; i < channelCount; i++) {
sprintf(buf, "CH %d", i+1);
channelNamesTxt += buf;
channelNamesTxt += '\0';
}
config.aquire();
if (config.conf["devices"].contains(selectedDevName)) {
if (config.conf["devices"][selectedDevName].contains("channel")) {
chanId = config.conf["devices"][selectedDevName]["channel"];
}
else { chanId = 0; }
}
else { chanId = 0; }
config.release();
chanId = std::clamp<int>(chanId, 0, channelCount - 1);
// List antennas
lms_name_t antennaNames[16];
antennaCount = LMS_GetAntennaList(dev, false, chanId, antennaNames);
for (int i = 0; i < antennaCount; i++) {
antennaNameList.push_back(antennaNames[i]);
antennaListTxt += antennaNames[i];
antennaListTxt += '\0';
}
// List supported sample rates
lms_range_t srRange;
LMS_GetSampleRateRange(dev, false, &srRange);
sampleRates.push_back(srRange.min);
sampleRatesTxt += getBandwdithScaled(srRange.min);
sampleRatesTxt += '\0';
for (int i = 1000000; i < srRange.max; i += 1000000) {
sampleRates.push_back(i);
sampleRatesTxt += getBandwdithScaled(i);
sampleRatesTxt += '\0';
}
sampleRates.push_back(srRange.max);
sampleRatesTxt += getBandwdithScaled(srRange.max);
sampleRatesTxt += '\0';
// List supported bandwidths
lms_range_t bwRange;
LMS_GetLPFBWRange(dev, false, &bwRange);
spdlog::warn("bw step {0}", bwRange.step);
bandwidths.push_back(bwRange.min);
bandwidthsTxt += getBandwdithScaled(bwRange.min);
bandwidthsTxt += '\0';
for (int i = 2000000; i < bwRange.max; i += 1000000) {
bandwidths.push_back(i);
bandwidthsTxt += getBandwdithScaled(i);
bandwidthsTxt += '\0';
}
bandwidths.push_back(bwRange.max);
bandwidthsTxt += getBandwdithScaled(bwRange.max);
bandwidthsTxt += '\0';
bandwidthsTxt += "Auto";
bandwidthsTxt += '\0';
config.aquire();
if (!config.conf["devices"].contains(selectedDevName)) {
config.conf["devices"][selectedDevName]["sampleRate"] = sampleRates[0];
config.conf["devices"][selectedDevName]["channel"] = 0;
config.conf["devices"][selectedDevName]["antenna"] = "LNAW";
config.conf["devices"][selectedDevName]["bandwidth"] = bandwidths.size();
config.conf["devices"][selectedDevName]["gain"] = 0;
}
// Load sample rate
if (config.conf["devices"][selectedDevName].contains("sampleRate")) {
bool found = false;
int sr = config.conf["devices"][selectedDevName]["sampleRate"];
for (int i = 0; i < sampleRates.size(); i++) {
if (sr == sampleRates[i]) {
srId = i;
sampleRate = sampleRates[i];
found = true;
break;
}
}
if (!found) {
srId = 0;
sampleRate = sampleRates[0];
}
}
else {
srId = 0;
sampleRate = sampleRates[0];
}
// Load antenna
if (config.conf["devices"][selectedDevName].contains("antenna")) {
std::string antName = config.conf["devices"][selectedDevName]["antenna"];
bool found = false;
for (int i = 0; i < antennaCount; i++) {
if (antennaNames[i] == antName) {
antennaId = i;
found = true;
break;
}
}
if (!found) {
for (int i = 0; i < antennaCount; i++) {
if (antennaNames[i] == "LNAW") {
antennaId = i;
found = true;
break;
}
}
if (!found) { antennaId = 0; }
}
}
else {
bool found = false;
for (int i = 0; i < antennaCount; i++) {
if (antennaNames[i] == "LNAW") {
antennaId = i;
found = true;
break;
}
}
if (!found) { antennaId = 0; }
}
// Load bandwidth
if (config.conf["devices"][selectedDevName].contains("bandwidth")) {
bwId = config.conf["devices"][selectedDevName]["bandwidth"];
bwId = std::clamp<int>(bwId, 0, bandwidths.size());
}
else {
bwId = bandwidths.size();
}
// Load gain
if (config.conf["devices"][selectedDevName].contains("gain")) {
gain = config.conf["devices"][selectedDevName]["bandwidth"];
gain = std::clamp<int>(bwId, 0, 73);
}
else {
gain = 0;
}
config.release(true);
LMS_Close(dev);
}
private:
std::string getBandwdithScaled(double bw) {
char buf[1024];
if (bw >= 1000000.0) {
sprintf(buf, "%.1lfMHz", bw / 1000000.0);
}
else if (bw >= 1000.0) {
sprintf(buf, "%.1lfKHz", bw / 1000.0);
}
else {
sprintf(buf, "%.1lfHz", bw);
}
return std::string(buf);
}
int getBestBandwidth(int sampleRate) {
for (int i = 0; i < bandwidths.size(); i++) {
if (bandwidths[i] >= sampleRate) {
spdlog::warn("Selected bandwidth is {0}", bandwidths[i]);
return bandwidths[i];
}
}
return bandwidths[bandwidths.size()-1];
}
static void menuSelected(void* ctx) {
LimeSDRSourceModule* _this = (LimeSDRSourceModule*)ctx;
core::setInputSampleRate(_this->sampleRate);
spdlog::info("LimeSDRSourceModule '{0}': Menu Select!", _this->name);
}
static void menuDeselected(void* ctx) {
LimeSDRSourceModule* _this = (LimeSDRSourceModule*)ctx;
spdlog::info("LimeSDRSourceModule '{0}': Menu Deselect!", _this->name);
}
static void start(void* ctx) {
LimeSDRSourceModule* _this = (LimeSDRSourceModule*)ctx;
if (_this->running) {
return;
}
// Open device
_this->openDev = NULL;
LMS_Open(&_this->openDev, _this->devList[_this->devId], NULL);
LMS_Init(_this->openDev);
spdlog::warn("Channel count: {0}", LMS_GetNumChannels(_this->openDev, false));
// Set options
LMS_EnableChannel(_this->openDev, false, _this->chanId, true);
LMS_SetSampleRate(_this->openDev, _this->sampleRate, 0);
LMS_SetLOFrequency(_this->openDev, false, _this->chanId, _this->freq);
LMS_SetGaindB(_this->openDev, false, _this->chanId, _this->gain);
LMS_SetLPFBW(_this->openDev, false, _this->chanId, (_this->bwId == _this->bandwidths.size()) ? _this->getBestBandwidth(_this->sampleRate) : _this->bandwidths[_this->bwId]);
LMS_SetLPF(_this->openDev, false, _this->chanId, true);
// Setup and start stream
int sampCount = _this->sampleRate / 200;
_this->devStream.isTx = false;
_this->devStream.channel = 0;
_this->devStream.fifoSize = sampCount; // TODO: Check what it's actually supposed to be
_this->devStream.throughputVsLatency = 0.5f;
_this->devStream.dataFmt = _this->devStream.LMS_FMT_F32;
LMS_SetupStream(_this->openDev, &_this->devStream);
// Start stream
_this->streamRunning = true;
LMS_StartStream(&_this->devStream);
_this->workerThread = std::thread(&LimeSDRSourceModule::worker, _this);
_this->running = true;
spdlog::info("LimeSDRSourceModule '{0}': Start!", _this->name);
}
static void stop(void* ctx) {
LimeSDRSourceModule* _this = (LimeSDRSourceModule*)ctx;
if (!_this->running) {
return;
}
_this->running = false;
_this->streamRunning = false;
if (_this->workerThread.joinable()) { _this->workerThread.join(); }
LMS_StopStream(&_this->devStream);
LMS_DestroyStream(_this->openDev, &_this->devStream);
LMS_Close(_this->openDev);
spdlog::info("LimeSDRSourceModule '{0}': Stop!", _this->name);
}
static void tune(double freq, void* ctx) {
LimeSDRSourceModule* _this = (LimeSDRSourceModule*)ctx;
_this->freq = freq;
if (_this->running) {
LMS_SetLOFrequency(_this->openDev, false, _this->chanId, freq);
}
spdlog::info("LimeSDRSourceModule '{0}': Tune: {1}!", _this->name, freq);
}
static void menuHandler(void* ctx) {
LimeSDRSourceModule* _this = (LimeSDRSourceModule*)ctx;
float menuWidth = ImGui::GetContentRegionAvailWidth();
if (_this->running) { style::beginDisabled(); }
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo("##limesdr_dev_sel", &_this->devId, _this->devListTxt.c_str())) {
_this->selectByInfoStr(_this->devList[_this->devId]);
core::setInputSampleRate(_this->sampleRate);
config.aquire();
config.conf["device"] = _this->selectedDevName;
config.release(true);
}
if (ImGui::Combo(CONCAT("##_limesdr_sr_sel_", _this->name), &_this->srId, _this->sampleRatesTxt.c_str())) {
_this->sampleRate = _this->sampleRates[_this->srId];
core::setInputSampleRate(_this->sampleRate);
if (_this->selectedDevName != "") {
config.aquire();
config.conf["devices"][_this->selectedDevName]["sampleRate"] = _this->sampleRates[_this->srId];
config.release(true);
}
}
// Refresh button
ImGui::SameLine();
float refreshBtnWdith = menuWidth - ImGui::GetCursorPosX();
if (ImGui::Button(CONCAT("Refresh##_limesdr_refr_", _this->name), ImVec2(refreshBtnWdith, 0))) {
_this->refresh();
_this->selectByName(_this->selectedDevName);
core::setInputSampleRate(_this->sampleRate);
}
if (_this->channelCount > 1) {
ImGui::Text("RX Channel");
ImGui::SameLine();
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
ImGui::Combo("##limesdr_ch_sel", &_this->chanId, _this->channelNamesTxt.c_str());
if (_this->selectedDevName != "") {
config.aquire();
config.conf["devices"][_this->selectedDevName]["channel"] = _this->chanId;
config.release(true);
}
}
if (_this->running) { style::endDisabled(); }
ImGui::Text("Antenna");
ImGui::SameLine();
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo("##limesdr_ant_sel", &_this->antennaId, _this->antennaListTxt.c_str())) {
if (_this->running) {
LMS_SetAntenna(_this->openDev, false, _this->chanId, _this->antennaId);
}
if (_this->selectedDevName != "") {
config.aquire();
config.conf["devices"][_this->selectedDevName]["antenna"] = _this->antennaNameList[_this->antennaId];
config.release(true);
}
}
ImGui::Text("Bandwidth");
ImGui::SameLine();
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo("##limesdr_bw_sel", &_this->bwId, _this->bandwidthsTxt.c_str())) {
if (_this->running) {
LMS_SetLPFBW(_this->openDev, false, _this->chanId, (_this->bwId == _this->bandwidths.size()) ? _this->getBestBandwidth(_this->sampleRate) : _this->bandwidths[_this->bwId]);
}
if (_this->selectedDevName != "") {
config.aquire();
config.conf["devices"][_this->selectedDevName]["bandwidth"] = _this->bwId;
config.release(true);
}
}
ImGui::Text("Gain");
ImGui::SameLine();
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::SliderInt("##limesdr_gain_sel", &_this->gain, 0, 73, "%ddB")) {
if (_this->running) {
LMS_SetGaindB(_this->openDev, false, _this->chanId, _this->gain);
}
if (_this->selectedDevName != "") {
config.aquire();
config.conf["devices"][_this->selectedDevName]["gain"] = _this->gain;
config.release(true);
}
}
}
void worker() {
int sampCount = sampleRate / 200;
lms_stream_meta_t meta;
while (streamRunning) {
int ret = LMS_RecvStream(&devStream, stream.writeBuf, sampCount, &meta, 1000);
if (!stream.swap(sampCount) || ret < 0) { break; }
}
}
std::string name;
dsp::stream<dsp::complex_t> stream;
double sampleRate;
SourceManager::SourceHandler handler;
bool running = false;
bool enabled = true;
bool streamRunning = false;
double freq;
int channelCount = 0;
int devId = 0;
int chanId = 0;
int srId = 0;
int bwId = 0;
int gain = 0;
std::vector<int> sampleRates;
std::string sampleRatesTxt;
std::vector<int> bandwidths;
std::string bandwidthsTxt;
lms_info_str_t devList[128];
int devCount = 0;
std::string devListTxt;
std::vector<std::string> devNames;
std::string selectedDevName;
lms_device_t* openDev;
lms_stream_t devStream;
std::string channelNamesTxt;
int antennaId = 0;
std::string antennaListTxt;
std::vector<std::string> antennaNameList;
int antennaCount = 0;
std::thread workerThread;
};
MOD_EXPORT void _INIT_() {
json def = json({});
def["devices"] = json({});
def["device"] = "";
config.setPath(options::opts.root + "/limesdr_config.json");
config.load(def);
config.enableAutoSave();
}
MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) {
return new LimeSDRSourceModule(name);
}
MOD_EXPORT void _DELETE_INSTANCE_(ModuleManager::Instance* instance) {
delete (LimeSDRSourceModule*)instance;
}
MOD_EXPORT void _END_() {
config.disableAutoSave();
config.save();
}

View File

@ -24,6 +24,9 @@ cp 'C:/Program Files/PothosSDR/bin/airspy.dll' sdrpp_windows_x64/
cp $build_dir/hackrf_source/Release/hackrf_source.dll sdrpp_windows_x64/modules/ cp $build_dir/hackrf_source/Release/hackrf_source.dll sdrpp_windows_x64/modules/
cp 'C:/Program Files/PothosSDR/bin/hackrf.dll' sdrpp_windows_x64/ cp 'C:/Program Files/PothosSDR/bin/hackrf.dll' sdrpp_windows_x64/
cp $build_dir/hackrf_source/Release/hackrf_source.dll sdrpp_windows_x64/modules/
cp 'C:/Program Files/PothosSDR/bin/hackrf.dll' sdrpp_windows_x64/
cp $build_dir/rtl_sdr_source/Release/rtl_sdr_source.dll sdrpp_windows_x64/modules/ cp $build_dir/rtl_sdr_source/Release/rtl_sdr_source.dll sdrpp_windows_x64/modules/
cp 'C:/Program Files/PothosSDR/bin/rtlsdr.dll' sdrpp_windows_x64/ cp 'C:/Program Files/PothosSDR/bin/rtlsdr.dll' sdrpp_windows_x64/

View File

@ -139,6 +139,16 @@ The modules built will be some of the following (Repeat the instructions above f
# Building on Linux / BSD # Building on Linux / BSD
## Select which modules you wish to build
Depending on which module you want to build, you will need to install some additional dependencies.
Here are listed every module that requires addition dependencies. If a module enabled by default and you do not wish to install a perticular dependency (or can't, eg. the BladeRF module on Debian Buster),
you can disable it using the module parameter listed in the table below
* soapy_source: SoapySDR + drivers for each SDRs (see SoapySDR docs)
* airspyhf_source: libairspyhf
* plutosdr_source: libiio, libad9361
* audio_sink: librtaudio-dev
## Install dependencies ## Install dependencies
* cmake * cmake
* fftw3 * fftw3
@ -146,11 +156,7 @@ The modules built will be some of the following (Repeat the instructions above f
* glew * glew
* libvolk * libvolk
Next install dependencies based on the modules you wish to build: Next install dependencies based on the modules you wish to build (See previous step)
* soapy_source: SoapySDR + drivers for each SDRs (see SoapySDR docs)
* airspyhf_source: libairspyhf
* plutosdr_source: libiio, libad9361
* audio_sink: librtaudio-dev
Note: make sure you're using GCC 8 or later as older versions do not have `std::filesystem` built-in. Note: make sure you're using GCC 8 or later as older versions do not have `std::filesystem` built-in.
@ -221,6 +227,80 @@ To install SDR++, run the following command in your ``build`` folder:
sudo make install sudo make install
``` ```
# Module List
Not all modules are built by default. I decided to disable the build of those with large libraries, libraries that can't be installed through the package manager (or pothos) and those that are still in beta.
Modules in beta are still included in releases for the most part but not enabled in SDR++ (need to be instantiated).
## Sources
| Name | Stage | Dependencies | Option | Built by default| Built in Release | Enabled in SDR++ by default |
|------------------|------------|-------------------|----------------------------|:---------------:|:-----------------------:|:---------------------------:|
| airspy_source | Working | libairspy | OPT_BUILD_AIRSPY_SOURCE | ✅ | ✅ | ✅ |
| airspyhf_source | Working | libairspyhf | OPT_BUILD_AIRSPYHF_SOURCE | ✅ | ✅ | ✅ |
| bladerf_source | Beta | libbladeRF | OPT_BUILD_BLADERF_SOURCE | ⛔ | ⚠️ (not Debian Buster) | ✅ |
| file_source | Working | - | OPT_BUILD_FILE_SOURCE | ✅ | ✅ | ✅ |
| hackrf_source | Working | libhackrf | OPT_BUILD_HACKRF_SOURCE | ✅ | ✅ | ✅ |
| limesdr_source | Beta | liblimesuite | OPT_BUILD_LIMESDR_SOURCE | ⛔ | ✅ | ✅ |
| sddc_source | Unfinished | - | OPT_BUILD_SDDC_SOURCE | ⛔ | ⛔ | ⛔ |
| rtl_sdr_source | Working | librtlsdr | OPT_BUILD_RTL_SDR_SOURCE | ✅ | ✅ | ✅ |
| rtl_tcp_source | Working | - | OPT_BUILD_RTL_TCP_SOURCE | ✅ | ✅ | ✅ |
| sdrplay_source | Working | SDRplay API | OPT_BUILD_SDRPLAY_SOURCE | ⛔ | ✅ | ✅ |
| soapy_source | Working | soapysdr | OPT_BUILD_SOAPY_SOURCE | ✅ | ✅ | ✅ |
| spyserver_source | Unfinished | - | OPT_BUILD_SPYSERVER_SOURCE | ⛔ | ⛔ | ⛔ |
| plutosdr_source | Working | libiio, libad9361 | OPT_BUILD_PLUTOSDR_SOURCE | ✅ | ✅ | ✅ |
## Sinks
| Name | Stage | Dependencies | Option | Built by default| Built in Release | Enabled in SDR++ by default |
|------------------|------------|-------------------|----------------------------|:---------------:|:-----------------------:|:---------------------------:|
| audio_sink | Working | rtaudio | OPT_BUILD_AUDIO_SINK | ✅ | ✅ | ✅ |
## Decoders
| Name | Stage | Dependencies | Option | Built by default| Built in Release | Enabled in SDR++ by default |
|---------------------|------------|--------------|-------------------------------|:---------------:|:-----------------------:|:---------------------------:|
| falcon9_decoder | Beta | ffplay | OPT_BUILD_FALCON9_DECODER | ⛔ | ⛔ | ⛔ |
| meteor_demodulator | Working | - | OPT_BUILD_METEOR_DEMODULATOR | ✅ | ✅ | ⛔ |
| radio | Working | - | OPT_BUILD_RADIO | ✅ | ✅ | ✅ |
| weather_sat_decoder | Unfinished | - | OPT_BUILD_WEATHER_SAT_DECODER | ⛔ | ⛔ | ⛔ |
## Misc
| Name | Stage | Dependencies | Option | Built by default| Built in Release | Enabled in SDR++ by default |
|---------------------|------------|--------------|-------------------------------|:---------------:|:-----------------------:|:---------------------------:|
| discord_integration | Working | - | OPT_BUILD_DISCORD_PRESENCE | ✅ | ✅ | ⛔ |
| frequency_manager | Unfinished | - | OPT_BUILD_FREQUENCY_MANAGER | ⛔ | ⛔ | ⛔ |
| recorder | Working | - | OPT_BUILD_RECORDER | ✅ | ✅ | ✅ |
# Toubleshooting
First, please make sure you're running the latest automated build. If your issue is linked to a bug it is likely that is has already been fixed in later releases
## "hash collision" error when starting
You likely installed the `soapysdr-module-all` package on Ubuntu/Debian. If not it's still a SoapySDR bug caused by multiple soapy modules comming in conflict. Uninstall anything related to SoapySDR then install soapysdr itself and only the soapy modules you actually need.
## "I don't see -insert module name here-, what's going on?"
If the module was included in a later update, it's not enabled in the config. The easiest way to fix this is just to delete the `config.json` file and let SDR++ recreate it (you will lose your setting relating to the main UI like VFO colors, zoom level and theme).
The best option however is to edit the config file to add an instance of the module you wish to hae enabled (see the Module List).
## SDR++ crashes when stopping a RTL-SDR
This is a bug recently introduced by libusb1.4
To solve, this, simply downgrade to libusb1.3
## SDR++ crashes when starting a HackRF
If you also have the SoapySDR module loaded (not necessarily enabled), this is a bug in libhackrf. It's caused by libhackrf not checking if it's already initialized.
The solution until a fixed libhackrf version is released is to completely remove the soapy_source module from SDR++. To do this, delete `modules/soapy_source.dll` on windows
or `/usr/share/sdrpp/plugins/soapy_source.so` on linux.
## Issue not listed here?
If you still have an issue, please open an issue about it or ask on the discord. I'll try to respond as quickly as I can. Please avoid trying to contact me on every platform imaginable thinking I'll respond faster though...
# Contributing # Contributing
Feel free to submit pull requests and report bugs via the GitHub issue tracker. Feel free to submit pull requests and report bugs via the GitHub issue tracker.