Merge branch 'master' into rtaudio

This commit is contained in:
Stefan Talpalaru 2017-02-06 17:52:15 +01:00
commit f4a60e6765
No known key found for this signature in database
GPG Key ID: CBF7934204F1B6F9
202 changed files with 20056 additions and 8944 deletions

View File

@ -6,19 +6,69 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
SET(CUBICSDR_VERSION_MAJOR "0") SET(CUBICSDR_VERSION_MAJOR "0")
SET(CUBICSDR_VERSION_MINOR "2") SET(CUBICSDR_VERSION_MINOR "2")
SET(CUBICSDR_VERSION_PATCH "0") SET(CUBICSDR_VERSION_PATCH "2")
SET(CUBICSDR_VERSION_REL "") SET(CUBICSDR_VERSION_SUFFIX "-alpha")
SET(CUBICSDR_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}${CUBICSDR_VERSION_REL}") SET(CUBICSDR_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}${CUBICSDR_VERSION_SUFFIX}")
SET(CPACK_PACKAGE_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}") SET(CPACK_PACKAGE_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}")
SET(CPACK_PACKAGE_VERSION_MAJOR ${CUBICSDR_VERSION_MAJOR}) SET(CPACK_PACKAGE_VERSION_MAJOR ${CUBICSDR_VERSION_MAJOR})
SET(CPACK_PACKAGE_VERSION_MINOR ${CUBICSDR_VERSION_MINOR}) SET(CPACK_PACKAGE_VERSION_MINOR ${CUBICSDR_VERSION_MINOR})
SET(CPACK_PACKAGE_VERSION_PATCH ${CUBICSDR_VERSION_PATCH}) SET(CPACK_PACKAGE_VERSION_PATCH ${CUBICSDR_VERSION_PATCH})
SET (VERSION_SUFFIX "" CACHE STRING "Add custom version suffix to CubicSDR application title.") SET (CUSTOM_BUILD OFF CACHE BOOL "Enable custom build options")
# Build options for custom deploys, optimization and debugging
IF(CUSTOM_BUILD)
SET (CUBICSDR_BUILD_TITLE CACHE STRING "Custom Title")
# bundle flags
SET (CUBICSDR_INSTALL_NAME CACHE "CubicSDR" "Installation Name")
SET (CUBICSDR_INSTALL_TITLE CACHE "CubicSDR" "Installation Title")
SET (CUBICSDR_HEADER_IMAGE CACHE "" "Image file to display in header")
SET (CUBICSDR_HEADER_BG CACHE "000000" "Background Color (HEX) for header")
# feature flags
SET (CUBICSDR_ENABLE_VIEW_DEMOD ON CACHE BOOL "Enable Second Demodulator Spectrum/Waterfall view.")
SET (CUBICSDR_ENABLE_VIEW_SCOPE ON CACHE BOOL "Enable Demodulator Scope/Spectrum view.")
SET (CUBICSDR_MODEM_EXCLUDE CACHE "" "Comma-separated list of modems to exclude.")
IF (NOT CUBICSDR_HEADER_IMAGE STREQUAL "")
SET(CUBICSDR_HAS_HEADER_IMAGE TRUE)
GET_FILENAME_COMPONENT(CUBICSDR_HEADER_IMAGE_FILE "${CUBICSDR_HEADER_IMAGE}" NAME)
GET_FILENAME_COMPONENT(CUBICSDR_HEADER_IMAGE_DIR "${CUBICSDR_HEADER_IMAGE}" PATH)
ADD_DEFINITIONS(
-DCUBICSDR_HEADER_IMAGE="${CUBICSDR_HEADER_IMAGE_FILE}"
-DCUBICSDR_HEADER_BG="${CUBICSDR_HEADER_BG}"
)
ENDIF()
IF (NOT CUBICSDR_MODEM_EXCLUDE STREQUAL "")
ADD_DEFINITIONS(
-DCUBICSDR_MODEM_EXCLUDE="${CUBICSDR_MODEM_EXCLUDE}"
)
ENDIF()
ELSE()
SET (CUBICSDR_BUILD_TITLE "CubicSDR v${CUBICSDR_VERSION} by Charles J. Cliffe (@ccliffe) :: www.cubicsdr.com")
# bundle flags
SET (CUBICSDR_INSTALL_NAME "CubicSDR")
SET (CUBICSDR_INSTALL_TITLE "CubicSDR ${CUBICSDR_VERSION} Installer")
SET (CUBICSDR_HEADER_IMAGE "")
SET (CUBICSDR_HEADER_BG "")
# feature flags
SET (CUBICSDR_ENABLE_VIEW_DEMOD TRUE)
SET (CUBICSDR_ENABLE_VIEW_SCOPE TRUE)
SET (CUBICSDR_EXCLUDE_MODEM "")
ENDIF()
IF(CUBICSDR_ENABLE_VIEW_DEMOD)
ADD_DEFINITIONS( -DCUBICSDR_ENABLE_VIEW_DEMOD=1 )
ENDIF()
IF(CUBICSDR_ENABLE_VIEW_SCOPE)
ADD_DEFINITIONS( -DCUBICSDR_ENABLE_VIEW_SCOPE=1 )
ENDIF()
ADD_DEFINITIONS( ADD_DEFINITIONS(
-DCUBICSDR_VERSION="${CUBICSDR_VERSION}${VERSION_SUFFIX}" -DCUBICSDR_INSTALL_NAME="${CUBICSDR_INSTALL_NAME}"
-DCUBICSDR_VERSION="${CUBICSDR_VERSION}"
-DCUBICSDR_BUILD_TITLE="${CUBICSDR_BUILD_TITLE}"
) )
SET (ENABLE_DIGITAL_LAB OFF CACHE BOOL "Enable 'Digital Lab' testing features.") SET (ENABLE_DIGITAL_LAB OFF CACHE BOOL "Enable 'Digital Lab' testing features.")
@ -26,16 +76,6 @@ IF(ENABLE_DIGITAL_LAB)
ADD_DEFINITIONS( ADD_DEFINITIONS(
-DENABLE_DIGITAL_LAB=1 -DENABLE_DIGITAL_LAB=1
) )
IF(MSVC)
SET (ENABLE_LIQUID_EXPERIMENTAL OFF CACHE BOOL "Enable experimental liquid-dsp features (requires latest liquid-dsp installed)")
ELSE()
SET (ENABLE_LIQUID_EXPERIMENTAL ON CACHE BOOL "Enable experimental liquid-dsp features (requires latest liquid-dsp installed)")
ENDIF()
IF(ENABLE_LIQUID_EXPERIMENTAL)
ADD_DEFINITIONS(
-DENABLE_LIQUID_EXPERIMENTAL=1
)
ENDIF()
ENDIF() ENDIF()
set(USE_HAMLIB OFF CACHE BOOL "Support hamlib for radio control functions.") set(USE_HAMLIB OFF CACHE BOOL "Support hamlib for radio control functions.")
@ -225,6 +265,7 @@ SET (cubicsdr_sources
src/DemodLabelDialog.cpp src/DemodLabelDialog.cpp
src/IOThread.cpp src/IOThread.cpp
src/ModemProperties.cpp src/ModemProperties.cpp
src/BookmarkMgr.cpp
src/sdr/SDRDeviceInfo.cpp src/sdr/SDRDeviceInfo.cpp
src/sdr/SDRPostThread.cpp src/sdr/SDRPostThread.cpp
src/sdr/SDREnumerator.cpp src/sdr/SDREnumerator.cpp
@ -271,6 +312,7 @@ SET (cubicsdr_sources
src/visual/SpectrumCanvas.cpp src/visual/SpectrumCanvas.cpp
src/visual/WaterfallCanvas.cpp src/visual/WaterfallCanvas.cpp
src/visual/GainCanvas.cpp src/visual/GainCanvas.cpp
src/visual/ImagePanel.cpp
src/process/VisualProcessor.cpp src/process/VisualProcessor.cpp
src/process/ScopeVisualProcessor.cpp src/process/ScopeVisualProcessor.cpp
src/process/SpectrumVisualProcessor.cpp src/process/SpectrumVisualProcessor.cpp
@ -282,6 +324,10 @@ SET (cubicsdr_sources
src/forms/SDRDevices/SDRDevicesForm.cpp src/forms/SDRDevices/SDRDevicesForm.cpp
src/forms/SDRDevices/SDRDeviceAdd.cpp src/forms/SDRDevices/SDRDeviceAdd.cpp
src/forms/SDRDevices/SDRDeviceAddForm.cpp src/forms/SDRDevices/SDRDeviceAddForm.cpp
src/forms/Bookmark/BookmarkPanel.cpp
src/forms/Bookmark/BookmarkView.cpp
src/forms/Dialog/ActionDialogBase.cpp
src/forms/Dialog/ActionDialog.cpp
external/lodepng/lodepng.cpp external/lodepng/lodepng.cpp
external/tinyxml/tinyxml.cpp external/tinyxml/tinyxml.cpp
external/tinyxml/tinystr.cpp external/tinyxml/tinystr.cpp
@ -306,13 +352,8 @@ IF(ENABLE_DIGITAL_LAB)
src/modules/modem/digital/ModemSQAM.cpp src/modules/modem/digital/ModemSQAM.cpp
src/modules/modem/digital/ModemQAM.cpp src/modules/modem/digital/ModemQAM.cpp
src/modules/modem/digital/ModemQPSK.cpp src/modules/modem/digital/ModemQPSK.cpp
)
IF(ENABLE_LIQUID_EXPERIMENTAL)
SET (cubicsdr_sources
${cubicsdr_sources}
src/modules/modem/digital/ModemFSK.cpp src/modules/modem/digital/ModemFSK.cpp
) )
ENDIF()
ENDIF() ENDIF()
SET (cubicsdr_headers SET (cubicsdr_headers
@ -324,6 +365,7 @@ SET (cubicsdr_headers
src/DemodLabelDialog.h src/DemodLabelDialog.h
src/IOThread.h src/IOThread.h
src/ModemProperties.h src/ModemProperties.h
src/BookmarkMgr.h
src/sdr/SDRDeviceInfo.h src/sdr/SDRDeviceInfo.h
src/sdr/SDRPostThread.h src/sdr/SDRPostThread.h
src/sdr/SDREnumerator.h src/sdr/SDREnumerator.h
@ -370,6 +412,7 @@ SET (cubicsdr_headers
src/visual/SpectrumCanvas.h src/visual/SpectrumCanvas.h
src/visual/WaterfallCanvas.h src/visual/WaterfallCanvas.h
src/visual/GainCanvas.h src/visual/GainCanvas.h
src/visual/ImagePanel.h
src/process/VisualProcessor.h src/process/VisualProcessor.h
src/process/ScopeVisualProcessor.h src/process/ScopeVisualProcessor.h
src/process/SpectrumVisualProcessor.h src/process/SpectrumVisualProcessor.h
@ -385,6 +428,10 @@ SET (cubicsdr_headers
src/forms/SDRDevices/SDRDevicesForm.h src/forms/SDRDevices/SDRDevicesForm.h
src/forms/SDRDevices/SDRDeviceAdd.h src/forms/SDRDevices/SDRDeviceAdd.h
src/forms/SDRDevices/SDRDeviceAddForm.h src/forms/SDRDevices/SDRDeviceAddForm.h
src/forms/Bookmark/BookmarkPanel.h
src/forms/Bookmark/BookmarkView.h
src/forms/Dialog/ActionDialogBase.h
src/forms/Dialog/ActionDialog.h
external/lodepng/lodepng.h external/lodepng/lodepng.h
external/tinyxml/tinyxml.h external/tinyxml/tinyxml.h
external/tinyxml/tinystr.h external/tinyxml/tinystr.h
@ -420,13 +467,8 @@ SET (cubicsdr_headers
src/modules/modem/digital/ModemSQAM.h src/modules/modem/digital/ModemSQAM.h
src/modules/modem/digital/ModemQAM.h src/modules/modem/digital/ModemQAM.h
src/modules/modem/digital/ModemQPSK.h src/modules/modem/digital/ModemQPSK.h
)
IF(ENABLE_LIQUID_EXPERIMENTAL)
SET (cubicsdr_sources
${cubicsdr_sources}
src/modules/modem/digital/ModemFSK.h src/modules/modem/digital/ModemFSK.h
) )
ENDIF()
ENDIF() ENDIF()
@ -471,6 +513,8 @@ set(REG_EXT "[^/]*([.]cpp|[.]c|[.]h|[.]hpp)$")
SOURCE_GROUP("Base" REGULAR_EXPRESSION "src/${REG_EXT}") SOURCE_GROUP("Base" REGULAR_EXPRESSION "src/${REG_EXT}")
SOURCE_GROUP("Forms\\SDRDevices" REGULAR_EXPRESSION "src/forms/SDRDevices/${REG_EXT}") SOURCE_GROUP("Forms\\SDRDevices" REGULAR_EXPRESSION "src/forms/SDRDevices/${REG_EXT}")
SOURCE_GROUP("Forms\\Bookmark" REGULAR_EXPRESSION "src/forms/Bookmark/${REG_EXT}")
SOURCE_GROUP("Forms\\Dialog" REGULAR_EXPRESSION "src/forms/Dialog/${REG_EXT}")
SOURCE_GROUP("SDR" REGULAR_EXPRESSION "src/sdr/${REG_EXT}") SOURCE_GROUP("SDR" REGULAR_EXPRESSION "src/sdr/${REG_EXT}")
IF(USE_HAMLIB) IF(USE_HAMLIB)
SOURCE_GROUP("Rig" REGULAR_EXPRESSION "src/rig/${REG_EXT}") SOURCE_GROUP("Rig" REGULAR_EXPRESSION "src/rig/${REG_EXT}")
@ -495,6 +539,8 @@ SOURCE_GROUP("_ext-CubicVR2" REGULAR_EXPRESSION "external/cubicvr2/.*${REG_EXT}"
include_directories ( include_directories (
${PROJECT_SOURCE_DIR}/src/forms/SDRDevices ${PROJECT_SOURCE_DIR}/src/forms/SDRDevices
${PROJECT_SOURCE_DIR}/src/forms/DigitalConsole ${PROJECT_SOURCE_DIR}/src/forms/DigitalConsole
${PROJECT_SOURCE_DIR}/src/forms/Bookmark
${PROJECT_SOURCE_DIR}/src/forms/Dialog
${PROJECT_SOURCE_DIR}/src/sdr ${PROJECT_SOURCE_DIR}/src/sdr
${PROJECT_SOURCE_DIR}/src/demod ${PROJECT_SOURCE_DIR}/src/demod
${PROJECT_SOURCE_DIR}/src/modules ${PROJECT_SOURCE_DIR}/src/modules
@ -535,6 +581,9 @@ IF (NOT BUNDLE_APP)
IF(MSVC) IF(MSVC)
configure_files(${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM}/ ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.dll") configure_files(${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM}/ ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.dll")
ENDIF() ENDIF()
IF (CUBICSDR_HAS_HEADER_IMAGE)
configure_files(${CUBICSDR_HEADER_IMAGE_DIR} ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} ${CUBICSDR_HEADER_IMAGE_FILE})
ENDIF()
add_executable(CubicSDR ${cubicsdr_sources} ${cubicsdr_headers} ${RES_FILES}) add_executable(CubicSDR ${cubicsdr_sources} ${cubicsdr_headers} ${RES_FILES})
target_link_libraries(CubicSDR ${LIQUID_LIB} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${OTHER_LIBRARIES}) target_link_libraries(CubicSDR ${LIQUID_LIB} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${OTHER_LIBRARIES})
ENDIF (NOT BUNDLE_APP) ENDIF (NOT BUNDLE_APP)
@ -549,6 +598,8 @@ IF (MSVC)
set_target_properties(CubicSDR PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS") set_target_properties(CubicSDR PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
set_target_properties(CubicSDR PROPERTIES COMPILE_DEFINITIONS_MINSIZEREL "_WINDOWS") set_target_properties(CubicSDR PROPERTIES COMPILE_DEFINITIONS_MINSIZEREL "_WINDOWS")
set(CMAKE_CREATE_WIN32_EXE "/SUBSYSTEM:WINDOWS /ENTRY:\"mainCRTStartup\"") set(CMAKE_CREATE_WIN32_EXE "/SUBSYSTEM:WINDOWS /ENTRY:\"mainCRTStartup\"")
set_target_properties (CubicSDR PROPERTIES OUTPUT_NAME "${CUBICSDR_INSTALL_NAME}")
ENDIF(MSVC) ENDIF(MSVC)
IF (APPLE) IF (APPLE)
@ -613,7 +664,7 @@ IF (APPLE AND BUNDLE_APP)
MACOSX_BUNDLE_INFO_STRING "CubicSDR Open-Source Software-Defined Radio Application" MACOSX_BUNDLE_INFO_STRING "CubicSDR Open-Source Software-Defined Radio Application"
MACOSX_BUNDLE_BUNDLE_NAME "CubicSDR" MACOSX_BUNDLE_BUNDLE_NAME "CubicSDR"
MACOSX_BUNDLE_BUNDLE_VERSION "${CUBICSDR_VERSION}" MACOSX_BUNDLE_BUNDLE_VERSION "${CUBICSDR_VERSION}"
MACOSX_BUNDLE_LONG_VERSION_STRING "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}.${CUBICSDR_VERSION_REL}" MACOSX_BUNDLE_LONG_VERSION_STRING "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}${CUBICSDR_VERSION_SUFFIX}"
MACOSX_BUNDLE_SHORT_VERSION_STRING "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}" MACOSX_BUNDLE_SHORT_VERSION_STRING "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}"
MACOSX_BUNDLE_GUI_IDENTIFIER "com.cubicproductions.cubicsdr" MACOSX_BUNDLE_GUI_IDENTIFIER "com.cubicproductions.cubicsdr"
MACOSX_BUNDLE_ICON_FILE "CubicSDR.icns" MACOSX_BUNDLE_ICON_FILE "CubicSDR.icns"
@ -625,9 +676,10 @@ IF (APPLE AND BUNDLE_APP)
# SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) # SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
IF (BUNDLE_SOAPY_MODS) IF (BUNDLE_SOAPY_MODS)
message(STATUS "SOAPY_ROOT: ${SOAPY_SDR_ROOT}") message(STATUS "SOAPY_ROOT: ${SOAPY_SDR_ROOT}")
file(GLOB SOAPY_MODS ${SOAPY_SDR_ROOT}/lib/SoapySDR/modules/*.so) SET(SOAPY_SDR_MOD_PATH "${SOAPY_SDR_ROOT}/lib/SoapySDR/modules/${SOAPY_SDR_ABI_VERSION}")
file(GLOB SOAPY_MODS ${SOAPY_MOD_PATH}/*.so)
FOREACH(SOAPY_MOD_FILE ${SOAPY_MODS}) FOREACH(SOAPY_MOD_FILE ${SOAPY_MODS})
INSTALL( FILES "${SOAPY_MOD_FILE}" INSTALL( FILES "${SOAPY_MOD_FILE}"
@ -708,6 +760,7 @@ IF (APPLE AND BUNDLE_APP)
include(CPack) include(CPack)
ENDIF() ENDIF()
IF(APPLE AND NOT BUNDLE_APP) IF(APPLE AND NOT BUNDLE_APP)
IF (NOT CMAKE_INSTALL_PREFIX) IF (NOT CMAKE_INSTALL_PREFIX)
SET(CMAKE_INSTALL_PREFIX "/usr/") SET(CMAKE_INSTALL_PREFIX "/usr/")
@ -764,28 +817,35 @@ IF (WIN32 AND NOT BUILD_INSTALLER)
INSTALL(FILES INSTALL(FILES
${CUBICSDR_FONTS} ${CUBICSDR_FONTS}
DESTINATION share/cubicsdr/fonts) DESTINATION share/cubicsdr/fonts)
IF (CUBICSDR_HAS_HEADER_IMAGE)
INSTALL(FILES
${CUBICSDR_HEADER_IMAGE}
DESTINATION share/cubicsdr/)
ENDIF()
ENDIF() ENDIF()
IF (WIN32 AND BUILD_INSTALLER) IF (WIN32 AND BUILD_INSTALLER)
set(BUNDLE_SOAPY_MODS OFF CACHE BOOL "Bundle local SoapySDR modules") set(BUNDLE_SOAPY_MODS OFF CACHE BOOL "Bundle local SoapySDR modules")
set(CPACK_GENERATOR NSIS) set(CPACK_GENERATOR NSIS)
set(CPACK_PACKAGE_NAME "CubicSDR") set(CPACK_PACKAGE_NAME "${CUBICSDR_INSTALL_NAME}")
set(CPACK_NSIS_DISPLAY_NAME "${CUBICSDR_INSTALL_TITLE}")
set(CPACK_PACKAGE_VENDOR "cubicsdr.com") set(CPACK_PACKAGE_VENDOR "cubicsdr.com")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "CubicSDR ${CUBICSDR_VERSION} Installer") set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CUBICSDR_INSTALL_NAME}")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "CubicSDR")
SET(CPACK_NSIS_INSTALLED_ICON_NAME "CubicSDR.ico") SET(CPACK_NSIS_INSTALLED_ICON_NAME "CubicSDR.ico")
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE") SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/icon\\\\NSIS_Header.bmp") set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/icon\\\\NSIS_Header.bmp")
IF(EX_PLATFORM EQUAL 64) IF(EX_PLATFORM EQUAL 64)
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64") SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
SET(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}") SET(CPACK_NSIS_PACKAGE_NAME "${CUBICSDR_INSTALL_NAME}")
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}") SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CUBICSDR_INSTALL_NAME} ${CPACK_PACKAGE_VERSION}")
set(CMAKE_CL_64 TRUE) # This gets around a bug in the CPack installer name generation for MinGW 64-bit since 2.8 set(CMAKE_CL_64 TRUE) # This gets around a bug in the CPack installer name generation for MinGW 64-bit since 2.8
ELSE(EX_PLATFORM EQUAL 64) ELSE(EX_PLATFORM EQUAL 64)
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES") SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
SET(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} (x86)") SET(CPACK_NSIS_PACKAGE_NAME "${CUBICSDR_INSTALL_NAME} (x86)")
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION} (x86)") SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CUBICSDR_INSTALL_NAME} ${CPACK_PACKAGE_VERSION} (x86)")
set(CMAKE_CL_64 FALSE) set(CMAKE_CL_64 FALSE)
ENDIF(EX_PLATFORM EQUAL 64) ENDIF(EX_PLATFORM EQUAL 64)
@ -801,6 +861,12 @@ IF (WIN32 AND BUILD_INSTALLER)
${CUBICSDR_FONTS} ${CUBICSDR_FONTS}
DESTINATION fonts) DESTINATION fonts)
IF (CUBICSDR_HAS_HEADER_IMAGE)
INSTALL(FILES
${CUBICSDR_HEADER_IMAGE}
DESTINATION .)
ENDIF()
IF(USE_HAMLIB) IF(USE_HAMLIB)
FOREACH(HAMLIB_DLL ${HAMLIB_DLLS}) FOREACH(HAMLIB_DLL ${HAMLIB_DLLS})
message(STATUS "Copying Hamlib DLL: ${HAMLIB_DLL}") message(STATUS "Copying Hamlib DLL: ${HAMLIB_DLL}")
@ -822,7 +888,7 @@ IF (WIN32 AND BUILD_INSTALLER)
ENDIF() ENDIF()
file(GLOB SOAPY_BINS ${SOAPY_SDR_ROOT}/bin/*.dll) file(GLOB SOAPY_BINS ${SOAPY_SDR_ROOT}/bin/*.dll)
file(GLOB SOAPY_MODS ${SOAPY_SDR_ROOT}/lib/SoapySDR/modules/*.dll) file(GLOB SOAPY_MODS ${SOAPY_SDR_ROOT}/lib/SoapySDR/modules${SOAPY_SDR_ABI_VERSION}/*.dll)
message(STATUS "SOAPY_BINS: ${SOAPY_BINS}") message(STATUS "SOAPY_BINS: ${SOAPY_BINS}")
message(STATUS "SOAPY_MODS: ${SOAPY_MODS}") message(STATUS "SOAPY_MODS: ${SOAPY_MODS}")
install(FILES ${SOAPY_BINS} DESTINATION .) install(FILES ${SOAPY_BINS} DESTINATION .)
@ -830,9 +896,8 @@ IF (WIN32 AND BUILD_INSTALLER)
ENDIF(BUNDLE_SOAPY_MODS) ENDIF(BUNDLE_SOAPY_MODS)
IF(MSVC AND EX_PLATFORM EQUAL 32) IF(MSVC AND EX_PLATFORM EQUAL 32)
install(FILES file(GLOB MSVC32_DEPS ${PROJECT_SOURCE_DIR}/external/msvc/${EX_PLATFORM_NAME}/*.dll)
${PROJECT_SOURCE_DIR}/external/msvc/${EX_PLATFORM_NAME}/libgcc_s_dw2-1.dll install(FILES ${MSVC32_DEPS} DESTINATION .)
DESTINATION .)
ENDIF(MSVC AND EX_PLATFORM EQUAL 32) ENDIF(MSVC AND EX_PLATFORM EQUAL 32)
set(CPACK_PACKAGE_EXECUTABLES CubicSDR "CubicSDR") set(CPACK_PACKAGE_EXECUTABLES CubicSDR "CubicSDR")
@ -912,6 +977,13 @@ IF(UNIX AND NOT APPLE AND NOT BUILD_DEB)
${CUBICSDR_FONTS} ${CUBICSDR_FONTS}
DESTINATION share/cubicsdr/fonts) DESTINATION share/cubicsdr/fonts)
IF (CUBICSDR_HAS_HEADER_IMAGE)
INSTALL(FILES
${CUBICSDR_HEADER_IMAGE}
DESTINATION share/cubicsdr)
ENDIF()
INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/CubicSDR.desktop" INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/CubicSDR.desktop"
DESTINATION share/applications) DESTINATION share/applications)

11
LICENSE
View File

@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/> Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@ -290,8 +290,8 @@ to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found. the "copyright" line and a pointer to where the full notice is found.
CubicSDR <one line to give the program's name and a brief idea of what it does.>
Copyright (C) 2014 Charles J. Cliffe Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -329,7 +329,7 @@ necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker. `Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989 <signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice Ty Coon, President of Vice
This General Public License does not permit incorporating your program into This General Public License does not permit incorporating your program into
@ -337,4 +337,3 @@ proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. Public License instead of this License.

View File

@ -48,4 +48,4 @@ Target Platforms:
License: License:
------- -------
- GPL - GPL-2.0+

View File

@ -0,0 +1,14 @@
- Building libliquid.dll and libliquid.a:
-----------------------------------------
- Install the Msys2 distribution as described on their site (https://msys2.github.io/)
- Add mingw32 and mingw64 compiler to the Msys2 installation.
- Copy config.h, makefile.mingw32, makefile.mingw64 in the liquid-dsp root directory.
- Run a Msys2 Win32 shell (mingw32.exe) and execute 'make -f makefile.mingw32 -j8' to compile a libliquid.dll 32bit Windows Dll.
- Run a Msys2 Win64 shell (mingw64.exe) and execute 'make -f makefile.mingw64 -j8' to compile a libliquid.dll 64bit Windows Dll.
Note that the Win32 dll needs libgcc_s_dw2-1.dll and libwinpthread-1.dll (as a libgcc_s_dw2-1.dll dependency) as dependencies.
On the other hand, Win64 dll has no external dependencies.
This process generates a .dll, .a together with libliquid.def the listing exported functions, and libliquid.lib the import lib matching the dll.
In order to develop with Visual Studio, you need both the include/liquid.h at source level, and the libliquid.lib import library referenced in your project.

192
external/liquid-dsp/config.h vendored Normal file
View File

@ -0,0 +1,192 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
#ifndef __LIQUID_CONFIG_H__
#define __LIQUID_CONFIG_H__
/* Define to 1 if you have the <complex.h> header file. */
#define HAVE_COMPLEX_H 1
/* Define to 1 if you have the <fec.h> header file. */
/* #undef HAVE_FEC_H */
/* Define to 1 if you have the <fftw3.h> header file. */
/* #undef HAVE_FFTW3_H */
/* Define to 1 if you have the <float.h> header file. */
#define HAVE_FLOAT_H 1
/* Define to 1 if you have the <getopt.h> header file. */
#define HAVE_GETOPT_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `c' library (-lc). */
#define HAVE_LIBC 1
/* Define to 1 if you have the `fec' library (-lfec). */
/* #undef HAVE_LIBFEC */
/* Define to 1 if you have the `fftw3f' library (-lfftw3f). */
/* #undef HAVE_LIBFFTW3F */
/* Define to 1 if you have the `m' library (-lm). */
#define HAVE_LIBM 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <mmintrin.h> header file. */ //MMX
#define HAVE_MMINTRIN_H 1
/* Define to 1 if you have the <xmmintrin.h> header file. */ //SSE
#define HAVE_XMMINTRIN_H 1
/* Define to 1 if you have the <emmintrin.h> header file. */ //SSE2
#define HAVE_EMMINTRIN_H 1
/* Define to 1 if you have the <pmmintrin.h> header file. */ //SSE3
#define HAVE_PMMINTRIN_H 1
/* Define to 1 if you have the <smmintrin.h> header file. */ //SSE4.1
//#define HAVE_SMMINTRIN_H 1
/* Define to 1 if you have the <immintrin.h> header file. */ //AVX
//#define HAVE_IMMINTRIN_H 1
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
/* The size of `unsigned int', as computed by sizeof. */
#define SIZEOF_UNSIGNED_INT 4
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
and to 0 otherwise. */
#define HAVE_REALLOC 1
/* Support MMX instructions */
#define HAVE_MMX /**/
/* Support SSE (Streaming SIMD Extensions) instructions */
#define HAVE_SSE /**/
/* Support SSE2 (Streaming SIMD Extensions 2) instructions */
#define HAVE_SSE2 /**/
/* Support SSE3 (Streaming SIMD Extensions 3) instructions */
#define HAVE_SSE3 /**/
/* Support SSE4.1 (Streaming SIMD Extensions 4.1) instructions */
#define HAVE_SSE41 /**/
/* Support SSE4.2 (Streaming SIMD Extensions 4.2) instructions */
#define HAVE_SSE42 1
/* Support SSSE3 (Supplemental Streaming SIMD Extensions 3) instructions */
#define HAVE_SSSE3 /**/
/* Support AVX (Advanced Vector Extensions) instructions */
#define HAVE_AVX /**/
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <tmmintrin.h> header file. */
#define HAVE_TMMINTRIN_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Force internal FFT even if libfftw is available */
/* #undef LIQUID_FFTOVERRIDE */
/* Force overriding of SIMD (use portable C code) */
/* #undef LIQUID_SIMDOVERRIDE */
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "support@liquidsdr.org"
/* Define to the full name of this package. */
#define PACKAGE_NAME "liquid-dsp"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "liquid-dsp 1.3.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "liquid-dsp"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.3.0"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT32_T */
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT8_T */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to rpl_realloc if the replacement function should be used. */
/* #undef realloc */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to the type of an unsigned integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint32_t */
/* Define to the type of an unsigned integer type of width exactly 8 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint8_t */
#endif // __LIQUID_CONFIG_H__

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

1687
external/liquid-dsp/makefile.mingw32 vendored Normal file

File diff suppressed because it is too large Load Diff

1687
external/liquid-dsp/makefile.mingw64 vendored Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
external/msvc/x86/libwinpthread-1.dll vendored Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "AppConfig.h" #include "AppConfig.h"
#include "CubicSDR.h" #include "CubicSDR.h"
@ -28,7 +31,6 @@ long long DeviceConfig::getOffset() {
return offset.load(); return offset.load();
} }
void DeviceConfig::setSampleRate(long srate) { void DeviceConfig::setSampleRate(long srate) {
sampleRate.store(srate); sampleRate.store(srate);
} }
@ -82,7 +84,7 @@ void DeviceConfig::save(DataNode *node) {
std::lock_guard < std::mutex > lock(busy_lock); std::lock_guard < std::mutex > lock(busy_lock);
*node->newChild("id") = deviceId; *node->newChild("id") = deviceId;
*node->newChild("name") = deviceName; *node->newChild("name") = deviceName;
*node->newChild("ppm") = (int)ppm.load(); *node->newChild("ppm") = ppm.load();
*node->newChild("offset") = offset.load(); *node->newChild("offset") = offset.load();
*node->newChild("sample_rate") = sampleRate.load(); *node->newChild("sample_rate") = sampleRate.load();
*node->newChild("agc_mode") = agcMode.load()?1:0; *node->newChild("agc_mode") = agcMode.load()?1:0;
@ -289,7 +291,13 @@ AppConfig::AppConfig() : configName("") {
centerFreq.store(100000000); centerFreq.store(100000000);
waterfallLinesPerSec.store(DEFAULT_WATERFALL_LPS); waterfallLinesPerSec.store(DEFAULT_WATERFALL_LPS);
spectrumAvgSpeed.store(0.65f); spectrumAvgSpeed.store(0.65f);
dbOffset.store(0);
modemPropsCollapsed.store(false); modemPropsCollapsed.store(false);
mainSplit = -1;
visSplit = -1;
bookmarkSplit = 200;
bookmarksVisible.store(true);
#ifdef USE_HAMLIB #ifdef USE_HAMLIB
rigEnabled.store(false); rigEnabled.store(false);
rigModel.store(1); rigModel.store(1);
@ -425,6 +433,14 @@ float AppConfig::getSpectrumAvgSpeed() {
return spectrumAvgSpeed.load(); return spectrumAvgSpeed.load();
} }
void AppConfig::setDBOffset(int offset) {
this->dbOffset.store(offset);
}
int AppConfig::getDBOffset() {
return dbOffset.load();
}
void AppConfig::setManualDevices(std::vector<SDRManualDef> manuals) { void AppConfig::setManualDevices(std::vector<SDRManualDef> manuals) {
manualDevices = manuals; manualDevices = manuals;
} }
@ -433,6 +449,39 @@ std::vector<SDRManualDef> AppConfig::getManualDevices() {
return manualDevices; return manualDevices;
} }
void AppConfig::setMainSplit(float value) {
mainSplit.store(value);
}
float AppConfig::getMainSplit() {
return mainSplit.load();
}
void AppConfig::setVisSplit(float value) {
visSplit.store(value);
}
float AppConfig::getVisSplit() {
return visSplit.load();
}
void AppConfig::setBookmarkSplit(float value) {
bookmarkSplit.store(value);
}
float AppConfig::getBookmarkSplit() {
return bookmarkSplit.load();
}
void AppConfig::setBookmarksVisible(bool state) {
bookmarksVisible.store(state);
}
bool AppConfig::getBookmarksVisible() {
return bookmarksVisible.load();
}
void AppConfig::setConfigName(std::string configName) { void AppConfig::setConfigName(std::string configName) {
this->configName = configName; this->configName = configName;
} }
@ -478,6 +527,12 @@ bool AppConfig::save() {
*window_node->newChild("waterfall_lps") = waterfallLinesPerSec.load(); *window_node->newChild("waterfall_lps") = waterfallLinesPerSec.load();
*window_node->newChild("spectrum_avg") = spectrumAvgSpeed.load(); *window_node->newChild("spectrum_avg") = spectrumAvgSpeed.load();
*window_node->newChild("modemprops_collapsed") = modemPropsCollapsed.load();; *window_node->newChild("modemprops_collapsed") = modemPropsCollapsed.load();;
*window_node->newChild("db_offset") = dbOffset.load();
*window_node->newChild("main_split") = mainSplit.load();
*window_node->newChild("vis_split") = visSplit.load();
*window_node->newChild("bookmark_split") = bookmarkSplit.load();
*window_node->newChild("bookmark_visible") = bookmarksVisible.load();
} }
DataNode *devices_node = cfg.rootNode()->newChild("devices"); DataNode *devices_node = cfg.rootNode()->newChild("devices");
@ -556,12 +611,13 @@ bool AppConfig::load() {
} }
if (cfg.rootNode()->hasAnother("window")) { if (cfg.rootNode()->hasAnother("window")) {
int x,y,w,h; int x = 0 ,y = 0 ,w = 0 ,h = 0;
int max,tips,lpm,mpc; int max = 0 ,tips = 0 ,lpm = 0 ,mpc = 0;
DataNode *win_node = cfg.rootNode()->getNext("window"); DataNode *win_node = cfg.rootNode()->getNext("window");
if (win_node->hasAnother("w") && win_node->hasAnother("h") && win_node->hasAnother("x") && win_node->hasAnother("y")) { if (win_node->hasAnother("w") && win_node->hasAnother("h") && win_node->hasAnother("x") && win_node->hasAnother("y")) {
win_node->getNext("x")->element()->get(x); win_node->getNext("x")->element()->get(x);
win_node->getNext("y")->element()->get(y); win_node->getNext("y")->element()->get(y);
win_node->getNext("w")->element()->get(w); win_node->getNext("w")->element()->get(w);
@ -628,6 +684,37 @@ bool AppConfig::load() {
win_node->getNext("modemprops_collapsed")->element()->get(mpc); win_node->getNext("modemprops_collapsed")->element()->get(mpc);
modemPropsCollapsed.store(mpc?true:false); modemPropsCollapsed.store(mpc?true:false);
} }
if (win_node->hasAnother("db_offset")) {
DataNode *offset_node = win_node->getNext("db_offset");
int offsetValue = 0;
offset_node->element()->get(offsetValue);
setDBOffset(offsetValue);
}
if (win_node->hasAnother("main_split")) {
float gVal;
win_node->getNext("main_split")->element()->get(gVal);
mainSplit.store(gVal);
}
if (win_node->hasAnother("vis_split")) {
float gVal;
win_node->getNext("vis_split")->element()->get(gVal);
visSplit.store(gVal);
}
if (win_node->hasAnother("bookmark_split")) {
float gVal;
win_node->getNext("bookmark_split")->element()->get(gVal);
bookmarkSplit.store(gVal);
}
if (win_node->hasAnother("bookmark_visible")) {
int bVal;
win_node->getNext("bookmark_visible")->element()->get(bVal);
bookmarksVisible.store(bVal);
}
} }
if (cfg.rootNode()->hasAnother("devices")) { if (cfg.rootNode()->hasAnother("devices")) {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
@ -112,9 +115,25 @@ public:
void setSpectrumAvgSpeed(float avgSpeed); void setSpectrumAvgSpeed(float avgSpeed);
float getSpectrumAvgSpeed(); float getSpectrumAvgSpeed();
void setDBOffset(int offset);
int getDBOffset();
void setManualDevices(std::vector<SDRManualDef> manuals); void setManualDevices(std::vector<SDRManualDef> manuals);
std::vector<SDRManualDef> getManualDevices(); std::vector<SDRManualDef> getManualDevices();
void setMainSplit(float value);
float getMainSplit();
void setVisSplit(float value);
float getVisSplit();
void setBookmarkSplit(float value);
float getBookmarkSplit();
void setBookmarksVisible(bool state);
bool getBookmarksVisible();
#if USE_HAMLIB #if USE_HAMLIB
int getRigModel(); int getRigModel();
void setRigModel(int rigModel); void setRigModel(int rigModel);
@ -157,8 +176,10 @@ private:
std::atomic_llong snap; std::atomic_llong snap;
std::atomic_llong centerFreq; std::atomic_llong centerFreq;
std::atomic_int waterfallLinesPerSec; std::atomic_int waterfallLinesPerSec;
std::atomic<float> spectrumAvgSpeed; std::atomic<float> spectrumAvgSpeed, mainSplit, visSplit, bookmarkSplit;
std::atomic_int dbOffset;
std::vector<SDRManualDef> manualDevices; std::vector<SDRManualDef> manualDevices;
std::atomic_bool bookmarksVisible;
#if USE_HAMLIB #if USE_HAMLIB
std::atomic_int rigModel, rigRate; std::atomic_int rigModel, rigRate;
std::string rigPort; std::string rigPort;

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,14 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <wx/frame.h> #include <wx/frame.h>
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/splitter.h> #include <wx/splitter.h>
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/bitmap.h>
#include <wx/statbmp.h>
#include "PrimaryGLContext.h" #include "PrimaryGLContext.h"
@ -19,6 +24,7 @@
#include "ModemProperties.h" #include "ModemProperties.h"
//#include "UITestCanvas.h" //#include "UITestCanvas.h"
#include "FrequencyDialog.h" #include "FrequencyDialog.h"
#include "BookmarkView.h"
#include <map> #include <map>
@ -32,9 +38,11 @@
#define wxID_AGC_CONTROL 2009 #define wxID_AGC_CONTROL 2009
#define wxID_SDR_START_STOP 2010 #define wxID_SDR_START_STOP 2010
#define wxID_LOW_PERF 2011 #define wxID_LOW_PERF 2011
#define wxID_SET_DB_OFFSET 2012
#define wxID_MAIN_SPLITTER 2050 #define wxID_MAIN_SPLITTER 2050
#define wxID_VIS_SPLITTER 2051 #define wxID_VIS_SPLITTER 2051
#define wxID_BM_SPLITTER 2052
#define wxID_THEME_DEFAULT 2100 #define wxID_THEME_DEFAULT 2100
#define wxID_THEME_SHARP 2101 #define wxID_THEME_SHARP 2101
@ -44,7 +52,10 @@
#define wxID_THEME_HD 2105 #define wxID_THEME_HD 2105
#define wxID_THEME_RADAR 2106 #define wxID_THEME_RADAR 2106
#define wxID_DISPLAY_BOOKMARKS 2107
#define wxID_BANDWIDTH_BASE 2150 #define wxID_BANDWIDTH_BASE 2150
#define wxID_BANDWIDTH_MANUAL_DIALOG 2199
#define wxID_BANDWIDTH_MANUAL 2200 #define wxID_BANDWIDTH_MANUAL 2200
#define wxID_DISPLAY_BASE 2250 #define wxID_DISPLAY_BASE 2250
@ -73,6 +84,7 @@ class AppFrame: public wxFrame {
public: public:
AppFrame(); AppFrame();
~AppFrame(); ~AppFrame();
void OnThread(wxCommandEvent& event); void OnThread(wxCommandEvent& event);
void OnEventInput(wxThreadEvent& event); void OnEventInput(wxThreadEvent& event);
void initDeviceParams(SDRDeviceInfo *devInfo); void initDeviceParams(SDRDeviceInfo *devInfo);
@ -101,8 +113,19 @@ public:
void setViewState(long long center_freq, int bandwidth); void setViewState(long long center_freq, int bandwidth);
void setViewState(long long center_freq); void setViewState(long long center_freq);
long long getViewCenterFreq();
int getViewBandwidth();
bool isUserDemodBusy(); bool isUserDemodBusy();
BookmarkView *getBookmarkView();
void disableSave(bool state);
//call this in case the main UI is not
//the origin of device changes / sample rate by operator,
//and must be notified back to update its UI elements
//(ex: SDR Devices dialog changing the configuration)
void notifyDeviceChanged();
#ifdef _WIN32 #ifdef _WIN32
bool canFocus(); bool canFocus();
#endif #endif
@ -115,6 +138,10 @@ private:
void OnDoubleClickSash(wxSplitterEvent& event); void OnDoubleClickSash(wxSplitterEvent& event);
void OnUnSplit(wxSplitterEvent& event); void OnUnSplit(wxSplitterEvent& event);
//manage Display menu actions, return true if the event has been
//treated.
bool actionOnMenuDisplay(wxCommandEvent& event);
ScopeCanvas *scopeCanvas; ScopeCanvas *scopeCanvas;
SpectrumCanvas *spectrumCanvas; SpectrumCanvas *spectrumCanvas;
WaterfallCanvas *waterfallCanvas; WaterfallCanvas *waterfallCanvas;
@ -133,8 +160,9 @@ private:
ModeSelectorCanvas *demodMuteButton, *peakHoldButton, *soloModeButton, *deltaLockButton; ModeSelectorCanvas *demodMuteButton, *peakHoldButton, *soloModeButton, *deltaLockButton;
GainCanvas *gainCanvas; GainCanvas *gainCanvas;
wxSizerItem *gainSizerItem, *gainSpacerItem; wxSizerItem *gainSizerItem, *gainSpacerItem;
wxSplitterWindow *mainVisSplitter, *mainSplitter; wxSplitterWindow *mainVisSplitter, *mainSplitter, *bookmarkSplitter;
wxBoxSizer *demodTray; wxBoxSizer *demodTray;
BookmarkView *bookmarkView;
DemodulatorInstance *activeDemodulator; DemodulatorInstance *activeDemodulator;
@ -147,16 +175,17 @@ private:
std::map<int, wxMenuItem *> directSamplingMenuItems; std::map<int, wxMenuItem *> directSamplingMenuItems;
wxMenuBar *menuBar; wxMenuBar *menuBar;
wxMenu *sampleRateMenu; wxMenu *sampleRateMenu = nullptr;
wxMenu *displayMenu; wxMenu *displayMenu = nullptr;
wxMenuItem *agcMenuItem; wxMenuItem *agcMenuItem = nullptr;
wxMenuItem *iqSwapMenuItem; wxMenuItem *iqSwapMenuItem = nullptr;
wxMenuItem *lowPerfMenuItem; wxMenuItem *lowPerfMenuItem = nullptr;
wxMenu *settingsMenu; wxMenu *settingsMenu = nullptr;
SoapySDR::ArgInfoList settingArgs; SoapySDR::ArgInfoList settingArgs;
int settingsIdMax; int settingsIdMax;
std::vector<long> sampleRates; std::vector<long> sampleRates;
long manualSampleRate = -1;
std::string currentSessionFile; std::string currentSessionFile;
@ -172,6 +201,9 @@ private:
bool lowPerfMode; bool lowPerfMode;
wxMenuItem *hideBookmarksItem;
bool saveDisabled;
#ifdef USE_HAMLIB #ifdef USE_HAMLIB
void enableRig(); void enableRig();
void disableRig(); void disableRig();
@ -184,6 +216,7 @@ private:
wxMenuItem *rigCenterLockMenuItem; wxMenuItem *rigCenterLockMenuItem;
wxMenuItem *rigFollowModemMenuItem; wxMenuItem *rigFollowModemMenuItem;
wxMenuItem *sdrIFMenuItem; wxMenuItem *sdrIFMenuItem;
std::map<int, wxMenuItem *> rigSerialMenuItems; std::map<int, wxMenuItem *> rigSerialMenuItems;
std::map<int, wxMenuItem *> rigModelMenuItems; std::map<int, wxMenuItem *> rigModelMenuItems;
int rigModel; int rigModel;

524
src/BookmarkMgr.cpp Normal file
View File

@ -0,0 +1,524 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "BookmarkMgr.h"
#include "CubicSDR.h"
#include "DataTree.h"
#define BOOKMARK_RECENTS_MAX 25
BookmarkMgr::BookmarkMgr() {
rangesSorted = false;
}
void BookmarkMgr::saveToFile(std::string bookmarkFn, bool backup) {
DataTree s("cubicsdr_bookmarks");
DataNode *header = s.rootNode()->newChild("header");
header->newChild("version")->element()->set(wxString(CUBICSDR_VERSION).ToStdWstring());
DataNode *branches = s.rootNode()->newChild("branches");
*branches->newChild("active") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("active")?1:0;
*branches->newChild("range") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("range")?1:0;
*branches->newChild("bookmark") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("bookmark")?1:0;
*branches->newChild("recent") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("recent")?1:0;
DataNode *view_ranges = s.rootNode()->newChild("ranges");
for (auto re_i : ranges) {
DataNode *range = view_ranges->newChild("range");
*range->newChild("label") = re_i->label;
*range->newChild("freq") = re_i->freq;
*range->newChild("start") = re_i->startFreq;
*range->newChild("end") = re_i->endFreq;
}
DataNode *modems = s.rootNode()->newChild("modems");
for (auto &bmd_i : bmData) {
DataNode *group = modems->newChild("group");
*group->newChild("@name") = bmd_i.first;
*group->newChild("@expanded") = (getExpandState(bmd_i.first)?std::string("true"):std::string("false"));
for (auto &bm_i : bmd_i.second ) {
group->newChildCloneFrom("modem", bm_i->node);
}
}
DataNode *recent_modems = s.rootNode()->newChild("recent_modems");
for (auto demod : wxGetApp().getDemodMgr().getDemodulators()) {
wxGetApp().getDemodMgr().saveInstance(recent_modems->newChild("modem"),demod);
}
for (auto &r_i : this->recents) {
recent_modems->newChildCloneFrom("modem", r_i->node);
}
wxFileName saveFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn);
wxFileName saveFileBackup(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".backup");
if (saveFile.IsDirWritable()) {
// Hopefully leave at least a readable backup in case of failure..
if (backup && saveFile.FileExists() && (!saveFileBackup.FileExists() || saveFileBackup.IsFileWritable())) {
wxCopyFile(saveFile.GetFullPath(wxPATH_NATIVE).ToStdString(), saveFileBackup.GetFullPath(wxPATH_NATIVE).ToStdString());
}
s.SaveToFileXML(saveFile.GetFullPath(wxPATH_NATIVE).ToStdString());
}
}
bool BookmarkMgr::loadFromFile(std::string bookmarkFn, bool backup) {
wxFileName loadFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn);
wxFileName failFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".failedload");
wxFileName lastLoaded(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".lastloaded");
wxFileName backupFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".backup");
DataTree s;
bool loadStatusOk = true;
// Clear any active data
bmData.erase(bmData.begin(),bmData.end());
recents.erase(recents.begin(),recents.end());
ranges.erase(ranges.begin(),ranges.end());
bmDataSorted.erase(bmDataSorted.begin(),bmDataSorted.end());
// File exists but is not readable
if (loadFile.FileExists() && !loadFile.IsFileReadable()) {
return false;
}
// New instance of bookmark savefiles
if (backup && !loadFile.FileExists() && !lastLoaded.FileExists() && !backupFile.FileExists()) {
wxGetApp().getAppFrame()->getBookmarkView()->loadDefaultRanges();
return true;
}
// Attempt to load file
if (!s.LoadFromFileXML(loadFile.GetFullPath(wxPATH_NATIVE).ToStdString())) {
return false;
}
if (s.rootNode()->hasAnother("branches")) {
DataNode *branches = s.rootNode()->getNext("branches");
int bActive = 1, bRange = 0, bBookmark = 1, bRecent = 1;
if (branches->hasAnother("active")) branches->getNext("active")->element()->get(bActive);
if (branches->hasAnother("range")) branches->getNext("range")->element()->get(bRange);
if (branches->hasAnother("bookmark")) branches->getNext("bookmark")->element()->get(bBookmark);
if (branches->hasAnother("recent")) branches->getNext("recent")->element()->get(bRecent);
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("active", bActive?true:false);
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("range", bRange?true:false);
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("bookmark", bBookmark?true:false);
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("recent", bRecent?true:false);
}
if (s.rootNode()->hasAnother("ranges")) {
DataNode *view_ranges = s.rootNode()->getNext("ranges");
while (view_ranges->hasAnother("range")) {
DataNode *range = view_ranges->getNext("range");
BookmarkRangeEntry *re = new BookmarkRangeEntry;
if (range->hasAnother("label")) range->getNext("label")->element()->get(re->label);
if (range->hasAnother("freq")) range->getNext("freq")->element()->get(re->freq);
if (range->hasAnother("start")) range->getNext("start")->element()->get(re->startFreq);
if (range->hasAnother("end")) range->getNext("end")->element()->get(re->endFreq);
addRange(re);
}
}
if (s.rootNode()->hasAnother("modems")) {
DataNode *modems = s.rootNode()->getNext("modems");
while (modems->hasAnother("group")) {
DataNode *group = modems->getNext("group");
std::string expandState = "true";
std::string groupName = "Unnamed";
if (group->hasAnother("@name")) {
groupName = group->getNext("@name")->element()->toString();
}
if (group->hasAnother("@expanded")) {
expandState = group->getNext("@expanded")->element()->toString();
}
setExpandState(groupName, (expandState == "true"));
while (group->hasAnother("modem")) {
DataNode *modem = group->getNext("modem");
BookmarkEntry *be = nodeToBookmark("modem", modem);
if (be) {
addBookmark(groupName.c_str(), be);
} else {
std::cout << "error loading bookmarked modem.." << std::endl;
loadStatusOk = false;
}
}
}
}
if (s.rootNode()->hasAnother("recent_modems")) {
DataNode *recent_modems = s.rootNode()->getNext("recent_modems");
while (recent_modems->hasAnother("modem")) {
DataNode *modem = recent_modems->getNext("modem");
BookmarkEntry *be = nodeToBookmark("modem", modem);
if (be) {
addRecent(be);
} else {
std::cout << "error loading recent modem.." << std::endl;
loadStatusOk = false;
}
}
}
if (backup) {
if (loadStatusOk) { // Loaded OK; keep a copy
if (loadFile.IsDirWritable()) {
if (loadFile.FileExists() && (!lastLoaded.FileExists() || lastLoaded.IsFileWritable())) {
wxCopyFile(loadFile.GetFullPath(wxPATH_NATIVE).ToStdString(), lastLoaded.GetFullPath(wxPATH_NATIVE).ToStdString());
}
}
} else if (!loadStatusOk) {
if (loadFile.IsDirWritable()) { // Load failed; keep a copy of the failed bookmark file for analysis?
if (loadFile.FileExists() && (!failFile.FileExists() || failFile.IsFileWritable())) {
wxCopyFile(loadFile.GetFullPath(wxPATH_NATIVE).ToStdString(), failFile.GetFullPath(wxPATH_NATIVE).ToStdString());
}
}
}
}
return loadStatusOk;
}
bool BookmarkMgr::hasLastLoad(std::string bookmarkFn) {
wxFileName lastLoaded(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".lastloaded");
return lastLoaded.FileExists() && lastLoaded.IsFileReadable();
}
bool BookmarkMgr::hasBackup(std::string bookmarkFn) {
wxFileName backupFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".backup");
return backupFile.FileExists() && backupFile.IsFileReadable();
}
void BookmarkMgr::addBookmark(std::string group, DemodulatorInstance *demod) {
std::lock_guard < std::mutex > lock(busy_lock);
BookmarkEntry *be = demodToBookmarkEntry(demod);
wxGetApp().getDemodMgr().saveInstance(be->node, demod);
bmData[group].push_back(be);
bmDataSorted[group] = false;
}
void BookmarkMgr::addBookmark(std::string group, BookmarkEntry *be) {
std::lock_guard < std::mutex > lock(busy_lock);
bmData[group].push_back(be);
bmDataSorted[group] = false;
}
void BookmarkMgr::removeBookmark(std::string group, BookmarkEntry *be) {
std::lock_guard < std::mutex > lockData(busy_lock);
std::lock_guard < std::mutex > lockEnt(be->busy_lock);
if (bmData.find(group) == bmData.end()) {
return;
}
BookmarkList::iterator i = std::find(bmData[group].begin(), bmData[group].end(), be);
if (i != bmData[group].end()) {
delete *i;
bmData[group].erase(i);
}
}
void BookmarkMgr::removeBookmark(BookmarkEntry *be) {
std::lock_guard < std::mutex > lockData(busy_lock);
std::lock_guard < std::mutex > lockEnt(be->busy_lock);
for (auto &bmd_i : bmData) {
BookmarkList::iterator i = std::find(bmd_i.second.begin(), bmd_i.second.end(), be);
if (i != bmd_i.second.end()) {
bmd_i.second.erase(i);
}
}
}
void BookmarkMgr::moveBookmark(BookmarkEntry *be, std::string group) {
std::lock_guard < std::mutex > lockData(busy_lock);
std::lock_guard < std::mutex > lockEnt(be->busy_lock);
for (auto &bmd_i : bmData) {
BookmarkList::iterator i = std::find(bmd_i.second.begin(), bmd_i.second.end(), be);
if (i != bmd_i.second.end()) {
if (bmd_i.first == group) {
return;
}
bmData[group].push_back(*i);
bmd_i.second.erase(i);
bmDataSorted[group] = false;
bmDataSorted[bmd_i.first] = false;
return;
}
}
}
void BookmarkMgr::addGroup(std::string group) {
std::lock_guard < std::mutex > lock(busy_lock);
if (bmData.find(group) == bmData.end()) {
BookmarkList dummy = bmData[group];
}
}
void BookmarkMgr::removeGroup(std::string group) {
std::lock_guard < std::mutex > lock(busy_lock);
BookmarkMap::iterator i = bmData.find(group);
if (i != bmData.end()) {
for (auto ii : bmData[group]) {
delete ii;
}
bmData.erase(group);
}
}
void BookmarkMgr::renameGroup(std::string group, std::string ngroup) {
if (group == ngroup) {
return;
}
std::lock_guard < std::mutex > lock(busy_lock);
BookmarkMap::iterator i = bmData.find(group);
BookmarkMap::iterator it = bmData.find(ngroup);
if (i != bmData.end() && it != bmData.end()) {
for (auto ii : bmData[group]) {
bmData[ngroup].push_back(ii);
}
bmData.erase(group);
} else if (i != bmData.end()) {
bmData[ngroup] = bmData[group];
bmData.erase(group);
}
}
BookmarkList BookmarkMgr::getBookmarks(std::string group) {
std::lock_guard < std::mutex > lock(busy_lock);
if (bmData.find(group) == bmData.end()) {
BookmarkList results;
return results;
}
if (!bmDataSorted[group]) {
std::sort(bmData[group].begin(), bmData[group].end(), BookmarkEntryCompare());
bmDataSorted[group] = true;
}
return bmData[group];
}
void BookmarkMgr::getGroups(BookmarkNames &arr) {
for (BookmarkMap::iterator i = bmData.begin(); i!= bmData.end(); ++i) {
arr.push_back(i->first);
}
}
void BookmarkMgr::getGroups(wxArrayString &arr) {
for (BookmarkMap::iterator i = bmData.begin(); i!= bmData.end(); ++i) {
arr.push_back(i->first);
}
}
void BookmarkMgr::setExpandState(std::string groupName, bool state) {
expandState[groupName] = state;
}
bool BookmarkMgr::getExpandState(std::string groupName) {
if (expandState.find(groupName) == expandState.end()) {
return true;
}
return expandState[groupName];
}
void BookmarkMgr::updateActiveList() {
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
if (bmv) {
bmv->updateActiveList();
}
}
void BookmarkMgr::updateBookmarks() {
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
if (bmv) {
bmv->updateBookmarks();
}
}
void BookmarkMgr::updateBookmarks(std::string group) {
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
if (bmv) {
bmv->updateBookmarks(group);
}
}
void BookmarkMgr::addRecent(DemodulatorInstance *demod) {
std::lock_guard < std::mutex > lock(busy_lock);
recents.push_back(demodToBookmarkEntry(demod));
trimRecents();
}
void BookmarkMgr::addRecent(BookmarkEntry *be) {
std::lock_guard < std::mutex > lock(busy_lock);
recents.push_back(be);
trimRecents();
}
void BookmarkMgr::removeRecent(BookmarkEntry *be) {
std::lock_guard < std::mutex > lock(busy_lock);
BookmarkList::iterator bm_i = std::find(recents.begin(),recents.end(), be);
if (bm_i != recents.end()) {
recents.erase(bm_i);
}
}
BookmarkList BookmarkMgr::getRecents() {
return BookmarkList(recents.rbegin(), recents.rend());
}
void BookmarkMgr::clearRecents() {
std::lock_guard < std::mutex > lock(busy_lock);
recents.erase(recents.begin(),recents.end());
}
void BookmarkMgr::trimRecents() {
if (recents.size() > BOOKMARK_RECENTS_MAX) {
delete *(recents.begin());
recents.erase(recents.begin(), recents.begin()+1);
}
}
void BookmarkMgr::addRange(BookmarkRangeEntry *re) {
std::lock_guard < std::mutex > lock(busy_lock);
ranges.push_back(re);
rangesSorted = false;
}
void BookmarkMgr::removeRange(BookmarkRangeEntry *re) {
std::lock_guard < std::mutex > lock(busy_lock);
BookmarkRangeList::iterator re_i = std::find(ranges.begin(), ranges.end(), re);
if (re_i != ranges.end()) {
ranges.erase(re_i);
}
}
BookmarkRangeList BookmarkMgr::getRanges() {
std::lock_guard < std::mutex > lock(busy_lock);
if (!rangesSorted) {
std::sort(ranges.begin(), ranges.end(), BookmarkRangeEntryCompare());
rangesSorted = true;
}
return ranges;
}
void BookmarkMgr::clearRanges() {
std::lock_guard < std::mutex > lock(busy_lock);
ranges.erase(ranges.begin(),ranges.end());
}
BookmarkEntry *BookmarkMgr::demodToBookmarkEntry(DemodulatorInstance *demod) {
BookmarkEntry *be = new BookmarkEntry;
be->bandwidth = demod->getBandwidth();
be->type = demod->getDemodulatorType();
be->label = demod->getDemodulatorUserLabel();
be->frequency = demod->getFrequency();
be->node = new DataNode;
wxGetApp().getDemodMgr().saveInstance(be->node, demod);
return be;
}
BookmarkEntry *BookmarkMgr::nodeToBookmark(const char *name_in, DataNode *node) {
if (!node->hasAnother("frequency") || !node->hasAnother("type") || !node->hasAnother("bandwidth")) {
return nullptr;
}
BookmarkEntry *be = new BookmarkEntry();
node->getNext("frequency")->element()->get(be->frequency);
node->getNext("type")->element()->get(be->type);
node->getNext("bandwidth")->element()->get(be->bandwidth);
if (node->hasAnother("user_label")) {
node->getNext("user_label")->element()->get(be->label);
}
node->rewindAll();
be->node = new DataNode("node",*node);
return be;
}
std::wstring BookmarkMgr::getBookmarkEntryDisplayName(BookmarkEntry *bmEnt) {
std::wstring dispName = bmEnt->label;
if (dispName == "") {
std::string freqStr = frequencyToStr(bmEnt->frequency) + " " + bmEnt->type;
dispName = wstring(freqStr.begin(),freqStr.end());
}
return dispName;
}
std::wstring BookmarkMgr::getActiveDisplayName(DemodulatorInstance *demod) {
std::wstring activeName = demod->getDemodulatorUserLabel();
if (activeName == "") {
std::string wstr = frequencyToStr(demod->getFrequency()) + " " + demod->getDemodulatorType();
activeName = std::wstring(wstr.begin(),wstr.end());
}
return activeName;
}

132
src/BookmarkMgr.h Normal file
View File

@ -0,0 +1,132 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once
#include <wx/arrstr.h>
#include <vector>
#include <set>
#include "DemodulatorInstance.h"
class DataNode;
class BookmarkEntry {
public:
std::mutex busy_lock;
std::string type;
std::wstring label;
std::wstring userLabel;
long long frequency;
int bandwidth;
DataNode *node;
};
class BookmarkRangeEntry {
public:
BookmarkRangeEntry() : label(L""), freq(0), startFreq(0), endFreq(0) {
}
BookmarkRangeEntry(std::wstring label, long long freq, long long startFreq, long long endFreq) : label(label), freq(freq), startFreq(startFreq), endFreq(endFreq) {
}
std::mutex busy_lock;
std::wstring label;
long long freq;
long long startFreq;
long long endFreq;
};
struct BookmarkEntryCompare : public std::binary_function<BookmarkEntry *,BookmarkEntry *,bool>
{
bool operator()(const BookmarkEntry *a, BookmarkEntry *b) const
{
return a->frequency < b->frequency;
}
};
struct BookmarkRangeEntryCompare : public std::binary_function<BookmarkRangeEntry *,BookmarkRangeEntry *,bool>
{
bool operator()(const BookmarkRangeEntry *a, BookmarkRangeEntry *b) const
{
return a->freq < b->freq;
}
};
typedef std::vector<BookmarkEntry *> BookmarkList;
typedef std::vector<BookmarkRangeEntry *> BookmarkRangeList;
typedef std::map<std::string, BookmarkList > BookmarkMap;
typedef std::map<std::string, bool > BookmarkMapSorted;
typedef std::vector<std::string> BookmarkNames;
typedef std::map<std::string, bool> BookmarkExpandState;
class BookmarkMgr {
public:
BookmarkMgr();
void saveToFile(std::string bookmarkFn, bool backup = true);
bool loadFromFile(std::string bookmarkFn, bool backup = true);
bool hasLastLoad(std::string bookmarkFn);
bool hasBackup(std::string bookmarkFn);
void addBookmark(std::string group, DemodulatorInstance *demod);
void addBookmark(std::string group, BookmarkEntry *be);
void removeBookmark(std::string group, BookmarkEntry *be);
void removeBookmark(BookmarkEntry *be);
void moveBookmark(BookmarkEntry *be, std::string group);
void addGroup(std::string group);
void removeGroup(std::string group);
void renameGroup(std::string group, std::string ngroup);
BookmarkList getBookmarks(std::string group);
void getGroups(BookmarkNames &arr);
void getGroups(wxArrayString &arr);
void setExpandState(std::string groupName, bool state);
bool getExpandState(std::string groupName);
void updateActiveList();
void updateBookmarks();
void updateBookmarks(std::string group);
void addRecent(DemodulatorInstance *demod);
void addRecent(BookmarkEntry *be);
void removeRecent(BookmarkEntry *be);
BookmarkList getRecents();
void clearRecents();
void addRange(BookmarkRangeEntry *re);
void removeRange(BookmarkRangeEntry *re);
BookmarkRangeList getRanges();
void clearRanges();
static std::wstring getBookmarkEntryDisplayName(BookmarkEntry *bmEnt);
static std::wstring getActiveDisplayName(DemodulatorInstance *demod);
protected:
void trimRecents();
BookmarkEntry *demodToBookmarkEntry(DemodulatorInstance *demod);
BookmarkEntry *nodeToBookmark(const char *name_in, DataNode *node);
BookmarkMap bmData;
BookmarkMapSorted bmDataSorted;
BookmarkList recents;
BookmarkRangeList ranges;
bool rangesSorted;
std::mutex busy_lock;
BookmarkExpandState expandState;
};

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#define OPENGL #define OPENGL
#include "CubicSDRDefs.h" #include "CubicSDRDefs.h"
@ -27,6 +30,9 @@ IMPLEMENT_APP(CubicSDR)
#include <fstream> #include <fstream>
#include <clocale> #include <clocale>
#include "ActionDialog.h"
//#ifdef ENABLE_DIGITAL_LAB //#ifdef ENABLE_DIGITAL_LAB
//// console output buffer for windows //// console output buffer for windows
//#ifdef _WINDOWS //#ifdef _WINDOWS
@ -133,8 +139,65 @@ long long strToFrequency(std::string freqStr) {
} }
CubicSDR::CubicSDR() : frequency(0), offset(0), ppm(0), snap(1), sampleRate(DEFAULT_SAMPLE_RATE),agcMode(false)
{ class ActionDialogBookmarkCatastophe : public ActionDialog {
public:
ActionDialogBookmarkCatastophe() : ActionDialog(wxGetApp().getAppFrame(), wxID_ANY, wxT("Bookmark Last-Loaded Backup Failure :( :( :(")) {
m_questionText->SetLabelText(wxT("All attempts to recover bookmarks have failed. \nWould you like to exit without touching any more save files?\nClick OK to exit without saving; or Cancel to continue anyways."));
}
void doClickOK() {
wxGetApp().getAppFrame()->disableSave(true);
wxGetApp().getAppFrame()->Close(false);
}
};
class ActionDialogBookmarkBackupLoadFailed : public ActionDialog {
public:
ActionDialogBookmarkBackupLoadFailed() : ActionDialog(wxGetApp().getAppFrame(), wxID_ANY, wxT("Bookmark Backup Load Failure :( :(")) {
m_questionText->SetLabelText(wxT("Sorry; unable to load your bookmarks backup file. \nWould you like to attempt to load the last succssfully loaded bookmarks file?"));
}
void doClickOK() {
if (wxGetApp().getBookmarkMgr().hasLastLoad("bookmarks.xml")) {
if (wxGetApp().getBookmarkMgr().loadFromFile("bookmarks.xml.lastloaded",false)) {
wxGetApp().getBookmarkMgr().updateBookmarks();
wxGetApp().getBookmarkMgr().updateActiveList();
} else {
ActionDialog::showDialog(new ActionDialogBookmarkCatastophe());
}
}
}
};
class ActionDialogBookmarkLoadFailed : public ActionDialog {
public:
ActionDialogBookmarkLoadFailed() : ActionDialog(wxGetApp().getAppFrame(), wxID_ANY, wxT("Bookmark Load Failure :(")) {
m_questionText->SetLabelText(wxT("Sorry; unable to load your bookmarks file. \nWould you like to attempt to load the backup file?"));
}
void doClickOK() {
bool loadOk = false;
if (wxGetApp().getBookmarkMgr().hasBackup("bookmarks.xml")) {
loadOk = wxGetApp().getBookmarkMgr().loadFromFile("bookmarks.xml.backup",false);
}
if (loadOk) {
wxGetApp().getBookmarkMgr().updateBookmarks();
wxGetApp().getBookmarkMgr().updateActiveList();
} else if (wxGetApp().getBookmarkMgr().hasLastLoad("bookmarks.xml")) {
ActionDialog::showDialog(new ActionDialogBookmarkBackupLoadFailed());
} else {
ActionDialog::showDialog(new ActionDialogBookmarkCatastophe());
}
}
};
CubicSDR::CubicSDR() : frequency(0), offset(0), ppm(0), snap(1), sampleRate(DEFAULT_SAMPLE_RATE), agcMode(false)
{
sampleRateInitialized.store(false); sampleRateInitialized.store(false);
agcMode.store(true); agcMode.store(true);
soloMode.store(false); soloMode.store(false);
@ -207,9 +270,7 @@ bool CubicSDR::OnInit() {
Modem::addModemFactory(ModemASK::factory, "ASK", 200000); Modem::addModemFactory(ModemASK::factory, "ASK", 200000);
Modem::addModemFactory(ModemBPSK::factory, "BPSK", 200000); Modem::addModemFactory(ModemBPSK::factory, "BPSK", 200000);
Modem::addModemFactory(ModemDPSK::factory, "DPSK", 200000); Modem::addModemFactory(ModemDPSK::factory, "DPSK", 200000);
#if ENABLE_LIQUID_EXPERIMENTAL
Modem::addModemFactory(ModemFSK::factory, "FSK", 19200); Modem::addModemFactory(ModemFSK::factory, "FSK", 19200);
#endif
Modem::addModemFactory(ModemGMSK::factory, "GMSK", 19200); Modem::addModemFactory(ModemGMSK::factory, "GMSK", 19200);
Modem::addModemFactory(ModemOOK::factory, "OOK", 200000); Modem::addModemFactory(ModemOOK::factory, "OOK", 200000);
Modem::addModemFactory(ModemPSK::factory, "PSK", 200000); Modem::addModemFactory(ModemPSK::factory, "PSK", 200000);
@ -228,26 +289,16 @@ bool CubicSDR::OnInit() {
// Visual Data // Visual Data
spectrumVisualThread = new SpectrumVisualDataThread(); spectrumVisualThread = new SpectrumVisualDataThread();
demodVisualThread = new SpectrumVisualDataThread();
pipeIQVisualData = new DemodulatorThreadInputQueue(); pipeIQVisualData = new DemodulatorThreadInputQueue();
pipeIQVisualData->set_max_num_items(1); pipeIQVisualData->set_max_num_items(1);
pipeDemodIQVisualData = new DemodulatorThreadInputQueue();
pipeDemodIQVisualData->set_max_num_items(1);
pipeWaterfallIQVisualData = new DemodulatorThreadInputQueue(); pipeWaterfallIQVisualData = new DemodulatorThreadInputQueue();
pipeWaterfallIQVisualData->set_max_num_items(128); pipeWaterfallIQVisualData->set_max_num_items(128);
getDemodSpectrumProcessor()->setInput(pipeDemodIQVisualData);
getSpectrumProcessor()->setInput(pipeIQVisualData); getSpectrumProcessor()->setInput(pipeIQVisualData);
getSpectrumProcessor()->setHideDC(true); getSpectrumProcessor()->setHideDC(true);
pipeAudioVisualData = new DemodulatorThreadOutputQueue();
pipeAudioVisualData->set_max_num_items(1);
scopeProcessor.setInput(pipeAudioVisualData);
// I/Q Data // I/Q Data
pipeSDRIQData = new SDRThreadIQDataQueue(); pipeSDRIQData = new SDRThreadIQDataQueue();
pipeSDRIQData->set_max_num_items(100); pipeSDRIQData->set_max_num_items(100);
@ -260,11 +311,42 @@ bool CubicSDR::OnInit() {
sdrPostThread->setOutputQueue("IQVisualDataOutput", pipeIQVisualData); sdrPostThread->setOutputQueue("IQVisualDataOutput", pipeIQVisualData);
sdrPostThread->setOutputQueue("IQDataOutput", pipeWaterfallIQVisualData); sdrPostThread->setOutputQueue("IQDataOutput", pipeWaterfallIQVisualData);
sdrPostThread->setOutputQueue("IQActiveDemodVisualDataOutput", pipeDemodIQVisualData);
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread); #if CUBICSDR_ENABLE_VIEW_SCOPE
pipeAudioVisualData = new DemodulatorThreadOutputQueue();
pipeAudioVisualData->set_max_num_items(1);
scopeProcessor.setInput(pipeAudioVisualData);
#else
pipeAudioVisualData = nullptr;
#endif
#if CUBICSDR_ENABLE_VIEW_DEMOD
demodVisualThread = new SpectrumVisualDataThread();
pipeDemodIQVisualData = new DemodulatorThreadInputQueue();
pipeDemodIQVisualData->set_max_num_items(1);
if (getDemodSpectrumProcessor()) {
getDemodSpectrumProcessor()->setInput(pipeDemodIQVisualData);
}
sdrPostThread->setOutputQueue("IQActiveDemodVisualDataOutput", pipeDemodIQVisualData);
#else
demodVisualThread = nullptr;
pipeDemodIQVisualData = nullptr;
t_DemodVisual = nullptr;
#endif
// Now that input/output queue plumbing is completely done, we can
//safely starts all the threads:
t_SpectrumVisual = new std::thread(&SpectrumVisualDataThread::threadMain, spectrumVisualThread); t_SpectrumVisual = new std::thread(&SpectrumVisualDataThread::threadMain, spectrumVisualThread);
if (demodVisualThread != nullptr) {
t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread); t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread);
}
//Start SDRPostThread last.
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
sdrEnum = new SDREnumerator(); sdrEnum = new SDREnumerator();
@ -283,6 +365,19 @@ bool CubicSDR::OnInit() {
// pthread_setschedparam(pthread_self(), main_policy, &main_param); // pthread_setschedparam(pthread_self(), main_policy, &main_param);
//#endif //#endif
if (!wxGetApp().getBookmarkMgr().loadFromFile("bookmarks.xml")) {
if (wxGetApp().getBookmarkMgr().hasBackup("bookmarks.xml")) {
ActionDialog::showDialog(new ActionDialogBookmarkLoadFailed());
} else if (wxGetApp().getBookmarkMgr().hasLastLoad("bookmarks.xml")) {
ActionDialog::showDialog(new ActionDialogBookmarkBackupLoadFailed());
} else {
ActionDialog::showDialog(new ActionDialogBookmarkCatastophe());
}
} else {
getBookmarkMgr().updateActiveList();
getBookmarkMgr().updateBookmarks();
}
return true; return true;
} }
@ -313,16 +408,20 @@ int CubicSDR::OnExit() {
std::cout << "Terminating Visual Processor threads.." << std::endl; std::cout << "Terminating Visual Processor threads.." << std::endl;
spectrumVisualThread->terminate(); spectrumVisualThread->terminate();
if (demodVisualThread) {
demodVisualThread->terminate(); demodVisualThread->terminate();
}
//Wait nicely //Wait nicely
sdrPostThread->isTerminated(1000); sdrPostThread->isTerminated(1000);
spectrumVisualThread->isTerminated(1000); spectrumVisualThread->isTerminated(1000);
if (demodVisualThread) {
demodVisualThread->isTerminated(1000); demodVisualThread->isTerminated(1000);
}
//Then join the thread themselves //Then join the thread themselves
t_PostSDR->join(); t_PostSDR->join();
t_DemodVisual->join(); if (t_DemodVisual) t_DemodVisual->join();
t_SpectrumVisual->join(); t_SpectrumVisual->join();
//Now only we can delete //Now only we can delete
@ -491,7 +590,9 @@ void CubicSDR::setFrequency(long long freq) {
getSpectrumProcessor()->setPeakHold(getSpectrumProcessor()->getPeakHold()); getSpectrumProcessor()->setPeakHold(getSpectrumProcessor()->getPeakHold());
//make the peak hold act on the current dmod also, like a zoomed-in version. //make the peak hold act on the current dmod also, like a zoomed-in version.
if (getDemodSpectrumProcessor()) {
getDemodSpectrumProcessor()->setPeakHold(getSpectrumProcessor()->getPeakHold()); getDemodSpectrumProcessor()->setPeakHold(getSpectrumProcessor()->getPeakHold());
}
} }
long long CubicSDR::getOffset() { long long CubicSDR::getOffset() {
@ -534,15 +635,15 @@ void CubicSDR::setSampleRate(long long rate_in) {
setFrequency(frequency); setFrequency(frequency);
if (rate_in <= CHANNELIZER_RATE_MAX / 8) { if (rate_in <= CHANNELIZER_RATE_MAX / 8) {
appframe->setMainWaterfallFFTSize(512); appframe->setMainWaterfallFFTSize(DEFAULT_FFT_SIZE / 4);
appframe->getWaterfallDataThread()->getProcessor()->setHideDC(false); appframe->getWaterfallDataThread()->getProcessor()->setHideDC(false);
spectrumVisualThread->getProcessor()->setHideDC(false); spectrumVisualThread->getProcessor()->setHideDC(false);
} else if (rate_in <= CHANNELIZER_RATE_MAX) { } else if (rate_in <= CHANNELIZER_RATE_MAX) {
appframe->setMainWaterfallFFTSize(1024); appframe->setMainWaterfallFFTSize(DEFAULT_FFT_SIZE / 2);
appframe->getWaterfallDataThread()->getProcessor()->setHideDC(false); appframe->getWaterfallDataThread()->getProcessor()->setHideDC(false);
spectrumVisualThread->getProcessor()->setHideDC(false); spectrumVisualThread->getProcessor()->setHideDC(false);
} else if (rate_in > CHANNELIZER_RATE_MAX) { } else if (rate_in > CHANNELIZER_RATE_MAX) {
appframe->setMainWaterfallFFTSize(2048); appframe->setMainWaterfallFFTSize(DEFAULT_FFT_SIZE);
appframe->getWaterfallDataThread()->getProcessor()->setHideDC(true); appframe->getWaterfallDataThread()->getProcessor()->setHideDC(true);
spectrumVisualThread->getProcessor()->setHideDC(true); spectrumVisualThread->getProcessor()->setHideDC(true);
} }
@ -652,7 +753,11 @@ SpectrumVisualProcessor *CubicSDR::getSpectrumProcessor() {
} }
SpectrumVisualProcessor *CubicSDR::getDemodSpectrumProcessor() { SpectrumVisualProcessor *CubicSDR::getDemodSpectrumProcessor() {
if (demodVisualThread) {
return demodVisualThread->getProcessor(); return demodVisualThread->getProcessor();
} else {
return nullptr;
}
} }
DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() { DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() {
@ -671,6 +776,10 @@ DemodulatorMgr &CubicSDR::getDemodMgr() {
return demodMgr; return demodMgr;
} }
BookmarkMgr &CubicSDR::getBookmarkMgr() {
return bookmarkMgr;
}
SDRPostThread *CubicSDR::getSDRPostThread() { SDRPostThread *CubicSDR::getSDRPostThread() {
return sdrPostThread; return sdrPostThread;
} }
@ -704,6 +813,7 @@ void CubicSDR::removeDemodulator(DemodulatorInstance *demod) {
} }
demod->setActive(false); demod->setActive(false);
sdrPostThread->removeDemodulator(demod); sdrPostThread->removeDemodulator(demod);
wxGetApp().getAppFrame()->notifyUpdateModemProperties();
} }
std::vector<SDRDeviceInfo*>* CubicSDR::getDevices() { std::vector<SDRDeviceInfo*>* CubicSDR::getDevices() {
@ -749,6 +859,7 @@ void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetM
switch (targetMode) { switch (targetMode) {
case FrequencyDialog::FDIALOG_TARGET_DEFAULT: case FrequencyDialog::FDIALOG_TARGET_DEFAULT:
case FrequencyDialog::FDIALOG_TARGET_FREQ:
title = demodMgr.getActiveDemodulator()?demodTitle:freqTitle; title = demodMgr.getActiveDemodulator()?demodTitle:freqTitle;
break; break;
case FrequencyDialog::FDIALOG_TARGET_BANDWIDTH: case FrequencyDialog::FDIALOG_TARGET_BANDWIDTH:
@ -806,6 +917,10 @@ bool CubicSDR::areDevicesReady() {
return devicesReady.load(); return devicesReady.load();
} }
void CubicSDR::notifyMainUIOfDeviceChange() {
appframe->notifyDeviceChanged();
}
bool CubicSDR::areDevicesEnumerating() { bool CubicSDR::areDevicesEnumerating() {
return !sdrEnum->isTerminated(); return !sdrEnum->isTerminated();
} }

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
//WX_GL_CORE_PROFILE 1 //WX_GL_CORE_PROFILE 1
@ -10,12 +13,8 @@
#include "PrimaryGLContext.h" #include "PrimaryGLContext.h"
#include "ThreadQueue.h" #include "ThreadQueue.h"
#ifdef USE_RTL_SDR #include "SoapySDRThread.h"
#include "SDRThread.h" #include "SDREnumerator.h"
#else
#include "SoapySDRThread.h"
#include "SDREnumerator.h"
#endif
#include "SDRPostThread.h" #include "SDRPostThread.h"
#include "AudioThread.h" #include "AudioThread.h"
#include "DemodulatorMgr.h" #include "DemodulatorMgr.h"
@ -23,6 +22,7 @@
#include "AppFrame.h" #include "AppFrame.h"
#include "FrequencyDialog.h" #include "FrequencyDialog.h"
#include "DemodLabelDialog.h" #include "DemodLabelDialog.h"
#include "BookmarkMgr.h"
#include "ScopeVisualProcessor.h" #include "ScopeVisualProcessor.h"
#include "SpectrumVisualProcessor.h" #include "SpectrumVisualProcessor.h"
@ -44,9 +44,7 @@
#include "ModemASK.h" #include "ModemASK.h"
#include "ModemBPSK.h" #include "ModemBPSK.h"
#include "ModemDPSK.h" #include "ModemDPSK.h"
#if ENABLE_LIQUID_EXPERIMENTAL
#include "ModemFSK.h" #include "ModemFSK.h"
#endif
#include "ModemGMSK.h" #include "ModemGMSK.h"
#include "ModemOOK.h" #include "ModemOOK.h"
#include "ModemPSK.h" #include "ModemPSK.h"
@ -94,6 +92,9 @@ public:
void setOffset(long long ofs); void setOffset(long long ofs);
long long getOffset(); long long getOffset();
void setDBOffset(int ofs);
int getDBOffset();
void setSampleRate(long long rate_in); void setSampleRate(long long rate_in);
long long getSampleRate(); long long getSampleRate();
@ -111,6 +112,7 @@ public:
DemodulatorThreadInputQueue* getWaterfallVisualQueue(); DemodulatorThreadInputQueue* getWaterfallVisualQueue();
DemodulatorThreadInputQueue* getActiveDemodVisualQueue(); DemodulatorThreadInputQueue* getActiveDemodVisualQueue();
DemodulatorMgr &getDemodMgr(); DemodulatorMgr &getDemodMgr();
BookmarkMgr &getBookmarkMgr();
SDRPostThread *getSDRPostThread(); SDRPostThread *getSDRPostThread();
SDRThread *getSDRThread(); SDRThread *getSDRThread();
@ -137,6 +139,8 @@ public:
bool areModulesMissing(); bool areModulesMissing();
std::string getNotification(); std::string getNotification();
void notifyMainUIOfDeviceChange();
void addRemote(std::string remoteAddr); void addRemote(std::string remoteAddr);
void removeRemote(std::string remoteAddr); void removeRemote(std::string remoteAddr);
@ -179,6 +183,7 @@ private:
std::vector<SDRDeviceInfo *> *devs = nullptr; std::vector<SDRDeviceInfo *> *devs = nullptr;
DemodulatorMgr demodMgr; DemodulatorMgr demodMgr;
BookmarkMgr bookmarkMgr;
std::atomic_llong frequency; std::atomic_llong frequency;
std::atomic_llong offset; std::atomic_llong offset;

View File

@ -1,6 +1,9 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#define CUBICSDR_TITLE "CubicSDR v" CUBICSDR_VERSION " by Charles J. Cliffe (@ccliffe) :: www.cubicsdr.com" #define CUBICSDR_TITLE "" CUBICSDR_BUILD_TITLE
#ifndef __BYTE_ORDER #ifndef __BYTE_ORDER
#ifdef _WIN32 #ifdef _WIN32
@ -28,13 +31,31 @@ const char filePathSeparator =
#define BUF_SIZE (16384*6) #define BUF_SIZE (16384*6)
#define DEFAULT_SAMPLE_RATE 2500000 #define DEFAULT_SAMPLE_RATE 2500000
//
#define DEFAULT_FFT_SIZE 2048 #define DEFAULT_FFT_SIZE 2048
#define DEFAULT_DMOD_FFT_SIZE (DEFAULT_FFT_SIZE / 2)
#define DEFAULT_SCOPE_FFT_SIZE (DEFAULT_FFT_SIZE / 2)
//Both must be a power of 2 to prevent terrible OpenGL performance.
//TODO: Make the waterfall resolutions an option.
#define DEFAULT_MAIN_WATERFALL_LINES_NB 512 // 1024
#define DEFAULT_DEMOD_WATERFALL_LINES_NB 256
#define DEFAULT_DEMOD_TYPE "FM" #define DEFAULT_DEMOD_TYPE "FM"
#define DEFAULT_DEMOD_BW 200000 #define DEFAULT_DEMOD_BW 200000
#define DEFAULT_WATERFALL_LPS 30 #define DEFAULT_WATERFALL_LPS 30
//Dmod waterfall lines per second is adjusted
//so that the whole demod waterfall show DEMOD_WATERFALL_DURATION_IN_SECONDS
//seconds.
#define DEMOD_WATERFALL_DURATION_IN_SECONDS 4.0
#define CHANNELIZER_RATE_MAX 500000 #define CHANNELIZER_RATE_MAX 500000
#define MANUAL_SAMPLE_RATE_MIN 2000000 // 2MHz
#define MANUAL_SAMPLE_RATE_MAX 200000000 // 200MHz (We are 2017+ after all)
//Represents the amount of time to process in the FFT distributor.
#define FFT_DISTRIBUTOR_BUFFER_IN_SECONDS 0.250

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "DemodLabelDialog.h" #include "DemodLabelDialog.h"
#include "wx/clipbrd.h" #include "wx/clipbrd.h"
@ -57,7 +60,7 @@ void DemodLabelDialog::OnChar(wxKeyEvent& event) {
else { else {
activeDemod->setDemodulatorUserLabel(L""); activeDemod->setDemodulatorUserLabel(L"");
} }
wxGetApp().getBookmarkMgr().updateActiveList();
Close(); Close();
break; break;
case WXK_ESCAPE: case WXK_ESCAPE:

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "wx/dialog.h" #include "wx/dialog.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "FrequencyDialog.h" #include "FrequencyDialog.h"
#include "wx/clipbrd.h" #include "wx/clipbrd.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "wx/dialog.h" #include "wx/dialog.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "IOThread.h" #include "IOThread.h"
#include <typeinfo> #include <typeinfo>
@ -77,20 +80,24 @@ void IOThread::onBindInput(std::string /* name */, ThreadQueueBase* /* threadQue
}; };
void IOThread::setInputQueue(std::string qname, ThreadQueueBase *threadQueue) { void IOThread::setInputQueue(std::string qname, ThreadQueueBase *threadQueue) {
std::lock_guard < std::mutex > lock(m_queue_bindings_mutex);
input_queues[qname] = threadQueue; input_queues[qname] = threadQueue;
this->onBindInput(qname, threadQueue); this->onBindInput(qname, threadQueue);
}; };
ThreadQueueBase *IOThread::getInputQueue(std::string qname) { ThreadQueueBase *IOThread::getInputQueue(std::string qname) {
std::lock_guard < std::mutex > lock(m_queue_bindings_mutex);
return input_queues[qname]; return input_queues[qname];
}; };
void IOThread::setOutputQueue(std::string qname, ThreadQueueBase *threadQueue) { void IOThread::setOutputQueue(std::string qname, ThreadQueueBase *threadQueue) {
std::lock_guard < std::mutex > lock(m_queue_bindings_mutex);
output_queues[qname] = threadQueue; output_queues[qname] = threadQueue;
this->onBindOutput(qname, threadQueue); this->onBindOutput(qname, threadQueue);
}; };
ThreadQueueBase *IOThread::getOutputQueue(std::string qname) { ThreadQueueBase *IOThread::getOutputQueue(std::string qname) {
std::lock_guard < std::mutex > lock(m_queue_bindings_mutex);
return output_queues[qname]; return output_queues[qname];
}; };

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <mutex> #include <mutex>
@ -219,6 +222,9 @@ protected:
std::map<std::string, ThreadQueueBase *, map_string_less> input_queues; std::map<std::string, ThreadQueueBase *, map_string_less> input_queues;
std::map<std::string, ThreadQueueBase *, map_string_less> output_queues; std::map<std::string, ThreadQueueBase *, map_string_less> output_queues;
//this protects against concurrent changes in input/output bindings: get/set/Input/OutPutQueue
mutable std::mutex m_queue_bindings_mutex;
//true when a termination is ordered //true when a termination is ordered
std::atomic_bool stopping; std::atomic_bool stopping;
Timer gTimer; Timer gTimer;
@ -227,4 +233,5 @@ private:
//true when the thread has really ended, i.e run() from threadMain() has returned. //true when the thread has really ended, i.e run() from threadMain() has returned.
std::atomic_bool terminated; std::atomic_bool terminated;
}; };

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemProperties.h" #include "ModemProperties.h"
#include "CubicSDR.h" #include "CubicSDR.h"
@ -30,26 +33,10 @@ void ModemProperties::OnShow(wxShowEvent & /* event */) {
} }
void ModemProperties::updateTheme() { void ModemProperties::updateTheme() {
wxColour bgColor( wxColour bgColor(ThemeMgr::mgr.currentTheme->generalBackground);
(unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.r * 255.0), wxColour textColor(ThemeMgr::mgr.currentTheme->text);
(unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.g * 255.0), wxColour btn(ThemeMgr::mgr.currentTheme->button);
(unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.b * 255.0)); wxColour btnHl(ThemeMgr::mgr.currentTheme->buttonHighlight);
wxColour textColor(
(unsigned char) (ThemeMgr::mgr.currentTheme->text.r * 255.0),
(unsigned char) (ThemeMgr::mgr.currentTheme->text.g * 255.0),
(unsigned char) (ThemeMgr::mgr.currentTheme->text.b * 255.0));
wxColour btn(
(unsigned char) (ThemeMgr::mgr.currentTheme->button.r * 255.0),
(unsigned char) (ThemeMgr::mgr.currentTheme->button.g * 255.0),
(unsigned char) (ThemeMgr::mgr.currentTheme->button.b * 255.0));
wxColour btnHl(
(unsigned char) (ThemeMgr::mgr.currentTheme->buttonHighlight.r * 255.0),
(unsigned char) (ThemeMgr::mgr.currentTheme->buttonHighlight.g * 255.0),
(unsigned char) (ThemeMgr::mgr.currentTheme->buttonHighlight.b * 255.0));
m_propertyGrid->SetEmptySpaceColour(bgColor); m_propertyGrid->SetEmptySpaceColour(bgColor);
m_propertyGrid->SetCellBackgroundColour(bgColor); m_propertyGrid->SetCellBackgroundColour(bgColor);
@ -122,10 +109,8 @@ void ModemProperties::initProperties(ModemArgInfoList newArgs, DemodulatorInstan
m_propertyGrid->Clear(); m_propertyGrid->Clear();
if (!demodInstance) { if (!demodInstance) {
Hide(); m_propertyGrid->Append(new wxPropertyCategory("Modem Settings"));
return; return;
} else {
Show();
} }
m_propertyGrid->Append(new wxPropertyCategory(demodInstance->getDemodulatorType() + " Settings")); m_propertyGrid->Append(new wxPropertyCategory(demodInstance->getDemodulatorType() + " Settings"));

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <wx/panel.h> #include <wx/panel.h>

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "AudioThread.h" #include "AudioThread.h"
#include "CubicSDRDefs.h" #include "CubicSDRDefs.h"
#include <vector> #include <vector>
@ -257,7 +260,7 @@ void AudioThread::enumerateDevices(std::vector<RtAudio::DeviceInfo> &devs) {
std::cout << "\t\t32-bit float normalized between plus/minus 1.0." << std::endl; std::cout << "\t\t32-bit float normalized between plus/minus 1.0." << std::endl;
} }
if (nFormats & RTAUDIO_FLOAT64) { if (nFormats & RTAUDIO_FLOAT64) {
std::cout << "\t\t32-bit float normalized between plus/minus 1.0." << std::endl; std::cout << "\t\t64-bit float normalized between plus/minus 1.0." << std::endl;
} }
std::vector<unsigned int>::iterator srate; std::vector<unsigned int>::iterator srate;

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <queue> #include <queue>

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "ThreadQueue.h" #include "ThreadQueue.h"
@ -56,6 +59,7 @@ class ModemKit;
class DemodulatorThreadPostIQData: public ReferenceCounter { class DemodulatorThreadPostIQData: public ReferenceCounter {
public: public:
std::vector<liquid_float_complex> data; std::vector<liquid_float_complex> data;
long long sampleRate; long long sampleRate;
std::string modemName; std::string modemName;
std::string modemType; std::string modemType;

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "DemodulatorInstance.h" #include "DemodulatorInstance.h"
#include "CubicSDR.h" #include "CubicSDR.h"
@ -80,6 +83,8 @@ DemodulatorInstance::~DemodulatorInstance() {
delete pipeIQDemodData; delete pipeIQDemodData;
delete threadQueueControl; delete threadQueueControl;
delete pipeAudioData; delete pipeAudioData;
wxGetApp().getBookmarkMgr().updateActiveList();
} }
void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) { void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) {
@ -118,6 +123,7 @@ void DemodulatorInstance::run() {
active = true; active = true;
wxGetApp().getBookmarkMgr().updateActiveList();
} }
void DemodulatorInstance::updateLabel(long long freq) { void DemodulatorInstance::updateLabel(long long freq) {
@ -125,6 +131,7 @@ void DemodulatorInstance::updateLabel(long long freq) {
newLabel.precision(3); newLabel.precision(3);
newLabel << std::fixed << ((long double) freq / 1000000.0); newLabel << std::fixed << ((long double) freq / 1000000.0);
setLabel(newLabel.str()); setLabel(newLabel.str());
wxGetApp().getBookmarkMgr().updateActiveList();
} }
void DemodulatorInstance::terminate() { void DemodulatorInstance::terminate() {
@ -227,6 +234,8 @@ void DemodulatorInstance::setActive(bool state) {
tracking = false; tracking = false;
} }
active = state; active = state;
wxGetApp().getBookmarkMgr().updateActiveList();
} }
void DemodulatorInstance::squelchAuto() { void DemodulatorInstance::squelchAuto() {
@ -331,7 +340,9 @@ void DemodulatorInstance::setDemodulatorType(std::string demod_type_in) {
outp->setTitle(getDemodulatorType() + ": " + frequencyToStr(getFrequency())); outp->setTitle(getDemodulatorType() + ": " + frequencyToStr(getFrequency()));
} }
#endif #endif
} }
wxGetApp().getBookmarkMgr().updateActiveList();
} }
std::string DemodulatorInstance::getDemodulatorType() { std::string DemodulatorInstance::getDemodulatorType() {
@ -391,6 +402,10 @@ void DemodulatorInstance::setFrequency(long long freq) {
wxGetApp().getRigThread()->setFrequency(freq,true); wxGetApp().getRigThread()->setFrequency(freq,true);
} }
#endif #endif
if (this->isActive()) {
wxGetApp().getBookmarkMgr().updateActiveList();
}
} }
long long DemodulatorInstance::getFrequency() { long long DemodulatorInstance::getFrequency() {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <vector> #include <vector>

View File

@ -1,15 +1,22 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include <DemodulatorMgr.h> #include <DemodulatorMgr.h>
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include "CubicSDR.h"
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include "DemodulatorMgr.h"
#include "CubicSDR.h"
#if USE_HAMLIB #if USE_HAMLIB
#include "RigThread.h" #include "RigThread.h"
#endif #endif
#include "DataTree.h"
bool demodFreqCompare (DemodulatorInstance *i, DemodulatorInstance *j) { return (i->getFrequency()<j->getFrequency()); } bool demodFreqCompare (DemodulatorInstance *i, DemodulatorInstance *j) { return (i->getFrequency()<j->getFrequency()); }
bool inactiveCompare (DemodulatorInstance *i, DemodulatorInstance *j) { return (i->isActive()<j->isActive()); } bool inactiveCompare (DemodulatorInstance *i, DemodulatorInstance *j) { return (i->isActive()<j->isActive()); }
@ -131,6 +138,8 @@ DemodulatorInstance *DemodulatorMgr::getFirstDemodulator() {
void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) { void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) {
std::lock_guard < std::recursive_mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
wxGetApp().getBookmarkMgr().addRecent(demod);
std::vector<DemodulatorInstance *>::iterator i; std::vector<DemodulatorInstance *>::iterator i;
i = std::find(demods.begin(), demods.end(), demod); i = std::find(demods.begin(), demods.end(), demod);
@ -215,6 +224,7 @@ void DemodulatorMgr::setActiveDemodulator(DemodulatorInstance *demod, bool tempo
wxGetApp().getRigThread()->setFrequency(lastActiveDemodulator.load()->getFrequency(),true); wxGetApp().getRigThread()->setFrequency(lastActiveDemodulator.load()->getFrequency(),true);
} }
#endif #endif
wxGetApp().getBookmarkMgr().updateActiveList();
} else { } else {
std::lock_guard < std::recursive_mutex > lock(demods_busy); std::lock_guard < std::recursive_mutex > lock(demods_busy);
garbageCollect(); garbageCollect();
@ -368,3 +378,138 @@ ModemSettings DemodulatorMgr::getLastModemSettings(std::string modemType) {
void DemodulatorMgr::setLastModemSettings(std::string modemType, ModemSettings settings) { void DemodulatorMgr::setLastModemSettings(std::string modemType, ModemSettings settings) {
lastModemSettings[modemType] = settings; lastModemSettings[modemType] = settings;
} }
void DemodulatorMgr::setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs) {
outputDevices = devs;
}
void DemodulatorMgr::saveInstance(DataNode *node, DemodulatorInstance *inst) {
*node->newChild("bandwidth") = inst->getBandwidth();
*node->newChild("frequency") = inst->getFrequency();
*node->newChild("type") = inst->getDemodulatorType();
node->newChild("user_label")->element()->set(inst->getDemodulatorUserLabel());
*node->newChild("squelch_level") = inst->getSquelchLevel();
*node->newChild("squelch_enabled") = inst->isSquelchEnabled() ? 1 : 0;
*node->newChild("output_device") = outputDevices[inst->getOutputDevice()].name;
*node->newChild("gain") = inst->getGain();
*node->newChild("muted") = inst->isMuted() ? 1 : 0;
if (inst->isDeltaLock()) {
*node->newChild("delta_lock") = inst->isDeltaLock() ? 1 : 0;
*node->newChild("delta_ofs") = inst->getDeltaLockOfs();
}
if (inst == getLastActiveDemodulator()) {
*node->newChild("active") = 1;
}
ModemSettings saveSettings = inst->readModemSettings();
if (saveSettings.size()) {
DataNode *settingsNode = node->newChild("settings");
for (ModemSettings::const_iterator msi = saveSettings.begin(); msi != saveSettings.end(); msi++) {
*settingsNode->newChild(msi->first.c_str()) = msi->second;
}
}
}
DemodulatorInstance *DemodulatorMgr::loadInstance(DataNode *node) {
DemodulatorInstance *newDemod = nullptr;
node->rewindAll();
long bandwidth = *node->getNext("bandwidth");
long long freq = *node->getNext("frequency");
float squelch_level = node->hasAnother("squelch_level") ? (float) *node->getNext("squelch_level") : 0;
int squelch_enabled = node->hasAnother("squelch_enabled") ? (int) *node->getNext("squelch_enabled") : 0;
int muted = node->hasAnother("muted") ? (int) *node->getNext("muted") : 0;
int delta_locked = node->hasAnother("delta_lock") ? (int) *node->getNext("delta_lock") : 0;
int delta_ofs = node->hasAnother("delta_ofs") ? (int) *node->getNext("delta_ofs") : 0;
std::string output_device = node->hasAnother("output_device") ? string(*(node->getNext("output_device"))) : "";
float gain = node->hasAnother("gain") ? (float) *node->getNext("gain") : 1.0;
std::string type = "FM";
DataNode *demodTypeNode = node->hasAnother("type")?node->getNext("type"):nullptr;
if (demodTypeNode && demodTypeNode->element()->getDataType() == DATA_INT) {
int legacyType = *demodTypeNode;
int legacyStereo = node->hasAnother("stereo") ? (int) *node->getNext("stereo") : 0;
switch (legacyType) { // legacy demod ID
case 1: type = legacyStereo?"FMS":"FM"; break;
case 2: type = "AM"; break;
case 3: type = "LSB"; break;
case 4: type = "USB"; break;
case 5: type = "DSB"; break;
case 6: type = "ASK"; break;
case 7: type = "APSK"; break;
case 8: type = "BPSK"; break;
case 9: type = "DPSK"; break;
case 10: type = "PSK"; break;
case 11: type = "OOK"; break;
case 12: type = "ST"; break;
case 13: type = "SQAM"; break;
case 14: type = "QAM"; break;
case 15: type = "QPSK"; break;
case 16: type = "I/Q"; break;
default: type = "FM"; break;
}
} else if (demodTypeNode && demodTypeNode->element()->getDataType() == DATA_STRING) {
demodTypeNode->element()->get(type);
}
//read the user label associated with the demodulator
std::wstring user_label = L"";
DataNode *demodUserLabel = node->hasAnother("user_label") ? node->getNext("user_label") : nullptr;
if (demodUserLabel) {
demodUserLabel->element()->get(user_label);
}
ModemSettings mSettings;
if (node->hasAnother("settings")) {
DataNode *modemSettings = node->getNext("settings");
for (int msi = 0, numSettings = modemSettings->numChildren(); msi < numSettings; msi++) {
DataNode *settingNode = modemSettings->child(msi);
std::string keyName = settingNode->getName();
std::string strSettingValue = settingNode->element()->toString();
if (keyName != "" && strSettingValue != "") {
mSettings[keyName] = strSettingValue;
}
}
}
newDemod = wxGetApp().getDemodMgr().newThread();
newDemod->setDemodulatorType(type);
newDemod->setDemodulatorUserLabel(user_label);
newDemod->writeModemSettings(mSettings);
newDemod->setBandwidth(bandwidth);
newDemod->setFrequency(freq);
newDemod->setGain(gain);
newDemod->updateLabel(freq);
newDemod->setMuted(muted?true:false);
if (delta_locked) {
newDemod->setDeltaLock(true);
newDemod->setDeltaLockOfs(delta_ofs);
}
if (squelch_enabled) {
newDemod->setSquelchEnabled(true);
newDemod->setSquelchLevel(squelch_level);
}
bool found_device = false;
std::map<int, RtAudio::DeviceInfo>::iterator i;
for (i = outputDevices.begin(); i != outputDevices.end(); i++) {
if (i->second.name == output_device) {
newDemod->setOutputDevice(i->first);
found_device = true;
}
}
return newDemod;
}

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <vector> #include <vector>
@ -6,6 +9,8 @@
#include "DemodulatorInstance.h" #include "DemodulatorInstance.h"
class DataNode;
class DemodulatorMgr { class DemodulatorMgr {
public: public:
DemodulatorMgr(); DemodulatorMgr();
@ -54,6 +59,10 @@ public:
void updateLastState(); void updateLastState();
void setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs);
void saveInstance(DataNode *node, DemodulatorInstance *inst);
DemodulatorInstance *loadInstance(DataNode *node);
private: private:
void garbageCollect(); void garbageCollect();
@ -79,4 +88,5 @@ private:
std::recursive_mutex demods_busy; std::recursive_mutex demods_busy;
std::map<std::string, ModemSettings> lastModemSettings; std::map<std::string, ModemSettings> lastModemSettings;
std::map<int,RtAudio::DeviceInfo> outputDevices;
}; };

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "CubicSDRDefs.h" #include "CubicSDRDefs.h"
#include <vector> #include <vector>

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <queue> #include <queue>

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "CubicSDRDefs.h" #include "CubicSDRDefs.h"
#include "DemodulatorThread.h" #include "DemodulatorThread.h"
#include "DemodulatorInstance.h" #include "DemodulatorInstance.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <queue> #include <queue>

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "DemodulatorWorkerThread.h" #include "DemodulatorWorkerThread.h"
#include "CubicSDRDefs.h" #include "CubicSDRDefs.h"
#include "CubicSDR.h" #include "CubicSDR.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <queue> #include <queue>

View File

@ -0,0 +1,136 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Aug 23 2015)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "BookmarkPanel.h"
///////////////////////////////////////////////////////////////////////////
BookmarkPanel::BookmarkPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
{
wxBoxSizer* bSizer1;
bSizer1 = new wxBoxSizer( wxVERTICAL );
m_searchText = new wxTextCtrl( this, wxID_ANY, wxT("Search.."), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
bSizer1->Add( m_searchText, 0, wxALL|wxEXPAND, 5 );
m_clearSearchButton = new wxButton( this, wxID_ANY, wxT("Clear Search"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer1->Add( m_clearSearchButton, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
m_treeView = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE|wxTR_EDIT_LABELS|wxTR_HAS_VARIABLE_ROW_HEIGHT|wxTR_HIDE_ROOT|wxTR_SINGLE );
bSizer1->Add( m_treeView, 1, wxEXPAND, 5 );
m_propPanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxFlexGridSizer* fgPropSizer;
fgPropSizer = new wxFlexGridSizer( 0, 2, 0, 0 );
fgPropSizer->AddGrowableCol( 1 );
fgPropSizer->SetFlexibleDirection( wxBOTH );
fgPropSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_labelLabel = new wxStaticText( m_propPanel, wxID_ANY, wxT("Label"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelLabel->Wrap( -1 );
fgPropSizer->Add( m_labelLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
m_labelText = new wxTextCtrl( m_propPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
fgPropSizer->Add( m_labelText, 0, wxALL|wxEXPAND, 5 );
m_frequencyLabel = new wxStaticText( m_propPanel, wxID_ANY, wxT("Freq"), wxDefaultPosition, wxDefaultSize, 0 );
m_frequencyLabel->Wrap( -1 );
fgPropSizer->Add( m_frequencyLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
m_frequencyVal = new wxStaticText( m_propPanel, wxID_ANY, wxT("FrequencyVal"), wxDefaultPosition, wxDefaultSize, 0 );
m_frequencyVal->Wrap( -1 );
fgPropSizer->Add( m_frequencyVal, 0, wxALL, 5 );
m_bandwidthLabel = new wxStaticText( m_propPanel, wxID_ANY, wxT("BW"), wxDefaultPosition, wxDefaultSize, 0 );
m_bandwidthLabel->Wrap( -1 );
fgPropSizer->Add( m_bandwidthLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
m_bandwidthVal = new wxStaticText( m_propPanel, wxID_ANY, wxT("BandwidthVal"), wxDefaultPosition, wxDefaultSize, 0 );
m_bandwidthVal->Wrap( -1 );
fgPropSizer->Add( m_bandwidthVal, 0, wxALL, 5 );
m_modulationLabel = new wxStaticText( m_propPanel, wxID_ANY, wxT("Type"), wxDefaultPosition, wxDefaultSize, 0 );
m_modulationLabel->Wrap( -1 );
fgPropSizer->Add( m_modulationLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
m_modulationVal = new wxStaticText( m_propPanel, wxID_ANY, wxT("TypeVal"), wxDefaultPosition, wxDefaultSize, 0 );
m_modulationVal->Wrap( -1 );
fgPropSizer->Add( m_modulationVal, 0, wxALL, 5 );
m_propPanel->SetSizer( fgPropSizer );
m_propPanel->Layout();
fgPropSizer->Fit( m_propPanel );
bSizer1->Add( m_propPanel, 0, wxALL|wxBOTTOM|wxEXPAND|wxTOP, 5 );
m_buttonPanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* m_buttonPanelSizer;
m_buttonPanelSizer = new wxBoxSizer( wxVERTICAL );
m_buttonPanel->SetSizer( m_buttonPanelSizer );
m_buttonPanel->Layout();
m_buttonPanelSizer->Fit( m_buttonPanel );
bSizer1->Add( m_buttonPanel, 0, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizer1 );
this->Layout();
m_updateTimer.SetOwner( this, wxID_ANY );
// Connect Events
this->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( BookmarkPanel::onEnterWindow ) );
this->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( BookmarkPanel::onLeaveWindow ) );
this->Connect( wxEVT_MOTION, wxMouseEventHandler( BookmarkPanel::onMotion ) );
m_searchText->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( BookmarkPanel::onSearchTextFocus ), NULL, this );
m_searchText->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( BookmarkPanel::onSearchText ), NULL, this );
m_clearSearchButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BookmarkPanel::onClearSearch ), NULL, this );
m_treeView->Connect( wxEVT_MOTION, wxMouseEventHandler( BookmarkPanel::onMotion ), NULL, this );
m_treeView->Connect( wxEVT_COMMAND_TREE_BEGIN_DRAG, wxTreeEventHandler( BookmarkPanel::onTreeBeginDrag ), NULL, this );
m_treeView->Connect( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, wxTreeEventHandler( BookmarkPanel::onTreeBeginLabelEdit ), NULL, this );
m_treeView->Connect( wxEVT_COMMAND_TREE_END_DRAG, wxTreeEventHandler( BookmarkPanel::onTreeEndDrag ), NULL, this );
m_treeView->Connect( wxEVT_COMMAND_TREE_END_LABEL_EDIT, wxTreeEventHandler( BookmarkPanel::onTreeEndLabelEdit ), NULL, this );
m_treeView->Connect( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEventHandler( BookmarkPanel::onTreeActivate ), NULL, this );
m_treeView->Connect( wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxTreeEventHandler( BookmarkPanel::onTreeCollapse ), NULL, this );
m_treeView->Connect( wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxTreeEventHandler( BookmarkPanel::onTreeExpanded ), NULL, this );
m_treeView->Connect( wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, wxTreeEventHandler( BookmarkPanel::onTreeItemGetTooltip ), NULL, this );
m_treeView->Connect( wxEVT_COMMAND_TREE_ITEM_MENU, wxTreeEventHandler( BookmarkPanel::onTreeItemMenu ), NULL, this );
m_treeView->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( BookmarkPanel::onTreeSelect ), NULL, this );
m_treeView->Connect( wxEVT_COMMAND_TREE_SEL_CHANGING, wxTreeEventHandler( BookmarkPanel::onTreeSelectChanging ), NULL, this );
m_labelText->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( BookmarkPanel::onLabelText ), NULL, this );
m_frequencyVal->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( BookmarkPanel::onDoubleClickFreq ), NULL, this );
m_bandwidthVal->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( BookmarkPanel::onDoubleClickBandwidth ), NULL, this );
this->Connect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( BookmarkPanel::onUpdateTimer ) );
}
BookmarkPanel::~BookmarkPanel()
{
// Disconnect Events
this->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( BookmarkPanel::onEnterWindow ) );
this->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( BookmarkPanel::onLeaveWindow ) );
this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( BookmarkPanel::onMotion ) );
m_searchText->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( BookmarkPanel::onSearchTextFocus ), NULL, this );
m_searchText->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( BookmarkPanel::onSearchText ), NULL, this );
m_clearSearchButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BookmarkPanel::onClearSearch ), NULL, this );
m_treeView->Disconnect( wxEVT_MOTION, wxMouseEventHandler( BookmarkPanel::onMotion ), NULL, this );
m_treeView->Disconnect( wxEVT_COMMAND_TREE_BEGIN_DRAG, wxTreeEventHandler( BookmarkPanel::onTreeBeginDrag ), NULL, this );
m_treeView->Disconnect( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, wxTreeEventHandler( BookmarkPanel::onTreeBeginLabelEdit ), NULL, this );
m_treeView->Disconnect( wxEVT_COMMAND_TREE_END_DRAG, wxTreeEventHandler( BookmarkPanel::onTreeEndDrag ), NULL, this );
m_treeView->Disconnect( wxEVT_COMMAND_TREE_END_LABEL_EDIT, wxTreeEventHandler( BookmarkPanel::onTreeEndLabelEdit ), NULL, this );
m_treeView->Disconnect( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEventHandler( BookmarkPanel::onTreeActivate ), NULL, this );
m_treeView->Disconnect( wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxTreeEventHandler( BookmarkPanel::onTreeCollapse ), NULL, this );
m_treeView->Disconnect( wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxTreeEventHandler( BookmarkPanel::onTreeExpanded ), NULL, this );
m_treeView->Disconnect( wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, wxTreeEventHandler( BookmarkPanel::onTreeItemGetTooltip ), NULL, this );
m_treeView->Disconnect( wxEVT_COMMAND_TREE_ITEM_MENU, wxTreeEventHandler( BookmarkPanel::onTreeItemMenu ), NULL, this );
m_treeView->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( BookmarkPanel::onTreeSelect ), NULL, this );
m_treeView->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGING, wxTreeEventHandler( BookmarkPanel::onTreeSelectChanging ), NULL, this );
m_labelText->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( BookmarkPanel::onLabelText ), NULL, this );
m_frequencyVal->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( BookmarkPanel::onDoubleClickFreq ), NULL, this );
m_bandwidthVal->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( BookmarkPanel::onDoubleClickBandwidth ), NULL, this );
this->Disconnect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( BookmarkPanel::onUpdateTimer ) );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Aug 23 2015)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __BOOKMARKPANEL_H__
#define __BOOKMARKPANEL_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/string.h>
#include <wx/textctrl.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/button.h>
#include <wx/treectrl.h>
#include <wx/stattext.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/timer.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class BookmarkPanel
///////////////////////////////////////////////////////////////////////////////
class BookmarkPanel : public wxPanel
{
private:
protected:
wxTextCtrl* m_searchText;
wxButton* m_clearSearchButton;
wxTreeCtrl* m_treeView;
wxPanel* m_propPanel;
wxStaticText* m_labelLabel;
wxTextCtrl* m_labelText;
wxStaticText* m_frequencyLabel;
wxStaticText* m_frequencyVal;
wxStaticText* m_bandwidthLabel;
wxStaticText* m_bandwidthVal;
wxStaticText* m_modulationLabel;
wxStaticText* m_modulationVal;
wxPanel* m_buttonPanel;
wxTimer m_updateTimer;
// Virtual event handlers, overide them in your derived class
virtual void onEnterWindow( wxMouseEvent& event ) { event.Skip(); }
virtual void onLeaveWindow( wxMouseEvent& event ) { event.Skip(); }
virtual void onMotion( wxMouseEvent& event ) { event.Skip(); }
virtual void onSearchTextFocus( wxMouseEvent& event ) { event.Skip(); }
virtual void onSearchText( wxCommandEvent& event ) { event.Skip(); }
virtual void onClearSearch( wxCommandEvent& event ) { event.Skip(); }
virtual void onTreeBeginDrag( wxTreeEvent& event ) { event.Skip(); }
virtual void onTreeBeginLabelEdit( wxTreeEvent& event ) { event.Skip(); }
virtual void onTreeEndDrag( wxTreeEvent& event ) { event.Skip(); }
virtual void onTreeEndLabelEdit( wxTreeEvent& event ) { event.Skip(); }
virtual void onTreeActivate( wxTreeEvent& event ) { event.Skip(); }
virtual void onTreeCollapse( wxTreeEvent& event ) { event.Skip(); }
virtual void onTreeExpanded( wxTreeEvent& event ) { event.Skip(); }
virtual void onTreeItemGetTooltip( wxTreeEvent& event ) { event.Skip(); }
virtual void onTreeItemMenu( wxTreeEvent& event ) { event.Skip(); }
virtual void onTreeSelect( wxTreeEvent& event ) { event.Skip(); }
virtual void onTreeSelectChanging( wxTreeEvent& event ) { event.Skip(); }
virtual void onLabelText( wxCommandEvent& event ) { event.Skip(); }
virtual void onDoubleClickFreq( wxMouseEvent& event ) { event.Skip(); }
virtual void onDoubleClickBandwidth( wxMouseEvent& event ) { event.Skip(); }
virtual void onUpdateTimer( wxTimerEvent& event ) { event.Skip(); }
public:
BookmarkPanel( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 169,471 ), long style = wxTAB_TRAVERSAL );
~BookmarkPanel();
};
#endif //__BOOKMARKPANEL_H__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,175 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once
#include "wx/choice.h"
#include "wx/dialog.h"
#include "BookmarkPanel.h"
#include "BookmarkMgr.h"
class TreeViewItem : public wxTreeItemData {
public:
enum TreeViewItemType {
TREEVIEW_ITEM_TYPE_GROUP,
TREEVIEW_ITEM_TYPE_ACTIVE,
TREEVIEW_ITEM_TYPE_RECENT,
TREEVIEW_ITEM_TYPE_BOOKMARK,
TREEVIEW_ITEM_TYPE_RANGE
};
TreeViewItem() {
bookmarkEnt = nullptr;
demod = nullptr;
rangeEnt = nullptr;
};
TreeViewItemType type;
BookmarkEntry *bookmarkEnt;
BookmarkRangeEntry *rangeEnt;
DemodulatorInstance *demod;
std::string groupName;
};
class BookmarkViewVisualDragItem : public wxDialog {
public:
BookmarkViewVisualDragItem(wxString labelValue = L"Popup");
};
class BookmarkView : public BookmarkPanel {
public:
BookmarkView( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1, -1 ), long style = wxTAB_TRAVERSAL );
void updateActiveList();
void updateBookmarks();
bool isKeywordMatch(std::wstring str, std::vector<std::wstring> &keywords);
void updateBookmarks(std::string group);
wxTreeItemId refreshBookmarks();
void updateTheme();
void onMenuItem(wxCommandEvent& event);
bool isMouseInView();
bool getExpandState(std::string branchName);
void setExpandState(std::string branchName, bool state);
void loadDefaultRanges();
static BookmarkRangeEntry *makeActiveRangeEntry();
protected:
void activeSelection(DemodulatorInstance *dsel);
void bookmarkSelection(BookmarkEntry *bmSel);
void rangeSelection(BookmarkRangeEntry *re);
void activateBookmark(BookmarkEntry *bmEnt);
void activateRange(BookmarkRangeEntry *rangeEnt);
void recentSelection(BookmarkEntry *bmSel);
void groupSelection(std::string groupName);
void bookmarkBranchSelection();
void recentBranchSelection();
void rangeBranchSelection();
void activeBranchSelection();
void hideProps();
void showProps();
void onUpdateTimer( wxTimerEvent& event );
void doUpdateActiveList();
void onTreeBeginLabelEdit( wxTreeEvent& event );
void onTreeEndLabelEdit( wxTreeEvent& event );
void onTreeActivate( wxTreeEvent& event );
void onTreeCollapse( wxTreeEvent& event );
void onTreeExpanded( wxTreeEvent& event );
void onTreeItemMenu( wxTreeEvent& event );
void onTreeSelect( wxTreeEvent& event );
void onTreeSelectChanging( wxTreeEvent& event );
void onLabelText( wxCommandEvent& event );
void onDoubleClickFreq( wxMouseEvent& event );
void onDoubleClickBandwidth( wxMouseEvent& event );
void onTreeBeginDrag( wxTreeEvent& event );
void onTreeEndDrag( wxTreeEvent& event );
void onTreeItemGetTooltip( wxTreeEvent& event );
void onEnterWindow( wxMouseEvent& event );
void onLeaveWindow( wxMouseEvent& event );
void onMotion( wxMouseEvent& event );
void onSearchTextFocus( wxMouseEvent& event );
void onSearchText( wxCommandEvent& event );
void onClearSearch( wxCommandEvent& event );
void clearButtons();
void showButtons();
void refreshLayout();
wxButton *makeButton(wxWindow *parent, std::string labelVal, wxObjectEventFunction handler);
wxButton *addButton(wxWindow *parent, std::string labelVal, wxObjectEventFunction handler);
void doBookmarkActive(std::string group, DemodulatorInstance *demod);
void doBookmarkRecent(std::string group, BookmarkEntry *be);
void doMoveBookmark(BookmarkEntry *be, std::string group);
void doRemoveActive(DemodulatorInstance *demod);
void doRemoveRecent(BookmarkEntry *be);
void doClearRecents();
void updateBookmarkChoices();
void addBookmarkChoice(wxWindow *parent);
void onBookmarkChoice( wxCommandEvent &event );
void onRemoveActive( wxCommandEvent& event );
void onRemoveBookmark( wxCommandEvent& event );
void onActivateBookmark( wxCommandEvent& event );
void onActivateRecent( wxCommandEvent& event );
void onRemoveRecent ( wxCommandEvent& event );
void onClearRecents ( wxCommandEvent& event );
void onAddGroup( wxCommandEvent& event );
void onRemoveGroup( wxCommandEvent& event );
void onRenameGroup( wxCommandEvent& event );
void onAddRange( wxCommandEvent& event );
void onRemoveRange( wxCommandEvent& event );
void onRenameRange( wxCommandEvent& event );
void onActivateRange( wxCommandEvent& event );
void onUpdateRange( wxCommandEvent& event );
TreeViewItem *itemToTVI(wxTreeItemId item);
std::atomic_bool mouseInView;
wxTreeItemId rootBranch, activeBranch, bookmarkBranch, recentBranch, rangeBranch;
std::map<std::string, bool> expandState;
TreeViewItem *dragItem;
wxTreeItemId dragItemId;
BookmarkViewVisualDragItem *visualDragItem;
bool editingLabel;
// Bookmarks
std::atomic_bool doUpdateBookmarks;
std::set< std::string > doUpdateBookmarkGroup;
BookmarkNames groupNames;
std::map<std::string, wxTreeItemId> groups;
wxArrayString bookmarkChoices;
wxChoice *bookmarkChoice;
// Active
std::atomic_bool doUpdateActive;
// Focus
BookmarkEntry *nextEnt;
BookmarkRangeEntry *nextRange;
DemodulatorInstance *nextDemod;
// Search
std::vector<std::wstring> searchKeywords;
};

