Merge pull request #1385 from AlexandreRouma/master

Keep new_sinks branch up to date
This commit is contained in:
AlexandreRouma 2024-04-18 03:14:40 +02:00 committed by GitHub
commit 40f1ee5651
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 1063 additions and 196 deletions

View File

@ -37,10 +37,10 @@ jobs:
run: 7z x libusb.7z -olibusb_old ; rm "C:/Program Files/PothosSDR/bin/libusb-1.0.dll" ; cp "libusb_old/MS64/dll/libusb-1.0.dll" "C:/Program Files/PothosSDR/bin/" ; rm "C:/Program Files/PothosSDR/lib/libusb-1.0.lib" ; cp "libusb_old/MS64/dll/libusb-1.0.lib" "C:/Program Files/PothosSDR/lib/" run: 7z x libusb.7z -olibusb_old ; rm "C:/Program Files/PothosSDR/bin/libusb-1.0.dll" ; cp "libusb_old/MS64/dll/libusb-1.0.dll" "C:/Program Files/PothosSDR/bin/" ; rm "C:/Program Files/PothosSDR/lib/libusb-1.0.lib" ; cp "libusb_old/MS64/dll/libusb-1.0.lib" "C:/Program Files/PothosSDR/lib/"
- name: Download SDRPlay API - name: Download SDRPlay API
run: Invoke-WebRequest -Uri "https://drive.google.com/uc?id=12UHPMwkfa67A11QZDmpCT4iwHnyJHWuu&confirm=t" -OutFile ${{runner.workspace}}/SDRPlay.zip run: Invoke-WebRequest -Uri "https://www.sdrpp.org/SDRplay.zip" -OutFile ${{runner.workspace}}/SDRplay.zip
- name: Install SDRPlay API - name: Install SDRPlay API
run: 7z x ${{runner.workspace}}/SDRPlay.zip -o"C:/Program Files/" run: 7z x ${{runner.workspace}}/SDRplay.zip -o"C:/Program Files/"
- name: Download codec2 - name: Download codec2
run: git clone https://github.com/AlexandreRouma/codec2 run: git clone https://github.com/AlexandreRouma/codec2
@ -84,8 +84,8 @@ jobs:
name: sdrpp_windows_x64 name: sdrpp_windows_x64
path: ${{runner.workspace}}/sdrpp_windows_x64.zip path: ${{runner.workspace}}/sdrpp_windows_x64.zip
build_macos: build_macos_intel:
runs-on: macos-latest runs-on: macos-12
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -93,9 +93,6 @@ jobs:
- name: Create Build Environment - name: Create Build Environment
run: cmake -E make_directory ${{runner.workspace}}/build run: cmake -E make_directory ${{runner.workspace}}/build
- name: Update brew repositories
run: brew update
- name: Install dependencies - name: Install dependencies
run: brew install pkg-config libusb fftw glfw airspy airspyhf portaudio hackrf libbladerf codec2 zstd autoconf automake libtool && pip3 install mako run: brew install pkg-config libusb fftw glfw airspy airspyhf portaudio hackrf libbladerf codec2 zstd autoconf automake libtool && pip3 install mako
@ -103,7 +100,7 @@ jobs:
run: git clone --recursive https://github.com/gnuradio/volk && cd volk && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ run: git clone --recursive https://github.com/gnuradio/volk && cd volk && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
- name: Install SDRplay API - name: Install SDRplay API
run: wget https://www.sdrplay.com/software/SDRplayAPI-macos-installer-universal-3.12.1.pkg && sudo installer -pkg SDRplayAPI-macos-installer-universal-3.12.1.pkg -target / run: wget https://www.sdrplay.com/software/SDRplayAPI-macos-installer-universal-3.14.0.pkg && sudo installer -pkg SDRplayAPI-macos-installer-universal-3.14.0.pkg -target /
- name: Install libiio - name: Install libiio
run: wget https://github.com/analogdevicesinc/libiio/archive/refs/tags/v0.25.zip && 7z x v0.25.zip && cd libiio-0.25 && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../ run: wget https://github.com/analogdevicesinc/libiio/archive/refs/tags/v0.25.zip && 7z x v0.25.zip && cd libiio-0.25 && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
@ -122,7 +119,7 @@ jobs:
- name: Prepare CMake - name: Prepare CMake
working-directory: ${{runner.workspace}}/build working-directory: ${{runner.workspace}}/build
run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_SOAPY_SOURCE=OFF -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_AUDIO_SOURCE=OFF -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_AUDIO_SOURCE=OFF -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release
- name: Build - name: Build
working-directory: ${{runner.workspace}}/build working-directory: ${{runner.workspace}}/build
@ -138,6 +135,57 @@ jobs:
name: sdrpp_macos_intel name: sdrpp_macos_intel
path: ${{runner.workspace}}/sdrpp_macos_intel.zip path: ${{runner.workspace}}/sdrpp_macos_intel.zip
build_macos_arm:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: Create Build Environment
run: cmake -E make_directory ${{runner.workspace}}/build
- name: Install dependencies
run: brew install pkg-config libusb fftw glfw airspy airspyhf portaudio hackrf libbladerf codec2 zstd autoconf automake libtool && pip3 install mako --break-system-packages
- name: Install volk
run: git clone --recursive https://github.com/gnuradio/volk && cd volk && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
- name: Install SDRplay API
run: wget https://www.sdrplay.com/software/SDRplayAPI-macos-installer-universal-3.14.0.pkg && sudo installer -pkg SDRplayAPI-macos-installer-universal-3.14.0.pkg -target /
- name: Install libiio
run: wget https://github.com/analogdevicesinc/libiio/archive/refs/tags/v0.25.zip && 7z x v0.25.zip && cd libiio-0.25 && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
- name: Install libad9361
run: git clone https://github.com/analogdevicesinc/libad9361-iio && cd libad9361-iio && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
- name: Install LimeSuite
run: git clone https://github.com/myriadrf/LimeSuite && cd LimeSuite && mkdir builddir && cd builddir && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
# - name: Install libperseus
# run: git clone https://github.com/Microtelecom/libperseus-sdr && cd libperseus-sdr && autoreconf -i && ./configure --prefix=/usr/local && make && make install && cd ..
- name: Install more recent librtlsdr
run: git clone https://github.com/osmocom/rtl-sdr && cd rtl-sdr && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 LIBRARY_PATH=$(pkg-config --libs-only-L libusb-1.0 | sed 's/\-L//') && sudo make install && cd ../../
- name: Prepare CMake
working-directory: ${{runner.workspace}}/build
run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF -DOPT_BUILD_PERSEUS_SOURCE=OFF -DOPT_BUILD_AUDIO_SOURCE=OFF -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release
- name: Build
working-directory: ${{runner.workspace}}/build
run: make VERBOSE=1 -j3
- name: Create Archive
working-directory: ${{runner.workspace}}
run: cd $GITHUB_WORKSPACE && sh make_macos_bundle.sh ${{runner.workspace}}/build ./SDR++.app && zip -r ${{runner.workspace}}/sdrpp_macos_arm.zip SDR++.app
- name: Save Archive
uses: actions/upload-artifact@v4
with:
name: sdrpp_macos_arm
path: ${{runner.workspace}}/sdrpp_macos_arm.zip
build_debian_buster: build_debian_buster:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -347,7 +395,7 @@ jobs:
path: ${{runner.workspace}}/sdrpp.apk path: ${{runner.workspace}}/sdrpp.apk
create_full_archive: create_full_archive:
needs: ['build_windows', 'build_macos', 'build_debian_buster', 'build_debian_bullseye', 'build_debian_bookworm', 'build_debian_sid', 'build_ubuntu_focal', 'build_ubuntu_jammy', 'build_ubuntu_mantic', 'build_raspios_bullseye_armhf', 'build_android'] needs: ['build_windows', 'build_macos_intel', 'build_macos_arm', 'build_debian_buster', 'build_debian_bullseye', 'build_debian_bookworm', 'build_debian_sid', 'build_ubuntu_focal', 'build_ubuntu_jammy', 'build_ubuntu_mantic', 'build_raspios_bullseye_armhf', 'build_android']
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -359,6 +407,7 @@ jobs:
mkdir sdrpp_all && mkdir sdrpp_all &&
mv sdrpp_windows_x64/sdrpp_windows_x64.zip sdrpp_all/ && mv sdrpp_windows_x64/sdrpp_windows_x64.zip sdrpp_all/ &&
mv sdrpp_macos_intel/sdrpp_macos_intel.zip sdrpp_all/ && mv sdrpp_macos_intel/sdrpp_macos_intel.zip sdrpp_all/ &&
mv sdrpp_macos_arm/sdrpp_macos_arm.zip sdrpp_all/ &&
mv sdrpp_debian_buster_amd64/sdrpp_debian_amd64.deb sdrpp_all/sdrpp_debian_buster_amd64.deb && mv sdrpp_debian_buster_amd64/sdrpp_debian_amd64.deb sdrpp_all/sdrpp_debian_buster_amd64.deb &&
mv sdrpp_debian_bullseye_amd64/sdrpp_debian_amd64.deb sdrpp_all/sdrpp_debian_bullseye_amd64.deb && mv sdrpp_debian_bullseye_amd64/sdrpp_debian_amd64.deb sdrpp_all/sdrpp_debian_bullseye_amd64.deb &&
mv sdrpp_debian_bookworm_amd64/sdrpp_debian_amd64.deb sdrpp_all/sdrpp_debian_bookworm_amd64.deb && mv sdrpp_debian_bookworm_amd64/sdrpp_debian_amd64.deb sdrpp_all/sdrpp_debian_bookworm_amd64.deb &&

View File

