mirror of
				https://github.com/AlexandreRouma/SDRPlusPlus.git
				synced 2025-10-31 00:48:11 +01:00 
			
		
		
		
	Compare commits
	
		
			6 Commits
		
	
	
		
			fobos_test
			...
			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 . | ||||
|  | ||||
|         - 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 | ||||
|           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 . | ||||
|  | ||||
|         - 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 . | ||||
|           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: Prepare CMake | ||||
|           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 | ||||
|           working-directory: ${{runner.workspace}}/build | ||||
| @@ -130,15 +127,12 @@ jobs: | ||||
|         - 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 .. | ||||
|  | ||||
|         - 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 | ||||
|           run: git clone https://github.com/osmocom/rtl-sdr && cd rtl-sdr && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 LIBRARY_PATH=$(pkg-config --libs-only-L libusb-1.0 | sed 's/\-L//') && sudo make install && cd ../../ | ||||
|  | ||||
|         - name: Prepare CMake | ||||
|           working-directory: ${{runner.workspace}}/build | ||||
|           run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=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 | ||||
|           working-directory: ${{runner.workspace}}/build | ||||
| @@ -187,15 +181,12 @@ jobs: | ||||
|         - 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 .. | ||||
|  | ||||
|         - 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 | ||||
|           run: git clone https://github.com/osmocom/rtl-sdr && cd rtl-sdr && mkdir build && cd build && cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=Release .. && make -j3 LIBRARY_PATH=$(pkg-config --libs-only-L libusb-1.0 | sed 's/\-L//') && sudo make install && cd ../../ | ||||
|  | ||||
|         - name: Prepare CMake | ||||
|           working-directory: ${{runner.workspace}}/build | ||||
|           run: cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF -DOPT_BUILD_PERSEUS_SOURCE=OFF -DOPT_BUILD_AUDIO_SOURCE=OFF -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 | ||||
|           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_BLADERF_SOURCE "Build BladeRF Source Module (Dependencies: libbladeRF)" OFF) | ||||
| 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_HAROGIC_SOURCE "Build Harogic Source Module (Dependencies: htra_api)" OFF) | ||||
| 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 | ||||
| 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_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) | ||||
| @@ -99,13 +97,56 @@ set(SDRPP_MODULE_COMPILER_FLAGS ${SDRPP_COMPILER_FLAGS}) | ||||
|  | ||||
| # Set a default install prefix | ||||
| 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) | ||||
|     else() | ||||
|         set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "..." FORCE) | ||||
|     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 | ||||
| if (ANDROID) | ||||
|     set(CMAKE_SHARED_LINKER_FLAGS | ||||
| @@ -144,10 +185,6 @@ if (OPT_BUILD_FILE_SOURCE) | ||||
| add_subdirectory("source_modules/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) | ||||
| add_subdirectory("source_modules/hackrf_source") | ||||
| endif (OPT_BUILD_HACKRF_SOURCE) | ||||
| @@ -248,10 +285,6 @@ if (OPT_BUILD_ATV_DECODER) | ||||
| add_subdirectory("decoder_modules/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) | ||||
| add_subdirectory("decoder_modules/falcon9_decoder") | ||||
| endif (OPT_BUILD_FALCON9_DECODER) | ||||
| @@ -373,17 +406,18 @@ endif () | ||||
| # Create module cmake file | ||||
| configure_file(${CMAKE_SOURCE_DIR}/sdrpp_module.cmake ${CMAKE_CURRENT_BINARY_DIR}/sdrpp_module.cmake @ONLY) | ||||
|  | ||||
| # Install directives | ||||
| 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) | ||||
| # Create desktop entry file | ||||
| 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") | ||||
|     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 () | ||||
|  | ||||
| # Create uninstall target | ||||
|   | ||||
| @@ -18,6 +18,10 @@ if (MSVC) | ||||
|     set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) | ||||
| 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 | ||||
| if (OPT_BACKEND_GLFW) | ||||
|     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 | ||||
| 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 | ||||
| target_include_directories(sdrpp_core PUBLIC "src/") | ||||
| 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" | ||||
|  | ||||
| # Install directives | ||||
| install(TARGETS sdrpp_core DESTINATION lib) | ||||
| install(TARGETS sdrpp_core DESTINATION ${SDRPP_LIB_INSTALL_DIR}) | ||||
| @@ -24,14 +24,16 @@ | ||||
| #include <Windows.h> | ||||
| #endif | ||||
|  | ||||
| #ifndef INSTALL_PREFIX | ||||
| #ifdef __APPLE__ | ||||
| #define INSTALL_PREFIX "/usr/local" | ||||
| #else | ||||
| #define INSTALL_PREFIX "/usr" | ||||
|  | ||||
| // Default install dirs to make the IDE happy | ||||
| #ifndef SDRPP_MODULES_LOAD_DIR | ||||
| #define SDRPP_MODULES_LOAD_DIR "" | ||||
| #endif | ||||
| #ifndef SDRPP_RES_LOAD_DIR | ||||
| #define SDRPP_RES_LOAD_DIR "" | ||||
| #endif | ||||
|  | ||||
|  | ||||
| namespace core { | ||||
|     ConfigManager configManager; | ||||
|     ModuleManager moduleManager; | ||||
| @@ -173,20 +175,16 @@ int sdrpp_main(int argc, char* argv[]) { | ||||
|     defConfig["moduleInstances"]["BladeRF Source"]["enabled"] = true; | ||||
|     defConfig["moduleInstances"]["File Source"]["module"] = "file_source"; | ||||
|     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"]["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"]["enabled"] = true; | ||||
|     defConfig["moduleInstances"]["LimeSDR Source"]["module"] = "limesdr_source"; | ||||
|     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"]["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"]["enabled"] = true; | ||||
|     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"]["SDR++ Server Source"]["module"] = "sdrpp_server_source"; | ||||
|     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"]["enabled"] = true; | ||||
|     defConfig["moduleInstances"]["USRP Source"]["module"] = "usrp_source"; | ||||
|     defConfig["moduleInstances"]["USRP Source"]["enabled"] = true; | ||||
|  | ||||
|     defConfig["moduleInstances"]["Audio Sink"] = "audio_sink"; | ||||
|     defConfig["moduleInstances"]["Network Sink"] = "network_sink"; | ||||
| @@ -256,19 +250,14 @@ int sdrpp_main(int argc, char* argv[]) { | ||||
|     defConfig["lockMenuOrder"] = false; | ||||
| #endif | ||||
|  | ||||
| #if defined(_WIN32) | ||||
|     defConfig["modulesDirectory"] = "./modules"; | ||||
|     defConfig["resourcesDirectory"] = "./res"; | ||||
| #elif defined(IS_MACOS_BUNDLE) | ||||
|     defConfig["modulesDirectory"] = "../Plugins"; | ||||
|     defConfig["resourcesDirectory"] = "../Resources"; | ||||
| #elif defined(__ANDROID__) | ||||
|     defConfig["modulesDirectory"] = root + "/modules"; | ||||
|     defConfig["resourcesDirectory"] = root + "/res"; | ||||
| #ifdef __ANDROID__ | ||||
|     defConfig["modulesDirectory"] = root + SDRPP_MODULES_LOAD_DIR; | ||||
|     defConfig["resourcesDirectory"] = root + SDRPP_RES_LOAD_DIR; | ||||
| #else | ||||
|     defConfig["modulesDirectory"] = INSTALL_PREFIX "/lib/sdrpp/plugins"; | ||||
|     defConfig["resourcesDirectory"] = INSTALL_PREFIX "/share/sdrpp"; | ||||
|     defConfig["modulesDirectory"] = SDRPP_MODULES_LOAD_DIR; | ||||
|     defConfig["resourcesDirectory"] = SDRPP_RES_LOAD_DIR; | ||||
| #endif | ||||
|      | ||||
|  | ||||
|     // Load config | ||||
|     flog::info("Loading config"); | ||||
|   | ||||
| @@ -37,12 +37,9 @@ namespace sdrpp_credits { | ||||
|     const char* hardwareDonators[] = { | ||||
|         "Aaronia AG", | ||||
|         "Airspy", | ||||
|         "Alex 4Z5LV", | ||||
|         "Analog Devices", | ||||
|         "CaribouLabs", | ||||
|         "Deepace", | ||||
|         "Ettus Research", | ||||
|         "Harogic", | ||||
|         "Howard Su", | ||||
|         "MicroPhase", | ||||
|         "Microtelecom", | ||||
| @@ -50,7 +47,6 @@ namespace sdrpp_credits { | ||||
|         "Nuand", | ||||
|         "RFNM", | ||||
|         "RFspace", | ||||
|         "RigExpert", | ||||
|         "RTL-SDRblog", | ||||
|         "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,163 +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> | ||||
|  | ||||
| #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("sync4.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, 1e-3, 246e-6, INPUT_SAMPLE_RATE); | ||||
|         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::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,34 +0,0 @@ | ||||
| 0123456789 | ||||
| ---  --- | ||||
|  | ||||
| 0*4 | ||||
| 1*5 | ||||
| 2*6 | ||||
|  | ||||
| 1*5 | ||||
| 2*6 = L + 3*7 - 0*4 | ||||
| 3*7 | ||||
|  | ||||
| 2*6 | ||||
| 3*7 = L + 4*8 - 1*5 | ||||
| 4*8 | ||||
|  | ||||
| 3*7 | ||||
| 4*8 = L + 5*9 - 2*6 | ||||
| 5*9 | ||||
|  | ||||
|  | ||||
|  | ||||
| 0*5 | ||||
| 1*6 | ||||
| 2*7 | ||||
|  | ||||
| 1*6 | ||||
| 2*7 | ||||
| 3*8 | ||||
|  | ||||
| 2*7 | ||||
| 3*8 | ||||
| 4*9 | ||||
|  | ||||
| => Use same technique to cache the interpolation results | ||||
| @@ -23,9 +23,9 @@ SDRPP_MOD_INFO{ | ||||
|     /* Max instances    */ -1 | ||||
| }; | ||||
|  | ||||
| #define INPUT_BANDWIDTH     600e3 | ||||
| #define INPUT_SAMPLE_RATE   1000e3 | ||||
| #define INPUT_BAUDRATE      500e3 | ||||
| #define INPUT_BANDWIDTH     138e3 | ||||
| #define INPUT_SAMPLE_RATE   250e3 | ||||
| #define INPUT_BAUDRATE      125e3 | ||||
|  | ||||
| #define SYMBOL_DIAG_RATE    30 | ||||
| #define SYMBOL_DIAG_COUNT   1024 | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| #pragma once | ||||
| #include <stdint.h> | ||||
| #include <stddef.h> | ||||
| #include "dsp/processor.h" | ||||
|  | ||||
| extern "C" { | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| #pragma once | ||||
| #include "dsp/processor.h" | ||||
| #include <stdint.h> | ||||
| #include <stddef.h> | ||||
|  | ||||
| namespace ryfi { | ||||
|     // Synchronization word. | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| #pragma once | ||||
| #include <stdint.h> | ||||
| #include <stddef.h> | ||||
|  | ||||
| namespace ryfi { | ||||
|     /** | ||||
|   | ||||
| @@ -72,7 +72,6 @@ namespace ryfi { | ||||
|         uint8_t* pktBuffer = new uint8_t[Packet::MAX_CONTENT_SIZE]; | ||||
|         int pktExpected = 0; | ||||
|         int pktRead = 0; | ||||
|         int valid = 0; | ||||
|  | ||||
|         while (true) { | ||||
|             // Read a frame | ||||
| @@ -81,7 +80,6 @@ namespace ryfi { | ||||
|  | ||||
|             // Deserialize the frame | ||||
|             Frame::deserialize(rs.out.readBuf, frame); | ||||
|             valid++; | ||||
|  | ||||
|             // Flush the stream | ||||
|             rs.out.flush(); | ||||
| @@ -95,12 +93,11 @@ namespace ryfi { | ||||
|             // If the frames aren't consecutive | ||||
|             int frameRead = 0; | ||||
|             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 | ||||
|                 pktExpected = 0; | ||||
|                 pktRead = 0; | ||||
|                 valid = 1; | ||||
|  | ||||
|                 // If this frame is not an idle frame or continuation frame | ||||
|                 if (frame.firstPacket != PKT_OFFS_NONE) { | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| #pragma once | ||||
| #include <stdint.h> | ||||
| #include <stddef.h> | ||||
| #include "dsp/processor.h" | ||||
|  | ||||
| extern "C" { | ||||
|   | ||||
| @@ -35,20 +35,10 @@ make -j2 | ||||
| make install | ||||
| 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 | ||||
| mkdir 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 | ||||
|  | ||||
| cd .. | ||||
|   | ||||
| @@ -35,20 +35,10 @@ make -j2 | ||||
| make install | ||||
| 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 | ||||
| mkdir 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 | ||||
|  | ||||
| cd .. | ||||
|   | ||||
| @@ -35,20 +35,10 @@ make -j2 | ||||
| make install | ||||
| 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 | ||||
| mkdir 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 | ||||
|  | ||||
| cd .. | ||||
|   | ||||
| @@ -35,20 +35,10 @@ make -j2 | ||||
| make install | ||||
| 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 | ||||
| mkdir 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 | ||||
|  | ||||
| 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 | ||||
| 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 | ||||
| echo 'prefix=/usr/' >> /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 | ||||
| mkdir 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 | ||||
|  | ||||
| # Generate package | ||||
|   | ||||
| @@ -35,20 +35,10 @@ make -j2 | ||||
| make install | ||||
| 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 | ||||
| mkdir 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 | ||||
|  | ||||
| cd .. | ||||
|   | ||||
| @@ -35,20 +35,10 @@ make -j2 | ||||
| make install | ||||
| 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 | ||||
| mkdir 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 | ||||
|  | ||||
| cd .. | ||||
|   | ||||
| @@ -35,20 +35,10 @@ make -j2 | ||||
| make install | ||||
| 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 | ||||
| mkdir 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 | ||||
|  | ||||
| cd .. | ||||
|   | ||||
| @@ -35,20 +35,10 @@ make -j2 | ||||
| make install | ||||
| 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 | ||||
| mkdir 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 | ||||
|  | ||||
| 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/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/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/hermes_source/hermes_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/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 '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         | ✅              | ✅                     | ✅                         | | ||||
| | bladerf_source       | Working    | libbladeRF        | OPT_BUILD_BLADERF_SOURCE       | ⛔              | ✅ (not Debian Buster) | ✅                         | | ||||
| | file_source          | Working    | -                 | OPT_BUILD_FILE_SOURCE          | ✅              | ✅                     | ✅                         | | ||||
| | fobossdr_source      | Beta       | libfobos          | OPT_BUILD_FOBOSSDR_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        | ✅              | ✅                     | ✅                         | | ||||
| | limesdr_source       | Working    | liblimesuite      | OPT_BUILD_LIMESDR_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  | ✅              | ✅                     | ✅                         | | ||||
| | soapy_source         | Deprecated | soapysdr          | OPT_BUILD_SOAPY_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     | ✅              | ✅                     | ✅                         | | ||||
| | usrp_source          | Beta       | libuhd            | OPT_BUILD_USRP_SOURCE          | ⛔              | ⛔                     | ✅                         | | ||||
| | usrp_source          | Beta       | libuhd            | OPT_BUILD_USRP_SOURCE          | ⛔              | ⛔                     | ⛔                         | | ||||
|  | ||||
| ## 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 | | ||||
| |---------------------|------------|--------------|-------------------------------|:---------------:|:----------------:|:---------------------------:| | ||||
| | atv_decoder         | Unfinished | -            | OPT_BUILD_ATV_DECODER         | ⛔              | ⛔              | ⛔                         | | ||||
| | dab_decoder         | Unfinished | -            | OPT_BUILD_DAB_DECODER         | ⛔              | ⛔              | ⛔                         | | ||||
| | falcon9_decoder     | Unfinished | ffplay       | OPT_BUILD_FALCON9_DECODER     | ⛔              | ⛔              | ⛔                         | | ||||
| | kgsstv_decoder      | Unfinished | -            | OPT_BUILD_KGSSTV_DECODER      | ⛔              | ⛔              | ⛔                         | | ||||
| | m17_decoder         | Working    | -            | OPT_BUILD_M17_DECODER         | ⛔              | ✅              | ⛔                         | | ||||
|   | ||||
| @@ -3,7 +3,7 @@ Encoding=UTF-8 | ||||
| Version=1.0 | ||||
| Type=Application | ||||
| Terminal=false | ||||
| Exec=@CMAKE_INSTALL_PREFIX@/bin/sdrpp | ||||
| Exec=@SDRPP_BIN_INSTALL_DIR@/sdrpp | ||||
| Name=SDR++ | ||||
| Icon=@CMAKE_INSTALL_PREFIX@/share/sdrpp/icons/sdrpp.png | ||||
| Icon=@SDRPP_RES_INSTALL_DIR@/icons/sdrpp.png | ||||
| Categories=HamRadio | ||||
| @@ -6,6 +6,10 @@ if (NOT SDRPP_MODULE_COMPILER_FLAGS) | ||||
|     set(SDRPP_MODULE_COMPILER_FLAGS @SDRPP_MODULE_COMPILER_FLAGS@) | ||||
| 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 | ||||
| add_library(${PROJECT_NAME} SHARED ${SRC}) | ||||
| 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}) | ||||
|  | ||||
| # 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() { | ||||
|         try { | ||||
|             if (modeId == SINK_MODE_TCP) { | ||||
|                 listener = net::listen(hostname, port); | ||||
|                 if (listener) { | ||||
|                     listener->acceptAsync(clientHandler, this); | ||||
|                 } | ||||
|             } | ||||
|             else { | ||||
|                 conn = net::openUDP("0.0.0.0", port, hostname, port, false); | ||||
|         if (modeId == SINK_MODE_TCP) { | ||||
|             listener = net::listen(hostname, port); | ||||
|             if (listener) { | ||||
|                 listener->acceptAsync(clientHandler, this); | ||||
|             } | ||||
|         } | ||||
|         catch (const std::exception& e) { | ||||
|             flog::error("Failed to open socket: {}", e.what()); | ||||
|         else { | ||||
|             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; | ||||
|         int sampCount = len / 2; | ||||
|         for (int i = 0; i < sampCount; i++) { | ||||
|             _this->stream.writeBuf[i].re = ((float)buf[i * 2] - 127.4) / 128.0f; | ||||
|             _this->stream.writeBuf[i].im = ((float)buf[(i * 2) + 1] - 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.4f) / 128.0f; | ||||
|         } | ||||
|         if (!_this->stream.swap(sampCount)) { return; } | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user