View File

@ -0,0 +1,61 @@
#include "ActionDialog.h"
ActionDialog *ActionDialog::activeDialog = nullptr;
ActionDialog::ActionDialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
: ActionDialogBase(parent, id, title, pos, size, style) {
}
ActionDialog::~ActionDialog() {
}
void ActionDialog::showDialog(ActionDialog *dlg) {
if (activeDialog) { // rejected
delete dlg;
return;
}
activeDialog = dlg;
dlg->Layout();
dlg->Fit();
dlg->ShowModal();
}
ActionDialog *ActionDialog::getActiveDialog() {
return activeDialog;
}
void ActionDialog::setActiveDialog(ActionDialog *dlg) {
activeDialog = dlg;
}
void ActionDialog::onClickCancel( wxCommandEvent& event ) {
ActionDialog *dlg = activeDialog;
ActionDialog::setActiveDialog(nullptr);
dlg->EndModal(0);
doClickCancel();
delete dlg;
}
void ActionDialog::onClickOK( wxCommandEvent& event ) {
ActionDialog *dlg = activeDialog;
ActionDialog::setActiveDialog(nullptr);
dlg->EndModal(0);
doClickOK();
delete dlg;
}
void ActionDialog::doClickCancel() {
}
void ActionDialog::doClickOK() {
}