@ -17,6 +17,7 @@ option(OPT_BUILD_FILE_SOURCE "Wav file source" ON)
option(OPT_BUILD_HACKRF_SOURCE "Build HackRF Source Module (Dependencies: libhackrf)" ON) option(OPT_BUILD_HACKRF_SOURCE "Build HackRF Source Module (Dependencies: libhackrf)" ON)
option(OPT_BUILD_HERMES_SOURCE "Build Hermes Source Module (no dependencies required)" ON) option(OPT_BUILD_HERMES_SOURCE "Build Hermes Source Module (no dependencies required)" ON)
option(OPT_BUILD_LIMESDR_SOURCE "Build LimeSDR Source Module (Dependencies: liblimesuite)" OFF) option(OPT_BUILD_LIMESDR_SOURCE "Build LimeSDR Source Module (Dependencies: liblimesuite)" OFF)
option(OPT_BUILD_NETWORK_SOURCE "Build Network Source Module (no dependencies required)" ON)
option(OPT_BUILD_PERSEUS_SOURCE "Build Perseus Source Module (Dependencies: libperseus-sdr)" OFF) option(OPT_BUILD_PERSEUS_SOURCE "Build Perseus Source Module (Dependencies: libperseus-sdr)" OFF)
option(OPT_BUILD_PLUTOSDR_SOURCE "Build PlutoSDR Source Module (Dependencies: libiio, libad9361)" ON) option(OPT_BUILD_PLUTOSDR_SOURCE "Build PlutoSDR Source Module (Dependencies: libiio, libad9361)" ON)
option(OPT_BUILD_RFSPACE_SOURCE "Build RFspace Source Module (no dependencies required)" ON) option(OPT_BUILD_RFSPACE_SOURCE "Build RFspace Source Module (no dependencies required)" ON)
@ -24,7 +25,7 @@ option(OPT_BUILD_RTL_SDR_SOURCE "Build RTL-SDR Source Module (Dependencies: libr
option(OPT_BUILD_RTL_TCP_SOURCE "Build RTL-TCP Source Module (no dependencies required)" ON) option(OPT_BUILD_RTL_TCP_SOURCE "Build RTL-TCP Source Module (no dependencies required)" ON)
option(OPT_BUILD_SDRPP_SERVER_SOURCE "Build SDR++ Server Source Module (no dependencies required)" ON) option(OPT_BUILD_SDRPP_SERVER_SOURCE "Build SDR++ Server Source Module (no dependencies required)" ON)
option(OPT_BUILD_SDRPLAY_SOURCE "Build SDRplay Source Module (Dependencies: libsdrplay)" OFF) option(OPT_BUILD_SDRPLAY_SOURCE "Build SDRplay Source Module (Dependencies: libsdrplay)" OFF)
option(OPT_BUILD_SOAPY_SOURCE "Build SoapySDR Source Module (Dependencies: soapysdr)" ON) option(OPT_BUILD_SOAPY_SOURCE "Build SoapySDR Source Module (Dependencies: soapysdr)" OFF)
option(OPT_BUILD_SPECTRAN_SOURCE "Build Spectran Source Module (Dependencies: Aaronia RTSA Suite)" OFF) option(OPT_BUILD_SPECTRAN_SOURCE "Build Spectran Source Module (Dependencies: Aaronia RTSA Suite)" OFF)
option(OPT_BUILD_SPECTRAN_HTTP_SOURCE "Build Spectran HTTP Source Module (no dependencies required)" ON) option(OPT_BUILD_SPECTRAN_HTTP_SOURCE "Build Spectran HTTP Source Module (no dependencies required)" ON)
option(OPT_BUILD_SPYSERVER_SOURCE "Build SpyServer Source Module (no dependencies required)" ON) option(OPT_BUILD_SPYSERVER_SOURCE "Build SpyServer Source Module (no dependencies required)" ON)
@ -43,14 +44,14 @@ option(OPT_BUILD_FALCON9_DECODER "Build the falcon9 live decoder (Dependencies:
option(OPT_BUILD_KG_SSTV_DECODER "Build the KG SSTV (KG-STV) decoder module (no dependencies required)" OFF) option(OPT_BUILD_KG_SSTV_DECODER "Build the KG SSTV (KG-STV) decoder module (no dependencies required)" OFF)
option(OPT_BUILD_M17_DECODER "Build the M17 decoder module (Dependencies: codec2)" OFF) option(OPT_BUILD_M17_DECODER "Build the M17 decoder module (Dependencies: codec2)" 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_PAGER_DECODER "Build the pager decoder module (no dependencies required)" OFF) option(OPT_BUILD_PAGER_DECODER "Build the pager decoder module (no dependencies required)" ON)
option(OPT_BUILD_RADIO "Main audio modulation decoder (AM, FM, SSB, etc...)" 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)" OFF) option(OPT_BUILD_WEATHER_SAT_DECODER "Build the HRPT decoder module (no dependencies required)" OFF)
# Misc # 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" ON)
option(OPT_BUILD_IQ_EXPORTER "Build the IQ Exporter module" OFF) option(OPT_BUILD_IQ_EXPORTER "Build the IQ Exporter module" ON)
option(OPT_BUILD_RECORDER "Audio and baseband recorder" 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" ON)
option(OPT_BUILD_RIGCTL_SERVER "Rigctl backend for controlling SDR++ with software like gpredict" ON) option(OPT_BUILD_RIGCTL_SERVER "Rigctl backend for controlling SDR++ with software like gpredict" ON)
@ -144,6 +145,10 @@ if (OPT_BUILD_LIMESDR_SOURCE)
add_subdirectory("source_modules/limesdr_source") add_subdirectory("source_modules/limesdr_source")
endif (OPT_BUILD_LIMESDR_SOURCE) endif (OPT_BUILD_LIMESDR_SOURCE)
if (OPT_BUILD_NETWORK_SOURCE)
add_subdirectory("source_modules/network_source")
endif (OPT_BUILD_NETWORK_SOURCE)
if (OPT_BUILD_PERSEUS_SOURCE) if (OPT_BUILD_PERSEUS_SOURCE)
add_subdirectory("source_modules/perseus_source") add_subdirectory("source_modules/perseus_source")
endif (OPT_BUILD_PERSEUS_SOURCE) endif (OPT_BUILD_PERSEUS_SOURCE)
@ -282,7 +287,12 @@ if (OPT_BUILD_SCHEDULER)
add_subdirectory("misc_modules/scheduler") add_subdirectory("misc_modules/scheduler")
endif (OPT_BUILD_SCHEDULER) endif (OPT_BUILD_SCHEDULER)
add_executable(sdrpp "src/main.cpp" "win32/resources.rc") if (MSVC)
add_executable(sdrpp "src/main.cpp" "win32/resources.rc")
else ()
add_executable(sdrpp "src/main.cpp")
endif ()
target_link_libraries(sdrpp PRIVATE sdrpp_core) target_link_libraries(sdrpp PRIVATE sdrpp_core)
# Compiler arguments # Compiler arguments

View File

@ -193,8 +193,6 @@ int sdrpp_main(int argc, char* argv[]) {
defConfig["moduleInstances"]["SDRplay Source"]["enabled"] = true; defConfig["moduleInstances"]["SDRplay Source"]["enabled"] = true;
defConfig["moduleInstances"]["SDR++ Server Source"]["module"] = "sdrpp_server_source"; defConfig["moduleInstances"]["SDR++ Server Source"]["module"] = "sdrpp_server_source";
defConfig["moduleInstances"]["SDR++ Server Source"]["enabled"] = true; defConfig["moduleInstances"]["SDR++ Server Source"]["enabled"] = true;
defConfig["moduleInstances"]["SoapySDR Source"]["module"] = "soapy_source";
defConfig["moduleInstances"]["SoapySDR Source"]["enabled"] = true;
defConfig["moduleInstances"]["SpyServer Source"]["module"] = "spyserver_source"; defConfig["moduleInstances"]["SpyServer Source"]["module"] = "spyserver_source";
defConfig["moduleInstances"]["SpyServer Source"]["enabled"] = true; defConfig["moduleInstances"]["SpyServer Source"]["enabled"] = true;

View File

@ -41,6 +41,7 @@ namespace sdrpp_credits {
"CaribouLabs", "CaribouLabs",
"Ettus Research", "Ettus Research",
"Howard Su", "Howard Su",
"MicroPhase",
"MyriadRF", "MyriadRF",
"Nuand", "Nuand",
"RFspace", "RFspace",
@ -54,6 +55,7 @@ namespace sdrpp_credits {
"Croccydile", "Croccydile",
"Dale L Puckett (K0HYD)", "Dale L Puckett (K0HYD)",
"Daniele D'Agnelli", "Daniele D'Agnelli",
"David Taylor (GM8ARV)",
"D. Jones", "D. Jones",
"Dexruus", "Dexruus",
"EB3FRN", "EB3FRN",
@ -81,6 +83,7 @@ namespace sdrpp_credits {
"Syne Ardwin (WI9SYN)", "Syne Ardwin (WI9SYN)",
"W4IPA", "W4IPA",
"William Arcand (W1WRA)", "William Arcand (W1WRA)",
"William Pitchford",
"Yves Rougy", "Yves Rougy",
"Zipper" "Zipper"
}; };

View File

@ -41,7 +41,11 @@ namespace dsp::channel {
} }
inline int process(int count, const complex_t* in, complex_t* out) { inline int process(int count, const complex_t* in, complex_t* out) {
#if VOLK_VERSION >= 030100
volk_32fc_s32fc_x2_rotator2_32fc((lv_32fc_t*)out, (lv_32fc_t*)in, &phaseDelta, &phase, count);
#else
volk_32fc_s32fc_x2_rotator_32fc((lv_32fc_t*)out, (lv_32fc_t*)in, phaseDelta, &phase, count); volk_32fc_s32fc_x2_rotator_32fc((lv_32fc_t*)out, (lv_32fc_t*)in, phaseDelta, &phase, count);
#endif
return count; return count;
} }

View File

@ -12,6 +12,10 @@ namespace dsp::compression {
void init(stream<complex_t>* in, PCMType pcmType) { void init(stream<complex_t>* in, PCMType pcmType) {
_pcmType = pcmType; _pcmType = pcmType;
// Set the output buffer size to the max size of a complex buffer + 8 bytes for the header
out.setBufferSize(STREAM_BUFFER_SIZE*sizeof(complex_t) + 8);
base_type::init(in); base_type::init(in);
} }

View File

@ -41,10 +41,10 @@ namespace dsp::filter {
// Move existing data to make transition seemless // Move existing data to make transition seemless
if (_taps.size < oldTC) { if (_taps.size < oldTC) {
memcpy(buffer, &buffer[oldTC - _taps.size], (_taps.size - 1) * sizeof(D)); memmove(buffer, &buffer[oldTC - _taps.size], (_taps.size - 1) * sizeof(D));
} }
else if (_taps.size > oldTC) { else if (_taps.size > oldTC) {
memcpy(&buffer[_taps.size - oldTC], buffer, (oldTC - 1) * sizeof(D)); memmove(&buffer[_taps.size - oldTC], buffer, (oldTC - 1) * sizeof(D));
buffer::clear<D>(buffer, _taps.size - oldTC); buffer::clear<D>(buffer, _taps.size - oldTC);
} }

View File

@ -436,6 +436,9 @@ void MainWindow::draw() {
showCredits = false; showCredits = false;
} }
// Reset waterfall lock
lockWaterfallControls = showCredits;
// Handle menu resize // Handle menu resize
ImVec2 winSize = ImGui::GetWindowSize(); ImVec2 winSize = ImGui::GetWindowSize();
ImVec2 mousePos = ImGui::GetMousePos(); ImVec2 mousePos = ImGui::GetMousePos();
@ -466,9 +469,10 @@ void MainWindow::draw() {
} }
} }
// Process menu keybinds
displaymenu::checkKeybinds();
// Left Column // Left Column
lockWaterfallControls = false;
if (showMenu) { if (showMenu) {
ImGui::Columns(3, "WindowColumns", false); ImGui::Columns(3, "WindowColumns", false);
ImGui::SetColumnWidth(0, menuWidth); ImGui::SetColumnWidth(0, menuWidth);
@ -577,6 +581,8 @@ void MainWindow::draw() {
// Handle scrollwheel // Handle scrollwheel
int wheel = ImGui::GetIO().MouseWheel; int wheel = ImGui::GetIO().MouseWheel;
if (wheel != 0 && (gui::waterfall.mouseInFFT || gui::waterfall.mouseInWaterfall)) { if (wheel != 0 && (gui::waterfall.mouseInFFT || gui::waterfall.mouseInWaterfall)) {
double nfreq;
if (vfo != NULL) {
// Select factor depending on modifier keys // Select factor depending on modifier keys
double interval; double interval;
if (ImGui::IsKeyDown(ImGuiKey_LeftShift)) { if (ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
@ -589,8 +595,6 @@ void MainWindow::draw() {
interval = vfo->snapInterval; interval = vfo->snapInterval;
} }
double nfreq;
if (vfo != NULL) {
nfreq = gui::waterfall.getCenterFrequency() + vfo->generalOffset + (interval * wheel); nfreq = gui::waterfall.getCenterFrequency() + vfo->generalOffset + (interval * wheel);
nfreq = roundl(nfreq / interval) * interval; nfreq = roundl(nfreq / interval) * interval;
} }

View File

@ -127,17 +127,26 @@ namespace displaymenu {
uiScaleId = uiScales.valueId(style::uiScale); uiScaleId = uiScales.valueId(style::uiScale);
} }
void draw(void* ctx) { void setWaterfallShown(bool shown) {
float menuWidth = ImGui::GetContentRegionAvail().x; showWaterfall = shown;
bool homePressed = ImGui::IsKeyPressed(ImGuiKey_Home, false);
if (ImGui::Checkbox("Show Waterfall##_sdrpp", &showWaterfall) || homePressed) {
if (homePressed) { showWaterfall = !showWaterfall; }
showWaterfall ? gui::waterfall.showWaterfall() : gui::waterfall.hideWaterfall(); showWaterfall ? gui::waterfall.showWaterfall() : gui::waterfall.hideWaterfall();
core::configManager.acquire(); core::configManager.acquire();
core::configManager.conf["showWaterfall"] = showWaterfall; core::configManager.conf["showWaterfall"] = showWaterfall;
core::configManager.release(true); core::configManager.release(true);
} }
void checkKeybinds() {
if (ImGui::IsKeyPressed(ImGuiKey_Home, false)) {
setWaterfallShown(!showWaterfall);
}
}
void draw(void* ctx) {
float menuWidth = ImGui::GetContentRegionAvail().x;
if (ImGui::Checkbox("Show Waterfall##_sdrpp", &showWaterfall)) {
setWaterfallShown(showWaterfall);
}
if (ImGui::Checkbox("Full Waterfall Update##_sdrpp", &fullWaterfallUpdate)) { if (ImGui::Checkbox("Full Waterfall Update##_sdrpp", &fullWaterfallUpdate)) {
gui::waterfall.setFullWaterfallUpdate(fullWaterfallUpdate); gui::waterfall.setFullWaterfallUpdate(fullWaterfallUpdate);
core::configManager.acquire(); core::configManager.acquire();

View File

@ -2,5 +2,6 @@
namespace displaymenu { namespace displaymenu {
void init(); void init();
void checkKeybinds();
void draw(void* ctx); void draw(void* ctx);
} }

View File

@ -39,7 +39,7 @@ namespace module_manager_menu {
ImVec2 btnSize = ImVec2(lheight, lheight - 1); ImVec2 btnSize = ImVec2(lheight, lheight - 1);
ImVec2 textOff = ImVec2(3.0f * style::uiScale, -5.0f * style::uiScale); ImVec2 textOff = ImVec2(3.0f * style::uiScale, -5.0f * style::uiScale);
if (ImGui::BeginTable("Module Manager Table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 200))) { if (ImGui::BeginTable("Module Manager Table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 200.0f * style::uiScale))) {
ImGui::TableSetupColumn("Name"); ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("Type"); ImGui::TableSetupColumn("Type");
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, cellWidth); ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, cellWidth);

View File

@ -230,7 +230,7 @@ namespace server {
// Compress data if needed and fill out header fields // Compress data if needed and fill out header fields
if (compression) { if (compression) {
bb_pkt_hdr->type = PACKET_TYPE_BASEBAND_COMPRESSED; bb_pkt_hdr->type = PACKET_TYPE_BASEBAND_COMPRESSED;
bb_pkt_hdr->size = sizeof(PacketHeader) + (uint32_t)ZSTD_compressCCtx(cctx, &bbuf[sizeof(PacketHeader)], SERVER_MAX_PACKET_SIZE, data, count, 1); bb_pkt_hdr->size = sizeof(PacketHeader) + (uint32_t)ZSTD_compressCCtx(cctx, &bbuf[sizeof(PacketHeader)], SERVER_MAX_PACKET_SIZE-sizeof(PacketHeader), data, count, 1);
} }
else { else {
bb_pkt_hdr->type = PACKET_TYPE_BASEBAND; bb_pkt_hdr->type = PACKET_TYPE_BASEBAND;

View File

@ -84,7 +84,7 @@ void SourceManager::tune(double freq) {
if (selectedHandler == NULL) { if (selectedHandler == NULL) {
return; return;
} }
// TODO: No need to always retune the hardware in panadpter mode // TODO: No need to always retune the hardware in Panadapter mode
selectedHandler->tuneHandler(((tuneMode == TuningMode::NORMAL) ? freq : ifFreq) + tuneOffset, selectedHandler->ctx); selectedHandler->tuneHandler(((tuneMode == TuningMode::NORMAL) ? freq : ifFreq) + tuneOffset, selectedHandler->ctx);
onRetune.emit(freq); onRetune.emit(freq);
currentFreq = freq; currentFreq = freq;
@ -100,7 +100,7 @@ void SourceManager::setTuningMode(TuningMode mode) {
tune(currentFreq); tune(currentFreq);
} }
void SourceManager::setPanadpterIF(double freq) { void SourceManager::setPanadapterIF(double freq) {
ifFreq = freq; ifFreq = freq;
tune(currentFreq); tune(currentFreq);
} }

View File

@ -35,7 +35,7 @@ public:
void tune(double freq); void tune(double freq);
void setTuningOffset(double offset); void setTuningOffset(double offset);
void setTuningMode(TuningMode mode); void setTuningMode(TuningMode mode);
void setPanadpterIF(double freq); void setPanadapterIF(double freq);
std::vector<std::string> getSourceNames(); std::vector<std::string> getSourceNames();

View File

@ -139,18 +139,19 @@ class ATVDecoderModule : public ModuleManager::Instance {
_this->pll.process(720, _this->fir.out.writeBuf, _this->pll.out.writeBuf, ((_this->ypos%2)==1) ^ _this->evenFrame); _this->pll.process(720, _this->fir.out.writeBuf, _this->pll.out.writeBuf, ((_this->ypos%2)==1) ^ _this->evenFrame);
// Render line to the image without color // Render line to the image without color
//int lypos = _this->ypos - 1; int lypos = _this->ypos - 1;
//if (lypos < 0) { lypos = 624; } if (lypos < 0) { lypos = 624; }
//uint32_t* lastLine = &((uint32_t *)_this->img.buffer)[(lypos < 313) ? (lypos*720*2) : ((((lypos - 313)*2)+1)*720) ]; uint32_t* lastLine = &((uint32_t *)_this->img.buffer)[(lypos < 313) ? (lypos*720*2) : ((((lypos - 313)*2)+1)*720) ];
//uint32_t* currentLine = &((uint32_t *)_this->img.buffer)[(_this->ypos < 313) ? (_this->ypos*720*2) : ((((_this->ypos - 313)*2)+1)*720) ]; uint32_t* currentLine = &((uint32_t *)_this->img.buffer)[(_this->ypos < 313) ? (_this->ypos*720*2) : ((((_this->ypos - 313)*2)+1)*720) ];
uint32_t* currentLine = &((uint32_t *)_this->img.buffer)[_this->ypos*720]; //uint32_t* currentLine = &((uint32_t *)_this->img.buffer)[_this->ypos*720];
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
//float imval = std::clamp<float>((data[i] - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255); int imval = std::clamp<float>((data[i] - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255);
uint32_t re = std::clamp<float>((_this->pll.out.writeBuf[i].re - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255); // uint32_t re = std::clamp<float>((_this->pll.out.writeBuf[i].re - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255);
uint32_t im = std::clamp<float>((_this->pll.out.writeBuf[i].im - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255); // uint32_t im = std::clamp<float>((_this->pll.out.writeBuf[i].im - _this->minLvl) * 255.0 / _this->spanLvl, 0, 255);
currentLine[i] = 0xFF000000 | (im << 8) | re; // currentLine[i] = 0xFF000000 | (im << 8) | re;
currentLine[i] = 0xFF000000 | (imval << 16) | (imval << 8) | imval;
} }
// Vertical scan logic // Vertical scan logic

View File

@ -36,7 +36,7 @@ public:
// Define protocols // Define protocols
protocols.define("POCSAG", PROTOCOL_POCSAG); protocols.define("POCSAG", PROTOCOL_POCSAG);
protocols.define("FLEX", PROTOCOL_FLEX); //protocols.define("FLEX", PROTOCOL_FLEX);
// Initialize VFO with default values // Initialize VFO with default values
vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, 0, 12500, 24000, 12500, 12500, true); vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, 0, 12500, 24000, 12500, 12500, true);

View File

@ -8,16 +8,12 @@
#include "dsp.h" #include "dsp.h"
#include "pocsag.h" #include "pocsag.h"
const char* msgTypes[] = { #define BAUDRATE 2400
"Numeric", #define SAMPLERATE (BAUDRATE*10)
"Unknown (0b01)",
"Unknown (0b10)",
"Alphanumeric",
};
class POCSAGDecoder : public Decoder { class POCSAGDecoder : public Decoder {
public: public:
POCSAGDecoder(const std::string& name, VFOManager::VFO* vfo) : diag(0.6, 2400) { POCSAGDecoder(const std::string& name, VFOManager::VFO* vfo) : diag(0.6, BAUDRATE) {
this->name = name; this->name = name;
this->vfo = vfo; this->vfo = vfo;
@ -28,9 +24,9 @@ public:
// Init DSP // Init DSP
vfo->setBandwidthLimits(12500, 12500, true); vfo->setBandwidthLimits(12500, 12500, true);
vfo->setSampleRate(24000, 12500); vfo->setSampleRate(SAMPLERATE, 12500);
dsp.init(vfo->output, 24000, 2400); dsp.init(vfo->output, SAMPLERATE, BAUDRATE);
reshape.init(&dsp.soft, 2400.0, (2400 / 30.0) - 2400.0); reshape.init(&dsp.soft, BAUDRATE, (BAUDRATE / 30.0) - BAUDRATE);
dataHandler.init(&dsp.out, _dataHandler, this); dataHandler.init(&dsp.out, _dataHandler, this);
diagHandler.init(&reshape.out, _diagHandler, this); diagHandler.init(&reshape.out, _diagHandler, this);
@ -61,7 +57,6 @@ public:
} }
void start() { void start() {
flog::debug("POCSAG start");
dsp.start(); dsp.start();
reshape.start(); reshape.start();
dataHandler.start(); dataHandler.start();
@ -69,7 +64,6 @@ public:
} }
void stop() { void stop() {
flog::debug("POCSAG stop");
dsp.stop(); dsp.stop();
reshape.stop(); reshape.stop();
dataHandler.stop(); dataHandler.stop();

View File

@ -19,18 +19,16 @@ public:
void init(dsp::stream<dsp::complex_t>* in, double samplerate, double baudrate) { void init(dsp::stream<dsp::complex_t>* in, double samplerate, double baudrate) {
// Save settings // Save settings
// TODO _samplerate = samplerate;
// Configure blocks // Configure blocks
demod.init(NULL, -4500.0, samplerate); demod.init(NULL, -4500.0, samplerate);
dcBlock.init(NULL, 0.001);
float taps[] = { 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f }; float taps[] = { 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f };
shape = dsp::taps::fromArray<float>(10, taps); shape = dsp::taps::fromArray<float>(10, taps);
fir.init(NULL, shape); fir.init(NULL, shape);
recov.init(NULL, samplerate/baudrate, 1e5, 0.1, 0.05); recov.init(NULL, samplerate/baudrate, 1e-4, 1.0, 0.05);
// Free useless buffers // Free useless buffers
dcBlock.out.free();
fir.out.free(); fir.out.free();
recov.out.free(); recov.out.free();
@ -40,13 +38,20 @@ public:
int process(int count, dsp::complex_t* in, float* softOut, uint8_t* out) { int process(int count, dsp::complex_t* in, float* softOut, uint8_t* out) {
count = demod.process(count, in, demod.out.readBuf); count = demod.process(count, in, demod.out.readBuf);
count = dcBlock.process(count, demod.out.readBuf, demod.out.readBuf);
count = fir.process(count, demod.out.readBuf, demod.out.readBuf); count = fir.process(count, demod.out.readBuf, demod.out.readBuf);
count = recov.process(count, demod.out.readBuf, softOut); count = recov.process(count, demod.out.readBuf, softOut);
dsp::digital::BinarySlicer::process(count, softOut, out); dsp::digital::BinarySlicer::process(count, softOut, out);
return count; return count;
} }
void setBaudrate(double baudrate) {
assert(base_type::_block_init);
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
base_type::tempStop();
base_type::tempStart();
}
int run() { int run() {
int count = base_type::_in->read(); int count = base_type::_in->read();
if (count < 0) { return -1; } if (count < 0) { return -1; }
@ -55,7 +60,7 @@ public:
base_type::_in->flush(); base_type::_in->flush();
if (!base_type::out.swap(count)) { return -1; } if (!base_type::out.swap(count)) { return -1; }
if (!soft.swap(count)) { return -1; } if (count) { if (!soft.swap(count)) { return -1; } }
return count; return count;
} }
@ -63,9 +68,9 @@ public:
private: private:
dsp::demod::Quadrature demod; dsp::demod::Quadrature demod;
dsp::correction::DCBlocker<float> dcBlock;
dsp::tap<float> shape; dsp::tap<float> shape;
dsp::filter::FIR<float, float> fir; dsp::filter::FIR<float, float> fir;
dsp::clock_recovery::MM<float> recov; dsp::clock_recovery::MM<float> recov;
double _samplerate;
}; };

View File

@ -5,6 +5,7 @@
#define POCSAG_FRAME_SYNC_CODEWORD ((uint32_t)(0b01111100110100100001010111011000)) #define POCSAG_FRAME_SYNC_CODEWORD ((uint32_t)(0b01111100110100100001010111011000))
#define POCSAG_IDLE_CODEWORD_DATA ((uint32_t)(0b011110101100100111000)) #define POCSAG_IDLE_CODEWORD_DATA ((uint32_t)(0b011110101100100111000))
#define POCSAG_BATCH_BIT_COUNT (POCSAG_BATCH_CODEWORD_COUNT*32) #define POCSAG_BATCH_BIT_COUNT (POCSAG_BATCH_CODEWORD_COUNT*32)
#define POCSAG_DATA_BITS_PER_CW 20
#define POCSAG_GEN_POLY ((uint32_t)(0b11101101001)) #define POCSAG_GEN_POLY ((uint32_t)(0b11101101001))
@ -28,6 +29,11 @@ namespace pocsag {
'[' '['
}; };
Decoder::Decoder() {
// Zero out batch
memset(batch, 0, sizeof(batch));
}
void Decoder::process(uint8_t* symbols, int count) { void Decoder::process(uint8_t* symbols, int count) {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
// Get symbol // Get symbol
@ -78,8 +84,26 @@ namespace pocsag {
void Decoder::flushMessage() { void Decoder::flushMessage() {
if (!msg.empty()) { if (!msg.empty()) {
// Send out message
onMessage(addr, msgType, msg); onMessage(addr, msgType, msg);
// Reset state
msg.clear(); msg.clear();
currChar = 0;
currOffset = 0;
}
}
void printbin(uint32_t cw) {
for (int i = 31; i >= 0; i--) {
printf("%c", ((cw >> i) & 1) ? '1':'0');
}
}
void bitswapChar(char in, char& out) {
out = 0;
for (int i = 0; i < 7; i++) {
out |= ((in >> (6-i)) & 1) << i;
} }
} }
@ -102,14 +126,14 @@ namespace pocsag {
if (type == CODEWORD_TYPE_IDLE) { if (type == CODEWORD_TYPE_IDLE) {
// If a non-empty message is available, send it out and clear // If a non-empty message is available, send it out and clear
flushMessage(); flushMessage();
flog::debug("[{}:{}]: IDLE", (i >> 1), i&1);
} }
else if (type == CODEWORD_TYPE_ADDRESS) { else if (type == CODEWORD_TYPE_ADDRESS) {
// If a non-empty message is available, send it out and clear // If a non-empty message is available, send it out and clear
flushMessage(); flushMessage();
// Decode message type // Decode message type
msgType = (MessageType)((cw >> 11) & 0b11); msgType = MESSAGE_TYPE_ALPHANUMERIC;
// msgType = (MessageType)((cw >> 11) & 0b11);
// Decode address and append lower 8 bits from position // Decode address and append lower 8 bits from position
addr = ((cw >> 13) & 0b111111111111111111) << 3; addr = ((cw >> 13) & 0b111111111111111111) << 3;
@ -129,11 +153,20 @@ namespace pocsag {
msg += NUMERIC_CHARSET[data & 0b1111]; msg += NUMERIC_CHARSET[data & 0b1111];
} }
else if (msgType == MESSAGE_TYPE_ALPHANUMERIC) { else if (msgType == MESSAGE_TYPE_ALPHANUMERIC) {
// Unpack ascii bits 7 at a time (TODO: could be more efficient)
for (int i = 19; i >= 0; i--) {
// Append bit to char
currChar |= ((data >> i) & 1) << (currOffset++);
// When the char is full, append to message
if (currOffset >= 7) {
// TODO: maybe replace with std::isprint
if (currChar) { msg += currChar; }
currChar = 0;
currOffset = 0;
}
}
} }
// Save last data
lastMsgData = data;
} }
} }
} }

View File

@ -23,6 +23,8 @@ namespace pocsag {
class Decoder { class Decoder {
public: public:
Decoder();
void process(uint8_t* symbols, int count); void process(uint8_t* symbols, int count);
NewEvent<Address, MessageType, const std::string&> onMessage; NewEvent<Address, MessageType, const std::string&> onMessage;
@ -43,6 +45,7 @@ namespace pocsag {
MessageType msgType; MessageType msgType;
std::string msg; std::string msg;
uint32_t lastMsgData; char currChar = 0;
int currOffset = 0;
}; };
} }

View File

@ -4,15 +4,15 @@ 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 libvolk2-dev libzstd-dev libsoapysdr-dev libairspyhf-dev libairspy-dev \ apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libvolk2-dev libzstd-dev libairspyhf-dev libairspy-dev \
libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \ libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \
libcodec2-dev autoconf libtool xxd libcodec2-dev autoconf libtool xxd
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.12.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1.run 7z x ./SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1 7z x ./SDRplay_RSP_API-Linux-3.14.0
cp x86_64/libsdrplay_api.so.3.12 /usr/lib/libsdrplay_api.so cp x86_64/libsdrplay_api.so.3.14 /usr/lib/libsdrplay_api.so
cp inc/* /usr/include/ cp inc/* /usr/include/
# Install libperseus # Install libperseus

View File

@ -4,15 +4,15 @@ 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 libvolk2-dev libzstd-dev libsoapysdr-dev libairspyhf-dev libairspy-dev \ apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libvolk2-dev libzstd-dev libairspyhf-dev libairspy-dev \
libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \ libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \
libcodec2-dev autoconf libtool xxd libcodec2-dev autoconf libtool xxd
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.12.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1.run 7z x ./SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1 7z x ./SDRplay_RSP_API-Linux-3.14.0
cp x86_64/libsdrplay_api.so.3.12 /usr/lib/libsdrplay_api.so cp x86_64/libsdrplay_api.so.3.14 /usr/lib/libsdrplay_api.so
cp inc/* /usr/include/ cp inc/* /usr/include/
# Install libperseus # Install libperseus

View File

@ -4,15 +4,15 @@ 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 libvolk1-dev libzstd-dev libsoapysdr-dev libairspyhf-dev libairspy-dev \ apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libvolk1-dev libzstd-dev libairspyhf-dev libairspy-dev \
libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \ libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \
libcodec2-dev autoconf libtool xxd libcodec2-dev autoconf libtool xxd
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.12.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1.run 7z x ./SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1 7z x ./SDRplay_RSP_API-Linux-3.14.0
cp x86_64/libsdrplay_api.so.3.12 /usr/lib/libsdrplay_api.so cp x86_64/libsdrplay_api.so.3.14 /usr/lib/libsdrplay_api.so
cp inc/* /usr/include/ cp inc/* /usr/include/
# Install libperseus # Install libperseus

View File

@ -4,15 +4,15 @@ 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 libvolk-dev libzstd-dev libsoapysdr-dev libairspyhf-dev libairspy-dev \ apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libvolk-dev libzstd-dev libairspyhf-dev libairspy-dev \
libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \ libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \
libcodec2-dev autoconf libtool xxd libcodec2-dev autoconf libtool xxd
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.12.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1.run 7z x ./SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1 7z x ./SDRplay_RSP_API-Linux-3.14.0
cp x86_64/libsdrplay_api.so.3.12 /usr/lib/libsdrplay_api.so cp x86_64/libsdrplay_api.so.3.14 /usr/lib/libsdrplay_api.so
cp inc/* /usr/include/ cp inc/* /usr/include/
# Install libperseus # Install libperseus

View File

@ -10,15 +10,15 @@ echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://ap
apt update apt update
# Install dependencies and tools # Install dependencies and tools
apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libvolk1-dev libzstd-dev libsoapysdr-dev libairspy-dev \ apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libvolk1-dev libzstd-dev libairspy-dev \
libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \ libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \
libcodec2-dev libudev-dev autoconf libtool xxd libcodec2-dev libudev-dev autoconf libtool xxd
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.12.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1.run 7z x ./SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1 7z x ./SDRplay_RSP_API-Linux-3.14.0
cp x86_64/libsdrplay_api.so.3.12 /usr/lib/libsdrplay_api.so cp x86_64/libsdrplay_api.so.3.14 /usr/lib/libsdrplay_api.so
cp inc/* /usr/include/ cp inc/* /usr/include/
# Install a more recent libusb version # Install a more recent libusb version

View File

@ -4,15 +4,15 @@ 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 libvolk2-dev libzstd-dev libsoapysdr-dev libairspyhf-dev libairspy-dev \ apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libvolk2-dev libzstd-dev libairspyhf-dev libairspy-dev \
libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \ libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \
libcodec2-dev autoconf libtool xxd libcodec2-dev autoconf libtool xxd
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.12.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1.run 7z x ./SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1 7z x ./SDRplay_RSP_API-Linux-3.14.0
cp x86_64/libsdrplay_api.so.3.12 /usr/lib/libsdrplay_api.so cp x86_64/libsdrplay_api.so.3.14 /usr/lib/libsdrplay_api.so
cp inc/* /usr/include/ cp inc/* /usr/include/
# Install libperseus # Install libperseus

View File

@ -4,15 +4,15 @@ 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 libvolk2-dev libzstd-dev libsoapysdr-dev libairspyhf-dev libairspy-dev \ apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libvolk2-dev libzstd-dev libairspyhf-dev libairspy-dev \
libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \ libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \
libcodec2-dev autoconf libtool xxd libcodec2-dev autoconf libtool xxd
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.12.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1.run 7z x ./SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1 7z x ./SDRplay_RSP_API-Linux-3.14.0
cp x86_64/libsdrplay_api.so.3.12 /usr/lib/libsdrplay_api.so cp x86_64/libsdrplay_api.so.3.14 /usr/lib/libsdrplay_api.so
cp inc/* /usr/include/ cp inc/* /usr/include/
# Install libperseus # Install libperseus

View File

@ -4,15 +4,15 @@ 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 libvolk-dev libzstd-dev libsoapysdr-dev libairspyhf-dev libairspy-dev \ apt install -y build-essential cmake git libfftw3-dev libglfw3-dev libvolk-dev libzstd-dev libairspyhf-dev libairspy-dev \
libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \ libiio-dev libad9361-dev librtaudio-dev libhackrf-dev librtlsdr-dev libbladerf-dev liblimesuite-dev p7zip-full wget portaudio19-dev \
libcodec2-dev autoconf libtool xxd libcodec2-dev autoconf libtool xxd
# Install SDRPlay libraries # Install SDRPlay libraries
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.12.1.run wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1.run 7z x ./SDRplay_RSP_API-Linux-3.14.0.run
7z x ./SDRplay_RSP_API-Linux-3.12.1 7z x ./SDRplay_RSP_API-Linux-3.14.0
cp x86_64/libsdrplay_api.so.3.12 /usr/lib/libsdrplay_api.so cp x86_64/libsdrplay_api.so.3.14 /usr/lib/libsdrplay_api.so
cp inc/* /usr/include/ cp inc/* /usr/include/
# Install libperseus # Install libperseus

View File

@ -27,6 +27,7 @@ bundle_is_not_to_be_installed() {
if [ "$1" = "SystemConfiguration" ]; then echo 1; fi if [ "$1" = "SystemConfiguration" ]; then echo 1; fi
if [ "$1" = "Security" ]; then echo 1; fi if [ "$1" = "Security" ]; then echo 1; fi
if [ "$1" = "AppleFSCompression" ]; then echo 1; fi if [ "$1" = "AppleFSCompression" ]; then echo 1; fi
if [ "$1" = "libsdrplay_api.so.3.14" ]; then echo 1; fi
} }
# ========================= FOR INTERNAL USE ONLY ========================= # ========================= FOR INTERNAL USE ONLY =========================

View File

@ -45,7 +45,6 @@ bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/rtl_tcp_source/rtl_tcp_source.dylib bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/rtl_tcp_source/rtl_tcp_source.dylib
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/sdrplay_source/sdrplay_source.dylib bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/sdrplay_source/sdrplay_source.dylib
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/sdrpp_server_source/sdrpp_server_source.dylib bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/sdrpp_server_source/sdrpp_server_source.dylib
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/soapy_source/soapy_source.dylib
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/spyserver_source/spyserver_source.dylib bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/spyserver_source/spyserver_source.dylib
# bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/usrp_source/usrp_source.dylib # bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/usrp_source/usrp_source.dylib

View File

@ -51,8 +51,6 @@ cp 'C:/Program Files/SDRplay/API/x64/sdrplay_api.dll' sdrpp_windows_x64/ -ErrorA
cp $build_dir/source_modules/sdrpp_server_source/Release/sdrpp_server_source.dll sdrpp_windows_x64/modules/ cp $build_dir/source_modules/sdrpp_server_source/Release/sdrpp_server_source.dll sdrpp_windows_x64/modules/
cp $build_dir/source_modules/soapy_source/Release/soapy_source.dll sdrpp_windows_x64/modules/
cp $build_dir/source_modules/spyserver_source/Release/spyserver_source.dll sdrpp_windows_x64/modules/ cp $build_dir/source_modules/spyserver_source/Release/spyserver_source.dll sdrpp_windows_x64/modules/
# cp $build_dir/source_modules/usrp_source/Release/usrp_source.dll sdrpp_windows_x64/modules/ # cp $build_dir/source_modules/usrp_source/Release/usrp_source.dll sdrpp_windows_x64/modules/
@ -79,6 +77,8 @@ cp $build_dir/misc_modules/discord_integration/Release/discord_integration.dll s
cp $build_dir/misc_modules/frequency_manager/Release/frequency_manager.dll sdrpp_windows_x64/modules/ cp $build_dir/misc_modules/frequency_manager/Release/frequency_manager.dll sdrpp_windows_x64/modules/
cp $build_dir/misc_modules/iq_exporter/Release/iq_exporter.dll sdrpp_windows_x64/modules/
cp $build_dir/misc_modules/recorder/Release/recorder.dll sdrpp_windows_x64/modules/ cp $build_dir/misc_modules/recorder/Release/recorder.dll sdrpp_windows_x64/modules/
cp $build_dir/misc_modules/rigctl_client/Release/rigctl_client.dll sdrpp_windows_x64/modules/ cp $build_dir/misc_modules/rigctl_client/Release/rigctl_client.dll sdrpp_windows_x64/modules/

View File

@ -485,7 +485,7 @@ private:
} }
// Bookmark list // Bookmark list
if (ImGui::BeginTable(("freq_manager_bkm_table" + _this->name).c_str(), 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 200))) { if (ImGui::BeginTable(("freq_manager_bkm_table" + _this->name).c_str(), 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 200.0f * style::uiScale))) {
ImGui::TableSetupColumn("Name"); ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("Bookmark"); ImGui::TableSetupColumn("Bookmark");
ImGui::TableSetupScrollFreeze(2, 1); ImGui::TableSetupScrollFreeze(2, 1);

View File

@ -408,9 +408,9 @@ private:
if (!_this->enabled) { ImGui::EndDisabled(); } if (!_this->enabled) { ImGui::EndDisabled(); }
} }
void setMode(Mode newMode, bool fromDisabled = false) { void setMode(Mode newMode, bool forceSet = false) {
// If there is no mode to change, do nothing // If there is no mode to change, do nothing
if (!fromDisabled && mode == newMode) { return; } if (!forceSet && mode == newMode) { return; }
// Stop the DSP // Stop the DSP
reshape.stop(); reshape.stop();
@ -421,14 +421,13 @@ private:
sigpath::vfoManager.deleteVFO(vfo); sigpath::vfoManager.deleteVFO(vfo);
vfo = NULL; vfo = NULL;
} }
if (mode == MODE_BASEBAND && !fromDisabled) { if (streamBound) {
sigpath::iqFrontEnd.unbindIQStream(&iqStream); sigpath::iqFrontEnd.unbindIQStream(&iqStream);
streamBound = false;
} }
// If the mode was none, we're done // If the mode was none, we're done
if (newMode == MODE_NONE) { if (newMode == MODE_NONE) { return; }
return;
}
// Create VFO or bind IQ stream // Create VFO or bind IQ stream
if (newMode == MODE_VFO) { if (newMode == MODE_VFO) {
@ -441,6 +440,7 @@ private:
else { else {
// Bind IQ stream // Bind IQ stream
sigpath::iqFrontEnd.bindIQStream(&iqStream); sigpath::iqFrontEnd.bindIQStream(&iqStream);
streamBound = true;
// Set its output as the input to the DSP // Set its output as the input to the DSP
reshape.setInput(&iqStream); reshape.setInput(&iqStream);
@ -509,7 +509,7 @@ private:
size = sizeof(int16_t)*2; size = sizeof(int16_t)*2;
break; break;
case SAMPLE_TYPE_INT32: case SAMPLE_TYPE_INT32:
volk_32f_s32f_convert_32i((int32_t*)_this->buffer, (float*)data, (float)2147483647.0f, count*2); volk_32f_s32f_convert_32i((int32_t*)_this->buffer, (float*)data, 2147483647.0f, count*2);
size = sizeof(int32_t)*2; size = sizeof(int32_t)*2;
break; break;
case SAMPLE_TYPE_FLOAT32: case SAMPLE_TYPE_FLOAT32:
@ -555,6 +555,7 @@ private:
OptionList<int, int> packetSizes; OptionList<int, int> packetSizes;
VFOManager::VFO* vfo = NULL; VFOManager::VFO* vfo = NULL;
bool streamBound = false;
dsp::stream<dsp::complex_t> iqStream; dsp::stream<dsp::complex_t> iqStream;
dsp::buffer::Reshaper<dsp::complex_t> reshape; dsp::buffer::Reshaper<dsp::complex_t> reshape;
dsp::sink::Handler<dsp::complex_t> handler; dsp::sink::Handler<dsp::complex_t> handler;
@ -570,7 +571,7 @@ private:
MOD_EXPORT void _INIT_() { MOD_EXPORT void _INIT_() {
json def = json({}); json def = json({});
std::string root = (std::string)core::args["root"]; std::string root = (std::string)core::args["root"];
config.setPath(root + "/iq_exporter_config_config.json"); config.setPath(root + "/iq_exporter_config.json");
config.load(def); config.load(def);
config.enableAutoSave(); config.enableAutoSave();
} }

View File

@ -86,7 +86,7 @@ public:
} }
// Switch source to panadapter mode // Switch source to panadapter mode
sigpath::sourceManager.setPanadpterIF(ifFreq); sigpath::sourceManager.setPanadapterIF(ifFreq);
sigpath::sourceManager.setTuningMode(SourceManager::TuningMode::PANADAPTER); sigpath::sourceManager.setTuningMode(SourceManager::TuningMode::PANADAPTER);
sigpath::sourceManager.onRetune.bindHandler(&_retuneHandler); sigpath::sourceManager.onRetune.bindHandler(&_retuneHandler);
@ -131,7 +131,7 @@ private:
ImGui::FillWidth(); ImGui::FillWidth();
if (ImGui::InputDouble(CONCAT("##_rigctl_if_freq_", _this->name), &_this->ifFreq, 100.0, 100000.0, "%.0f")) { if (ImGui::InputDouble(CONCAT("##_rigctl_if_freq_", _this->name), &_this->ifFreq, 100.0, 100000.0, "%.0f")) {
if (_this->running) { if (_this->running) {
sigpath::sourceManager.setPanadpterIF(_this->ifFreq); sigpath::sourceManager.setPanadapterIF(_this->ifFreq);
} }
config.acquire(); config.acquire();
config.conf[_this->name]["ifFreq"] = _this->ifFreq; config.conf[_this->name]["ifFreq"] = _this->ifFreq;

View File

@ -334,7 +334,7 @@ private:
} }
std::map<int, const char*> radioModeToString = { std::map<int, const char*> radioModeToString = {
{ RADIO_IFACE_MODE_NFM, "NFM" }, { RADIO_IFACE_MODE_NFM, "FM" },
{ RADIO_IFACE_MODE_WFM, "WFM" }, { RADIO_IFACE_MODE_WFM, "WFM" },
{ RADIO_IFACE_MODE_AM, "AM" }, { RADIO_IFACE_MODE_AM, "AM" },
{ RADIO_IFACE_MODE_DSB, "DSB" }, { RADIO_IFACE_MODE_DSB, "DSB" },

View File

@ -89,7 +89,7 @@ private:
} }
} }
if (ImGui::BeginTable(("freq_manager_bkm_table" + _this->name).c_str(), 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 200))) { if (ImGui::BeginTable(("freq_manager_bkm_table" + _this->name).c_str(), 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 200.0f * style::uiScale))) {
ImGui::TableSetupColumn("Name"); ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("Countdown"); ImGui::TableSetupColumn("Countdown");
ImGui::TableSetupScrollFreeze(2, 1); ImGui::TableSetupScrollFreeze(2, 1);

View File

@ -52,7 +52,7 @@ public:
} }
} }
if (ImGui::BeginTable("scheduler_task_triggers", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 100))) { if (ImGui::BeginTable("scheduler_task_triggers", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 100.0f * style::uiScale))) {
ImGui::TableSetupColumn("Triggers"); ImGui::TableSetupColumn("Triggers");
ImGui::TableSetupScrollFreeze(1, 1); ImGui::TableSetupScrollFreeze(1, 1);
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
@ -65,7 +65,7 @@ public:
ImGui::EndTable(); ImGui::EndTable();
} }
if (ImGui::BeginTable("scheduler_task_actions", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 100))) { if (ImGui::BeginTable("scheduler_task_actions", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 100.0f * style::uiScale))) {
ImGui::TableSetupColumn("Actions"); ImGui::TableSetupColumn("Actions");
ImGui::TableSetupScrollFreeze(1, 1); ImGui::TableSetupScrollFreeze(1, 1);
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();

View File

@ -44,7 +44,7 @@ Download the latest release from [the Releases page](https://github.com/Alexandr
Then, run: Then, run:
```sh ```sh
sudo apt install libfftw3-dev libglfw3-dev libvolk2-dev libzstd-dev libsoapysdr-dev libairspyhf-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev sudo apt install libfftw3-dev libglfw3-dev libvolk2-dev libzstd-dev libairspyhf-dev libiio-dev libad9361-dev librtaudio-dev libhackrf-dev
sudo dpkg -i sdrpp_debian_amd64.deb sudo dpkg -i sdrpp_debian_amd64.deb
``` ```
@ -135,7 +135,6 @@ As mentioned previously you need to edit `root_dev/config.json` to add the modul
"./build/radio/Release/radio.dll", "./build/radio/Release/radio.dll",
"./build/recorder/Release/recorder.dll", "./build/recorder/Release/recorder.dll",
"./build/rtl_tcp_source/Release/rtl_tcp_source.dll", "./build/rtl_tcp_source/Release/rtl_tcp_source.dll",
"./build/soapy_source/Release/soapy_source.dll",
"./build/audio_sink/Release/audio_sink.dll" "./build/audio_sink/Release/audio_sink.dll"
] ]
... ...
@ -166,7 +165,6 @@ The modules built will be some of the following (Repeat the instructions above f
* `build/recorder/Release/` * `build/recorder/Release/`
* `build/rtl_tcp_source/Release/` * `build/rtl_tcp_source/Release/`
* `build/spyserver_source/Release/` * `build/spyserver_source/Release/`
* `build/soapy_source/Release/`
* `build/airspyhf_source/Release/` * `build/airspyhf_source/Release/`
* `build/plutosdr_source/Release/` * `build/plutosdr_source/Release/`
* `build/audio_sink/Release/` * `build/audio_sink/Release/`
@ -176,13 +174,9 @@ The modules built will be some of the following (Repeat the instructions above f
## Select which modules you wish to build ## Select which modules you wish to build
Depending on which module you want to build, you will need to install some additional dependencies. 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 particular dependency (or can't, eg. the BladeRF module on Debian Buster), Please refer to the module list table further down in this readme for the names, dependencies and build options of each module.
you can disable it using the module parameter listed in the table below
* soapy_source: SoapySDR + drivers for each SDRs (see SoapySDR docs) The build options are then passed to the cmake command as such `cmake .. -DOPTION_NAME_HERE=ON -DANOTHER_OPTION_HERE=OFF` etc...
* airspyhf_source: libairspyhf
* plutosdr_source: libiio, libad9361
* audio_sink: librtaudio-dev
## Install dependencies ## Install dependencies
@ -231,7 +225,6 @@ Then, you will need to edit the `root_dev/config.json` file to point to the modu
"./build/radio/radio.so", "./build/radio/radio.so",
"./build/recorder/recorder.so", "./build/recorder/recorder.so",
"./build/rtl_tcp_source/rtl_tcp_source.so", "./build/rtl_tcp_source/rtl_tcp_source.so",
"./build/soapy_source/soapy_source.so",
"./build/audio_sink/audio_sink.so" "./build/audio_sink/audio_sink.so"
] ]
... ...
@ -329,11 +322,13 @@ Modules in beta are still included in releases for the most part but not enabled
|----------------------|------------|-------------------|--------------------------------|:---------------:|:-----------------------:|:---------------------------:| |----------------------|------------|-------------------|--------------------------------|:---------------:|:-----------------------:|:---------------------------:|
| airspy_source | Working | libairspy | OPT_BUILD_AIRSPY_SOURCE | ✅ | ✅ | ✅ | | airspy_source | Working | libairspy | OPT_BUILD_AIRSPY_SOURCE | ✅ | ✅ | ✅ |
| airspyhf_source | Working | libairspyhf | OPT_BUILD_AIRSPYHF_SOURCE | ✅ | ✅ | ✅ | | airspyhf_source | Working | libairspyhf | OPT_BUILD_AIRSPYHF_SOURCE | ✅ | ✅ | ✅ |
| audio_source | Working | rtaudio | OPT_BUILD_AUDIO_SOURCE | ✅ | ✅ | ✅ |
| bladerf_source | Working | libbladeRF | OPT_BUILD_BLADERF_SOURCE | ⛔ | ✅ (not Debian Buster) | ✅ | | bladerf_source | Working | libbladeRF | OPT_BUILD_BLADERF_SOURCE | ⛔ | ✅ (not Debian Buster) | ✅ |
| file_source | Working | - | OPT_BUILD_FILE_SOURCE | ✅ | ✅ | ✅ | | file_source | Working | - | OPT_BUILD_FILE_SOURCE | ✅ | ✅ | ✅ |
| hackrf_source | Working | libhackrf | OPT_BUILD_HACKRF_SOURCE | ✅ | ✅ | ✅ | | hackrf_source | Working | libhackrf | OPT_BUILD_HACKRF_SOURCE | ✅ | ✅ | ✅ |
| hermes_source | Beta | - | OPT_BUILD_HERMES_SOURCE | ✅ | ✅ | ✅ | | hermes_source | Beta | - | OPT_BUILD_HERMES_SOURCE | ✅ | ✅ | ✅ |
| limesdr_source | Working | liblimesuite | OPT_BUILD_LIMESDR_SOURCE | ⛔ | ✅ | ✅ | | limesdr_source | Working | liblimesuite | OPT_BUILD_LIMESDR_SOURCE | ⛔ | ✅ | ✅ |
| network_source | Unfinished | - | OPT_BUILD_NETWORK_SOURCE | ✅ | ✅ | ⛔ |
| perseus_source | Beta | libperseus-sdr | OPT_BUILD_PERSEUS_SOURCE | ⛔ | ✅ | ✅ | | perseus_source | Beta | libperseus-sdr | OPT_BUILD_PERSEUS_SOURCE | ⛔ | ✅ | ✅ |
| plutosdr_source | Working | libiio, libad9361 | OPT_BUILD_PLUTOSDR_SOURCE | ✅ | ✅ | ✅ | | plutosdr_source | Working | libiio, libad9361 | OPT_BUILD_PLUTOSDR_SOURCE | ✅ | ✅ | ✅ |
| rfspace_source | Working | - | OPT_BUILD_RFSPACE_SOURCE | ✅ | ✅ | ✅ | | rfspace_source | Working | - | OPT_BUILD_RFSPACE_SOURCE | ✅ | ✅ | ✅ |
@ -341,9 +336,9 @@ Modules in beta are still included in releases for the most part but not enabled
| rtl_tcp_source | Working | - | OPT_BUILD_RTL_TCP_SOURCE | ✅ | ✅ | ✅ | | rtl_tcp_source | Working | - | OPT_BUILD_RTL_TCP_SOURCE | ✅ | ✅ | ✅ |
| sdrplay_source | Working | SDRplay API | OPT_BUILD_SDRPLAY_SOURCE | ⛔ | ✅ | ✅ | | sdrplay_source | Working | SDRplay API | OPT_BUILD_SDRPLAY_SOURCE | ⛔ | ✅ | ✅ |
| sdrpp_server_source | Working | - | OPT_BUILD_SDRPP_SERVER_SOURCE | ✅ | ✅ | ✅ | | sdrpp_server_source | Working | - | OPT_BUILD_SDRPP_SERVER_SOURCE | ✅ | ✅ | ✅ |
| soapy_source | Working | soapysdr | OPT_BUILD_SOAPY_SOURCE | ✅ | ✅ | ✅ | | soapy_source | Deprecated | soapysdr | OPT_BUILD_SOAPY_SOURCE | ⛔ | ⛔ | ⛔ |
| spectran_source | Unfinished | RTSA Suite | OPT_BUILD_SPECTRAN_SOURCE | ⛔ | ⛔ | ⛔ | | spectran_source | Unfinished | RTSA Suite | OPT_BUILD_SPECTRAN_SOURCE | ⛔ | ⛔ | ⛔ |
| spectran_http_source | Unfinished | - | OPT_BUILD_SPECTRAN_HTTP_SOURCE | ✅ | ✅ | ⛔ | | spectran_http_source | Beta | - | OPT_BUILD_SPECTRAN_HTTP_SOURCE | ✅ | ✅ | ⛔ |
| spyserver_source | Working | - | OPT_BUILD_SPYSERVER_SOURCE | ✅ | ✅ | ✅ | | spyserver_source | Working | - | OPT_BUILD_SPYSERVER_SOURCE | ✅ | ✅ | ✅ |
| usrp_source | Beta | libuhd | OPT_BUILD_USRP_SOURCE | ⛔ | ⛔ | ⛔ | | usrp_source | Beta | libuhd | OPT_BUILD_USRP_SOURCE | ⛔ | ⛔ | ⛔ |
@ -362,10 +357,9 @@ Modules in beta are still included in releases for the most part but not enabled
| Name | Stage | Dependencies | Option | Built by default| Built in Release | Enabled in SDR++ by default | | Name | Stage | Dependencies | Option | Built by default| Built in Release | Enabled in SDR++ by default |
|---------------------|------------|--------------|-------------------------------|:---------------:|:----------------:|:---------------------------:| |---------------------|------------|--------------|-------------------------------|:---------------:|:----------------:|:---------------------------:|
| atv_decoder | Unfinished | - | OPT_BUILD_ATV_DECODER | ⛔ | ⛔ | ⛔ | | atv_decoder | Unfinished | - | OPT_BUILD_ATV_DECODER | ⛔ | ⛔ | ⛔ |
| dmr_decoder | Unfinished | - | OPT_BUILD_DMR_DECODER | ⛔ | ⛔ | ⛔ |
| falcon9_decoder | Unfinished | ffplay | OPT_BUILD_FALCON9_DECODER | ⛔ | ⛔ | ⛔ | | falcon9_decoder | Unfinished | ffplay | OPT_BUILD_FALCON9_DECODER | ⛔ | ⛔ | ⛔ |
| kgsstv_decoder | Unfinished | - | OPT_BUILD_KGSSTV_DECODER | ⛔ | ⛔ | ⛔ | | kgsstv_decoder | Unfinished | - | OPT_BUILD_KGSSTV_DECODER | ⛔ | ⛔ | ⛔ |
| m17_decoder | Beta | - | OPT_BUILD_M17_DECODER | ⛔ | ✅ | ⛔ | | m17_decoder | Working | - | OPT_BUILD_M17_DECODER | ⛔ | ✅ | ⛔ |
| meteor_demodulator | Working | - | OPT_BUILD_METEOR_DEMODULATOR | ✅ | ✅ | ⛔ | | meteor_demodulator | Working | - | OPT_BUILD_METEOR_DEMODULATOR | ✅ | ✅ | ⛔ |
| pager_decoder | Unfinished | - | OPT_BUILD_PAGER_DECODER | ⛔ | ⛔ | ⛔ | | pager_decoder | Unfinished | - | OPT_BUILD_PAGER_DECODER | ⛔ | ⛔ | ⛔ |
| radio | Working | - | OPT_BUILD_RADIO | ✅ | ✅ | ✅ | | radio | Working | - | OPT_BUILD_RADIO | ✅ | ✅ | ✅ |
@ -377,7 +371,7 @@ Modules in beta are still included in releases for the most part but not enabled
|---------------------|------------|--------------|-----------------------------|:----------------:|:----------------:|:---------------------------:| |---------------------|------------|--------------|-----------------------------|:----------------:|:----------------:|:---------------------------:|
| discord_integration | Working | - | OPT_BUILD_DISCORD_PRESENCE | ✅ | ✅ | ⛔ | | discord_integration | Working | - | OPT_BUILD_DISCORD_PRESENCE | ✅ | ✅ | ⛔ |
| frequency_manager | Working | - | OPT_BUILD_FREQUENCY_MANAGER | ✅ | ✅ | ✅ | | frequency_manager | Working | - | OPT_BUILD_FREQUENCY_MANAGER | ✅ | ✅ | ✅ |
| iq_exporter | Unfinished | - | OPT_BUILD_IQ_EXPORTER | ⛔ | ⛔ | ⛔ | | iq_exporter | Working | - | OPT_BUILD_IQ_EXPORTER | ✅ | ✅ | ⛔ |
| recorder | Working | - | OPT_BUILD_RECORDER | ✅ | ✅ | ✅ | | recorder | Working | - | OPT_BUILD_RECORDER | ✅ | ✅ | ✅ |
| rigctl_client | Unfinished | - | OPT_BUILD_RIGCTL_CLIENT | ✅ | ✅ | ⛔ | | rigctl_client | Unfinished | - | OPT_BUILD_RIGCTL_CLIENT | ✅ | ✅ | ⛔ |
| rigctl_server | Working | - | OPT_BUILD_RIGCTL_SERVER | ✅ | ✅ | ✅ | | rigctl_server | Working | - | OPT_BUILD_RIGCTL_SERVER | ✅ | ✅ | ✅ |
@ -433,6 +427,7 @@ I will soon publish a contributing.md listing the code style to use.
* Croccydile * Croccydile
* Dale L Puckett (K0HYD) * Dale L Puckett (K0HYD)
* [Daniele D'Agnelli](https://linkedin.com/in/dagnelli) * [Daniele D'Agnelli](https://linkedin.com/in/dagnelli)
* [David Taylor (GM8ARV)](https://twitter.com/gm8arv)
* D. Jones * D. Jones
* Dexruus * Dexruus
* [EB3FRN](https://www.eb3frn.net/) * [EB3FRN](https://www.eb3frn.net/)
@ -460,6 +455,7 @@ I will soon publish a contributing.md listing the code style to use.
* Syne Ardwin (WI9SYN) * Syne Ardwin (WI9SYN)
* [W4IPA](https://twitter.com/W4IPAstroke5) * [W4IPA](https://twitter.com/W4IPAstroke5)
* William Arcand (W1WRA) * William Arcand (W1WRA)
* William Pitchford
* [Yves Rougy](https://www.twitch.tv/yorzian) * [Yves Rougy](https://www.twitch.tv/yorzian)
* [Zipper](https://github.com/reppiZ) * [Zipper](https://github.com/reppiZ)

View File

@ -2,74 +2,290 @@
"name": "Germany", "name": "Germany",
"country_name": "Germany", "country_name": "Germany",
"country_code": "DE", "country_code": "DE",
"author_name": "Manawyrm", "author_name": "Manawyrm, LEDFlighter",
"author_url": "https://tbspace.de", "author_url": "https://tbspace.de",
"bands": [ "bands": [
{ {
"name": "LW", "name": "LW-Amateur",
"type": "amateur", "type": "amateur",
"start": 135700, "start": 135700,
"end": 137800 "end": 137800
}, },
{ {
"name": "630m", "name": "LW-Broadcast",
"type": "broadcast",
"start": 148500,
"end": 283500
},
{
"name": "630m-Amateur",
"type": "amateur", "type": "amateur",
"start": 472000, "start": 472000,
"end": 479000 "end": 479000
}, },
{ {
"name": "160m", "name": "MW-Broadcast",
"type": "broadcast",
"start": 526500,
"end": 1606500
},
{
"name": "160m-Amateur",
"type": "amateur", "type": "amateur",
"start": 1810000, "start": 1810000,
"end": 2000000 "end": 2000000
}, },
{ {
"name": "80m", "name": "Maritime",
"type": "marine",
"start": 2045000,
"end": 2300000
},
{
"name": "120m-Broadcast",
"type": "broadcast",
"start": 2300000,
"end": 2495000
},
{
"name": "Aeronautical HF",
"type": "aviation",
"start": 2850000,
"end": 3155000
},
{
"name": "90m-Broadcast",
"type": "broadcast",
"start": 3200000,
"end": 3400000
},
{
"name": "Aeronautical HF",
"type": "aviation",
"start": 3400000,
"end": 3500000
},
{
"name": "80m-Amateur",
"type": "amateur", "type": "amateur",
"start": 3500000, "start": 3500000,
"end": 3800000 "end": 3800000
}, },
{ {
"name": "60m", "name": "75m-Broadcast",
"type": "broadcast",
"start": 3900000,
"end": 4000000
},
{
"name": "Maritime",
"type": "marine",
"start": 4063000,
"end": 4438000
},
{
"name": "Aeronautical HF",
"type": "aviation",
"start": 4650000,
"end": 4750000
},
{
"name": "60m-Broadcast",
"type": "broadcast",
"start": 4750000,
"end": 5060000
},
{
"name": "60m-Amateur",
"type": "amateur", "type": "amateur",
"start": 5351500, "start": 5351500,
"end": 5366500 "end": 5366500
}, },
{ {
"name": "40m", "name": "Aeronautical HF",
"type": "aviation",
"start": 5480000,
"end": 5730000
},
{
"name": "49m-Broadcast",
"type": "broadcast",
"start": 5900000,
"end": 6200000
},
{
"name": "Maritime",
"type": "marine",
"start": 6200000,
"end": 6525000
},
{
"name": "Aeronautical HF",
"type": "aviation",
"start": 6525000,
"end": 6765000
},
{
"name": "40m-Amateur",
"type": "amateur", "type": "amateur",
"start": 7000000, "start": 7000000,
"end": 7200000 "end": 7200000
}, },
{ {
"name": "30m", "name": "41m-Broadcast",
"type": "broadcast",
"start": 7200000,
"end": 7450000
},
{
"name": "Maritime",
"type": "marine",
"start": 8195000,
"end": 8815000
},
{
"name": "31m-Broadcast",
"type": "broadcast",
"start": 9400000,
"end": 9900000
},
{
"name": "Aeronautical HF",
"type": "aviation",
"start": 8815000,
"end": 9040000
},
{
"name": "Aeronautical HF",
"type": "aviation",
"start": 10005000,
"end": 10100000
},
{
"name": "30m-Amateur",
"type": "amateur", "type": "amateur",
"start": 10100000, "start": 10100000,
"end": 10150000 "end": 10150000
}, },
{ {
"name": "20m", "name": "Aeronautical HF",
"type": "aviation",
"start": 11175000,
"end": 11400000
},
{
"name": "25m-Broadcast",
"type": "broadcast",
"start": 11600000,
"end": 12100000
},
{
"name": "Maritime",
"type": "marine",
"start": 12230000,
"end": 13200000
},
{
"name": "Aeronautical HF",
"type": "aviation",
"start": 13200000,
"end": 13360000
},
{
"name": "22m-Broadcast",
"type": "broadcast",
"start": 13570000,
"end": 13870000
},
{
"name": "20m-Amateur",
"type": "amateur", "type": "amateur",
"start": 14000000, "start": 14000000,
"end": 14350000 "end": 14350000
}, },
{ {
"name": "17m", "name": "Aeronautical HF",
"type": "aviation",
"start": 15010000,
"end": 15100000
},
{
"name": "Maritime",
"type": "marine",
"start": 16360000,
"end": 17410000
},
{
"name": "19m-Broadcast",
"type": "broadcast",
"start": 15100000,
"end": 15800000
},
{
"name": "16m-Broadcast",
"type": "broadcast",
"start": 17480000,
"end": 17900000
},
{
"name": "17m-Amateur",
"type": "amateur", "type": "amateur",
"start": 18068000, "start": 18068000,
"end": 18168000 "end": 18168000
}, },
{ {
"name": "15m", "name": "Maritime - ship tx",
"type": "marine",
"start": 18780000,
"end": 18900000
},
{
"name": "15m-Broadcast",
"type": "broadcast",
"start": 18900000,
"end": 19020000
},
{
"name": "Maritime - coast tx",
"type": "marine",
"start": 19680000,
"end": 19990000
},
{
"name": "15m-Amateur",
"type": "amateur", "type": "amateur",
"start": 21000000, "start": 21000000,
"end": 21450000 "end": 21450000
}, },
{ {
"name": "12m", "name": "13m-Broadcast",
"type": "broadcast",
"start": 21450000,
"end": 21850000
},
{
"name": "Aeronautical HF",
"type": "aviation",
"start": 21870000,
"end": 22000000
},
{
"name": "Aeronautical HF",
"type": "aviation",
"start": 23200000,
"end": 23350000
},
{
"name": "12m-Amateur",
"type": "amateur", "type": "amateur",
"start": 24890000, "start": 24890000,
"end": 24990000 "end": 24990000
},
{
"name": "11m-Broadcast",
"type": "broadcast",
"start": 25670000,
"end": 26100000
}, },
{ {
"name": "CB", "name": "CB",
@ -78,31 +294,55 @@
"end": 27405000 "end": 27405000
}, },
{ {
"name": "10m", "name": "10m-Amateur",
"type": "amateur", "type": "amateur",
"start": 28000000, "start": 28000000,
"end": 29700000 "end": 29700000
}, },
{ {
"name": "6m", "name": "6m-Amateur",
"type": "amateur", "type": "amateur",
"start": 50030000, "start": 50030000,
"end": 51000000 "end": 51000000
}, },
{ {
"name": "4m", "name": "4m-Amateur",
"type": "amateur", "type": "amateur",
"start": 70150000, "start": 70150000,
"end": 70200000 "end": 70200000
}, },
{ {
"name": "FM", "name": "FM-Broadcast",
"type": "broadcast", "type": "broadcast",
"start": 87500000, "start": 87500000,
"end": 108000000 "end": 108000000
}, },
{ {
"name": "2m", "name": "Air Band VOR/ILS",
"type": "aviation",
"start": 108000000,
"end": 118000000
},
{
"name": "Air Band Voice",
"type": "aviation",
"start": 118000000,
"end": 136700000
},
{
"name": "Air Band CPDLC/Datalink",
"type": "aviation",
"start": 136700000,
"end": 137000000
},
{
"name": "Earth orbiting Satellites",
"type": "satellite",
"start": 137000000,
"end": 138000000
},
{
"name": "2m-Amateur",
"type": "amateur", "type": "amateur",
"start": 144000000, "start": 144000000,
"end": 146000000 "end": 146000000
@ -114,7 +354,49 @@
"end": 149115625 "end": 149115625
}, },
{ {
"name": "70cm", "name": "Marine",
"type": "marine",
"start": 156000000,
"end": 162025000
},
{
"name": "Pager BOS",
"type": "other",
"start": 163000000,
"end": 174000000
},
{
"name": "DAB+ (digital broadcast)",
"type": "broadcast",
"start": 174000000,
"end": 225000000
},
{
"name": "Air Band Military",
"type": "military",
"start": 225000000,
"end": 380000000
},
{
"name": "TETRA BOS",
"type": "other",
"start": 388000000,
"end": 397000000
},
{
"name": "Weathersondes",
"type": "other",
"start": 401000000,
"end": 410000000
},
{
"name": "TETRA Civil",
"type": "other",
"start": 423000000,
"end": 430000000
},
{
"name": "70cm-Amateur",
"type": "amateur", "type": "amateur",
"start": 430000000, "start": 430000000,
"end": 440000000 "end": 440000000
@ -126,16 +408,58 @@
"end": 446196875 "end": 446196875
}, },
{ {
"name": "23cm", "name": "Pager Civil",
"type": "other",
"start": 446500000,
"end": 470000000
},
{
"name": "DVB-T2 (TV)",
"type": "broadcast",
"start": 470000000,
"end": 690000000
},
{
"name": "868 MHz ISM-Devices",
"type": "other",
"start": 866500000,
"end": 871000000
},
{
"name": "23cm-Amateur",
"type": "amateur", "type": "amateur",
"start": 1240000000, "start": 1240000000,
"end": 1300000000 "end": 1300000000
}, },
{ {
"name": "13cm", "name": "L-Band",
"type": "other",
"start": 1300000000,
"end": 2000000000
},
{
"name": "13cm-Amateur",
"type": "amateur", "type": "amateur",
"start": 2320000000, "start": 2320000000,
"end": 2450000000 "end": 2450000000
},
{
"name": "9cm-Amateur",
"type": "amateur",
"start": 3400000000,
"end": 3475000000
},
{
"name": "6cm-Amateur",
"type": "amateur",
"start": 5650000000,
"end": 5850000000
},
{
"name": "3cm-Amateur",
"type": "amateur",
"start": 10000000000,
"end": 10500000000
} }
] ]
} }

View File

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.13)
project(network_source)
file(GLOB SRC "src/*.cpp")
include(${SDRPP_MODULE_CMAKE})

View File

@ -0,0 +1,366 @@
#include <utils/net.h>
#include <utils/flog.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 <gui/smgui.h>
#include <gui/widgets/stepped_slider.h>
#include <utils/optionlist.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
SDRPP_MOD_INFO{
/* Name: */ "network_source",
/* Description: */ "UDP/TCP Source Module",
/* Author: */ "Ryzerth",
/* Version: */ 0, 1, 0,
/* Max instances */ 1
};
ConfigManager config;
enum Protocol {
PROTOCOL_TCP_SERVER,
PROTOCOL_TCP_CLIENT,
PROTOCOL_UDP
};
enum SampleType {
SAMPLE_TYPE_INT8,
SAMPLE_TYPE_INT16,
SAMPLE_TYPE_INT32,
SAMPLE_TYPE_FLOAT32
};
const size_t SAMPLE_TYPE_SIZE[] {
sizeof(int8_t)*2,
sizeof(int16_t)*2,
sizeof(int32_t)*2,
sizeof(float)*2,
};
class NetworkSourceModule : public ModuleManager::Instance {
public:
NetworkSourceModule(std::string name) {
this->name = name;
samplerate = 1000000.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;
// Define samplerates
for (int i = 3000; i <= 192000; i <<= 1) {
samplerates.define(i, getSrScaled(i), i);
}
for (int i = 250000; i < 1000000; i += 250000) {
samplerates.define(i, getSrScaled(i), i);
}
for (int i = 1000000; i < 10000000; i += 500000) {
samplerates.define(i, getSrScaled(i), i);
}
for (int i = 10000000; i <= 100000000; i += 5000000) {
samplerates.define(i, getSrScaled(i), i);
}
// Define protocols
// protocols.define("TCP (Server)", PROTOCOL_TCP_SERVER);
protocols.define("TCP (Client)", PROTOCOL_TCP_CLIENT);
protocols.define("UDP", PROTOCOL_UDP);
// Define sample types
sampleTypes.define("Int8", SAMPLE_TYPE_INT8);
sampleTypes.define("Int16", SAMPLE_TYPE_INT16);
sampleTypes.define("Int32", SAMPLE_TYPE_INT32);
sampleTypes.define("Float32", SAMPLE_TYPE_FLOAT32);
// Load config
config.acquire();
if (config.conf[name].contains("samplerate")) {
int sr = config.conf[name]["samplerate"];
if (samplerates.keyExists(sr)) { samplerate = samplerates.value(samplerates.keyId(sr)); }
}
if (config.conf[name].contains("protocol")) {
std::string protoStr = config.conf[name]["protocol"];
if (protocols.keyExists(protoStr)) { proto = protocols.value(protocols.keyId(protoStr)); }
}
if (config.conf[name].contains("sampleType")) {
std::string sampTypeStr = config.conf[name]["sampleType"];
if (sampleTypes.keyExists(sampTypeStr)) { sampType = sampleTypes.value(sampleTypes.keyId(sampTypeStr)); }
}
if (config.conf[name].contains("host")) {
std::string hostStr = config.conf[name]["host"];
strcpy(hostname, hostStr.c_str());
}
if (config.conf[name].contains("port")) {
port = config.conf[name]["port"];
port = std::clamp<int>(port, 1, 65535);
}
config.release();
// Set menu IDs
srId = samplerates.valueId(samplerate);
protoId = protocols.valueId(proto);
sampTypeId = sampleTypes.valueId(sampType);
sigpath::sourceManager.registerSource("Network", &handler);
}
~NetworkSourceModule() {
stop(this);
sigpath::sourceManager.unregisterSource("Network");
}
void postInit() {}
void enable() {
enabled = true;
}
void disable() {
enabled = false;
}
bool isEnabled() {
return enabled;
}
private:
std::string getSrScaled(double sr) {
char buf[1024];
if (sr >= 1000000.0) {
sprintf(buf, "%.1lf MS/s", sr / 1000000.0);
}
else if (sr >= 1000.0) {
sprintf(buf, "%.1lf KS/s", sr / 1000.0);
}
else {
sprintf(buf, "%.1lf S/s", sr);
}
return std::string(buf);
}
static void menuSelected(void* ctx) {
NetworkSourceModule* _this = (NetworkSourceModule*)ctx;
core::setInputSampleRate(_this->samplerate);
flog::info("NetworkSourceModule '{0}': Menu Select!", _this->name);
}
static void menuDeselected(void* ctx) {
NetworkSourceModule* _this = (NetworkSourceModule*)ctx;
flog::info("NetworkSourceModule '{0}': Menu Deselect!", _this->name);
}
static void start(void* ctx) {
NetworkSourceModule* _this = (NetworkSourceModule*)ctx;
if (_this->running) { return; }
// Depends on protocol
try {
if (_this->proto == PROTOCOL_TCP_SERVER) {
// Create TCP listener
// TODO
// Start listen worker
// TODO
}
else if (_this->proto == PROTOCOL_TCP_CLIENT) {
// Connect to TCP server
_this->sock = net::connect(_this->hostname, _this->port);
}
else if (_this->proto == PROTOCOL_UDP) {
// Open UDP socket
_this->sock = net::openudp("0.0.0.0", _this->port, _this->hostname, _this->port, true);
}
}
catch (const std::exception& e) {
flog::error("Could not start Network Source: {}", e.what());
return;
}
// Start receive worker
_this->workerThread = std::thread(&NetworkSourceModule::worker, _this);
_this->running = true;
flog::info("NetworkSourceModule '{0}': Start!", _this->name);
}
static void stop(void* ctx) {
NetworkSourceModule* _this = (NetworkSourceModule*)ctx;
if (!_this->running) { return; }
// Stop listen worker
// TODO
// Close connection
if (_this->sock) { _this->sock->close(); }
// Stop worker thread
_this->stream.stopWriter();
if (_this->workerThread.joinable()) { _this->workerThread.join(); }
_this->stream.clearWriteStop();
_this->running = false;
flog::info("NetworkSourceModule '{0}': Stop!", _this->name);
}
static void tune(double freq, void* ctx) {
NetworkSourceModule* _this = (NetworkSourceModule*)ctx;
if (_this->running) {
// Nothing for now
}
_this->freq = freq;
flog::info("NetworkSourceModule '{0}': Tune: {1}!", _this->name, freq);
}
static void menuHandler(void* ctx) {
NetworkSourceModule* _this = (NetworkSourceModule*)ctx;
if (_this->running) { SmGui::BeginDisabled(); }
// Hostname and port field
if (ImGui::InputText(("##iq_exporter_host_" + _this->name).c_str(), _this->hostname, sizeof(_this->hostname))) {
config.acquire();
config.conf[_this->name]["host"] = _this->hostname;
config.release(true);
}
ImGui::SameLine();
ImGui::FillWidth();
if (ImGui::InputInt(("##iq_exporter_port_" + _this->name).c_str(), &_this->port, 0, 0)) {
_this->port = std::clamp<int>(_this->port, 1, 65535);
config.acquire();
config.conf[_this->name]["port"] = _this->port;
config.release(true);
}
// Samplerate selector
ImGui::LeftLabel("Samplerate");
ImGui::FillWidth();
if (ImGui::Combo(("##iq_exporter_sr_" + _this->name).c_str(), &_this->srId, _this->samplerates.txt)) {
_this->samplerate = _this->samplerates.value(_this->srId);
core::setInputSampleRate(_this->samplerate);
config.acquire();
config.conf[_this->name]["samplerate"] = _this->samplerates.key(_this->srId);
config.release(true);
}
// Mode protocol selector
ImGui::LeftLabel("Protocol");
ImGui::FillWidth();
if (ImGui::Combo(("##iq_exporter_proto_" + _this->name).c_str(), &_this->protoId, _this->protocols.txt)) {
_this->proto = _this->protocols.value(_this->protoId);
config.acquire();
config.conf[_this->name]["protocol"] = _this->protocols.key(_this->protoId);
config.release(true);
}
// Sample type selector
ImGui::LeftLabel("Sample type");
ImGui::FillWidth();
if (ImGui::Combo(("##iq_exporter_samp_" + _this->name).c_str(), &_this->sampTypeId, _this->sampleTypes.txt)) {
_this->sampType = _this->sampleTypes.value(_this->sampTypeId);
config.acquire();
config.conf[_this->name]["sampleType"] = _this->sampleTypes.key(_this->sampTypeId);
config.release(true);
}
if (_this->running) { SmGui::EndDisabled(); }
}
void worker() {
// Compute sizes
int blockSize = samplerate / 200;
int sampleSize = SAMPLE_TYPE_SIZE[sampType];
int frameSize = blockSize*sampleSize;
// Allocate receive buffer
uint8_t* buffer = dsp::buffer::alloc<uint8_t>(frameSize);
while (true) {
// Read samples from socket
int bytes = sock->recv(buffer, frameSize, true);
if (bytes <= 0) { break; }
// Convert to CF32 (note: problem if partial sample)
int count = bytes / sampleSize;
switch (sampType) {
case SAMPLE_TYPE_INT8:
volk_8i_s32f_convert_32f((float*)stream.writeBuf, (int8_t*)buffer, 128.0f, count*2);
break;
case SAMPLE_TYPE_INT16:
volk_16i_s32f_convert_32f((float*)stream.writeBuf, (int16_t*)buffer, 32768.0f, count*2);
break;
case SAMPLE_TYPE_INT32:
volk_32i_s32f_convert_32f((float*)stream.writeBuf, (int32_t*)buffer, 2147483647.0f, count*2);
break;
case SAMPLE_TYPE_FLOAT32:
memcpy(stream.writeBuf, buffer, bytes);
break;
default:
break;
}
// Send out converted samples
if (!stream.swap(count)) { break; }
}
// Free receive buffer
dsp::buffer::free(buffer);
}
std::string name;
bool enabled = true;
dsp::stream<dsp::complex_t> stream;
SourceManager::SourceHandler handler;
bool running = false;
double freq;
int samplerate = 1000000;
int srId;
Protocol proto = PROTOCOL_UDP;
int protoId;
SampleType sampType = SAMPLE_TYPE_INT16;
int sampTypeId;
char hostname[1024] = "localhost";
int port = 1234;
OptionList<int, int> samplerates;
OptionList<std::string, Protocol> protocols;
OptionList<std::string, SampleType> sampleTypes;
std::thread workerThread;
std::thread listenWorkerThread;
std::mutex sockMtx;
std::shared_ptr<net::Socket> sock;
std::shared_ptr<net::Listener> listener;
};
MOD_EXPORT void _INIT_() {
json def = json({});
config.setPath(core::args["root"].s() + "/network_source_config.json");
config.load(def);
config.enableAutoSave();
}
MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) {
return new NetworkSourceModule(name);
}
MOD_EXPORT void _DELETE_INSTANCE_(ModuleManager::Instance* instance) {
delete (NetworkSourceModule*)instance;
}
MOD_EXPORT void _END_() {
config.disableAutoSave();
config.save();
}

View File

@ -30,7 +30,7 @@ namespace server {
dctx = ZSTD_createDCtx(); dctx = ZSTD_createDCtx();
// Initialize DSP // Initialize DSP
decompIn.setBufferSize((sizeof(dsp::complex_t) * STREAM_BUFFER_SIZE) + 8); decompIn.setBufferSize(STREAM_BUFFER_SIZE*sizeof(dsp::complex_t) + 8);
decompIn.clearWriteStop(); decompIn.clearWriteStop();
decomp.init(&decompIn); decomp.init(&decompIn);
link.init(&decomp.out, output); link.init(&decomp.out, output);
@ -42,8 +42,20 @@ namespace server {
// Ask for a UI // Ask for a UI
int res = getUI(); int res = getUI();
if (res == -1) { throw std::runtime_error("Timed out"); } if (res < 0) {
else if (res == -2) { throw std::runtime_error("Server busy"); } // Close client
close();
// Throw error
switch (res) {
case CONN_ERR_TIMEOUT:
throw std::runtime_error("Timed out");
case CONN_ERR_BUSY:
throw std::runtime_error("Server busy");
default:
throw std::runtime_error("Unknown error");
}
}
} }
Client::~Client() { Client::~Client() {
@ -209,7 +221,7 @@ namespace server {
if (!decompIn.swap(r_pkt_hdr->size - sizeof(PacketHeader))) { break; } if (!decompIn.swap(r_pkt_hdr->size - sizeof(PacketHeader))) { break; }
} }
else if (r_pkt_hdr->type == PACKET_TYPE_BASEBAND_COMPRESSED) { else if (r_pkt_hdr->type == PACKET_TYPE_BASEBAND_COMPRESSED) {
size_t outCount = ZSTD_decompressDCtx(dctx, decompIn.writeBuf, STREAM_BUFFER_SIZE, r_pkt_data, r_pkt_hdr->size - sizeof(PacketHeader)); size_t outCount = ZSTD_decompressDCtx(dctx, decompIn.writeBuf, STREAM_BUFFER_SIZE*sizeof(dsp::complex_t)+8, r_pkt_data, r_pkt_hdr->size - sizeof(PacketHeader));
if (outCount) { if (outCount) {
if (!decompIn.swap(outCount)) { break; } if (!decompIn.swap(outCount)) { break; }
}; };
@ -234,7 +246,7 @@ namespace server {
else { else {
if (!serverBusy) { flog::error("Timeout out after asking for UI"); }; if (!serverBusy) { flog::error("Timeout out after asking for UI"); };
waiter->handled(); waiter->handled();
return serverBusy ? -2 : -1; return serverBusy ? CONN_ERR_BUSY : CONN_ERR_TIMEOUT;
} }
waiter->handled(); waiter->handled();
return 0; return 0;

View File

@ -71,6 +71,11 @@ namespace server {
std::mutex handledMtx; std::mutex handledMtx;
}; };
enum ConnectionError {
CONN_ERR_TIMEOUT = -1,
CONN_ERR_BUSY = -2
};
class Client { class Client {
public: public:
Client(std::shared_ptr<net::Socket> sock, dsp::stream<dsp::complex_t>* out); Client(std::shared_ptr<net::Socket> sock, dsp::stream<dsp::complex_t>* out);

View File

@ -81,8 +81,15 @@ public:
private: private:
void refresh() { void refresh() {
devList = SoapySDR::Device::enumerate();
txtDevList = ""; txtDevList = "";
try {
devList = SoapySDR::Device::enumerate();
}
catch (const std::exception& e) {
flog::error("Could not list devices: {}", e.what());
return;
}
int i = 0; int i = 0;
for (auto& dev : devList) { for (auto& dev : devList) {
txtDevList += dev["label"] != "" ? dev["label"] : dev["driver"]; txtDevList += dev["label"] != "" ? dev["label"] : dev["driver"];
@ -153,7 +160,14 @@ private:
return; return;
} }
SoapySDR::Device* dev = SoapySDR::Device::make(devArgs); SoapySDR::Device* dev = NULL;
try {
dev = SoapySDR::Device::make(devArgs);
}
catch (const std::exception& e) {
flog::error("Could not open device: {}", e.what());
return;
}
antennaList = dev->listAntennas(SOAPY_SDR_RX, channelId); antennaList = dev->listAntennas(SOAPY_SDR_RX, channelId);
txtAntennaList = ""; txtAntennaList = "";
@ -307,7 +321,13 @@ private:
return; return;
} }
try {
_this->dev = SoapySDR::Device::make(_this->devArgs); _this->dev = SoapySDR::Device::make(_this->devArgs);
}
catch (const std::exception& e) {
flog::error("Failed to open device: {}", e.what());
return;
}
_this->dev->setSampleRate(SOAPY_SDR_RX, _this->channelId, _this->sampleRate); _this->dev->setSampleRate(SOAPY_SDR_RX, _this->channelId, _this->sampleRate);

View File

@ -144,9 +144,7 @@ private:
_this->tryConnect(); _this->tryConnect();
} }
else if (connected && SmGui::Button("Disconnect##spectran_http_source")) { else if (connected && SmGui::Button("Disconnect##spectran_http_source")) {
_this->client->onCenterFrequencyChanged.unbind(_this->onFreqChangedId); _this->disconnect();
_this->client->onCenterFrequencyChanged.unbind(_this->onSamplerateChangedId);
_this->client->close();
} }
if (_this->running) { style::endDisabled(); } if (_this->running) { style::endDisabled(); }
@ -173,6 +171,12 @@ private:
} }
} }
void disconnect() {
client->onCenterFrequencyChanged.unbind(onFreqChangedId);
client->onSamplerateChanged.unbind(onSamplerateChangedId);
client->close();
}
void onFreqChanged(double newFreq) { void onFreqChanged(double newFreq) {
if (lastReportedFreq == newFreq) { return; } if (lastReportedFreq == newFreq) { return; }
lastReportedFreq = newFreq; lastReportedFreq = newFreq;

View File

@ -11,12 +11,15 @@ SpectranHTTPClient::SpectranHTTPClient(std::string host, int port, dsp::stream<d
sock = net::connect(host, port); sock = net::connect(host, port);
http = net::http::Client(sock); http = net::http::Client(sock);
// Make request // Send sttream request
net::http::RequestHeader rqhdr(net::http::METHOD_GET, "/stream?format=float32", host); net::http::RequestHeader rqhdr(net::http::METHOD_GET, "/stream?format=float32", host);
http.sendRequestHeader(rqhdr); http.sendRequestHeader(rqhdr);
// Receive for response
net::http::ResponseHeader rshdr; net::http::ResponseHeader rshdr;
http.recvResponseHeader(rshdr, 5000); http.recvResponseHeader(rshdr, 5000);
// Check the status
if (rshdr.getStatusCode() != net::http::STATUS_CODE_OK) { if (rshdr.getStatusCode() != net::http::STATUS_CODE_OK) {
flog::error("HTTP request did not return ok: {}", rshdr.getStatusString()); flog::error("HTTP request did not return ok: {}", rshdr.getStatusString());
throw std::runtime_error("HTTP request did not return ok"); throw std::runtime_error("HTTP request did not return ok");
@ -48,20 +51,29 @@ void SpectranHTTPClient::setCenterFrequency(uint64_t freq) {
auto controlSock = net::connect(host, port); auto controlSock = net::connect(host, port);
auto controlHttp = net::http::Client(controlSock); auto controlHttp = net::http::Client(controlSock);
// Make request // Encode request body
net::http::RequestHeader rqhdr(net::http::METHOD_PUT, "/control", host); net::http::RequestHeader rqhdr(net::http::METHOD_PUT, "/remoteconfig", host);
char buf[1024]; char buf[1024];
sprintf(buf, "{\"frequencyCenter\":%" PRIu64 ",\"frequencySpan\":%" PRIu64 ",\"type\":\"capture\"}", freq, _samplerate); sprintf(buf, "{\"receiverName\": \"Block_IQDemodulator_0\", \"simpleconfig\": {\"main\": {\"centerfreq\": %" PRIu64 ", \"samplerate\": %" PRIu64 ", \"spanfreq\": %" PRIu64 "}}}", freq, _samplerate, _samplerate);
std::string data = buf; std::string data = buf;
char lenBuf[16]; char lenBuf[16];
sprintf(lenBuf, "%" PRIu64, (uint64_t)data.size()); sprintf(lenBuf, "%" PRIu64, (uint64_t)data.size());
// Setup request headers
rqhdr.setField("Content-Length", lenBuf); rqhdr.setField("Content-Length", lenBuf);
// Send request
controlHttp.sendRequestHeader(rqhdr); controlHttp.sendRequestHeader(rqhdr);
controlSock->sendstr(data); controlSock->sendstr(data);
// Receive response
net::http::ResponseHeader rshdr; net::http::ResponseHeader rshdr;
controlHttp.recvResponseHeader(rshdr, 5000); controlHttp.recvResponseHeader(rshdr, 5000);
// Log error if there is one
if (rshdr.getStatusCode() < 200 || rshdr.getStatusCode() >= 300) {
flog::debug("Response: {}", rshdr.getStatusString()); flog::debug("Response: {}", rshdr.getStatusString());
}
} }
void SpectranHTTPClient::worker() { void SpectranHTTPClient::worker() {
@ -101,11 +113,10 @@ void SpectranHTTPClient::worker() {
auto sampleFreqEnd = jsonData.find(',', sampleFreqBegin); auto sampleFreqEnd = jsonData.find(',', sampleFreqBegin);
std::string sampleFreqStr = jsonData.substr(sampleFreqBegin + 18, sampleFreqEnd - sampleFreqBegin - 18); std::string sampleFreqStr = jsonData.substr(sampleFreqBegin + 18, sampleFreqEnd - sampleFreqBegin - 18);
sampleFreq = std::stoll(sampleFreqStr); sampleFreq = std::stoll(sampleFreqStr);
//flog::debug("{}", jsonData);
} }
// Calculate and update center freq // Calculate and update center freq
int64_t samplerate = /* sampleFreqReceived ? sampleFreq : */(endFreq - startFreq); int64_t samplerate = sampleFreqReceived ? sampleFreq : (endFreq - startFreq);
int64_t centerFreq = round(((double)endFreq + (double)startFreq) / 2.0); int64_t centerFreq = round(((double)endFreq + (double)startFreq) / 2.0);
if (centerFreq != _centerFreq) { if (centerFreq != _centerFreq) {
flog::debug("New center freq: {}", centerFreq); flog::debug("New center freq: {}", centerFreq);

View File

@ -78,6 +78,10 @@ public:
std::string serial = devAddr["serial"]; std::string serial = devAddr["serial"];
std::string model = devAddr.has_key("product") ? devAddr["product"] : devAddr["type"]; std::string model = devAddr.has_key("product") ? devAddr["product"] : devAddr["type"];
sprintf(buf, "USRP %s [%s]", model.c_str(), serial.c_str()); sprintf(buf, "USRP %s [%s]", model.c_str(), serial.c_str());
// Work-around for UHD sometimes reporting the same device twice
if (devices.keyExists(serial)) { continue; }
devices.define(serial, buf, devAddr); devices.define(serial, buf, devAddr);
} }
} }
@ -107,7 +111,7 @@ public:
channels.clear(); channels.clear();
auto subdevs = dev->get_rx_subdev_spec(); auto subdevs = dev->get_rx_subdev_spec();
for (int i = 0; i < subdevs.size(); i++) { for (int i = 0; i < subdevs.size(); i++) {
std::string slot = subdevs[i].db_name; std::string slot = subdevs[i].db_name + ',' + subdevs[i].sd_name;
sprintf(buf, "%s [%s]", dev->get_rx_subdev_name(i).c_str(), slot.c_str()); sprintf(buf, "%s [%s]", dev->get_rx_subdev_name(i).c_str(), slot.c_str());
channels.define(buf, buf, buf); channels.define(buf, buf, buf);
} }