mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-07-09 10:35:21 +02:00
Compare commits
6 Commits
dab_experi
...
better_ins
Author | SHA1 | Date | |
---|---|---|---|
eb19f193bc | |||
7336b19bee | |||
f9feec0abf | |||
4113e92759 | |||
d905d19020 | |||
d5bc0fa3c3 |
19
.github/workflows/build_all.yml
vendored
19
.github/workflows/build_all.yml
vendored
@ -71,17 +71,14 @@ jobs:
|
|||||||
run: git clone https://github.com/thestk/rtaudio ; cd rtaudio ; git checkout 2f2fca4502d506abc50f6d4473b2836d24cfb1e3 ; mkdir build ; cd build ; cmake .. ; cmake --build . --config Release ; cmake --install .
|
run: git clone https://github.com/thestk/rtaudio ; cd rtaudio ; git checkout 2f2fca4502d506abc50f6d4473b2836d24cfb1e3 ; mkdir build ; cd build ; cmake .. ; cmake --build . --config Release ; cmake --install .
|
||||||
|
|
||||||
- name: Install libperseus-sdr
|
- name: Install libperseus-sdr
|
||||||
run: git clone https://github.com/AlexandreRouma/libperseus-sdr ; cd libperseus-sdr ; mkdir build ; cd build ; cmake -DCMAKE_BUILD_TYPE=Release "-DLIBUSB_LIBRARIES=C:/Program Files/PothosSDR/lib/libusb-1.0.lib" "-DLIBUSB_INCLUDE_DIRS=C:/Program Files/PothosSDR/include/libusb-1.0" .. "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" ; cmake --build . --config Release ; mkdir "C:/Program Files/PothosSDR/include/perseus-sdr" ; cp Release/perseus-sdr.dll "C:/Program Files/PothosSDR/bin" ; cp Release/perseus-sdr.lib "C:/Program Files/PothosSDR/bin" ; cd .. ; xcopy "src" "C:/Program Files/PothosSDR/include/perseus-sdr"
|
run: git clone https://github.com/AlexandreRouma/libperseus-sdr ; cd libperseus-sdr ; mkdir build ; cd build ; cmake "-DLIBUSB_LIBRARIES=C:/Program Files/PothosSDR/lib/libusb-1.0.lib" "-DLIBUSB_INCLUDE_DIRS=C:/Program Files/PothosSDR/include/libusb-1.0" .. "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" ; cmake --build . --config Release ; mkdir "C:/Program Files/PothosSDR/include/perseus-sdr" ; cp Release/perseus-sdr.dll "C:/Program Files/PothosSDR/bin" ; cp Release/perseus-sdr.lib "C:/Program Files/PothosSDR/bin" ; cd .. ; xcopy "src" "C:/Program Files/PothosSDR/include/perseus-sdr"
|
||||||
|
|
||||||
- name: Install librfnm
|
- name: Install librfnm
|
||||||
run: git clone https://github.com/AlexandreRouma/librfnm ; cd librfnm ; mkdir build ; cd build ; cmake .. -DCMAKE_BUILD_TYPE=Release "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" ; cmake --build . --config Release ; cmake --install .
|
run: git clone https://github.com/AlexandreRouma/librfnm ; cd librfnm ; mkdir build ; cd build ; cmake .. "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" ; cmake --build . --config Release ; cmake --install .
|
||||||
|
|
||||||
- name: Install libfobos
|
|
||||||
run: git clone https://github.com/AlexandreRouma/libfobos ; cd libfobos ; mkdir build ; cd build ; cmake .. -DCMAKE_BUILD_TYPE=Release "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" ; cmake --build . --config Release ; cmake --install .
|
|
||||||
|
|
||||||
- name: Prepare CMake
|
- name: Prepare CMake
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
run: cmake -DCOPY_MSVC_REDISTRIBUTABLES=ON "$Env:GITHUB_WORKSPACE" "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON
|
run: cmake -DCOPY_MSVC_REDISTRIBUTABLES=ON "$Env:GITHUB_WORKSPACE" "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_RFNM_SOURCE=ON
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
@ -130,15 +127,12 @@ jobs:
|
|||||||
- name: Install librfnm
|
- name: Install librfnm
|
||||||
run: git clone https://github.com/AlexandreRouma/librfnm && cd librfnm && mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && make && sudo make install && cd ..
|
run: git clone https://github.com/AlexandreRouma/librfnm && cd librfnm && mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && make && sudo make install && cd ..
|
||||||
|
|
||||||
- name: Install libfobos
|
|
||||||
run: git clone https://github.com/AlexandreRouma/libfobos && cd libfobos && mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && make && sudo make install && cd ..
|
|
||||||
|
|
||||||
- name: Install more recent librtlsdr
|
- 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 ../../
|
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
|
- 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_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 -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON -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 -DOPT_BUILD_RFNM_SOURCE=ON -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
@ -187,15 +181,12 @@ jobs:
|
|||||||
- name: Install librfnm
|
- name: Install librfnm
|
||||||
run: git clone https://github.com/AlexandreRouma/librfnm && cd librfnm && mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && make && sudo make install && cd ..
|
run: git clone https://github.com/AlexandreRouma/librfnm && cd librfnm && mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && make && sudo make install && cd ..
|
||||||
|
|
||||||
- name: Install libfobos
|
|
||||||
run: git clone https://github.com/AlexandreRouma/libfobos && cd libfobos && mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && make && sudo make install && cd ..
|
|
||||||
|
|
||||||
- name: Install more recent librtlsdr
|
- 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 ../../
|
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
|
- 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_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 -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON -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=OFF -DOPT_BUILD_PERSEUS_SOURCE=OFF -DOPT_BUILD_AUDIO_SOURCE=OFF -DOPT_BUILD_RFNM_SOURCE=ON -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
|
@ -15,7 +15,6 @@ option(OPT_BUILD_AUDIO_SOURCE "Build Audio Source Module (Dependencies: rtaudio)
|
|||||||
option(OPT_BUILD_BADGESDR_SOURCE "Build BadgeSDR Source Module (Dependencies: libusb)" OFF)
|
option(OPT_BUILD_BADGESDR_SOURCE "Build BadgeSDR Source Module (Dependencies: libusb)" OFF)
|
||||||
option(OPT_BUILD_BLADERF_SOURCE "Build BladeRF Source Module (Dependencies: libbladeRF)" OFF)
|
option(OPT_BUILD_BLADERF_SOURCE "Build BladeRF Source Module (Dependencies: libbladeRF)" OFF)
|
||||||
option(OPT_BUILD_FILE_SOURCE "Wav file source" ON)
|
option(OPT_BUILD_FILE_SOURCE "Wav file source" ON)
|
||||||
option(OPT_BUILD_FOBOSSDR_SOURCE "Build FobosSDR Source Module (Dependencies: libfobos)" OFF)
|
|
||||||
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_HAROGIC_SOURCE "Build Harogic Source Module (Dependencies: htra_api)" OFF)
|
option(OPT_BUILD_HAROGIC_SOURCE "Build Harogic Source Module (Dependencies: htra_api)" OFF)
|
||||||
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)
|
||||||
@ -44,7 +43,6 @@ option(OPT_BUILD_PORTAUDIO_SINK "Build PortAudio Sink Module (Dependencies: port
|
|||||||
|
|
||||||
# Decoders
|
# Decoders
|
||||||
option(OPT_BUILD_ATV_DECODER "Build ATV decoder (no dependencies required)" OFF)
|
option(OPT_BUILD_ATV_DECODER "Build ATV decoder (no dependencies required)" OFF)
|
||||||
option(OPT_BUILD_DAB_DECODER "Build the DAB/DAB+ decoder (no dependencies required)" OFF)
|
|
||||||
option(OPT_BUILD_FALCON9_DECODER "Build the falcon9 live decoder (Dependencies: ffplay)" OFF)
|
option(OPT_BUILD_FALCON9_DECODER "Build the falcon9 live decoder (Dependencies: ffplay)" OFF)
|
||||||
option(OPT_BUILD_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)
|
||||||
@ -99,13 +97,56 @@ set(SDRPP_MODULE_COMPILER_FLAGS ${SDRPP_COMPILER_FLAGS})
|
|||||||
|
|
||||||
# Set a default install prefix
|
# Set a default install prefix
|
||||||
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
if (MSVC)
|
||||||
|
set(CMAKE_INSTALL_PREFIX "C:/Program Files/SDR++/" CACHE PATH "..." FORCE)
|
||||||
|
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "..." FORCE)
|
set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "..." FORCE)
|
||||||
else()
|
else()
|
||||||
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "..." FORCE)
|
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "..." FORCE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Include standard install directory definitions
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
# Set up SDR++ directory load paths
|
||||||
|
if (MSVC)
|
||||||
|
set(SDRPP_MODULES_LOAD_DIR "./modules")
|
||||||
|
set(SDRPP_RES_LOAD_DIR "./res")
|
||||||
|
elseif (USE_BUNDLE_DEFAULTS)
|
||||||
|
set(SDRPP_MODULES_LOAD_DIR "../Plugins")
|
||||||
|
set(SDRPP_RES_LOAD_DIR "../Resources")
|
||||||
|
elseif (ANDROID)
|
||||||
|
set(SDRPP_MODULES_LOAD_DIR "/modules")
|
||||||
|
set(SDRPP_RES_LOAD_DIR "/res")
|
||||||
|
else()
|
||||||
|
set(SDRPP_MODULES_LOAD_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/sdrpp/plugins")
|
||||||
|
set(SDRPP_RES_LOAD_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/sdrpp")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set up SDR++ directory install paths
|
||||||
|
if (MSVC)
|
||||||
|
set(SDRPP_BIN_INSTALL_DIR "/")
|
||||||
|
set(SDRPP_LIB_INSTALL_DIR "/")
|
||||||
|
set(SDRPP_MODULES_INSTALL_DIR "modules")
|
||||||
|
set(SDRPP_RES_INSTALL_DIR "res")
|
||||||
|
elseif (USE_BUNDLE_DEFAULTS)
|
||||||
|
set(SDRPP_BIN_INSTALL_DIR "Contents/MacOS")
|
||||||
|
set(SDRPP_LIB_INSTALL_DIR "Contents/Frameworks")
|
||||||
|
set(SDRPP_MODULES_INSTALL_DIR "Contents/Plugins")
|
||||||
|
set(SDRPP_RES_INSTALL_DIR "Contents/Resources")
|
||||||
|
elseif (ANDROID)
|
||||||
|
set(SDRPP_BIN_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}")
|
||||||
|
set(SDRPP_LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
set(SDRPP_MODULES_INSTALL_DIR "/modules")
|
||||||
|
set(SDRPP_RES_INSTALL_DIR "/res")
|
||||||
|
else()
|
||||||
|
set(SDRPP_BIN_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}")
|
||||||
|
set(SDRPP_LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
set(SDRPP_MODULES_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/sdrpp/plugins")
|
||||||
|
set(SDRPP_RES_INSTALL_DIR "${CMAKE_INSTALL_DATAROOTDIR}/sdrpp")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Configure toolchain for android
|
# Configure toolchain for android
|
||||||
if (ANDROID)
|
if (ANDROID)
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS
|
set(CMAKE_SHARED_LINKER_FLAGS
|
||||||
@ -144,10 +185,6 @@ if (OPT_BUILD_FILE_SOURCE)
|
|||||||
add_subdirectory("source_modules/file_source")
|
add_subdirectory("source_modules/file_source")
|
||||||
endif (OPT_BUILD_FILE_SOURCE)
|
endif (OPT_BUILD_FILE_SOURCE)
|
||||||
|
|
||||||
if (OPT_BUILD_FOBOSSDR_SOURCE)
|
|
||||||
add_subdirectory("source_modules/fobossdr_source")
|
|
||||||
endif (OPT_BUILD_FOBOSSDR_SOURCE)
|
|
||||||
|
|
||||||
if (OPT_BUILD_HACKRF_SOURCE)
|
if (OPT_BUILD_HACKRF_SOURCE)
|
||||||
add_subdirectory("source_modules/hackrf_source")
|
add_subdirectory("source_modules/hackrf_source")
|
||||||
endif (OPT_BUILD_HACKRF_SOURCE)
|
endif (OPT_BUILD_HACKRF_SOURCE)
|
||||||
@ -248,10 +285,6 @@ if (OPT_BUILD_ATV_DECODER)
|
|||||||
add_subdirectory("decoder_modules/atv_decoder")
|
add_subdirectory("decoder_modules/atv_decoder")
|
||||||
endif (OPT_BUILD_ATV_DECODER)
|
endif (OPT_BUILD_ATV_DECODER)
|
||||||
|
|
||||||
if (OPT_BUILD_DAB_DECODER)
|
|
||||||
add_subdirectory("decoder_modules/dab_decoder")
|
|
||||||
endif (OPT_BUILD_DAB_DECODER)
|
|
||||||
|
|
||||||
if (OPT_BUILD_FALCON9_DECODER)
|
if (OPT_BUILD_FALCON9_DECODER)
|
||||||
add_subdirectory("decoder_modules/falcon9_decoder")
|
add_subdirectory("decoder_modules/falcon9_decoder")
|
||||||
endif (OPT_BUILD_FALCON9_DECODER)
|
endif (OPT_BUILD_FALCON9_DECODER)
|
||||||
@ -373,17 +406,18 @@ endif ()
|
|||||||
# Create module cmake file
|
# Create module cmake file
|
||||||
configure_file(${CMAKE_SOURCE_DIR}/sdrpp_module.cmake ${CMAKE_CURRENT_BINARY_DIR}/sdrpp_module.cmake @ONLY)
|
configure_file(${CMAKE_SOURCE_DIR}/sdrpp_module.cmake ${CMAKE_CURRENT_BINARY_DIR}/sdrpp_module.cmake @ONLY)
|
||||||
|
|
||||||
# Install directives
|
# Create desktop entry file
|
||||||
install(TARGETS sdrpp DESTINATION bin)
|
|
||||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/root/res/bandplans DESTINATION share/sdrpp)
|
|
||||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/root/res/colormaps DESTINATION share/sdrpp)
|
|
||||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/root/res/fonts DESTINATION share/sdrpp)
|
|
||||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/root/res/icons DESTINATION share/sdrpp)
|
|
||||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/root/res/themes DESTINATION share/sdrpp)
|
|
||||||
configure_file(${CMAKE_SOURCE_DIR}/sdrpp.desktop ${CMAKE_CURRENT_BINARY_DIR}/sdrpp.desktop @ONLY)
|
configure_file(${CMAKE_SOURCE_DIR}/sdrpp.desktop ${CMAKE_CURRENT_BINARY_DIR}/sdrpp.desktop @ONLY)
|
||||||
|
|
||||||
|
# Install directives
|
||||||
|
install(TARGETS sdrpp DESTINATION ${SDRPP_BIN_INSTALL_DIR})
|
||||||
|
install(DIRECTORY ${CMAKE_SOURCE_DIR}/root/res/bandplans DESTINATION ${SDRPP_RES_INSTALL_DIR})
|
||||||
|
install(DIRECTORY ${CMAKE_SOURCE_DIR}/root/res/colormaps DESTINATION ${SDRPP_RES_INSTALL_DIR})
|
||||||
|
install(DIRECTORY ${CMAKE_SOURCE_DIR}/root/res/fonts DESTINATION ${SDRPP_RES_INSTALL_DIR})
|
||||||
|
install(DIRECTORY ${CMAKE_SOURCE_DIR}/root/res/icons DESTINATION ${SDRPP_RES_INSTALL_DIR})
|
||||||
|
install(DIRECTORY ${CMAKE_SOURCE_DIR}/root/res/themes DESTINATION ${SDRPP_RES_INSTALL_DIR})
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sdrpp.desktop DESTINATION share/applications)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sdrpp.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# Create uninstall target
|
# Create uninstall target
|
||||||
|
@ -18,6 +18,10 @@ if (MSVC)
|
|||||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
# Add compiler definitions for the directories
|
||||||
|
add_definitions(-DSDRPP_MODULES_LOAD_DIR="${SDRPP_MODULES_LOAD_DIR}")
|
||||||
|
add_definitions(-DSDRPP_RES_LOAD_DIR="${SDRPP_RES_LOAD_DIR}")
|
||||||
|
|
||||||
# Configure backend sources
|
# Configure backend sources
|
||||||
if (OPT_BACKEND_GLFW)
|
if (OPT_BACKEND_GLFW)
|
||||||
file(GLOB_RECURSE BACKEND_SRC "backends/glfw/*.cpp" "backends/glfw/*.c")
|
file(GLOB_RECURSE BACKEND_SRC "backends/glfw/*.cpp" "backends/glfw/*.c")
|
||||||
@ -33,9 +37,6 @@ add_library(sdrpp_core SHARED ${SRC} ${BACKEND_SRC})
|
|||||||
# Set compiler options
|
# Set compiler options
|
||||||
target_compile_options(sdrpp_core PRIVATE ${SDRPP_COMPILER_FLAGS})
|
target_compile_options(sdrpp_core PRIVATE ${SDRPP_COMPILER_FLAGS})
|
||||||
|
|
||||||
# Set the install prefix
|
|
||||||
target_compile_definitions(sdrpp_core PUBLIC INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
|
|
||||||
|
|
||||||
# Include core headers
|
# Include core headers
|
||||||
target_include_directories(sdrpp_core PUBLIC "src/")
|
target_include_directories(sdrpp_core PUBLIC "src/")
|
||||||
target_include_directories(sdrpp_core PUBLIC "src/imgui")
|
target_include_directories(sdrpp_core PUBLIC "src/imgui")
|
||||||
@ -167,4 +168,4 @@ set(CORE_FILES ${RUNTIME_OUTPUT_DIRECTORY} PARENT_SCOPE)
|
|||||||
# cmake .. "-DCMAKE_TOOLCHAIN_FILE=C:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake"
|
# cmake .. "-DCMAKE_TOOLCHAIN_FILE=C:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake"
|
||||||
|
|
||||||
# Install directives
|
# Install directives
|
||||||
install(TARGETS sdrpp_core DESTINATION lib)
|
install(TARGETS sdrpp_core DESTINATION ${SDRPP_LIB_INSTALL_DIR})
|
@ -24,14 +24,16 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INSTALL_PREFIX
|
|
||||||
#ifdef __APPLE__
|
// Default install dirs to make the IDE happy
|
||||||
#define INSTALL_PREFIX "/usr/local"
|
#ifndef SDRPP_MODULES_LOAD_DIR
|
||||||
#else
|
#define SDRPP_MODULES_LOAD_DIR ""
|
||||||
#define INSTALL_PREFIX "/usr"
|
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef SDRPP_RES_LOAD_DIR
|
||||||
|
#define SDRPP_RES_LOAD_DIR ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace core {
|
namespace core {
|
||||||
ConfigManager configManager;
|
ConfigManager configManager;
|
||||||
ModuleManager moduleManager;
|
ModuleManager moduleManager;
|
||||||
@ -173,20 +175,16 @@ int sdrpp_main(int argc, char* argv[]) {
|
|||||||
defConfig["moduleInstances"]["BladeRF Source"]["enabled"] = true;
|
defConfig["moduleInstances"]["BladeRF Source"]["enabled"] = true;
|
||||||
defConfig["moduleInstances"]["File Source"]["module"] = "file_source";
|
defConfig["moduleInstances"]["File Source"]["module"] = "file_source";
|
||||||
defConfig["moduleInstances"]["File Source"]["enabled"] = true;
|
defConfig["moduleInstances"]["File Source"]["enabled"] = true;
|
||||||
defConfig["moduleInstances"]["FobosSDR Source"]["module"] = "fobossdr_source";
|
|
||||||
defConfig["moduleInstances"]["FobosSDR Source"]["enabled"] = true;
|
|
||||||
defConfig["moduleInstances"]["HackRF Source"]["module"] = "hackrf_source";
|
defConfig["moduleInstances"]["HackRF Source"]["module"] = "hackrf_source";
|
||||||
defConfig["moduleInstances"]["HackRF Source"]["enabled"] = true;
|
defConfig["moduleInstances"]["HackRF Source"]["enabled"] = true;
|
||||||
defConfig["moduleInstances"]["Harogic Source"]["module"] = "harogic_source";
|
|
||||||
defConfig["moduleInstances"]["Harogic Source"]["enabled"] = true;
|
|
||||||
defConfig["moduleInstances"]["Hermes Source"]["module"] = "hermes_source";
|
defConfig["moduleInstances"]["Hermes Source"]["module"] = "hermes_source";
|
||||||
defConfig["moduleInstances"]["Hermes Source"]["enabled"] = true;
|
defConfig["moduleInstances"]["Hermes Source"]["enabled"] = true;
|
||||||
defConfig["moduleInstances"]["LimeSDR Source"]["module"] = "limesdr_source";
|
defConfig["moduleInstances"]["LimeSDR Source"]["module"] = "limesdr_source";
|
||||||
defConfig["moduleInstances"]["LimeSDR Source"]["enabled"] = true;
|
defConfig["moduleInstances"]["LimeSDR Source"]["enabled"] = true;
|
||||||
defConfig["moduleInstances"]["PerseusSDR Source"]["module"] = "perseus_source";
|
|
||||||
defConfig["moduleInstances"]["PerseusSDR Source"]["enabled"] = true;
|
|
||||||
defConfig["moduleInstances"]["PlutoSDR Source"]["module"] = "plutosdr_source";
|
defConfig["moduleInstances"]["PlutoSDR Source"]["module"] = "plutosdr_source";
|
||||||
defConfig["moduleInstances"]["PlutoSDR Source"]["enabled"] = true;
|
defConfig["moduleInstances"]["PlutoSDR Source"]["enabled"] = true;
|
||||||
|
defConfig["moduleInstances"]["PerseusSDR Source"]["module"] = "perseus_source";
|
||||||
|
defConfig["moduleInstances"]["PerseusSDR Source"]["enabled"] = true;
|
||||||
defConfig["moduleInstances"]["RFNM Source"]["module"] = "rfnm_source";
|
defConfig["moduleInstances"]["RFNM Source"]["module"] = "rfnm_source";
|
||||||
defConfig["moduleInstances"]["RFNM Source"]["enabled"] = true;
|
defConfig["moduleInstances"]["RFNM Source"]["enabled"] = true;
|
||||||
defConfig["moduleInstances"]["RFspace Source"]["module"] = "rfspace_source";
|
defConfig["moduleInstances"]["RFspace Source"]["module"] = "rfspace_source";
|
||||||
@ -199,12 +197,8 @@ 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"]["Spectran HTTP Source"]["module"] = "spectran_http_source";
|
|
||||||
defConfig["moduleInstances"]["Spectran HTTP 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;
|
||||||
defConfig["moduleInstances"]["USRP Source"]["module"] = "usrp_source";
|
|
||||||
defConfig["moduleInstances"]["USRP Source"]["enabled"] = true;
|
|
||||||
|
|
||||||
defConfig["moduleInstances"]["Audio Sink"] = "audio_sink";
|
defConfig["moduleInstances"]["Audio Sink"] = "audio_sink";
|
||||||
defConfig["moduleInstances"]["Network Sink"] = "network_sink";
|
defConfig["moduleInstances"]["Network Sink"] = "network_sink";
|
||||||
@ -256,19 +250,14 @@ int sdrpp_main(int argc, char* argv[]) {
|
|||||||
defConfig["lockMenuOrder"] = false;
|
defConfig["lockMenuOrder"] = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#ifdef __ANDROID__
|
||||||
defConfig["modulesDirectory"] = "./modules";
|
defConfig["modulesDirectory"] = root + SDRPP_MODULES_LOAD_DIR;
|
||||||
defConfig["resourcesDirectory"] = "./res";
|
defConfig["resourcesDirectory"] = root + SDRPP_RES_LOAD_DIR;
|
||||||
#elif defined(IS_MACOS_BUNDLE)
|
|
||||||
defConfig["modulesDirectory"] = "../Plugins";
|
|
||||||
defConfig["resourcesDirectory"] = "../Resources";
|
|
||||||
#elif defined(__ANDROID__)
|
|
||||||
defConfig["modulesDirectory"] = root + "/modules";
|
|
||||||
defConfig["resourcesDirectory"] = root + "/res";
|
|
||||||
#else
|
#else
|
||||||
defConfig["modulesDirectory"] = INSTALL_PREFIX "/lib/sdrpp/plugins";
|
defConfig["modulesDirectory"] = SDRPP_MODULES_LOAD_DIR;
|
||||||
defConfig["resourcesDirectory"] = INSTALL_PREFIX "/share/sdrpp";
|
defConfig["resourcesDirectory"] = SDRPP_RES_LOAD_DIR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
flog::info("Loading config");
|
flog::info("Loading config");
|
||||||
|
@ -37,12 +37,9 @@ namespace sdrpp_credits {
|
|||||||
const char* hardwareDonators[] = {
|
const char* hardwareDonators[] = {
|
||||||
"Aaronia AG",
|
"Aaronia AG",
|
||||||
"Airspy",
|
"Airspy",
|
||||||
"Alex 4Z5LV",
|
|
||||||
"Analog Devices",
|
"Analog Devices",
|
||||||
"CaribouLabs",
|
"CaribouLabs",
|
||||||
"Deepace",
|
|
||||||
"Ettus Research",
|
"Ettus Research",
|
||||||
"Harogic",
|
|
||||||
"Howard Su",
|
"Howard Su",
|
||||||
"MicroPhase",
|
"MicroPhase",
|
||||||
"Microtelecom",
|
"Microtelecom",
|
||||||
@ -50,7 +47,6 @@ namespace sdrpp_credits {
|
|||||||
"Nuand",
|
"Nuand",
|
||||||
"RFNM",
|
"RFNM",
|
||||||
"RFspace",
|
"RFspace",
|
||||||
"RigExpert",
|
|
||||||
"RTL-SDRblog",
|
"RTL-SDRblog",
|
||||||
"SDRplay"
|
"SDRplay"
|
||||||
};
|
};
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
|
||||||
project(dab_decoder)
|
|
||||||
|
|
||||||
file(GLOB_RECURSE SRC "src/*.cpp" "src/*.c")
|
|
||||||
|
|
||||||
include(${SDRPP_MODULE_CMAKE})
|
|
||||||
|
|
||||||
target_include_directories(dab_decoder PRIVATE "src/")
|
|
||||||
|
|
||||||
if (MSVC)
|
|
||||||
# Lib path
|
|
||||||
target_include_directories(dab_decoder PRIVATE "C:/Program Files/codec2/include/")
|
|
||||||
target_link_directories(dab_decoder PRIVATE "C:/Program Files/codec2/lib")
|
|
||||||
|
|
||||||
target_link_libraries(dab_decoder PRIVATE libcodec2)
|
|
||||||
elseif (ANDROID)
|
|
||||||
target_include_directories(dab_decoder PUBLIC
|
|
||||||
/sdr-kit/${ANDROID_ABI}/include/codec2
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(dab_decoder PUBLIC
|
|
||||||
/sdr-kit/${ANDROID_ABI}/lib/libcodec2.so
|
|
||||||
)
|
|
||||||
else ()
|
|
||||||
find_package(PkgConfig)
|
|
||||||
|
|
||||||
pkg_check_modules(LIBCODEC2 REQUIRED codec2)
|
|
||||||
|
|
||||||
target_include_directories(dab_decoder PRIVATE ${LIBCODEC2_INCLUDE_DIRS})
|
|
||||||
target_link_directories(dab_decoder PRIVATE ${LIBCODEC2_LIBRARY_DIRS})
|
|
||||||
target_link_libraries(dab_decoder PRIVATE ${LIBCODEC2_LIBRARIES})
|
|
||||||
|
|
||||||
# Include it because for some reason pkgconfig doesn't look here?
|
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
|
||||||
target_include_directories(dab_decoder PRIVATE "/usr/local/include")
|
|
||||||
endif()
|
|
||||||
endif ()
|
|
@ -1,280 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <dsp/processor.h>
|
|
||||||
#include <utils/flog.h>
|
|
||||||
#include <fftw3.h>
|
|
||||||
#include "dab_phase_sym.h"
|
|
||||||
|
|
||||||
namespace dab {
|
|
||||||
// class CyclicSync : public dsp::Processor<dsp::complex_t, dsp::complex_t> {
|
|
||||||
// using base_type = dsp::Processor<dsp::complex_t, dsp::complex_t>;
|
|
||||||
// public:
|
|
||||||
// CyclicSync() {}
|
|
||||||
|
|
||||||
// // TODO: The default AGC rate is probably way too fast, plot out the avgCorr to see how much it moves
|
|
||||||
// CyclicSync(dsp::stream<dsp::complex_t>* in, double symbolLength, double cyclicPrefixLength, double samplerate, float agcRate = 1e-3) { init(in, symbolLength, cyclicPrefixLength, samplerate, agcRate); }
|
|
||||||
|
|
||||||
// void init(dsp::stream<dsp::complex_t>* in, double symbolLength, double cyclicPrefixLength, double samplerate, float agcRate = 1e-3) {
|
|
||||||
// // Computer the number of samples for the symbol and its cyclic prefix
|
|
||||||
// symbolSamps = round(samplerate * symbolLength);
|
|
||||||
// prefixSamps = round(samplerate * cyclicPrefixLength);
|
|
||||||
|
|
||||||
// // Allocate and clear the delay buffer
|
|
||||||
// delayBuf = dsp::buffer::alloc<dsp::complex_t>(STREAM_BUFFER_SIZE + 64000);
|
|
||||||
// dsp::buffer::clear(delayBuf, symbolSamps);
|
|
||||||
|
|
||||||
// // Allocate and clear the history buffer
|
|
||||||
// histBuf = dsp::buffer::alloc<dsp::complex_t>(prefixSamps);
|
|
||||||
// dsp::buffer::clear(histBuf, prefixSamps);
|
|
||||||
|
|
||||||
// // Compute the delay input addresses
|
|
||||||
// delayBufInput = &delayBuf[symbolSamps];
|
|
||||||
|
|
||||||
// // Compute the correlation AGC configuration
|
|
||||||
// this->agcRate = agcRate;
|
|
||||||
// agcRateInv = 1.0f - agcRate;
|
|
||||||
|
|
||||||
// base_type::init(in);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void reset() {
|
|
||||||
// assert(base_type::_block_init);
|
|
||||||
// std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
|
||||||
// base_type::tempStop();
|
|
||||||
|
|
||||||
// base_type::tempStart();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// int run() {
|
|
||||||
// int count = base_type::_in->read();
|
|
||||||
// if (count < 0) { return -1; }
|
|
||||||
|
|
||||||
// // Copy the data into the normal delay buffer
|
|
||||||
// memcpy(delayBufInput, base_type::_in->readBuf, count * sizeof(dsp::complex_t));
|
|
||||||
|
|
||||||
// // Flush the input stream
|
|
||||||
// base_type::_in->flush();
|
|
||||||
|
|
||||||
// // Do cross-correlation
|
|
||||||
// for (int i = 0; i < count; i++) {
|
|
||||||
// // Get the current history slot
|
|
||||||
// dsp::complex_t* slot = &histBuf[histId++];
|
|
||||||
|
|
||||||
// // Wrap around the history slot index (TODO: Check that the history buffer's length is correct)
|
|
||||||
// histId %= prefixSamps;
|
|
||||||
|
|
||||||
// // Kick out last value from the correlation
|
|
||||||
// corr -= *slot;
|
|
||||||
|
|
||||||
// // Save input value and compute the new prodct
|
|
||||||
// dsp::complex_t val = delayBuf[i];
|
|
||||||
// dsp::complex_t prod = val.conj()*delayBuf[i+symbolSamps];
|
|
||||||
|
|
||||||
// // Add the new value to the correlation
|
|
||||||
// *slot = prod;
|
|
||||||
|
|
||||||
// // Add the new value to the history buffer
|
|
||||||
// corr += prod;
|
|
||||||
|
|
||||||
// // Compute sample amplitude
|
|
||||||
// float rcorr = corr.amplitude();
|
|
||||||
|
|
||||||
// // If a high enough peak is reached, reset the symbol counter
|
|
||||||
// if (rcorr > avgCorr && rcorr > peakCorr) { // Note keeping an average level might not be needed
|
|
||||||
// peakCorr = rcorr;
|
|
||||||
// peakLCorr = lastCorr;
|
|
||||||
// samplesSincePeak = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // If this is the sample right after the peak, save it
|
|
||||||
// if (samplesSincePeak == 1) {
|
|
||||||
// peakRCorr = rcorr;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Write the sample to the output
|
|
||||||
// out.writeBuf[samplesSincePeak++] = val;
|
|
||||||
|
|
||||||
// // If the end of the symbol is reached, send it off
|
|
||||||
// if (samplesSincePeak >= symbolSamps) {
|
|
||||||
// if (!out.swap(symbolSamps)) {
|
|
||||||
// return -1;
|
|
||||||
// }
|
|
||||||
// samplesSincePeak = 0;
|
|
||||||
// peakCorr = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Update the average correlation
|
|
||||||
// lastCorr = rcorr;
|
|
||||||
|
|
||||||
// // Update the average correlation value
|
|
||||||
// avgCorr = agcRate*rcorr + agcRateInv*avgCorr;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Move unused data
|
|
||||||
// memmove(delayBuf, &delayBuf[count], symbolSamps * sizeof(dsp::complex_t));
|
|
||||||
|
|
||||||
// return count;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// protected:
|
|
||||||
// int symbolSamps;
|
|
||||||
// int prefixSamps;
|
|
||||||
|
|
||||||
// int histId = 0;
|
|
||||||
// dsp::complex_t* histBuf;
|
|
||||||
|
|
||||||
// dsp::complex_t* delayBuf;
|
|
||||||
// dsp::complex_t* delayBufInput;
|
|
||||||
|
|
||||||
// dsp::complex_t corr = { 0.0f, 0.0f };
|
|
||||||
|
|
||||||
// int samplesSincePeak = 0;
|
|
||||||
// float lastCorr = 0.0f;
|
|
||||||
// float peakCorr = 0.0f;
|
|
||||||
// float peakLCorr = 0.0f;
|
|
||||||
// float peakRCorr = 0.0f;
|
|
||||||
|
|
||||||
// // Note only required for DAB
|
|
||||||
// float avgCorr = 0.0f;
|
|
||||||
// float agcRate;
|
|
||||||
// float agcRateInv;
|
|
||||||
// };
|
|
||||||
|
|
||||||
class FrameFreqSync : public dsp::Processor<dsp::complex_t, dsp::complex_t> {
|
|
||||||
using base_type = dsp::Processor<dsp::complex_t, dsp::complex_t>;
|
|
||||||
public:
|
|
||||||
FrameFreqSync() {}
|
|
||||||
|
|
||||||
FrameFreqSync(dsp::stream<dsp::complex_t>* in, float agcRate = 0.01f) { init(in, agcRate); }
|
|
||||||
|
|
||||||
void init(dsp::stream<dsp::complex_t>* in, float agcRate = 0.01f) {
|
|
||||||
// Allocate buffers
|
|
||||||
amps = dsp::buffer::alloc<float>(2048);
|
|
||||||
conjRef = dsp::buffer::alloc<dsp::complex_t>(2048);
|
|
||||||
corrIn = (dsp::complex_t*)fftwf_alloc_complex(2048);
|
|
||||||
corrOut = (dsp::complex_t*)fftwf_alloc_complex(2048);
|
|
||||||
|
|
||||||
// Copy the phase reference
|
|
||||||
memcpy(conjRef, DAB_PHASE_SYM_CONJ, 2048 * sizeof(dsp::complex_t));
|
|
||||||
|
|
||||||
// Plan the FFT computation
|
|
||||||
plan = fftwf_plan_dft_1d(2048, (fftwf_complex*)corrIn, (fftwf_complex*)corrOut, FFTW_FORWARD, FFTW_ESTIMATE);
|
|
||||||
|
|
||||||
// Compute the correlation AGC configuration
|
|
||||||
this->agcRate = agcRate;
|
|
||||||
agcRateInv = 1.0f - agcRate;
|
|
||||||
|
|
||||||
base_type::init(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
assert(base_type::_block_init);
|
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
|
||||||
base_type::tempStop();
|
|
||||||
|
|
||||||
base_type::tempStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
int run() {
|
|
||||||
int count = base_type::_in->read();
|
|
||||||
if (count < 0) { return -1; }
|
|
||||||
|
|
||||||
// Apply frequency shift
|
|
||||||
lv_32fc_t phase = lv_cmake(1.0f, 0.0f);
|
|
||||||
lv_32fc_t phaseDelta = lv_cmake(cos(offset), sin(offset));
|
|
||||||
#if VOLK_VERSION >= 030100
|
|
||||||
volk_32fc_s32fc_x2_rotator2_32fc((lv_32fc_t*)_in->readBuf, (lv_32fc_t*)_in->readBuf, phaseDelta, &phase, count);
|
|
||||||
#else
|
|
||||||
volk_32fc_s32fc_x2_rotator_32fc((lv_32fc_t*)_in->readBuf, (lv_32fc_t*)_in->readBuf, phaseDelta, &phase, count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Compute the amplitude amplitude of all samples
|
|
||||||
volk_32fc_magnitude_32f(amps, (lv_32fc_t*)_in->readBuf, 2048);
|
|
||||||
|
|
||||||
// Compute the average signal level by adding up all values
|
|
||||||
float level = 0.0f;
|
|
||||||
volk_32f_accumulator_s32f(&level, amps, 2048);
|
|
||||||
|
|
||||||
// Detect a frame sync condition
|
|
||||||
if (level < avgLvl * 0.5f) {
|
|
||||||
// Reset symbol counter
|
|
||||||
sym = 1;
|
|
||||||
|
|
||||||
// Update the average level
|
|
||||||
avgLvl = agcRate*level + agcRateInv*avgLvl;
|
|
||||||
|
|
||||||
// Flush the input stream and return
|
|
||||||
base_type::_in->flush();
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the average level
|
|
||||||
avgLvl = agcRate*level + agcRateInv*avgLvl;
|
|
||||||
|
|
||||||
// Handle phase reference
|
|
||||||
if (sym == 1) {
|
|
||||||
// Output the symbols (DEBUG ONLY)
|
|
||||||
memcpy(corrIn, _in->readBuf, 2048 * sizeof(dsp::complex_t));
|
|
||||||
fftwf_execute(plan);
|
|
||||||
volk_32fc_magnitude_32f(amps, (lv_32fc_t*)corrOut, 2048);
|
|
||||||
int outCount = 0;
|
|
||||||
dsp::complex_t pi4 = { cos(3.1415926535*0.25), sin(3.1415926535*0.25) };
|
|
||||||
for (int i = -767; i < 768; i++) {
|
|
||||||
if (!i) { continue; }
|
|
||||||
int cid0 = ((i-1) >= 0) ? (i-1) : 2048+(i-1);
|
|
||||||
int cid1 = (i >= 0) ? i : 2048+i;;
|
|
||||||
out.writeBuf[outCount++] = pi4 * (corrOut[cid1] * corrOut[cid0].conj()) * (1.0f/(amps[cid0]*amps[cid0]));
|
|
||||||
}
|
|
||||||
out.swap(outCount);
|
|
||||||
|
|
||||||
// Multiply the samples with the conjugated phase reference signal
|
|
||||||
volk_32fc_x2_multiply_32fc((lv_32fc_t*)corrIn, (lv_32fc_t*)_in->readBuf, (lv_32fc_t*)conjRef, 2048);
|
|
||||||
|
|
||||||
// Compute the FFT of the product
|
|
||||||
fftwf_execute(plan);
|
|
||||||
|
|
||||||
// Compute the amplitude of the bins
|
|
||||||
volk_32fc_magnitude_32f(amps, (lv_32fc_t*)corrOut, 2048);
|
|
||||||
|
|
||||||
// Locate highest power bin
|
|
||||||
uint32_t peakId;
|
|
||||||
volk_32f_index_max_32u(&peakId, amps, 2048);
|
|
||||||
|
|
||||||
// Obtain the value of the bins next to the peak
|
|
||||||
float peakL = amps[(peakId + 2047) % 2048];
|
|
||||||
float peakR = amps[(peakId + 1) % 2048];
|
|
||||||
|
|
||||||
// Compute the integer frequency offset
|
|
||||||
float offInt = (peakId < 1024) ? (float)peakId : ((float)peakId - 2048.0f);
|
|
||||||
|
|
||||||
// Compute the frequency offset in rad/samp
|
|
||||||
float off = 3.1415926535f * (offInt + ((peakR - peakL) / (peakR + peakL))) * (1.0f / 1024.0f);
|
|
||||||
|
|
||||||
// Run control loop
|
|
||||||
offset -= 0.1f*off;
|
|
||||||
flog::debug("Offset: {} Hz, Error: {} Hz, Avg Level: {}", offset * (0.5f/3.1415926535f)*2.048e6, off * (0.5f/3.1415926535f)*2.048e6, avgLvl);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment the symbol counter
|
|
||||||
sym++;
|
|
||||||
|
|
||||||
// Flush the input stream and return
|
|
||||||
base_type::_in->flush();
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
fftwf_plan plan;
|
|
||||||
|
|
||||||
float* amps;
|
|
||||||
dsp::complex_t* conjRef;
|
|
||||||
dsp::complex_t* corrIn;
|
|
||||||
dsp::complex_t* corrOut;
|
|
||||||
|
|
||||||
int sym;
|
|
||||||
float offset = 0.0f;
|
|
||||||
|
|
||||||
float avgLvl = 0.0f;
|
|
||||||
float agcRate;
|
|
||||||
float agcRateInv;
|
|
||||||
};
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,165 +0,0 @@
|
|||||||
#include <imgui.h>
|
|
||||||
#include <config.h>
|
|
||||||
#include <core.h>
|
|
||||||
#include <gui/style.h>
|
|
||||||
#include <gui/gui.h>
|
|
||||||
#include <signal_path/signal_path.h>
|
|
||||||
#include <module.h>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <dsp/stream.h>
|
|
||||||
#include <dsp/buffer/reshaper.h>
|
|
||||||
#include <dsp/multirate/rational_resampler.h>
|
|
||||||
#include <dsp/sink/handler_sink.h>
|
|
||||||
#include <fstream>
|
|
||||||
#include <chrono>
|
|
||||||
#include "dab_dsp.h"
|
|
||||||
#include <gui/widgets/constellation_diagram.h>
|
|
||||||
#include "ofdm.h"
|
|
||||||
|
|
||||||
#define CONCAT(a, b) ((std::string(a) + b).c_str())
|
|
||||||
|
|
||||||
SDRPP_MOD_INFO{
|
|
||||||
/* Name: */ "dab_decoder",
|
|
||||||
/* Description: */ "DAB/DAB+ Decoder for SDR++",
|
|
||||||
/* Author: */ "Ryzerth",
|
|
||||||
/* Version: */ 0, 1, 0,
|
|
||||||
/* Max instances */ -1
|
|
||||||
};
|
|
||||||
|
|
||||||
ConfigManager config;
|
|
||||||
|
|
||||||
#define INPUT_SAMPLE_RATE 2.048e6
|
|
||||||
#define VFO_BANDWIDTH 1.6e6
|
|
||||||
|
|
||||||
class M17DecoderModule : public ModuleManager::Instance {
|
|
||||||
public:
|
|
||||||
M17DecoderModule(std::string name) {
|
|
||||||
this->name = name;
|
|
||||||
|
|
||||||
file = std::ofstream("sync5.f32", std::ios::out | std::ios::binary);
|
|
||||||
|
|
||||||
// Load config
|
|
||||||
config.acquire();
|
|
||||||
|
|
||||||
config.release(true);
|
|
||||||
|
|
||||||
// Initialize VFO
|
|
||||||
vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, 0, VFO_BANDWIDTH, INPUT_SAMPLE_RATE, VFO_BANDWIDTH, VFO_BANDWIDTH, true);
|
|
||||||
vfo->setSnapInterval(250);
|
|
||||||
|
|
||||||
// Initialize DSP here
|
|
||||||
csync.init(vfo->output, 2048, 504, 1e-3, INPUT_SAMPLE_RATE, 1e-6, 0.01, 0.005);
|
|
||||||
ffsync.init(&csync.out);
|
|
||||||
ns.init(&ffsync.out, handler, this);
|
|
||||||
|
|
||||||
// Start DSO Here
|
|
||||||
csync.start();
|
|
||||||
ffsync.start();
|
|
||||||
ns.start();
|
|
||||||
|
|
||||||
gui::menu.registerEntry(name, menuHandler, this, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
~M17DecoderModule() {
|
|
||||||
gui::menu.removeEntry(name);
|
|
||||||
// Stop DSP Here
|
|
||||||
if (enabled) {
|
|
||||||
csync.stop();
|
|
||||||
ffsync.stop();
|
|
||||||
ns.stop();
|
|
||||||
sigpath::vfoManager.deleteVFO(vfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
sigpath::sinkManager.unregisterStream(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void postInit() {}
|
|
||||||
|
|
||||||
void enable() {
|
|
||||||
double bw = gui::waterfall.getBandwidth();
|
|
||||||
vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, std::clamp<double>(0, -bw / 2.0, bw / 2.0), VFO_BANDWIDTH, INPUT_SAMPLE_RATE, VFO_BANDWIDTH, VFO_BANDWIDTH, true);
|
|
||||||
vfo->setSnapInterval(250);
|
|
||||||
|
|
||||||
// Set Input of demod here
|
|
||||||
csync.setInput(vfo->output);
|
|
||||||
|
|
||||||
// Start DSP here
|
|
||||||
csync.start();
|
|
||||||
ffsync.start();
|
|
||||||
ns.start();
|
|
||||||
|
|
||||||
enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable() {
|
|
||||||
// Stop DSP here
|
|
||||||
csync.stop();
|
|
||||||
ffsync.stop();
|
|
||||||
ns.stop();
|
|
||||||
|
|
||||||
sigpath::vfoManager.deleteVFO(vfo);
|
|
||||||
enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void menuHandler(void* ctx) {
|
|
||||||
M17DecoderModule* _this = (M17DecoderModule*)ctx;
|
|
||||||
|
|
||||||
float menuWidth = ImGui::GetContentRegionAvail().x;
|
|
||||||
|
|
||||||
if (!_this->enabled) { style::beginDisabled(); }
|
|
||||||
|
|
||||||
_this->constDiagram.draw();
|
|
||||||
|
|
||||||
if (!_this->enabled) { style::endDisabled(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ofstream file;
|
|
||||||
|
|
||||||
static void handler(dsp::complex_t* data, int count, void* ctx) {
|
|
||||||
M17DecoderModule* _this = (M17DecoderModule*)ctx;
|
|
||||||
//_this->file.write((char*)data, count * sizeof(dsp::complex_t));
|
|
||||||
|
|
||||||
dsp::complex_t* buf = _this->constDiagram.acquireBuffer();
|
|
||||||
memcpy(buf, data, 1024 * sizeof(dsp::complex_t));
|
|
||||||
_this->constDiagram.releaseBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name;
|
|
||||||
bool enabled = true;
|
|
||||||
|
|
||||||
//dab::CyclicSync csync;
|
|
||||||
dab::FrameFreqSync ffsync;
|
|
||||||
dsp::ofdm::CyclicTimeSync csync;
|
|
||||||
dsp::sink::Handler<dsp::complex_t> ns;
|
|
||||||
|
|
||||||
ImGui::ConstellationDiagram constDiagram;
|
|
||||||
|
|
||||||
// DSP Chain
|
|
||||||
VFOManager::VFO* vfo;
|
|
||||||
};
|
|
||||||
|
|
||||||
MOD_EXPORT void _INIT_() {
|
|
||||||
// Create default recording directory
|
|
||||||
json def = json({});
|
|
||||||
config.setPath(core::args["root"].s() + "/dab_decoder_config.json");
|
|
||||||
config.load(def);
|
|
||||||
config.enableAutoSave();
|
|
||||||
}
|
|
||||||
|
|
||||||
MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) {
|
|
||||||
return new M17DecoderModule(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
MOD_EXPORT void _DELETE_INSTANCE_(void* instance) {
|
|
||||||
delete (M17DecoderModule*)instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOD_EXPORT void _END_() {
|
|
||||||
config.disableAutoSave();
|
|
||||||
config.save();
|
|
||||||
}
|
|
@ -1,324 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <dsp/processor.h>
|
|
||||||
#include <dsp/loop/phase_control_loop.h>
|
|
||||||
#include <dsp/taps/windowed_sinc.h>
|
|
||||||
#include <dsp/multirate/polyphase_bank.h>
|
|
||||||
#include <dsp/math/step.h>
|
|
||||||
|
|
||||||
namespace dsp::ofdm {
|
|
||||||
class CyclicTimeSync : public Processor<complex_t, complex_t> {
|
|
||||||
using base_type = Processor<complex_t, complex_t> ;
|
|
||||||
public:
|
|
||||||
CyclicTimeSync() {}
|
|
||||||
|
|
||||||
CyclicTimeSync(stream<complex_t>* in, int fftSize, int cpSize, double usefulSymbolTime, double samplerate,
|
|
||||||
double omegaGain, double muGain, double omegaRelLimit, int interpPhaseCount = 128, int interpTapCount = 8) {
|
|
||||||
init(in, fftSize, cpSize, usefulSymbolTime, samplerate, omegaGain, muGain, omegaRelLimit, interpPhaseCount, interpTapCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
~CyclicTimeSync() {
|
|
||||||
if (!base_type::_block_init) { return; }
|
|
||||||
base_type::stop();
|
|
||||||
dsp::multirate::freePolyphaseBank(interpBank);
|
|
||||||
buffer::free(corrSampCache);
|
|
||||||
buffer::free(corrProdCache);
|
|
||||||
buffer::free(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void init(stream<complex_t>* in, int fftSize, int cpSize, double usefulSymbolTime, double samplerate,
|
|
||||||
double omegaGain, double muGain, double omegaRelLimit, int interpPhaseCount = 128, int interpTapCount = 8) {
|
|
||||||
// Save parameters
|
|
||||||
this->fftSize = fftSize;
|
|
||||||
this->cpSize = cpSize;
|
|
||||||
period = fftSize + cpSize;
|
|
||||||
|
|
||||||
// Compute the interpolator settings
|
|
||||||
omega = (usefulSymbolTime * samplerate) / (double)fftSize;
|
|
||||||
this->omegaGain = omegaGain;
|
|
||||||
this->muGain = muGain;
|
|
||||||
this->omegaRelLimit = omegaRelLimit;
|
|
||||||
this->interpPhaseCount = interpPhaseCount;
|
|
||||||
this->interpTapCount = interpTapCount;
|
|
||||||
|
|
||||||
// Compute the correlator AGC settings
|
|
||||||
// TODO: Compute it using he FFT and CP sizes
|
|
||||||
this->corrAgcRate = 1e-4;
|
|
||||||
corrAgcInvRate = 1.0f - corrAgcRate;
|
|
||||||
|
|
||||||
// Initialize the control loop
|
|
||||||
pcl.init(muGain, omegaGain, 0.0, 0.0, 1.0, omega, omega * (1.0 - omegaRelLimit), omega * (1.0 + omegaRelLimit));
|
|
||||||
|
|
||||||
// Generate the interpolation taps
|
|
||||||
generateInterpTaps();
|
|
||||||
|
|
||||||
// Allocate the buffers
|
|
||||||
corrSampCache = buffer::alloc<complex_t>(fftSize);
|
|
||||||
corrProdCache = buffer::alloc<complex_t>(cpSize);
|
|
||||||
buffer = buffer::alloc<complex_t>(STREAM_BUFFER_SIZE + interpTapCount);
|
|
||||||
bufStart = &buffer[interpTapCount - 1];
|
|
||||||
|
|
||||||
// Clear the buffers
|
|
||||||
buffer::clear(corrSampCache, fftSize);
|
|
||||||
buffer::clear(corrProdCache, cpSize);
|
|
||||||
buffer::clear(buffer, interpTapCount - 1);
|
|
||||||
|
|
||||||
base_type::init(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void setOmegaGain(double omegaGain) {
|
|
||||||
assert(base_type::_block_init);
|
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
|
||||||
this->omegaGain = omegaGain;
|
|
||||||
pcl.setCoefficients(muGain, omegaGain);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setMuGain(double muGain) {
|
|
||||||
assert(base_type::_block_init);
|
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
|
||||||
this->muGain = muGain;
|
|
||||||
pcl.setCoefficients(muGain, omegaGain);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setOmegaRelLimit(double omegaRelLimit) {
|
|
||||||
assert(base_type::_block_init);
|
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
|
||||||
this->omegaRelLimit = omegaRelLimit;
|
|
||||||
pcl.setFreqLimits(omega * (1.0 - omegaRelLimit), omega * (1.0 + omegaRelLimit));
|
|
||||||
}
|
|
||||||
|
|
||||||
void setInterpParams(int interpPhaseCount, int interpTapCount) {
|
|
||||||
assert(base_type::_block_init);
|
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
|
||||||
base_type::tempStop();
|
|
||||||
this->interpPhaseCount = interpPhaseCount;
|
|
||||||
this->interpTapCount = interpTapCount;
|
|
||||||
dsp::multirate::freePolyphaseBank(interpBank);
|
|
||||||
buffer::free(buffer);
|
|
||||||
generateInterpTaps();
|
|
||||||
buffer = buffer::alloc<complex_t>(STREAM_BUFFER_SIZE + interpTapCount);
|
|
||||||
bufStart = &buffer[interpTapCount - 1];
|
|
||||||
base_type::tempStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
assert(base_type::_block_init);
|
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
|
||||||
base_type::tempStop();
|
|
||||||
offset = 0;
|
|
||||||
pcl.phase = 0.0f;
|
|
||||||
pcl.freq = omega;
|
|
||||||
// TODO: The rest
|
|
||||||
base_type::tempStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
int run() {
|
|
||||||
int count = base_type::_in->read();
|
|
||||||
if (count < 0) { return -1; }
|
|
||||||
|
|
||||||
// Copy data to work buffer
|
|
||||||
memcpy(bufStart, base_type::_in->readBuf, count * sizeof(complex_t));
|
|
||||||
|
|
||||||
// Process all samples
|
|
||||||
while (offset < count) {
|
|
||||||
// Get the cache slots
|
|
||||||
complex_t* sampSlot = &corrSampCache[corrSampCacheId++];
|
|
||||||
complex_t* prodSlot = &corrProdCache[corrProdCacheId++];
|
|
||||||
corrSampCacheId %= fftSize;
|
|
||||||
corrProdCacheId %= cpSize;
|
|
||||||
|
|
||||||
// Compute the interpolated sample
|
|
||||||
complex_t sample;
|
|
||||||
int phase = std::clamp<int>(floorf(pcl.phase * (float)interpPhaseCount), 0, interpPhaseCount - 1);
|
|
||||||
volk_32fc_32f_dot_prod_32fc((lv_32fc_t*)&sample, (lv_32fc_t*)&buffer[offset], interpBank.phases[phase], interpTapCount);
|
|
||||||
|
|
||||||
// Write the sample to the output
|
|
||||||
if (outCount >= cpSize) {
|
|
||||||
out.writeBuf[outCount - cpSize] = sample;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send out a symbol when it's fully received
|
|
||||||
if ((++outCount) >= fftSize+cpSize) {
|
|
||||||
if (!out.swap(outCount)) { break; }
|
|
||||||
outCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run autocorrelation
|
|
||||||
complex_t prod = sample.conj()*(*sampSlot);
|
|
||||||
corr += prod;
|
|
||||||
corr -= *prodSlot;
|
|
||||||
|
|
||||||
// Write back the new sample and product value to the cache
|
|
||||||
*sampSlot = sample;
|
|
||||||
*prodSlot = prod;
|
|
||||||
|
|
||||||
// Compute the correlation level
|
|
||||||
float corrLvl = corr.amplitude();
|
|
||||||
|
|
||||||
// Detect peak in autocorrelation (TODO: level check maybe not needed now that corrPeak is reset to corrLvl)
|
|
||||||
if (corrLvl > corrAvg && corrLvl > corrPeak) {
|
|
||||||
// Save the current correlation as the peak
|
|
||||||
corrPeak = corrLvl;
|
|
||||||
|
|
||||||
// Save the value of the previous correlation as the left side of the peak
|
|
||||||
corrPeakL = corrLast;
|
|
||||||
|
|
||||||
// Reset the peak distance counter
|
|
||||||
sincePeak = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The first sample after a peak is the right-side sample
|
|
||||||
if (sincePeak == 1) {
|
|
||||||
corrPeakR = corrLvl;
|
|
||||||
}
|
|
||||||
else if (sincePeak == cpSize) {
|
|
||||||
// Start the useful symbol counter
|
|
||||||
sinceCp = 0;
|
|
||||||
|
|
||||||
// Compute the fractional error (TODO: Probably very inaccurate with noise, use real slopes instead)
|
|
||||||
if (corrPeakL > corrPeakR) {
|
|
||||||
float maxSlope = corrPeakR - corrPeak;
|
|
||||||
float slope = corrPeak - corrPeakL;
|
|
||||||
fracErr = std::clamp<float>(0.5f * (1.0f + slope / maxSlope), -0.5f, 0.5f);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
float maxSlope = corrPeak - corrPeakL;
|
|
||||||
float slope = corrPeakR - corrPeak;
|
|
||||||
fracErr = std::clamp<float>(-0.5f * (1.0f + slope / maxSlope), -0.5f, 0.5f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sincePeak == fftSize) {
|
|
||||||
// Reset the peak detector
|
|
||||||
corrPeak = corrAvg;
|
|
||||||
}
|
|
||||||
// NOTE: THIS IS ONLY NEEDED FOR DAB
|
|
||||||
// Detect a wider-than-normal distance to adapt the output counter
|
|
||||||
else if (sincePeak == 2656) {
|
|
||||||
// Reset the output counter
|
|
||||||
outCount = 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Last sample of useful symbol
|
|
||||||
if (sinceCp == fftSize) {
|
|
||||||
// If the fractional error is valid, run closed-loop
|
|
||||||
float err = 0.0f;
|
|
||||||
if (!std::isnan(fracErr)) {
|
|
||||||
// Compute the measured period using the distance to the last symbol
|
|
||||||
float measuredPeriod = (float)sinceLastSym - fracErr;
|
|
||||||
// NOTE: THIS IS ONLY NEEDED FOR DAB
|
|
||||||
if (measuredPeriod > 3828.0f) {
|
|
||||||
// Null symbol
|
|
||||||
err = measuredPeriod - (2552.0f+2656.0f);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Regular symbol
|
|
||||||
err = measuredPeriod - period;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = std::clamp<float>(err, -10.0f, 10.0f);
|
|
||||||
|
|
||||||
// Run the control loop in closed-loop mode
|
|
||||||
pcl.advance(err);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Otherwise, run open-loop
|
|
||||||
pcl.advancePhase();
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("%d\n", outCount);
|
|
||||||
|
|
||||||
// Nudge the symbol window if it's too out of sync
|
|
||||||
if (outCount > 100) {
|
|
||||||
// TODO: MOVE THE LAST SAMPLES OR THE SYMBOL WILL BE CORRUPTED!
|
|
||||||
outCount = 50;
|
|
||||||
flog::debug("NUDGE!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the period counter
|
|
||||||
sinceLastSym = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Run the control loop in open-loop mode
|
|
||||||
pcl.advancePhase();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the offset and phase
|
|
||||||
float delta = floorf(pcl.phase);
|
|
||||||
offset += delta;
|
|
||||||
pcl.phase -= delta;
|
|
||||||
|
|
||||||
// Update the last correlation level
|
|
||||||
corrLast = corrLvl;
|
|
||||||
|
|
||||||
// Update correlation AGC
|
|
||||||
corrAvg = corrAvg*corrAgcInvRate + corrLvl*corrAgcRate;
|
|
||||||
|
|
||||||
// Increment the distance counters (TODO: Check if they happen at the right point, eg. after being reset to zero)
|
|
||||||
sincePeak++;
|
|
||||||
sinceLastSym++;
|
|
||||||
sinceCp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare offset for next buffer of samples
|
|
||||||
offset -= count;
|
|
||||||
|
|
||||||
// Update delay buffer
|
|
||||||
memmove(buffer, &buffer[count], (interpTapCount - 1) * sizeof(complex_t));
|
|
||||||
|
|
||||||
// Swap if some data was generated
|
|
||||||
base_type::_in->flush();
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void generateInterpTaps() {
|
|
||||||
double bw = 0.5 / (double)interpPhaseCount;
|
|
||||||
dsp::tap<float> lp = dsp::taps::windowedSinc<float>(interpPhaseCount * interpTapCount, dsp::math::hzToRads(bw, 1.0), dsp::window::nuttall, interpPhaseCount);
|
|
||||||
interpBank = dsp::multirate::buildPolyphaseBank<float>(interpPhaseCount, lp);
|
|
||||||
taps::free(lp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// OFDM Configuration
|
|
||||||
int fftSize;
|
|
||||||
int cpSize;
|
|
||||||
float period;
|
|
||||||
|
|
||||||
// Interpolator
|
|
||||||
dsp::multirate::PolyphaseBank<float> interpBank;
|
|
||||||
int interpPhaseCount;
|
|
||||||
int interpTapCount;
|
|
||||||
int offset = 0;
|
|
||||||
complex_t* buffer = NULL;
|
|
||||||
complex_t* bufStart;
|
|
||||||
|
|
||||||
// Control loop
|
|
||||||
loop::PhaseControlLoop<float, false> pcl;
|
|
||||||
double omega;
|
|
||||||
double omegaGain;
|
|
||||||
double muGain;
|
|
||||||
double omegaRelLimit;
|
|
||||||
float fracErr = 0.0f;
|
|
||||||
|
|
||||||
// Autocorrelator
|
|
||||||
complex_t corr = {0.0f, 0.0f};
|
|
||||||
complex_t* corrSampCache = NULL;
|
|
||||||
complex_t* corrProdCache = NULL;
|
|
||||||
int corrSampCacheId = 0;
|
|
||||||
int corrProdCacheId = 0;
|
|
||||||
float corrAgcRate;
|
|
||||||
float corrAgcInvRate;
|
|
||||||
float corrAvg = 0;
|
|
||||||
float corrLast = 0;
|
|
||||||
float corrPeakR = 0;
|
|
||||||
float corrPeak = 0;
|
|
||||||
float corrPeakL = 0;
|
|
||||||
|
|
||||||
// Peak detection
|
|
||||||
int sincePeak = 0;
|
|
||||||
int sinceLastSym = 0;
|
|
||||||
int sinceCp = 0;
|
|
||||||
|
|
||||||
// Other shit to categorize
|
|
||||||
int outCount = 0;
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,31 +0,0 @@
|
|||||||
cyclicLen = 4
|
|
||||||
usefulLen = 12
|
|
||||||
|
|
||||||
A = 0*12 + 1*13 + 2*14 + 3*15
|
|
||||||
B = 1*13 + 2*14 + 3*15 + 4*16 = A - 0*12 + 4*16
|
|
||||||
C = 2*14 + 3*15 + 4*16 + 5*17 = B - 1*13 + 5*17
|
|
||||||
D = 3*15 + 4*16 + 5*17 + 6*18 = C - 2*14 + 6*18
|
|
||||||
E = 4*16 + 5*17 + 6*18 + 7*19 = D - 3*15 + 7*19
|
|
||||||
F = 5*17 + 6*18 + 7*19 + 8*20 = E - 4*16 + 8*20
|
|
||||||
G = 6*18 + 7*19 + 8*20 + 9*21 = F - 5*17 + 9*21
|
|
||||||
H = 7*19 + 8*20 + 9*21 + 10*22 = G - 6*18 + 10*22
|
|
||||||
I = 8*20 + 9*21 + 10*22 + 11*23 = H - 7*19 + 11*23
|
|
||||||
J = 9*21 + 10*22 + 11*23 + 12*24 = I - 8*20 + 12*24
|
|
||||||
K = 10*22 + 11*23 + 12*24 + 13*25 = J - 9*21 + 13*25
|
|
||||||
L = 11*23 + 12*24 + 13*25 + 14*26 = K - 10*22 + 14*26
|
|
||||||
M = 12*24 + 13*25 + 14*26 + 15*27 = L - 11*23 + 15*27
|
|
||||||
N = 13*25 + 14*26 + 15*27 + 16*28 = M - 12*24 + 16*28
|
|
||||||
O = 14*26 + 15*27 + 16*28 + 17*29 = N - 13*25 + 17*29
|
|
||||||
P = 15*27 + 16*28 + 17*29 + 18*30 = O - 14*26 + 18*30
|
|
||||||
Q = 16*28 + 17*29 + 18*30 + 19*31 = P - 15*27 + 19*31
|
|
||||||
R = 17*29 + 18*30 + 19*31 + 20*32 = Q - 16*28 + 20*32
|
|
||||||
S = 18*30 + 19*31 + 20*32 + 21*33 = R - 17*29 + 21*33
|
|
||||||
T = 19*31 + 20*32 + 21*33 + 22*34 = S - 18*30 + 22*34
|
|
||||||
U = 20*32 + 21*33 + 22*34 + 23*35 = T - 19*31 + 23*35
|
|
||||||
|
|
||||||
Conclusion:
|
|
||||||
sampCacheLen = usefulLen
|
|
||||||
prodCacheLen = cyclicLen
|
|
||||||
|
|
||||||
Peak correlation occurs when the current interpolated value is the last FFT sample
|
|
||||||
|
|
@ -1,397 +0,0 @@
|
|||||||
5209
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2555
|
|
||||||
2549
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2554
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2552
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2548
|
|
||||||
2558
|
|
||||||
2551
|
|
||||||
2546
|
|
||||||
2559
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2554
|
|
||||||
2555
|
|
||||||
2549
|
|
||||||
2550
|
|
||||||
2549
|
|
||||||
2557
|
|
||||||
2551
|
|
||||||
2554
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2546
|
|
||||||
2559
|
|
||||||
2551
|
|
||||||
2554
|
|
||||||
2550
|
|
||||||
2550
|
|
||||||
2557
|
|
||||||
2550
|
|
||||||
2556
|
|
||||||
2543
|
|
||||||
2556
|
|
||||||
2551
|
|
||||||
2554
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2554
|
|
||||||
2550
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2546
|
|
||||||
2558
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2550
|
|
||||||
2555
|
|
||||||
2551
|
|
||||||
2551
|
|
||||||
2554
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2549
|
|
||||||
2552
|
|
||||||
5208
|
|
||||||
2554
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2550
|
|
||||||
2554
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2552
|
|
||||||
2546
|
|
||||||
2557
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2548
|
|
||||||
2557
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2562
|
|
||||||
2539
|
|
||||||
2559
|
|
||||||
2548
|
|
||||||
2551
|
|
||||||
2551
|
|
||||||
2550
|
|
||||||
2556
|
|
||||||
2551
|
|
||||||
2554
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2548
|
|
||||||
2556
|
|
||||||
2550
|
|
||||||
2554
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2550
|
|
||||||
2555
|
|
||||||
2558
|
|
||||||
2545
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2548
|
|
||||||
2555
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2557
|
|
||||||
2550
|
|
||||||
2548
|
|
||||||
2553
|
|
||||||
2554
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2547
|
|
||||||
2558
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2555
|
|
||||||
2549
|
|
||||||
2552
|
|
||||||
5208
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2550
|
|
||||||
2555
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2547
|
|
||||||
2557
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2546
|
|
||||||
2558
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2556
|
|
||||||
2548
|
|
||||||
2551
|
|
||||||
2555
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2555
|
|
||||||
2549
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2554
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2548
|
|
||||||
2550
|
|
||||||
2555
|
|
||||||
2554
|
|
||||||
2553
|
|
||||||
2556
|
|
||||||
2547
|
|
||||||
2552
|
|
||||||
2554
|
|
||||||
2552
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
5209
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2551
|
|
||||||
2547
|
|
||||||
2558
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2552
|
|
||||||
2549
|
|
||||||
2551
|
|
||||||
2557
|
|
||||||
2549
|
|
||||||
2554
|
|
||||||
2551
|
|
||||||
2554
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2551
|
|
||||||
2548
|
|
||||||
2559
|
|
||||||
2549
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2551
|
|
||||||
2550
|
|
||||||
2557
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2555
|
|
||||||
2549
|
|
||||||
2557
|
|
||||||
2549
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2549
|
|
||||||
2554
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2547
|
|
||||||
2557
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2549
|
|
||||||
2555
|
|
||||||
2556
|
|
||||||
2550
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2541
|
|
||||||
2563
|
|
||||||
2552
|
|
||||||
5210
|
|
||||||
2550
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2558
|
|
||||||
2547
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2550
|
|
||||||
2554
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2550
|
|
||||||
2551
|
|
||||||
2555
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2558
|
|
||||||
2546
|
|
||||||
2553
|
|
||||||
2554
|
|
||||||
2550
|
|
||||||
2552
|
|
||||||
2553
|
|
||||||
2548
|
|
||||||
2554
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2551
|
|
||||||
2554
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2550
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2554
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2551
|
|
||||||
2555
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2552
|
|
||||||
2550
|
|
||||||
2554
|
|
||||||
2550
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2553
|
|
||||||
2550
|
|
||||||
5210
|
|
||||||
2553
|
|
||||||
2549
|
|
||||||
2553
|
|
||||||
2551
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2556
|
|
||||||
2548
|
|
||||||
2549
|
|
||||||
2555
|
|
||||||
2551
|
|
||||||
2557
|
|
||||||
2548
|
|
||||||
2552
|
|
||||||
2552
|
|
||||||
2552
|
|
@ -23,9 +23,9 @@ SDRPP_MOD_INFO{
|
|||||||
/* Max instances */ -1
|
/* Max instances */ -1
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INPUT_BANDWIDTH 600e3
|
#define INPUT_BANDWIDTH 138e3
|
||||||
#define INPUT_SAMPLE_RATE 1000e3
|
#define INPUT_SAMPLE_RATE 250e3
|
||||||
#define INPUT_BAUDRATE 500e3
|
#define INPUT_BAUDRATE 125e3
|
||||||
|
|
||||||
#define SYMBOL_DIAG_RATE 30
|
#define SYMBOL_DIAG_RATE 30
|
||||||
#define SYMBOL_DIAG_COUNT 1024
|
#define SYMBOL_DIAG_COUNT 1024
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include "dsp/processor.h"
|
#include "dsp/processor.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "dsp/processor.h"
|
#include "dsp/processor.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
namespace ryfi {
|
namespace ryfi {
|
||||||
// Synchronization word.
|
// Synchronization word.
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
namespace ryfi {
|
namespace ryfi {
|
||||||
/**
|
/**
|
||||||
|
@ -72,7 +72,6 @@ namespace ryfi {
|
|||||||
uint8_t* pktBuffer = new uint8_t[Packet::MAX_CONTENT_SIZE];
|
uint8_t* pktBuffer = new uint8_t[Packet::MAX_CONTENT_SIZE];
|
||||||
int pktExpected = 0;
|
int pktExpected = 0;
|
||||||
int pktRead = 0;
|
int pktRead = 0;
|
||||||
int valid = 0;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Read a frame
|
// Read a frame
|
||||||
@ -81,7 +80,6 @@ namespace ryfi {
|
|||||||
|
|
||||||
// Deserialize the frame
|
// Deserialize the frame
|
||||||
Frame::deserialize(rs.out.readBuf, frame);
|
Frame::deserialize(rs.out.readBuf, frame);
|
||||||
valid++;
|
|
||||||
|
|
||||||
// Flush the stream
|
// Flush the stream
|
||||||
rs.out.flush();
|
rs.out.flush();
|
||||||
@ -95,12 +93,11 @@ namespace ryfi {
|
|||||||
// If the frames aren't consecutive
|
// If the frames aren't consecutive
|
||||||
int frameRead = 0;
|
int frameRead = 0;
|
||||||
if (frame.counter != expectedCounter) {
|
if (frame.counter != expectedCounter) {
|
||||||
flog::warn("Lost at least {} frames after {} valid frames", ((int)frame.counter - (int)expectedCounter + 0x10000) % 0x10000, valid);
|
flog::warn("Lost at least {} frames", ((int)frame.counter - (int)expectedCounter + 0x10000) % 0x10000);
|
||||||
|
|
||||||
// Cancel the partial packet if there was one
|
// Cancel the partial packet if there was one
|
||||||
pktExpected = 0;
|
pktExpected = 0;
|
||||||
pktRead = 0;
|
pktRead = 0;
|
||||||
valid = 1;
|
|
||||||
|
|
||||||
// If this frame is not an idle frame or continuation frame
|
// If this frame is not an idle frame or continuation frame
|
||||||
if (frame.firstPacket != PKT_OFFS_NONE) {
|
if (frame.firstPacket != PKT_OFFS_NONE) {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include "dsp/processor.h"
|
#include "dsp/processor.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -35,20 +35,10 @@ make -j2
|
|||||||
make install
|
make install
|
||||||
cd ../../
|
cd ../../
|
||||||
|
|
||||||
# Install libfobos
|
|
||||||
git clone https://github.com/AlexandreRouma/libfobos
|
|
||||||
cd libfobos
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
|
||||||
make -j2
|
|
||||||
make install
|
|
||||||
cd ../../
|
|
||||||
|
|
||||||
cd SDRPlusPlus
|
cd SDRPlusPlus
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON
|
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON
|
||||||
make VERBOSE=1 -j2
|
make VERBOSE=1 -j2
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
@ -35,20 +35,10 @@ make -j2
|
|||||||
make install
|
make install
|
||||||
cd ../../
|
cd ../../
|
||||||
|
|
||||||
# Install libfobos
|
|
||||||
git clone https://github.com/AlexandreRouma/libfobos
|
|
||||||
cd libfobos
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
|
||||||
make -j2
|
|
||||||
make install
|
|
||||||
cd ../../
|
|
||||||
|
|
||||||
cd SDRPlusPlus
|
cd SDRPlusPlus
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON
|
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON
|
||||||
make VERBOSE=1 -j2
|
make VERBOSE=1 -j2
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
@ -35,20 +35,10 @@ make -j2
|
|||||||
make install
|
make install
|
||||||
cd ../../
|
cd ../../
|
||||||
|
|
||||||
# Install libfobos
|
|
||||||
git clone https://github.com/AlexandreRouma/libfobos
|
|
||||||
cd libfobos
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
|
||||||
make -j2
|
|
||||||
make install
|
|
||||||
cd ../../
|
|
||||||
|
|
||||||
cd SDRPlusPlus
|
cd SDRPlusPlus
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=OFF -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON
|
cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=OFF -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON
|
||||||
make VERBOSE=1 -j2
|
make VERBOSE=1 -j2
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
@ -35,20 +35,10 @@ make -j2
|
|||||||
make install
|
make install
|
||||||
cd ../../
|
cd ../../
|
||||||
|
|
||||||
# Install libfobos
|
|
||||||
git clone https://github.com/AlexandreRouma/libfobos
|
|
||||||
cd libfobos
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
|
||||||
make -j2
|
|
||||||
make install
|
|
||||||
cd ../../
|
|
||||||
|
|
||||||
cd SDRPlusPlus
|
cd SDRPlusPlus
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON
|
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON
|
||||||
make VERBOSE=1 -j2
|
make VERBOSE=1 -j2
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
4
docker_builds/fedora_40/Dockerfile
Normal file
4
docker_builds/fedora_40/Dockerfile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
FROM fedora:40
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
COPY do_build.sh /root
|
||||||
|
RUN chmod +x /root/do_build.sh
|
31
docker_builds/fedora_40/do_build.sh
Normal file
31
docker_builds/fedora_40/do_build.sh
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
cd /root
|
||||||
|
|
||||||
|
# Install dependencies and tools
|
||||||
|
dnf update -y
|
||||||
|
dnf install -y make gcc g++ cmake git wget p7zip fftw-devel glfw-devel volk-devel libzstd-devel codec2-devel airspyone_host-devel rtaudio-devel \
|
||||||
|
hackrf-devel rtl-sdr-devel portaudio-devel spdlog-devel libusbg-devel
|
||||||
|
|
||||||
|
# Install SDRPlay libraries
|
||||||
|
wget https://www.sdrplay.com/software/SDRplay_RSP_API-Linux-3.15.1.run
|
||||||
|
7za x ./SDRplay_RSP_API-Linux-3.15.1.run
|
||||||
|
7za x ./SDRplay_RSP_API-Linux-3.15.1
|
||||||
|
cp x86_64/libsdrplay_api.so.3.15 /usr/lib/libsdrplay_api.so
|
||||||
|
cp inc/* /usr/include/
|
||||||
|
|
||||||
|
# Install librfnm
|
||||||
|
git clone https://github.com/AlexandreRouma/librfnm
|
||||||
|
cd librfnm
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
||||||
|
make -j2
|
||||||
|
make install
|
||||||
|
cd ../../
|
||||||
|
|
||||||
|
cd SDRPlusPlus
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. -DOPT_BUILD_AIRSPYHF_SOURCE=OFF -DOPT_BUILD_PLUTOSDR_SOURCE=OFF -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON
|
||||||
|
make VERBOSE=1 -j2
|
@ -61,16 +61,6 @@ make -j2
|
|||||||
make install
|
make install
|
||||||
cd ../../
|
cd ../../
|
||||||
|
|
||||||
# Install libfobos
|
|
||||||
git clone https://github.com/AlexandreRouma/libfobos
|
|
||||||
cd libfobos
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
|
||||||
make -j2
|
|
||||||
make install
|
|
||||||
cd ../../
|
|
||||||
|
|
||||||
# Fix missing .pc file for codec2
|
# Fix missing .pc file for codec2
|
||||||
echo 'prefix=/usr/' >> /usr/share/pkgconfig/codec2.pc
|
echo 'prefix=/usr/' >> /usr/share/pkgconfig/codec2.pc
|
||||||
echo 'libdir=/usr/include/x86_64-linux-gnu/' >> /usr/share/pkgconfig/codec2.pc
|
echo 'libdir=/usr/include/x86_64-linux-gnu/' >> /usr/share/pkgconfig/codec2.pc
|
||||||
@ -86,7 +76,7 @@ echo 'Cflags: -I/usr/include/codec2' >> /usr/share/pkgconfig/codec2.pc
|
|||||||
cd SDRPlusPlus
|
cd SDRPlusPlus
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=OFF -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_OVERRIDE_STD_FILESYSTEM=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON
|
cmake .. -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=OFF -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_OVERRIDE_STD_FILESYSTEM=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON
|
||||||
make VERBOSE=1 -j2
|
make VERBOSE=1 -j2
|
||||||
|
|
||||||
# Generate package
|
# Generate package
|
||||||
|
@ -35,20 +35,10 @@ make -j2
|
|||||||
make install
|
make install
|
||||||
cd ../../
|
cd ../../
|
||||||
|
|
||||||
# Install libfobos
|
|
||||||
git clone https://github.com/AlexandreRouma/libfobos
|
|
||||||
cd libfobos
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
|
||||||
make -j2
|
|
||||||
make install
|
|
||||||
cd ../../
|
|
||||||
|
|
||||||
cd SDRPlusPlus
|
cd SDRPlusPlus
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON
|
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON
|
||||||
make VERBOSE=1 -j2
|
make VERBOSE=1 -j2
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
@ -35,20 +35,10 @@ make -j2
|
|||||||
make install
|
make install
|
||||||
cd ../../
|
cd ../../
|
||||||
|
|
||||||
# Install libfobos
|
|
||||||
git clone https://github.com/AlexandreRouma/libfobos
|
|
||||||
cd libfobos
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
|
||||||
make -j2
|
|
||||||
make install
|
|
||||||
cd ../../
|
|
||||||
|
|
||||||
cd SDRPlusPlus
|
cd SDRPlusPlus
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON
|
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON
|
||||||
make VERBOSE=1 -j2
|
make VERBOSE=1 -j2
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
@ -35,20 +35,10 @@ make -j2
|
|||||||
make install
|
make install
|
||||||
cd ../../
|
cd ../../
|
||||||
|
|
||||||
# Install libfobos
|
|
||||||
git clone https://github.com/AlexandreRouma/libfobos
|
|
||||||
cd libfobos
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
|
||||||
make -j2
|
|
||||||
make install
|
|
||||||
cd ../../
|
|
||||||
|
|
||||||
cd SDRPlusPlus
|
cd SDRPlusPlus
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON
|
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON
|
||||||
make VERBOSE=1 -j2
|
make VERBOSE=1 -j2
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
@ -35,20 +35,10 @@ make -j2
|
|||||||
make install
|
make install
|
||||||
cd ../../
|
cd ../../
|
||||||
|
|
||||||
# Install libfobos
|
|
||||||
git clone https://github.com/AlexandreRouma/libfobos
|
|
||||||
cd libfobos
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
|
||||||
make -j2
|
|
||||||
make install
|
|
||||||
cd ../../
|
|
||||||
|
|
||||||
cd SDRPlusPlus
|
cd SDRPlusPlus
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON -DOPT_BUILD_FOBOSSDR_SOURCE=ON
|
cmake .. -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=ON -DOPT_BUILD_PERSEUS_SOURCE=ON -DOPT_BUILD_RFNM_SOURCE=ON
|
||||||
make VERBOSE=1 -j2
|
make VERBOSE=1 -j2
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
@ -35,7 +35,6 @@ bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules
|
|||||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/airspyhf_source/airspyhf_source.dylib
|
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/airspyhf_source/airspyhf_source.dylib
|
||||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/bladerf_source/bladerf_source.dylib
|
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/bladerf_source/bladerf_source.dylib
|
||||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/file_source/file_source.dylib
|
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/file_source/file_source.dylib
|
||||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/file_source/fobossdr_source.dylib
|
|
||||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/hackrf_source/hackrf_source.dylib
|
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/hackrf_source/hackrf_source.dylib
|
||||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/hermes_source/hermes_source.dylib
|
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/hermes_source/hermes_source.dylib
|
||||||
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/limesdr_source/limesdr_source.dylib
|
bundle_install_binary $BUNDLE $BUNDLE/Contents/Plugins $BUILD_DIR/source_modules/limesdr_source/limesdr_source.dylib
|
||||||
|
@ -24,9 +24,6 @@ cp 'C:/Program Files/PothosSDR/bin/bladeRF.dll' sdrpp_windows_x64/
|
|||||||
|
|
||||||
cp $build_dir/source_modules/file_source/Release/file_source.dll sdrpp_windows_x64/modules/
|
cp $build_dir/source_modules/file_source/Release/file_source.dll sdrpp_windows_x64/modules/
|
||||||
|
|
||||||
cp $build_dir/source_modules/fobossdr_source/Release/fobossdr_source.dll sdrpp_windows_x64/modules/
|
|
||||||
cp 'C:/Program Files/RigExpert/Fobos/bin/fobos.dll' sdrpp_windows_x64/
|
|
||||||
|
|
||||||
cp $build_dir/source_modules/hackrf_source/Release/hackrf_source.dll sdrpp_windows_x64/modules/
|
cp $build_dir/source_modules/hackrf_source/Release/hackrf_source.dll sdrpp_windows_x64/modules/
|
||||||
cp 'C:/Program Files/PothosSDR/bin/hackrf.dll' sdrpp_windows_x64/
|
cp 'C:/Program Files/PothosSDR/bin/hackrf.dll' sdrpp_windows_x64/
|
||||||
|
|
||||||
|
@ -324,9 +324,8 @@ Modules in beta are still included in releases for the most part but not enabled
|
|||||||
| audio_source | Working | rtaudio | OPT_BUILD_AUDIO_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 | ✅ | ✅ | ✅ |
|
||||||
| fobossdr_source | Beta | libfobos | OPT_BUILD_FOBOSSDR_SOURCE | ✅ | ✅ | ✅ |
|
|
||||||
| hackrf_source | Working | libhackrf | OPT_BUILD_HACKRF_SOURCE | ✅ | ✅ | ✅ |
|
| hackrf_source | Working | libhackrf | OPT_BUILD_HACKRF_SOURCE | ✅ | ✅ | ✅ |
|
||||||
| harogic_source | Beta | htra_api | OPT_BUILD_HAROGIC_SOURCE | ⛔ | ⛔ | ✅ |
|
| harogic_source | Unfinished | htra_api | OPT_BUILD_HAROGIC_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 | ✅ | ✅ | ⛔ |
|
| network_source | Unfinished | - | OPT_BUILD_NETWORK_SOURCE | ✅ | ✅ | ⛔ |
|
||||||
@ -340,9 +339,9 @@ Modules in beta are still included in releases for the most part but not enabled
|
|||||||
| sdrpp_server_source | Working | - | OPT_BUILD_SDRPP_SERVER_SOURCE | ✅ | ✅ | ✅ |
|
| sdrpp_server_source | Working | - | OPT_BUILD_SDRPP_SERVER_SOURCE | ✅ | ✅ | ✅ |
|
||||||
| soapy_source | Deprecated | 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 | Beta | - | 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 | ⛔ | ⛔ | ⛔ |
|
||||||
|
|
||||||
## Sinks
|
## Sinks
|
||||||
|
|
||||||
@ -359,7 +358,6 @@ 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 | ⛔ | ⛔ | ⛔ |
|
||||||
| dab_decoder | Unfinished | - | OPT_BUILD_DAB_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 | Working | - | OPT_BUILD_M17_DECODER | ⛔ | ✅ | ⛔ |
|
| m17_decoder | Working | - | OPT_BUILD_M17_DECODER | ⛔ | ✅ | ⛔ |
|
||||||
|
@ -3,7 +3,7 @@ Encoding=UTF-8
|
|||||||
Version=1.0
|
Version=1.0
|
||||||
Type=Application
|
Type=Application
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Exec=@CMAKE_INSTALL_PREFIX@/bin/sdrpp
|
Exec=@SDRPP_BIN_INSTALL_DIR@/sdrpp
|
||||||
Name=SDR++
|
Name=SDR++
|
||||||
Icon=@CMAKE_INSTALL_PREFIX@/share/sdrpp/icons/sdrpp.png
|
Icon=@SDRPP_RES_INSTALL_DIR@/icons/sdrpp.png
|
||||||
Categories=HamRadio
|
Categories=HamRadio
|
@ -6,6 +6,10 @@ if (NOT SDRPP_MODULE_COMPILER_FLAGS)
|
|||||||
set(SDRPP_MODULE_COMPILER_FLAGS @SDRPP_MODULE_COMPILER_FLAGS@)
|
set(SDRPP_MODULE_COMPILER_FLAGS @SDRPP_MODULE_COMPILER_FLAGS@)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
# Add compiler definitions for the directories
|
||||||
|
add_definitions(-DSDRPP_MODULES_LOAD_DIR="${SDRPP_MODULES_LOAD_DIR}")
|
||||||
|
add_definitions(-DSDRPP_RES_LOAD_DIR="${SDRPP_RES_LOAD_DIR}")
|
||||||
|
|
||||||
# Created shared lib and link to core
|
# Created shared lib and link to core
|
||||||
add_library(${PROJECT_NAME} SHARED ${SRC})
|
add_library(${PROJECT_NAME} SHARED ${SRC})
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE sdrpp_core)
|
target_link_libraries(${PROJECT_NAME} PRIVATE sdrpp_core)
|
||||||
@ -16,4 +20,4 @@ set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
|
|||||||
target_compile_options(${PROJECT_NAME} PRIVATE ${SDRPP_MODULE_COMPILER_FLAGS})
|
target_compile_options(${PROJECT_NAME} PRIVATE ${SDRPP_MODULE_COMPILER_FLAGS})
|
||||||
|
|
||||||
# Install directives
|
# Install directives
|
||||||
install(TARGETS ${PROJECT_NAME} DESTINATION lib/sdrpp/plugins)
|
install(TARGETS ${PROJECT_NAME} DESTINATION ${SDRPP_MODULES_INSTALL_DIR})
|
@ -217,19 +217,14 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void startServer() {
|
void startServer() {
|
||||||
try {
|
if (modeId == SINK_MODE_TCP) {
|
||||||
if (modeId == SINK_MODE_TCP) {
|
listener = net::listen(hostname, port);
|
||||||
listener = net::listen(hostname, port);
|
if (listener) {
|
||||||
if (listener) {
|
listener->acceptAsync(clientHandler, this);
|
||||||
listener->acceptAsync(clientHandler, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
conn = net::openUDP("0.0.0.0", port, hostname, port, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
else {
|
||||||
flog::error("Failed to open socket: {}", e.what());
|
conn = net::openUDP("0.0.0.0", port, hostname, port, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
|
||||||
project(fobossdr_source)
|
|
||||||
|
|
||||||
file(GLOB SRC "src/*.cpp")
|
|
||||||
|
|
||||||
include(${SDRPP_MODULE_CMAKE})
|
|
||||||
|
|
||||||
if (MSVC)
|
|
||||||
# Lib path
|
|
||||||
target_link_directories(fobossdr_source PRIVATE "C:/Program Files/RigExpert/Fobos/lib/")
|
|
||||||
target_include_directories(fobossdr_source PRIVATE "C:/Program Files/RigExpert/Fobos/include/")
|
|
||||||
target_link_libraries(fobossdr_source PRIVATE fobos)
|
|
||||||
else (MSVC)
|
|
||||||
find_package(PkgConfig)
|
|
||||||
|
|
||||||
pkg_check_modules(LIBFOBOS REQUIRED libfobos)
|
|
||||||
|
|
||||||
target_include_directories(fobossdr_source PRIVATE ${LIBFOBOS_INCLUDE_DIRS})
|
|
||||||
target_link_directories(fobossdr_source PRIVATE ${LIBFOBOS_LIBRARY_DIRS})
|
|
||||||
target_link_libraries(fobossdr_source PRIVATE ${LIBFOBOS_LIBRARIES})
|
|
||||||
endif ()
|
|
@ -1,560 +0,0 @@
|
|||||||
#include <imgui.h>
|
|
||||||
#include <module.h>
|
|
||||||
#include <gui/gui.h>
|
|
||||||
#include <gui/smgui.h>
|
|
||||||
#include <signal_path/signal_path.h>
|
|
||||||
#include <core.h>
|
|
||||||
#include <utils/optionlist.h>
|
|
||||||
#include <atomic>
|
|
||||||
#include <fobos.h>
|
|
||||||
|
|
||||||
SDRPP_MOD_INFO{
|
|
||||||
/* Name: */ "fobossdr_source",
|
|
||||||
/* Description: */ "FobosSDR Source Module",
|
|
||||||
/* Author: */ "Ryzerth",
|
|
||||||
/* Version: */ 0, 1, 0,
|
|
||||||
/* Max instances */ -1
|
|
||||||
};
|
|
||||||
|
|
||||||
ConfigManager config;
|
|
||||||
|
|
||||||
#define CONCAT(a, b) ((std::string(a) + b).c_str())
|
|
||||||
|
|
||||||
// Work around for the fobos API not including
|
|
||||||
#define FOBOS_LNA_GAIN_MIN 1
|
|
||||||
#define FOBOS_LNA_GAIN_MAX 3
|
|
||||||
#define FOBOS_VGA_GAIN_MIN 0
|
|
||||||
#define FOBOS_VGA_GAIN_MAX 31
|
|
||||||
|
|
||||||
class FobosSDRSourceModule : public ModuleManager::Instance {
|
|
||||||
public:
|
|
||||||
FobosSDRSourceModule(std::string name) {
|
|
||||||
this->name = name;
|
|
||||||
|
|
||||||
sampleRate = 50000000.0;
|
|
||||||
|
|
||||||
// Initialize the DDC
|
|
||||||
ddc.init(&ddcIn, 50e6, 50e6, 50e6, 0.0);
|
|
||||||
|
|
||||||
handler.ctx = this;
|
|
||||||
handler.selectHandler = menuSelected;
|
|
||||||
handler.deselectHandler = menuDeselected;
|
|
||||||
handler.menuHandler = menuHandler;
|
|
||||||
handler.startHandler = start;
|
|
||||||
handler.stopHandler = stop;
|
|
||||||
handler.tuneHandler = tune;
|
|
||||||
handler.stream = &ddc.out;
|
|
||||||
|
|
||||||
// Refresh devices
|
|
||||||
refresh();
|
|
||||||
|
|
||||||
// Select device from config
|
|
||||||
config.acquire();
|
|
||||||
std::string devSerial = config.conf["device"];
|
|
||||||
config.release();
|
|
||||||
select(devSerial);
|
|
||||||
|
|
||||||
sigpath::sourceManager.registerSource("FobosSDR", &handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
~FobosSDRSourceModule() {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
void postInit() {}
|
|
||||||
|
|
||||||
void enable() {
|
|
||||||
enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable() {
|
|
||||||
enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Port {
|
|
||||||
PORT_RF,
|
|
||||||
PORT_HF1,
|
|
||||||
PORT_HF2
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string getBandwdithScaled(double bw) {
|
|
||||||
char buf[1024];
|
|
||||||
if (bw >= 1000000.0) {
|
|
||||||
sprintf(buf, "%.1lfMHz", bw / 1000000.0);
|
|
||||||
}
|
|
||||||
else if (bw >= 1000.0) {
|
|
||||||
sprintf(buf, "%.1lfKHz", bw / 1000.0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sprintf(buf, "%.1lfHz", bw);
|
|
||||||
}
|
|
||||||
return std::string(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void refresh() {
|
|
||||||
devices.clear();
|
|
||||||
|
|
||||||
// Get device list
|
|
||||||
char serials[1024];
|
|
||||||
memset(serials, 0, sizeof(serials));
|
|
||||||
int devCount = fobos_rx_list_devices(serials);
|
|
||||||
if (devCount < 0) {
|
|
||||||
flog::error("Failed to get device list: {}", devCount);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no device, give up
|
|
||||||
if (!devCount) { return; }
|
|
||||||
|
|
||||||
// Generate device entries
|
|
||||||
const char* _serials = serials;
|
|
||||||
int index = 0;
|
|
||||||
while (*_serials) {
|
|
||||||
// Read serial until space
|
|
||||||
std::string serial = "";
|
|
||||||
while (*_serials) {
|
|
||||||
// Get a character
|
|
||||||
char c = *(_serials++);
|
|
||||||
|
|
||||||
// If it's a space, we're done
|
|
||||||
if (c == ' ') { break; }
|
|
||||||
|
|
||||||
// Otherwise, add it to the string
|
|
||||||
serial += c;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create entry
|
|
||||||
devices.define(serial, serial, index++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void select(const std::string& serial) {
|
|
||||||
// If there are no devices, give up
|
|
||||||
if (devices.empty()) {
|
|
||||||
selectedSerial.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the serial was not found, select the first available serial
|
|
||||||
if (!devices.keyExists(serial)) {
|
|
||||||
select(devices.key(0));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the ID in the list
|
|
||||||
int id = devices.keyId(serial);
|
|
||||||
selectedDevId = devices[id];
|
|
||||||
|
|
||||||
// Open the device
|
|
||||||
fobos_dev_t* dev;
|
|
||||||
int err = fobos_rx_open(&dev, selectedDevId);
|
|
||||||
if (err) {
|
|
||||||
flog::error("Failed to open device: {}", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a list of supported samplerates
|
|
||||||
double srList[128];
|
|
||||||
unsigned int srCount;
|
|
||||||
err = fobos_rx_get_samplerates(dev, srList, &srCount);
|
|
||||||
if (err) {
|
|
||||||
flog::error("Failed to get samplerate list: {}", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate samplerate list
|
|
||||||
samplerates.clear();
|
|
||||||
for (int i = 0; i < srCount; i++) {
|
|
||||||
std::string str = getBandwdithScaled(srList[i]);
|
|
||||||
samplerates.define(srList[i], str, srList[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add some custom samplerates
|
|
||||||
samplerates.define(5e6, "5.0MHz", 5e6);
|
|
||||||
samplerates.define(2.5e6, "2.5MHz", 2.5e6);
|
|
||||||
samplerates.define(1.25e6, "1.25MHz", 1.25e6);
|
|
||||||
|
|
||||||
// Define the ports
|
|
||||||
ports.clear();
|
|
||||||
ports.define("rf", "RF", PORT_RF);
|
|
||||||
ports.define("hf1", "HF1", PORT_HF1);
|
|
||||||
ports.define("hf2", "HF2", PORT_HF2);
|
|
||||||
|
|
||||||
// Define clock sources
|
|
||||||
clockSources.clear();
|
|
||||||
clockSources.define("internal", "Internal", 0);
|
|
||||||
clockSources.define("external", "External", 1);
|
|
||||||
|
|
||||||
// Close the device
|
|
||||||
fobos_rx_close(dev);
|
|
||||||
|
|
||||||
// Save serial number
|
|
||||||
selectedSerial = serial;
|
|
||||||
devId = id;
|
|
||||||
|
|
||||||
// Load default options
|
|
||||||
sampleRate = 50e6;
|
|
||||||
srId = samplerates.valueId(sampleRate);
|
|
||||||
port = PORT_RF;
|
|
||||||
portId = ports.valueId(port);
|
|
||||||
clkSrcId = clockSources.nameId("Internal");
|
|
||||||
lnaGain = 0;
|
|
||||||
vgaGain = 0;
|
|
||||||
|
|
||||||
// Load config
|
|
||||||
config.acquire();
|
|
||||||
if (config.conf["devices"][selectedSerial].contains("samplerate")) {
|
|
||||||
int desiredSr = config.conf["devices"][selectedSerial]["samplerate"];
|
|
||||||
if (samplerates.keyExists(desiredSr)) {
|
|
||||||
srId = samplerates.keyId(desiredSr);
|
|
||||||
sampleRate = samplerates[srId];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (config.conf["devices"][selectedSerial].contains("port")) {
|
|
||||||
std::string desiredPort = config.conf["devices"][selectedSerial]["port"];
|
|
||||||
if (ports.keyExists(desiredPort)) {
|
|
||||||
portId = ports.keyId(desiredPort);
|
|
||||||
port = ports[portId];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (config.conf["devices"][selectedSerial].contains("clkSrc")) {
|
|
||||||
std::string desiredClkSrc = config.conf["devices"][selectedSerial]["clkSrc"];
|
|
||||||
if (clockSources.keyExists(desiredClkSrc)) {
|
|
||||||
clkSrcId = clockSources.keyId(desiredClkSrc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (config.conf["devices"][selectedSerial].contains("lnaGain")) {
|
|
||||||
lnaGain = std::clamp<int>(config.conf["devices"][selectedSerial]["lnaGain"], FOBOS_LNA_GAIN_MIN, FOBOS_LNA_GAIN_MAX);
|
|
||||||
}
|
|
||||||
if (config.conf["devices"][selectedSerial].contains("vgaGain")) {
|
|
||||||
vgaGain = std::clamp<int>(config.conf["devices"][selectedSerial]["vgaGain"], FOBOS_VGA_GAIN_MIN, FOBOS_VGA_GAIN_MAX);
|
|
||||||
}
|
|
||||||
config.release();
|
|
||||||
|
|
||||||
// Update the samplerate
|
|
||||||
core::setInputSampleRate(sampleRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void menuSelected(void* ctx) {
|
|
||||||
FobosSDRSourceModule* _this = (FobosSDRSourceModule*)ctx;
|
|
||||||
core::setInputSampleRate(_this->sampleRate);
|
|
||||||
flog::info("FobosSDRSourceModule '{0}': Menu Select!", _this->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void menuDeselected(void* ctx) {
|
|
||||||
FobosSDRSourceModule* _this = (FobosSDRSourceModule*)ctx;
|
|
||||||
flog::info("FobosSDRSourceModule '{0}': Menu Deselect!", _this->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void start(void* ctx) {
|
|
||||||
FobosSDRSourceModule* _this = (FobosSDRSourceModule*)ctx;
|
|
||||||
if (_this->running) { return; }
|
|
||||||
|
|
||||||
// Open the device
|
|
||||||
int err = fobos_rx_open(&_this->openDev, _this->selectedDevId);
|
|
||||||
if (err) {
|
|
||||||
flog::error("Failed to open device: {}", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the selected port
|
|
||||||
_this->port = _this->ports[_this->portId];
|
|
||||||
|
|
||||||
// Configure the device
|
|
||||||
double actualSr, actualFreq;
|
|
||||||
fobos_rx_set_samplerate(_this->openDev, (_this->sampleRate >= 50e6) ? _this->sampleRate : 50e6, &actualSr);
|
|
||||||
fobos_rx_set_frequency(_this->openDev, _this->freq, &actualFreq);
|
|
||||||
fobos_rx_set_direct_sampling(_this->openDev, _this->port != PORT_RF);
|
|
||||||
fobos_rx_set_clk_source(_this->openDev, _this->clockSources[_this->clkSrcId]);
|
|
||||||
fobos_rx_set_lna_gain(_this->openDev, _this->lnaGain);
|
|
||||||
fobos_rx_set_vga_gain(_this->openDev, _this->vgaGain);
|
|
||||||
|
|
||||||
// Configure the DDC
|
|
||||||
if (_this->port == PORT_RF && _this->sampleRate >= 50e6) {
|
|
||||||
// Set the frequency
|
|
||||||
fobos_rx_set_frequency(_this->openDev, _this->freq, &actualFreq);
|
|
||||||
}
|
|
||||||
else if (_this->port == PORT_RF) {
|
|
||||||
// Set the frequency
|
|
||||||
fobos_rx_set_frequency(_this->openDev, _this->freq, &actualFreq);
|
|
||||||
|
|
||||||
// Configure and start the DDC for decimation only
|
|
||||||
_this->ddc.setInSamplerate(actualSr);
|
|
||||||
_this->ddc.setOutSamplerate(_this->sampleRate, _this->sampleRate);
|
|
||||||
_this->ddc.setOffset(0.0);
|
|
||||||
_this->ddc.start();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Configure and start the DDC
|
|
||||||
_this->ddc.setInSamplerate(actualSr);
|
|
||||||
_this->ddc.setOutSamplerate(_this->sampleRate, _this->sampleRate);
|
|
||||||
_this->ddc.setOffset(_this->freq);
|
|
||||||
_this->ddc.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute buffer size (Lower than usual, but it's a workaround for their API having broken streaming)
|
|
||||||
_this->bufferSize = _this->sampleRate / 400.0;
|
|
||||||
|
|
||||||
// Start streaming
|
|
||||||
err = fobos_rx_start_sync(_this->openDev, _this->bufferSize);
|
|
||||||
if (err) {
|
|
||||||
flog::error("Failed to start stream: {}", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start worker
|
|
||||||
_this->run = true;
|
|
||||||
_this->workerThread = std::thread(&FobosSDRSourceModule::worker, _this);
|
|
||||||
|
|
||||||
_this->running = true;
|
|
||||||
flog::info("FobosSDRSourceModule '{0}': Start!", _this->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stop(void* ctx) {
|
|
||||||
FobosSDRSourceModule* _this = (FobosSDRSourceModule*)ctx;
|
|
||||||
if (!_this->running) { return; }
|
|
||||||
_this->running = false;
|
|
||||||
|
|
||||||
// Stop worker
|
|
||||||
_this->run = false;
|
|
||||||
if (_this->port == PORT_RF && _this->sampleRate >= 50e6) {
|
|
||||||
_this->ddc.out.stopWriter();
|
|
||||||
if (_this->workerThread.joinable()) { _this->workerThread.join(); }
|
|
||||||
_this->ddc.out.clearWriteStop();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_this->ddcIn.stopWriter();
|
|
||||||
if (_this->workerThread.joinable()) { _this->workerThread.join(); }
|
|
||||||
_this->ddcIn.clearWriteStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop streaming
|
|
||||||
fobos_rx_stop_sync(_this->openDev);
|
|
||||||
|
|
||||||
// Stop the DDC
|
|
||||||
_this->ddc.stop();
|
|
||||||
|
|
||||||
// Close the device
|
|
||||||
fobos_rx_close(_this->openDev);
|
|
||||||
|
|
||||||
flog::info("FobosSDRSourceModule '{0}': Stop!", _this->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tune(double freq, void* ctx) {
|
|
||||||
FobosSDRSourceModule* _this = (FobosSDRSourceModule*)ctx;
|
|
||||||
if (_this->running) {
|
|
||||||
if (_this->port == PORT_RF) {
|
|
||||||
double actual; // Dummy, don't care
|
|
||||||
fobos_rx_set_frequency(_this->openDev, freq, &actual);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_this->ddc.setOffset(freq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_this->freq = freq;
|
|
||||||
flog::info("FobosSDRSourceModule '{0}': Tune: {1}!", _this->name, freq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void menuHandler(void* ctx) {
|
|
||||||
FobosSDRSourceModule* _this = (FobosSDRSourceModule*)ctx;
|
|
||||||
|
|
||||||
if (_this->running) { SmGui::BeginDisabled(); }
|
|
||||||
|
|
||||||
SmGui::FillWidth();
|
|
||||||
SmGui::ForceSync();
|
|
||||||
if (SmGui::Combo(CONCAT("##_fobossdr_dev_sel_", _this->name), &_this->devId, _this->devices.txt)) {
|
|
||||||
_this->select(_this->devices.key(_this->devId));
|
|
||||||
core::setInputSampleRate(_this->sampleRate);
|
|
||||||
config.acquire();
|
|
||||||
config.conf["device"] = _this->selectedSerial;
|
|
||||||
config.release(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SmGui::Combo(CONCAT("##_fobossdr_sr_sel_", _this->name), &_this->srId, _this->samplerates.txt)) {
|
|
||||||
_this->sampleRate = _this->samplerates.value(_this->srId);
|
|
||||||
core::setInputSampleRate(_this->sampleRate);
|
|
||||||
if (!_this->selectedSerial.empty()) {
|
|
||||||
config.acquire();
|
|
||||||
config.conf["devices"][_this->selectedSerial]["samplerate"] = _this->samplerates.key(_this->srId);
|
|
||||||
config.release(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SmGui::SameLine();
|
|
||||||
SmGui::FillWidth();
|
|
||||||
SmGui::ForceSync();
|
|
||||||
if (SmGui::Button(CONCAT("Refresh##_fobossdr_refr_", _this->name))) {
|
|
||||||
_this->refresh();
|
|
||||||
_this->select(_this->selectedSerial);
|
|
||||||
core::setInputSampleRate(_this->sampleRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
SmGui::LeftLabel("Antenna Port");
|
|
||||||
SmGui::FillWidth();
|
|
||||||
if (SmGui::Combo(CONCAT("##_fobossdr_port_", _this->name), &_this->portId, _this->ports.txt)) {
|
|
||||||
if (!_this->selectedSerial.empty()) {
|
|
||||||
config.acquire();
|
|
||||||
config.conf["devices"][_this->selectedSerial]["port"] = _this->ports.key(_this->portId);
|
|
||||||
config.release(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_this->running) { SmGui::EndDisabled(); }
|
|
||||||
|
|
||||||
SmGui::LeftLabel("Clock Source");
|
|
||||||
SmGui::FillWidth();
|
|
||||||
if (SmGui::Combo(CONCAT("##_fobossdr_clk_", _this->name), &_this->clkSrcId, _this->clockSources.txt)) {
|
|
||||||
if (_this->running) {
|
|
||||||
fobos_rx_set_clk_source(_this->openDev, _this->clockSources[_this->clkSrcId]);
|
|
||||||
}
|
|
||||||
if (!_this->selectedSerial.empty()) {
|
|
||||||
config.acquire();
|
|
||||||
config.conf["devices"][_this->selectedSerial]["clkSrc"] = _this->clockSources.key(_this->clkSrcId);
|
|
||||||
config.release(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_this->port == PORT_RF) {
|
|
||||||
SmGui::LeftLabel("LNA Gain");
|
|
||||||
SmGui::FillWidth();
|
|
||||||
if (SmGui::SliderInt(CONCAT("##_fobossdr_lna_gain_", _this->name), &_this->lnaGain, FOBOS_LNA_GAIN_MIN, FOBOS_LNA_GAIN_MAX)) {
|
|
||||||
if (_this->running) {
|
|
||||||
fobos_rx_set_lna_gain(_this->openDev, _this->lnaGain);
|
|
||||||
}
|
|
||||||
if (!_this->selectedSerial.empty()) {
|
|
||||||
config.acquire();
|
|
||||||
config.conf["devices"][_this->selectedSerial]["lnaGain"] = _this->lnaGain;
|
|
||||||
config.release(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SmGui::LeftLabel("VGA Gain");
|
|
||||||
SmGui::FillWidth();
|
|
||||||
if (SmGui::SliderInt(CONCAT("##_fobossdr_vga_gain_", _this->name), &_this->vgaGain, FOBOS_VGA_GAIN_MIN, FOBOS_VGA_GAIN_MAX)) {
|
|
||||||
if (_this->running) {
|
|
||||||
fobos_rx_set_vga_gain(_this->openDev, _this->vgaGain);
|
|
||||||
}
|
|
||||||
if (!_this->selectedSerial.empty()) {
|
|
||||||
config.acquire();
|
|
||||||
config.conf["devices"][_this->selectedSerial]["vgaGain"] = _this->vgaGain;
|
|
||||||
config.release(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void worker() {
|
|
||||||
// Select different processing depending on the mode
|
|
||||||
if (port == PORT_RF && sampleRate >= 50e6) {
|
|
||||||
while (run) {
|
|
||||||
// Read samples
|
|
||||||
unsigned int sampCount = 0;
|
|
||||||
int err = fobos_rx_read_sync(openDev, (float*)ddc.out.writeBuf, &sampCount);
|
|
||||||
if (err) { break; }
|
|
||||||
|
|
||||||
// Send out samples to the core
|
|
||||||
if (!ddc.out.swap(sampCount)) { break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (port == PORT_RF) {
|
|
||||||
while (run) {
|
|
||||||
// Read samples
|
|
||||||
unsigned int sampCount = 0;
|
|
||||||
int err = fobos_rx_read_sync(openDev, (float*)ddcIn.writeBuf, &sampCount);
|
|
||||||
if (err) { break; }
|
|
||||||
|
|
||||||
// Send samples to the DDC
|
|
||||||
if (!ddcIn.swap(sampCount)) { break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (port == PORT_HF1) {
|
|
||||||
while (run) {
|
|
||||||
// Read samples
|
|
||||||
unsigned int sampCount = 0;
|
|
||||||
int err = fobos_rx_read_sync(openDev, (float*)ddcIn.writeBuf, &sampCount);
|
|
||||||
if (err) { break; }
|
|
||||||
|
|
||||||
// Null out the HF2 samples
|
|
||||||
for (int i = 0; i < sampCount; i++) {
|
|
||||||
ddcIn.writeBuf[i].im = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send samples to the DDC
|
|
||||||
if (!ddcIn.swap(sampCount)) { break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (port == PORT_HF2) {
|
|
||||||
while (run) {
|
|
||||||
// Read samples
|
|
||||||
unsigned int sampCount = 0;
|
|
||||||
int err = fobos_rx_read_sync(openDev, (float*)ddcIn.writeBuf, &sampCount);
|
|
||||||
if (err) { break; }
|
|
||||||
|
|
||||||
// Null out the HF2 samples
|
|
||||||
for (int i = 0; i < sampCount; i++) {
|
|
||||||
ddcIn.writeBuf[i].re = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send samples to the DDC
|
|
||||||
if (!ddcIn.swap(sampCount)) { break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name;
|
|
||||||
bool enabled = true;
|
|
||||||
double sampleRate;
|
|
||||||
SourceManager::SourceHandler handler;
|
|
||||||
bool running = false;
|
|
||||||
double freq;
|
|
||||||
|
|
||||||
OptionList<std::string, int> devices;
|
|
||||||
OptionList<int, double> samplerates;
|
|
||||||
OptionList<std::string, Port> ports;
|
|
||||||
OptionList<std::string, int> clockSources;
|
|
||||||
int devId = 0;
|
|
||||||
int srId = 0;
|
|
||||||
int portId = 0;
|
|
||||||
int clkSrcId = 0;
|
|
||||||
Port port;
|
|
||||||
int lnaGain = 0;
|
|
||||||
int vgaGain = 0;
|
|
||||||
std::string selectedSerial;
|
|
||||||
int selectedDevId;
|
|
||||||
|
|
||||||
fobos_dev_t* openDev;
|
|
||||||
|
|
||||||
int bufferSize;
|
|
||||||
std::thread workerThread;
|
|
||||||
std::atomic<bool> run = false;
|
|
||||||
|
|
||||||
dsp::stream<dsp::complex_t> ddcIn;
|
|
||||||
dsp::channel::RxVFO ddc;
|
|
||||||
};
|
|
||||||
|
|
||||||
MOD_EXPORT void _INIT_() {
|
|
||||||
json def = json({});
|
|
||||||
def["devices"] = json({});
|
|
||||||
def["device"] = "";
|
|
||||||
config.setPath(core::args["root"].s() + "/fobossdr_config.json");
|
|
||||||
config.load(def);
|
|
||||||
config.enableAutoSave();
|
|
||||||
}
|
|
||||||
|
|
||||||
MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) {
|
|
||||||
return new FobosSDRSourceModule(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
MOD_EXPORT void _DELETE_INSTANCE_(void* instance) {
|
|
||||||
delete (FobosSDRSourceModule*)instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOD_EXPORT void _END_() {
|
|
||||||
config.disableAutoSave();
|
|
||||||
config.save();
|
|
||||||
}
|
|
@ -523,8 +523,8 @@ private:
|
|||||||
RTLSDRSourceModule* _this = (RTLSDRSourceModule*)ctx;
|
RTLSDRSourceModule* _this = (RTLSDRSourceModule*)ctx;
|
||||||
int sampCount = len / 2;
|
int sampCount = len / 2;
|
||||||
for (int i = 0; i < sampCount; i++) {
|
for (int i = 0; i < sampCount; i++) {
|
||||||
_this->stream.writeBuf[i].re = ((float)buf[i * 2] - 127.4) / 128.0f;
|
_this->stream.writeBuf[i].re = ((float)buf[i * 2] - 127.4f) / 128.0f;
|
||||||
_this->stream.writeBuf[i].im = ((float)buf[(i * 2) + 1] - 127.4) / 128.0f;
|
_this->stream.writeBuf[i].im = ((float)buf[(i * 2) + 1] - 127.4f) / 128.0f;
|
||||||
}
|
}
|
||||||
if (!_this->stream.swap(sampCount)) { return; }
|
if (!_this->stream.swap(sampCount)) { return; }
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user