View File

@ -0,0 +1,21 @@
#include "ActionDialogBase.h"
#include <mutex>
class ActionDialog : public ActionDialogBase {
public:
ActionDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("QuestionTitle"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
~ActionDialog();
void onClickCancel( wxCommandEvent& event );
void onClickOK( wxCommandEvent& event );
virtual void doClickCancel();
virtual void doClickOK();
static ActionDialog *getActiveDialog();
static void setActiveDialog(ActionDialog *dlg);
static void showDialog(ActionDialog *dlg);
private:
static ActionDialog *activeDialog;
};

View File

@ -0,0 +1,53 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Aug 23 2015)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "ActionDialogBase.h"
///////////////////////////////////////////////////////////////////////////
ActionDialogBase::ActionDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* mainSizer;
mainSizer = new wxBoxSizer( wxVERTICAL );
m_questionText = new wxStaticText( this, wxID_ANY, wxT("Question"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
m_questionText->Wrap( -1 );
mainSizer->Add( m_questionText, 1, wxALL|wxEXPAND, 5 );
wxBoxSizer* buttonSizer;
buttonSizer = new wxBoxSizer( wxHORIZONTAL );
m_cancelButton = new wxButton( this, wxID_ANY, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
buttonSizer->Add( m_cancelButton, 1, wxALL|wxEXPAND, 5 );
m_okButton = new wxButton( this, wxID_ANY, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 );
buttonSizer->Add( m_okButton, 1, wxALL|wxEXPAND, 5 );
mainSizer->Add( buttonSizer, 1, wxEXPAND, 5 );
this->SetSizer( mainSizer );
this->Layout();
mainSizer->Fit( this );
this->Centre( wxBOTH );
// Connect Events
m_cancelButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ActionDialogBase::onClickCancel ), NULL, this );
m_okButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ActionDialogBase::onClickOK ), NULL, this );
}
ActionDialogBase::~ActionDialogBase()
{
// Disconnect Events
m_cancelButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ActionDialogBase::onClickCancel ), NULL, this );
m_okButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ActionDialogBase::onClickOK ), NULL, this );
}

