mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2024-11-10 04:37:37 +01:00
Merge pull request #1385 from AlexandreRouma/master
Keep new_sinks branch up to date
This commit is contained in:
commit
40f1ee5651
69
.github/workflows/build_all.yml
vendored
69
.github/workflows/build_all.yml
vendored
@ -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 &&
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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"
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -2,5 +2,6 @@
|
|||||||
|
|
||||||
namespace displaymenu {
|
namespace displaymenu {
|
||||||
void init();
|
void init();
|
||||||
|
void checkKeybinds();
|
||||||
void draw(void* ctx);
|
void draw(void* ctx);
|
||||||
}
|
}
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
@ -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();
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
};
|
};
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 =========================
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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/
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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" },
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
26
readme.md
26
readme.md
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
6
source_modules/network_source/CMakeLists.txt
Normal file
6
source_modules/network_source/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
project(network_source)
|
||||||
|
|
||||||
|
file(GLOB SRC "src/*.cpp")
|
||||||
|
|
||||||
|
include(${SDRPP_MODULE_CMAKE})
|
366
source_modules/network_source/src/main.cpp
Normal file
366
source_modules/network_source/src/main.cpp
Normal 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();
|
||||||
|
}
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user