View File

@ -0,0 +1,369 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="13" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">ActionDialogBase</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="internationalize">0</property>
<property name="name">ActionDialogBase</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="center">wxBOTH</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">ActionDialogBase</property>
<property name="pos"></property>
<property name="size"></property>
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
<property name="subclass"></property>
<property name="title">QuestionTitle</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnActivate"></event>
<event name="OnActivateApp"></event>
<event name="OnAuiFindManager"></event>
<event name="OnAuiPaneButton"></event>
<event name="OnAuiPaneClose"></event>
<event name="OnAuiPaneMaximize"></event>
<event name="OnAuiPaneRestore"></event>
<event name="OnAuiRender"></event>
<event name="OnChar"></event>
<event name="OnClose"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnHibernate"></event>
<event name="OnIconize"></event>
<event name="OnIdle"></event>
<event name="OnInitDialog"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">mainSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Question</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_questionText</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxALIGN_CENTRE</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">buttonSizer</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Cancel</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cancelButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onClickCancel</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">OK</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_okButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onClickOK</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>

View File

@ -0,0 +1,50 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Aug 23 2015)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __ACTIONDIALOGBASE_H__
#define __ACTIONDIALOGBASE_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class ActionDialogBase
///////////////////////////////////////////////////////////////////////////////
class ActionDialogBase : public wxDialog
{
private:
protected:
wxStaticText* m_questionText;
wxButton* m_cancelButton;
wxButton* m_okButton;
// Virtual event handlers, overide them in your derived class
virtual void onClickCancel( wxCommandEvent& event ) { event.Skip(); }
virtual void onClickOK( wxCommandEvent& event ) { event.Skip(); }
public:
ActionDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("QuestionTitle"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
~ActionDialogBase();
};
#endif //__ACTIONDIALOGBASE_H__

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "DigitalConsole.h" #include "DigitalConsole.h"
#include "CubicSDR.h" #include "CubicSDR.h"
#include <iomanip> #include <iomanip>

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <map> #include <map>

View File

@ -1,5 +1,7 @@
#include "SDRDeviceAdd.h" // Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "SDRDeviceAdd.h"
#include "SDREnumerator.h" #include "SDREnumerator.h"
SDRDeviceAddDialog::SDRDeviceAddDialog( wxWindow* parent ): SDRDeviceAddForm( parent ) { SDRDeviceAddDialog::SDRDeviceAddDialog( wxWindow* parent ): SDRDeviceAddForm( parent ) {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "SDRDeviceAddForm.h" #include "SDRDeviceAddForm.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "SDRDevices.h" #include "SDRDevices.h"
#include <wx/textdlg.h> #include <wx/textdlg.h>
@ -5,7 +8,11 @@
#include "CubicSDR.h" #include "CubicSDR.h"
SDRDevicesDialog::SDRDevicesDialog( wxWindow* parent ): devFrame( parent ) { #ifdef __linux__
#include "CubicSDR.xpm"
#endif
SDRDevicesDialog::SDRDevicesDialog( wxWindow* parent ): devFrame( parent, wxID_ANY, wxT(CUBICSDR_INSTALL_NAME " :: SDR Devices")) {
refresh = true; refresh = true;
failed = false; failed = false;
m_refreshButton->Disable(); m_refreshButton->Disable();
@ -17,6 +24,13 @@ SDRDevicesDialog::SDRDevicesDialog( wxWindow* parent ): devFrame( parent ) {
removeId = nullptr; removeId = nullptr;
devAddDialog = nullptr; devAddDialog = nullptr;
dev = nullptr; dev = nullptr;
#ifdef __linux__
SetIcon(wxICON(cubicsdr));
#elif _WIN32
SetIcon(wxICON(frame_icon));
#endif
} }
void SDRDevicesDialog::OnClose( wxCloseEvent& /* event */) { void SDRDevicesDialog::OnClose( wxCloseEvent& /* event */) {
@ -113,8 +127,8 @@ void SDRDevicesDialog::refreshDeviceProperties() {
devSettings["name"] = m_propertyGrid->Append( new wxStringProperty("Name", wxPG_LABEL, devConfig->getDeviceName()) ); devSettings["name"] = m_propertyGrid->Append( new wxStringProperty("Name", wxPG_LABEL, devConfig->getDeviceName()) );
devSettings["offset"] = m_propertyGrid->Append( new wxIntProperty("Offset (Hz)", wxPG_LABEL, devConfig->getOffset()) ); devSettings["offset"] = m_propertyGrid->Append( new wxIntProperty("Offset (Hz)", wxPG_LABEL, devConfig->getOffset()) );
int currentSampleRate = wxGetApp().getSampleRate(); long currentSampleRate = wxGetApp().getSampleRate();
int deviceSampleRate = devConfig->getSampleRate(); long deviceSampleRate = devConfig->getSampleRate();
if (!deviceSampleRate) { if (!deviceSampleRate) {
deviceSampleRate = selDev->getSampleRateNear(SOAPY_SDR_RX, 0, currentSampleRate); deviceSampleRate = selDev->getSampleRateNear(SOAPY_SDR_RX, 0, currentSampleRate);
@ -315,7 +329,7 @@ void SDRDevicesDialog::OnUseSelected( wxMouseEvent& event) {
wxGetApp().setDeviceArgs(settingArgs); wxGetApp().setDeviceArgs(settingArgs);
wxGetApp().setStreamArgs(streamArgs); wxGetApp().setStreamArgs(streamArgs);
wxGetApp().setDevice(dev,0); wxGetApp().setDevice(dev,0);
wxGetApp().notifyMainUIOfDeviceChange();
Close(); Close();
} }
event.Skip(); event.Skip();
@ -435,13 +449,14 @@ void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) {
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId()); DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
std::string strRate = deviceArgs["sample_rate"].options[event.GetPropertyValue().GetInteger()]; std::string strRate = deviceArgs["sample_rate"].options[event.GetPropertyValue().GetInteger()];
int srate = 0; long srate = 0;
try { try {
srate = std::stoi(strRate); srate = std::stol(strRate);
devConfig->setSampleRate(srate); devConfig->setSampleRate(srate);
if (dev->isActive() || !wxGetApp().getDevice()) { if (dev->isActive() || !wxGetApp().getDevice()) {
wxGetApp().setSampleRate(srate); wxGetApp().setSampleRate(srate);
wxGetApp().notifyMainUIOfDeviceChange();
} }
} catch (std::invalid_argument e) { } catch (std::invalid_argument e) {
// nop // nop

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include <map> #include <map>

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "Modem.h" #include "Modem.h"
#include "CubicSDR.h" #include "CubicSDR.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "liquid/liquid.h" #include "liquid/liquid.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemAnalog.h" #include "ModemAnalog.h"
ModemAnalog::ModemAnalog() : Modem(), aOutputCeil(1), aOutputCeilMA(1), aOutputCeilMAA(1) { ModemAnalog::ModemAnalog() : Modem(), aOutputCeil(1), aOutputCeilMA(1), aOutputCeilMAA(1) {
@ -12,7 +15,7 @@ int ModemAnalog::checkSampleRate(long long sampleRate, int /* audioSampleRate */
if (sampleRate < MIN_BANDWIDTH) { if (sampleRate < MIN_BANDWIDTH) {
return MIN_BANDWIDTH; return MIN_BANDWIDTH;
} }
return sampleRate; return (int)sampleRate;
} }
ModemKit *ModemAnalog::buildKit(long long sampleRate, int audioSampleRate) { ModemKit *ModemAnalog::buildKit(long long sampleRate, int audioSampleRate) {
@ -24,7 +27,7 @@ ModemKit *ModemAnalog::buildKit(long long sampleRate, int audioSampleRate) {
akit->sampleRate = sampleRate; akit->sampleRate = sampleRate;
akit->audioSampleRate = audioSampleRate; akit->audioSampleRate = audioSampleRate;
akit->audioResampleRatio = double(audioSampleRate) / double(sampleRate); akit->audioResampleRatio = double(audioSampleRate) / double(sampleRate);
akit->audioResampler = msresamp_rrrf_create(akit->audioResampleRatio, As); akit->audioResampler = msresamp_rrrf_create((float)akit->audioResampleRatio, As);
return akit; return akit;
} }
@ -82,7 +85,7 @@ void ModemAnalog::buildAudioOutput(ModemKitAnalog *akit, AudioThreadInput *audio
} }
} }
msresamp_rrrf_execute(akit->audioResampler, &demodOutputData[0], demodOutputData.size(), &resampledOutputData[0], &numAudioWritten); msresamp_rrrf_execute(akit->audioResampler, &demodOutputData[0], (int)demodOutputData.size(), &resampledOutputData[0], &numAudioWritten);
audioOut->channels = 1; audioOut->channels = 1;
audioOut->sampleRate = akit->audioSampleRate; audioOut->sampleRate = akit->audioSampleRate;

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "Modem.h" #include "Modem.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemDigital.h" #include "ModemDigital.h"
@ -23,7 +26,7 @@ int ModemDigital::checkSampleRate(long long sampleRate, int /* audioSampleRate *
if (sampleRate < MIN_BANDWIDTH) { if (sampleRate < MIN_BANDWIDTH) {
return MIN_BANDWIDTH; return MIN_BANDWIDTH;
} }
return sampleRate; return (int)sampleRate;
} }
ModemKit *ModemDigital::buildKit(long long sampleRate, int audioSampleRate) { ModemKit *ModemDigital::buildKit(long long sampleRate, int audioSampleRate) {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "Modem.h" #include "Modem.h"
#include <map> #include <map>

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemAM.h" #include "ModemAM.h"
ModemAM::ModemAM() : ModemAnalog() { ModemAM::ModemAM() : ModemAnalog() {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "Modem.h" #include "Modem.h"
#include "ModemAnalog.h" #include "ModemAnalog.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemDSB.h" #include "ModemDSB.h"
ModemDSB::ModemDSB() : ModemAnalog() { ModemDSB::ModemDSB() : ModemAnalog() {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "Modem.h" #include "Modem.h"
#include "ModemAnalog.h" #include "ModemAnalog.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemFM.h" #include "ModemFM.h"
ModemFM::ModemFM() : ModemAnalog() { ModemFM::ModemFM() : ModemAnalog() {
@ -30,7 +33,7 @@ void ModemFM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *au
return; return;
} }
freqdem_demodulate_block(demodFM, &input->data[0], bufSize, &demodOutputData[0]); freqdem_demodulate_block(demodFM, &input->data[0], (int)bufSize, &demodOutputData[0]);
buildAudioOutput(fmkit, audioOut, false); buildAudioOutput(fmkit, audioOut, false);
} }

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "Modem.h" #include "Modem.h"
#include "ModemAnalog.h" #include "ModemAnalog.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemFMStereo.h" #include "ModemFMStereo.h"
ModemFMStereo::ModemFMStereo() { ModemFMStereo::ModemFMStereo() {
@ -27,7 +30,7 @@ int ModemFMStereo::checkSampleRate(long long sampleRate, int /* audioSampleRate
} else if (sampleRate < 1500) { } else if (sampleRate < 1500) {
return 1500; return 1500;
} else { } else {
return sampleRate; return (int)sampleRate;
} }
} }
@ -92,13 +95,13 @@ ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) {
float As = 60.0f; // stop-band attenuation [dB] float As = 60.0f; // stop-band attenuation [dB]
kit->audioResampler = msresamp_rrrf_create(kit->audioResampleRatio, As); kit->audioResampler = msresamp_rrrf_create((float)kit->audioResampleRatio, As);
kit->stereoResampler = msresamp_rrrf_create(kit->audioResampleRatio, As); kit->stereoResampler = msresamp_rrrf_create((float)kit->audioResampleRatio, As);
// Stereo filters / shifters // Stereo filters / shifters
double firStereoCutoff = 16000.0 / double(audioSampleRate); float firStereoCutoff = 16000.0f / float(audioSampleRate);
// filter transition // filter transition
float ft = 1000.0f / double(audioSampleRate); float ft = 1000.0f / float(audioSampleRate);
// fractional timing offset // fractional timing offset
float mu = 0.0f; float mu = 0.0f;
@ -139,13 +142,13 @@ ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) {
kit->demph = _demph; kit->demph = _demph;
if (_demph) { if (_demph) {
float f = (1.0f / (2.0f * M_PI * double(_demph) * 1e-6)); double f = (1.0 / (2.0 * M_PI * double(_demph) * 1e-6));
float t = 1.0f / (2.0f * M_PI * f); double t = 1.0 / (2.0 * M_PI * f);
t = 1.0f / (2.0f * float(audioSampleRate) * tan(1.0f / (2.0f * float(audioSampleRate) * t))); t = 1.0 / (2.0 * double(audioSampleRate) * tan(1.0 / (2.0 * double(audioSampleRate) * t)));
float tb = (1.0f + 2.0f * t * float(audioSampleRate)); double tb = (1.0 + 2.0 * t * double(audioSampleRate));
float b_demph[2] = { 1.0f / tb, 1.0f / tb }; float b_demph[2] = { (float)(1.0 / tb), (float)(1.0 / tb) };
float a_demph[2] = { 1.0f, (1.0f - 2.0f * t * float(audioSampleRate)) / tb }; float a_demph[2] = { 1.0, (float)((1.0 - 2.0 * t * double(audioSampleRate)) / tb) };
kit->iirDemphL = iirfilt_rrrf_create(b_demph, 2, a_demph, 2); kit->iirDemphL = iirfilt_rrrf_create(b_demph, 2, a_demph, 2);
kit->iirDemphR = iirfilt_rrrf_create(b_demph, 2, a_demph, 2); kit->iirDemphR = iirfilt_rrrf_create(b_demph, 2, a_demph, 2);
@ -188,7 +191,7 @@ void ModemFMStereo::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInp
size_t audio_out_size = (size_t)ceil((double) (bufSize) * audio_resample_ratio) + 512; size_t audio_out_size = (size_t)ceil((double) (bufSize) * audio_resample_ratio) + 512;
freqdem_demodulate_block(demodFM, &input->data[0], bufSize, &demodOutputData[0]); freqdem_demodulate_block(demodFM, &input->data[0], (int)bufSize, &demodOutputData[0]);
if (resampledOutputData.size() != audio_out_size) { if (resampledOutputData.size() != audio_out_size) {
if (resampledOutputData.capacity() < audio_out_size) { if (resampledOutputData.capacity() < audio_out_size) {
@ -199,7 +202,7 @@ void ModemFMStereo::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInp
unsigned int numAudioWritten; unsigned int numAudioWritten;
msresamp_rrrf_execute(fmkit->audioResampler, &demodOutputData[0], bufSize, &resampledOutputData[0], &numAudioWritten); msresamp_rrrf_execute(fmkit->audioResampler, &demodOutputData[0], (int)bufSize, &resampledOutputData[0], &numAudioWritten);
if (demodStereoData.size() != bufSize) { if (demodStereoData.size() != bufSize) {
if (demodStereoData.capacity() < bufSize) { if (demodStereoData.capacity() < bufSize) {
@ -249,7 +252,7 @@ void ModemFMStereo::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInp
resampledStereoData.resize(audio_out_size); resampledStereoData.resize(audio_out_size);
} }
msresamp_rrrf_execute(fmkit->stereoResampler, &demodStereoData[0], bufSize, &resampledStereoData[0], &numAudioWritten); msresamp_rrrf_execute(fmkit->stereoResampler, &demodStereoData[0], (int)bufSize, &resampledStereoData[0], &numAudioWritten);
audioOut->channels = 2; audioOut->channels = 2;
if (audioOut->data.capacity() < (numAudioWritten * 2)) { if (audioOut->data.capacity() < (numAudioWritten * 2)) {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "Modem.h" #include "Modem.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemIQ.h" #include "ModemIQ.h"
ModemIQ::ModemIQ() { ModemIQ::ModemIQ() {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "Modem.h" #include "Modem.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemLSB.h" #include "ModemLSB.h"
ModemLSB::ModemLSB() : ModemAnalog() { ModemLSB::ModemLSB() : ModemAnalog() {
@ -9,7 +12,7 @@ ModemLSB::ModemLSB() : ModemAnalog() {
ssbFilt = iirfilt_crcf_create_lowpass(6, 0.25); ssbFilt = iirfilt_crcf_create_lowpass(6, 0.25);
#endif #endif
ssbShift = nco_crcf_create(LIQUID_NCO); ssbShift = nco_crcf_create(LIQUID_NCO);
nco_crcf_set_frequency(ssbShift, (2.0 * M_PI) * 0.25); nco_crcf_set_frequency(ssbShift, (float)((2.0 * M_PI) * 0.25));
c2rFilt = firhilbf_create(5, 90.0); c2rFilt = firhilbf_create(5, 90.0);
useSignalOutput(true); useSignalOutput(true);
} }
@ -38,9 +41,9 @@ int ModemLSB::checkSampleRate(long long sampleRate, int /* audioSampleRate */) {
return MIN_BANDWIDTH; return MIN_BANDWIDTH;
} }
if (sampleRate % 2 == 0) { if (sampleRate % 2 == 0) {
return sampleRate; return (int)sampleRate;
} }
return sampleRate+1; return (int)(sampleRate+1);
} }
int ModemLSB::getDefaultSampleRate() { int ModemLSB::getDefaultSampleRate() {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "ModemAnalog.h" #include "ModemAnalog.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemNBFM.h" #include "ModemNBFM.h"
ModemNBFM::ModemNBFM() : ModemAnalog() { ModemNBFM::ModemNBFM() : ModemAnalog() {
@ -30,7 +33,7 @@ void ModemNBFM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *
return; return;
} }
freqdem_demodulate_block(demodFM, &input->data[0], bufSize, &demodOutputData[0]); freqdem_demodulate_block(demodFM, &input->data[0], (unsigned int)bufSize, &demodOutputData[0]);
buildAudioOutput(fmkit, audioOut, false); buildAudioOutput(fmkit, audioOut, false);
} }

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "Modem.h" #include "Modem.h"
#include "ModemAnalog.h" #include "ModemAnalog.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemUSB.h" #include "ModemUSB.h"
ModemUSB::ModemUSB() : ModemAnalog() { ModemUSB::ModemUSB() : ModemAnalog() {
@ -9,7 +12,7 @@ ModemUSB::ModemUSB() : ModemAnalog() {
ssbFilt = iirfilt_crcf_create_lowpass(6, 0.25); ssbFilt = iirfilt_crcf_create_lowpass(6, 0.25);
#endif #endif
ssbShift = nco_crcf_create(LIQUID_NCO); ssbShift = nco_crcf_create(LIQUID_NCO);
nco_crcf_set_frequency(ssbShift, (2.0f * M_PI) * 0.25f); nco_crcf_set_frequency(ssbShift, (float)((2.0 * M_PI) * 0.25));
c2rFilt = firhilbf_create(5, 90.0); c2rFilt = firhilbf_create(5, 90.0);
useSignalOutput(true); useSignalOutput(true);
} }
@ -38,9 +41,9 @@ int ModemUSB::checkSampleRate(long long sampleRate, int /* audioSampleRate */) {
return MIN_BANDWIDTH; return MIN_BANDWIDTH;
} }
if (sampleRate % 2 == 0) { if (sampleRate % 2 == 0) {
return sampleRate; return (int)sampleRate;
} }
return sampleRate+1; return (int)(sampleRate+1);
} }
int ModemUSB::getDefaultSampleRate() { int ModemUSB::getDefaultSampleRate() {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "ModemAnalog.h" #include "ModemAnalog.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemAPSK.h" #include "ModemAPSK.h"
ModemAPSK::ModemAPSK() : ModemDigital() { ModemAPSK::ModemAPSK() : ModemDigital() {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "ModemDigital.h" #include "ModemDigital.h"

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemASK.h" #include "ModemASK.h"
ModemASK::ModemASK() : ModemDigital() { ModemASK::ModemASK() : ModemDigital() {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once #pragma once
#include "ModemDigital.h" #include "ModemDigital.h"

Some files were not shown because too many files have changed in this diff Show More