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_MINOR "2")
SET(CUBICSDR_VERSION_PATCH "0")
SET(CUBICSDR_VERSION_REL "")
SET(CUBICSDR_VERSION "${CUBICSDR_VERSION_MAJOR}.${CUBICSDR_VERSION_MINOR}.${CUBICSDR_VERSION_PATCH}${CUBICSDR_VERSION_REL}")
SET(CUBICSDR_VERSION_PATCH "2")
SET(CUBICSDR_VERSION_SUFFIX "-alpha")
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_MAJOR ${CUBICSDR_VERSION_MAJOR})
SET(CPACK_PACKAGE_VERSION_MINOR ${CUBICSDR_VERSION_MINOR})
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(
-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.")
@ -26,16 +76,6 @@ IF(ENABLE_DIGITAL_LAB)
ADD_DEFINITIONS(
-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()
set(USE_HAMLIB OFF CACHE BOOL "Support hamlib for radio control functions.")
@ -225,6 +265,7 @@ SET (cubicsdr_sources
src/DemodLabelDialog.cpp
src/IOThread.cpp
src/ModemProperties.cpp
src/BookmarkMgr.cpp
src/sdr/SDRDeviceInfo.cpp
src/sdr/SDRPostThread.cpp
src/sdr/SDREnumerator.cpp
@ -271,6 +312,7 @@ SET (cubicsdr_sources
src/visual/SpectrumCanvas.cpp
src/visual/WaterfallCanvas.cpp
src/visual/GainCanvas.cpp
src/visual/ImagePanel.cpp
src/process/VisualProcessor.cpp
src/process/ScopeVisualProcessor.cpp
src/process/SpectrumVisualProcessor.cpp
@ -282,6 +324,10 @@ SET (cubicsdr_sources
src/forms/SDRDevices/SDRDevicesForm.cpp
src/forms/SDRDevices/SDRDeviceAdd.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/tinyxml/tinyxml.cpp
external/tinyxml/tinystr.cpp
@ -306,14 +352,9 @@ IF(ENABLE_DIGITAL_LAB)
src/modules/modem/digital/ModemSQAM.cpp
src/modules/modem/digital/ModemQAM.cpp
src/modules/modem/digital/ModemQPSK.cpp
)
IF(ENABLE_LIQUID_EXPERIMENTAL)
SET (cubicsdr_sources
${cubicsdr_sources}
src/modules/modem/digital/ModemFSK.cpp
)
ENDIF()
ENDIF()
SET (cubicsdr_headers
src/CubicSDRDefs.h
@ -324,6 +365,7 @@ SET (cubicsdr_headers
src/DemodLabelDialog.h
src/IOThread.h
src/ModemProperties.h
src/BookmarkMgr.h
src/sdr/SDRDeviceInfo.h
src/sdr/SDRPostThread.h
src/sdr/SDREnumerator.h
@ -370,6 +412,7 @@ SET (cubicsdr_headers
src/visual/SpectrumCanvas.h
src/visual/WaterfallCanvas.h
src/visual/GainCanvas.h
src/visual/ImagePanel.h
src/process/VisualProcessor.h
src/process/ScopeVisualProcessor.h
src/process/SpectrumVisualProcessor.h
@ -385,6 +428,10 @@ SET (cubicsdr_headers
src/forms/SDRDevices/SDRDevicesForm.h
src/forms/SDRDevices/SDRDeviceAdd.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/tinyxml/tinyxml.h
external/tinyxml/tinystr.h
@ -420,14 +467,9 @@ SET (cubicsdr_headers
src/modules/modem/digital/ModemSQAM.h
src/modules/modem/digital/ModemQAM.h
src/modules/modem/digital/ModemQPSK.h
)
IF(ENABLE_LIQUID_EXPERIMENTAL)
SET (cubicsdr_sources
${cubicsdr_sources}
src/modules/modem/digital/ModemFSK.h
)
ENDIF()
ENDIF()
IF (USE_HAMLIB)
@ -471,6 +513,8 @@ set(REG_EXT "[^/]*([.]cpp|[.]c|[.]h|[.]hpp)$")
SOURCE_GROUP("Base" REGULAR_EXPRESSION "src/${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}")
IF(USE_HAMLIB)
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 (
${PROJECT_SOURCE_DIR}/src/forms/SDRDevices
${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/demod
${PROJECT_SOURCE_DIR}/src/modules
@ -535,6 +581,9 @@ IF (NOT BUNDLE_APP)
IF(MSVC)
configure_files(${PROJECT_SOURCE_DIR}/external/liquid-dsp/msvc/${EX_PLATFORM}/ ${CMAKE_BINARY_DIR}/${EX_PLATFORM_NAME} "*.dll")
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})
target_link_libraries(CubicSDR ${LIQUID_LIB} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${OTHER_LIBRARIES})
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 COMPILE_DEFINITIONS_MINSIZEREL "_WINDOWS")
set(CMAKE_CREATE_WIN32_EXE "/SUBSYSTEM:WINDOWS /ENTRY:\"mainCRTStartup\"")
set_target_properties (CubicSDR PROPERTIES OUTPUT_NAME "${CUBICSDR_INSTALL_NAME}")
ENDIF(MSVC)
IF (APPLE)
@ -613,7 +664,7 @@ IF (APPLE AND BUNDLE_APP)
MACOSX_BUNDLE_INFO_STRING "CubicSDR Open-Source Software-Defined Radio Application"
MACOSX_BUNDLE_BUNDLE_NAME "CubicSDR"
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_GUI_IDENTIFIER "com.cubicproductions.cubicsdr"
MACOSX_BUNDLE_ICON_FILE "CubicSDR.icns"
@ -625,9 +676,10 @@ IF (APPLE AND BUNDLE_APP)
# SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
IF (BUNDLE_SOAPY_MODS)
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})
INSTALL( FILES "${SOAPY_MOD_FILE}"
@ -708,6 +760,7 @@ IF (APPLE AND BUNDLE_APP)
include(CPack)
ENDIF()
IF(APPLE AND NOT BUNDLE_APP)
IF (NOT CMAKE_INSTALL_PREFIX)
SET(CMAKE_INSTALL_PREFIX "/usr/")
@ -764,28 +817,35 @@ IF (WIN32 AND NOT BUILD_INSTALLER)
INSTALL(FILES
${CUBICSDR_FONTS}
DESTINATION share/cubicsdr/fonts)
IF (CUBICSDR_HAS_HEADER_IMAGE)
INSTALL(FILES
${CUBICSDR_HEADER_IMAGE}
DESTINATION share/cubicsdr/)
ENDIF()
ENDIF()
IF (WIN32 AND BUILD_INSTALLER)
set(BUNDLE_SOAPY_MODS OFF CACHE BOOL "Bundle local SoapySDR modules")
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_DESCRIPTION_SUMMARY "CubicSDR ${CUBICSDR_VERSION} Installer")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "CubicSDR")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CUBICSDR_INSTALL_NAME}")
SET(CPACK_NSIS_INSTALLED_ICON_NAME "CubicSDR.ico")
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/icon\\\\NSIS_Header.bmp")
IF(EX_PLATFORM EQUAL 64)
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
SET(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
SET(CPACK_NSIS_PACKAGE_NAME "${CUBICSDR_INSTALL_NAME}")
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
ELSE(EX_PLATFORM EQUAL 64)
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
SET(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} (x86)")
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION} (x86)")
SET(CPACK_NSIS_PACKAGE_NAME "${CUBICSDR_INSTALL_NAME} (x86)")
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CUBICSDR_INSTALL_NAME} ${CPACK_PACKAGE_VERSION} (x86)")
set(CMAKE_CL_64 FALSE)
ENDIF(EX_PLATFORM EQUAL 64)
@ -801,6 +861,12 @@ IF (WIN32 AND BUILD_INSTALLER)
${CUBICSDR_FONTS}
DESTINATION fonts)
IF (CUBICSDR_HAS_HEADER_IMAGE)
INSTALL(FILES
${CUBICSDR_HEADER_IMAGE}
DESTINATION .)
ENDIF()
IF(USE_HAMLIB)
FOREACH(HAMLIB_DLL ${HAMLIB_DLLS})
message(STATUS "Copying Hamlib DLL: ${HAMLIB_DLL}")
@ -822,7 +888,7 @@ IF (WIN32 AND BUILD_INSTALLER)
ENDIF()
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_MODS: ${SOAPY_MODS}")
install(FILES ${SOAPY_BINS} DESTINATION .)
@ -830,9 +896,8 @@ IF (WIN32 AND BUILD_INSTALLER)
ENDIF(BUNDLE_SOAPY_MODS)
IF(MSVC AND EX_PLATFORM EQUAL 32)
install(FILES
${PROJECT_SOURCE_DIR}/external/msvc/${EX_PLATFORM_NAME}/libgcc_s_dw2-1.dll
DESTINATION .)
file(GLOB MSVC32_DEPS ${PROJECT_SOURCE_DIR}/external/msvc/${EX_PLATFORM_NAME}/*.dll)
install(FILES ${MSVC32_DEPS} DESTINATION .)
ENDIF(MSVC AND EX_PLATFORM EQUAL 32)
set(CPACK_PACKAGE_EXECUTABLES CubicSDR "CubicSDR")
@ -912,6 +977,13 @@ IF(UNIX AND NOT APPLE AND NOT BUILD_DEB)
${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"
DESTINATION share/applications)

View File

@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
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
Everyone is permitted to copy and distribute verbatim copies
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
the "copyright" line and a pointer to where the full notice is found.
CubicSDR
Copyright (C) 2014 Charles J. Cliffe
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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
@ -329,7 +329,7 @@ necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`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
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
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@ -48,4 +48,4 @@ Target Platforms:
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 "CubicSDR.h"
@ -28,7 +31,6 @@ long long DeviceConfig::getOffset() {
return offset.load();
}
void DeviceConfig::setSampleRate(long srate) {
sampleRate.store(srate);
}
@ -82,7 +84,7 @@ void DeviceConfig::save(DataNode *node) {
std::lock_guard < std::mutex > lock(busy_lock);
*node->newChild("id") = deviceId;
*node->newChild("name") = deviceName;
*node->newChild("ppm") = (int)ppm.load();
*node->newChild("ppm") = ppm.load();
*node->newChild("offset") = offset.load();
*node->newChild("sample_rate") = sampleRate.load();
*node->newChild("agc_mode") = agcMode.load()?1:0;
@ -289,7 +291,13 @@ AppConfig::AppConfig() : configName("") {
centerFreq.store(100000000);
waterfallLinesPerSec.store(DEFAULT_WATERFALL_LPS);
spectrumAvgSpeed.store(0.65f);
dbOffset.store(0);
modemPropsCollapsed.store(false);
mainSplit = -1;
visSplit = -1;
bookmarkSplit = 200;
bookmarksVisible.store(true);
#ifdef USE_HAMLIB
rigEnabled.store(false);
rigModel.store(1);
@ -425,6 +433,14 @@ float AppConfig::getSpectrumAvgSpeed() {
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) {
manualDevices = manuals;
}
@ -433,6 +449,39 @@ std::vector<SDRManualDef> AppConfig::getManualDevices() {
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) {
this->configName = configName;
}
@ -478,6 +527,12 @@ bool AppConfig::save() {
*window_node->newChild("waterfall_lps") = waterfallLinesPerSec.load();
*window_node->newChild("spectrum_avg") = spectrumAvgSpeed.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");
@ -556,12 +611,13 @@ bool AppConfig::load() {
}
if (cfg.rootNode()->hasAnother("window")) {
int x,y,w,h;
int max,tips,lpm,mpc;
int x = 0 ,y = 0 ,w = 0 ,h = 0;
int max = 0 ,tips = 0 ,lpm = 0 ,mpc = 0;
DataNode *win_node = cfg.rootNode()->getNext("window");
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("y")->element()->get(y);
win_node->getNext("w")->element()->get(w);
@ -628,6 +684,37 @@ bool AppConfig::load() {
win_node->getNext("modemprops_collapsed")->element()->get(mpc);
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")) {

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once
#include <wx/stdpaths.h>
@ -112,9 +115,25 @@ public:
void setSpectrumAvgSpeed(float avgSpeed);
float getSpectrumAvgSpeed();
void setDBOffset(int offset);
int getDBOffset();
void setManualDevices(std::vector<SDRManualDef> manuals);
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
int getRigModel();
void setRigModel(int rigModel);
@ -157,8 +176,10 @@ private:
std::atomic_llong snap;
std::atomic_llong centerFreq;
std::atomic_int waterfallLinesPerSec;
std::atomic<float> spectrumAvgSpeed;
std::atomic<float> spectrumAvgSpeed, mainSplit, visSplit, bookmarkSplit;
std::atomic_int dbOffset;
std::vector<SDRManualDef> manualDevices;
std::atomic_bool bookmarksVisible;
#if USE_HAMLIB
std::atomic_int rigModel, rigRate;
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
#include <wx/frame.h>
#include <wx/panel.h>
#include <wx/splitter.h>
#include <wx/sizer.h>
#include <wx/bitmap.h>
#include <wx/statbmp.h>
#include "PrimaryGLContext.h"
@ -19,6 +24,7 @@
#include "ModemProperties.h"
//#include "UITestCanvas.h"
#include "FrequencyDialog.h"
#include "BookmarkView.h"
#include <map>
@ -32,9 +38,11 @@
#define wxID_AGC_CONTROL 2009
#define wxID_SDR_START_STOP 2010
#define wxID_LOW_PERF 2011
#define wxID_SET_DB_OFFSET 2012
#define wxID_MAIN_SPLITTER 2050
#define wxID_VIS_SPLITTER 2051
#define wxID_BM_SPLITTER 2052
#define wxID_THEME_DEFAULT 2100
#define wxID_THEME_SHARP 2101
@ -44,7 +52,10 @@
#define wxID_THEME_HD 2105
#define wxID_THEME_RADAR 2106
#define wxID_DISPLAY_BOOKMARKS 2107
#define wxID_BANDWIDTH_BASE 2150
#define wxID_BANDWIDTH_MANUAL_DIALOG 2199
#define wxID_BANDWIDTH_MANUAL 2200
#define wxID_DISPLAY_BASE 2250
@ -73,6 +84,7 @@ class AppFrame: public wxFrame {
public:
AppFrame();
~AppFrame();
void OnThread(wxCommandEvent& event);
void OnEventInput(wxThreadEvent& event);
void initDeviceParams(SDRDeviceInfo *devInfo);
@ -101,8 +113,19 @@ public:
void setViewState(long long center_freq, int bandwidth);
void setViewState(long long center_freq);
long long getViewCenterFreq();
int getViewBandwidth();
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
bool canFocus();
#endif
@ -115,6 +138,10 @@ private:
void OnDoubleClickSash(wxSplitterEvent& event);
void OnUnSplit(wxSplitterEvent& event);
//manage Display menu actions, return true if the event has been
//treated.
bool actionOnMenuDisplay(wxCommandEvent& event);
ScopeCanvas *scopeCanvas;
SpectrumCanvas *spectrumCanvas;
WaterfallCanvas *waterfallCanvas;
@ -133,8 +160,9 @@ private:
ModeSelectorCanvas *demodMuteButton, *peakHoldButton, *soloModeButton, *deltaLockButton;
GainCanvas *gainCanvas;
wxSizerItem *gainSizerItem, *gainSpacerItem;
wxSplitterWindow *mainVisSplitter, *mainSplitter;
wxSplitterWindow *mainVisSplitter, *mainSplitter, *bookmarkSplitter;
wxBoxSizer *demodTray;
BookmarkView *bookmarkView;
DemodulatorInstance *activeDemodulator;
@ -147,16 +175,17 @@ private:
std::map<int, wxMenuItem *> directSamplingMenuItems;
wxMenuBar *menuBar;
wxMenu *sampleRateMenu;
wxMenu *displayMenu;
wxMenuItem *agcMenuItem;
wxMenuItem *iqSwapMenuItem;
wxMenuItem *lowPerfMenuItem;
wxMenu *settingsMenu;
wxMenu *sampleRateMenu = nullptr;
wxMenu *displayMenu = nullptr;
wxMenuItem *agcMenuItem = nullptr;
wxMenuItem *iqSwapMenuItem = nullptr;
wxMenuItem *lowPerfMenuItem = nullptr;
wxMenu *settingsMenu = nullptr;
SoapySDR::ArgInfoList settingArgs;
int settingsIdMax;
std::vector<long> sampleRates;
long manualSampleRate = -1;
std::string currentSessionFile;
@ -172,6 +201,9 @@ private:
bool lowPerfMode;
wxMenuItem *hideBookmarksItem;
bool saveDisabled;
#ifdef USE_HAMLIB
void enableRig();
void disableRig();
@ -184,6 +216,7 @@ private:
wxMenuItem *rigCenterLockMenuItem;
wxMenuItem *rigFollowModemMenuItem;
wxMenuItem *sdrIFMenuItem;
std::map<int, wxMenuItem *> rigSerialMenuItems;
std::map<int, wxMenuItem *> rigModelMenuItems;
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
#include "CubicSDRDefs.h"
@ -27,6 +30,9 @@ IMPLEMENT_APP(CubicSDR)
#include <fstream>
#include <clocale>
#include "ActionDialog.h"
//#ifdef ENABLE_DIGITAL_LAB
//// console output buffer for windows
//#ifdef _WINDOWS
@ -133,6 +139,63 @@ long long strToFrequency(std::string freqStr) {
}
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);
@ -207,9 +270,7 @@ bool CubicSDR::OnInit() {
Modem::addModemFactory(ModemASK::factory, "ASK", 200000);
Modem::addModemFactory(ModemBPSK::factory, "BPSK", 200000);
Modem::addModemFactory(ModemDPSK::factory, "DPSK", 200000);
#if ENABLE_LIQUID_EXPERIMENTAL
Modem::addModemFactory(ModemFSK::factory, "FSK", 19200);
#endif
Modem::addModemFactory(ModemGMSK::factory, "GMSK", 19200);
Modem::addModemFactory(ModemOOK::factory, "OOK", 200000);
Modem::addModemFactory(ModemPSK::factory, "PSK", 200000);
@ -228,26 +289,16 @@ bool CubicSDR::OnInit() {
// Visual Data
spectrumVisualThread = new SpectrumVisualDataThread();
demodVisualThread = new SpectrumVisualDataThread();
pipeIQVisualData = new DemodulatorThreadInputQueue();
pipeIQVisualData->set_max_num_items(1);
pipeDemodIQVisualData = new DemodulatorThreadInputQueue();
pipeDemodIQVisualData->set_max_num_items(1);
pipeWaterfallIQVisualData = new DemodulatorThreadInputQueue();
pipeWaterfallIQVisualData->set_max_num_items(128);
getDemodSpectrumProcessor()->setInput(pipeDemodIQVisualData);
getSpectrumProcessor()->setInput(pipeIQVisualData);
getSpectrumProcessor()->setHideDC(true);
pipeAudioVisualData = new DemodulatorThreadOutputQueue();
pipeAudioVisualData->set_max_num_items(1);
scopeProcessor.setInput(pipeAudioVisualData);
// I/Q Data
pipeSDRIQData = new SDRThreadIQDataQueue();
pipeSDRIQData->set_max_num_items(100);
@ -260,11 +311,42 @@ bool CubicSDR::OnInit() {
sdrPostThread->setOutputQueue("IQVisualDataOutput", pipeIQVisualData);
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);
if (demodVisualThread != nullptr) {
t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread);
}
//Start SDRPostThread last.
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
sdrEnum = new SDREnumerator();
@ -283,6 +365,19 @@ bool CubicSDR::OnInit() {
// pthread_setschedparam(pthread_self(), main_policy, &main_param);
//#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;
}
@ -313,16 +408,20 @@ int CubicSDR::OnExit() {
std::cout << "Terminating Visual Processor threads.." << std::endl;
spectrumVisualThread->terminate();
if (demodVisualThread) {
demodVisualThread->terminate();
}
//Wait nicely
sdrPostThread->isTerminated(1000);
spectrumVisualThread->isTerminated(1000);
if (demodVisualThread) {
demodVisualThread->isTerminated(1000);
}
//Then join the thread themselves
t_PostSDR->join();
t_DemodVisual->join();
if (t_DemodVisual) t_DemodVisual->join();
t_SpectrumVisual->join();
//Now only we can delete
@ -491,8 +590,10 @@ void CubicSDR::setFrequency(long long freq) {
getSpectrumProcessor()->setPeakHold(getSpectrumProcessor()->getPeakHold());
//make the peak hold act on the current dmod also, like a zoomed-in version.
if (getDemodSpectrumProcessor()) {
getDemodSpectrumProcessor()->setPeakHold(getSpectrumProcessor()->getPeakHold());
}
}
long long CubicSDR::getOffset() {
return offset;
@ -534,15 +635,15 @@ void CubicSDR::setSampleRate(long long rate_in) {
setFrequency(frequency);
if (rate_in <= CHANNELIZER_RATE_MAX / 8) {
appframe->setMainWaterfallFFTSize(512);
appframe->setMainWaterfallFFTSize(DEFAULT_FFT_SIZE / 4);
appframe->getWaterfallDataThread()->getProcessor()->setHideDC(false);
spectrumVisualThread->getProcessor()->setHideDC(false);
} else if (rate_in <= CHANNELIZER_RATE_MAX) {
appframe->setMainWaterfallFFTSize(1024);
appframe->setMainWaterfallFFTSize(DEFAULT_FFT_SIZE / 2);
appframe->getWaterfallDataThread()->getProcessor()->setHideDC(false);
spectrumVisualThread->getProcessor()->setHideDC(false);
} else if (rate_in > CHANNELIZER_RATE_MAX) {
appframe->setMainWaterfallFFTSize(2048);
appframe->setMainWaterfallFFTSize(DEFAULT_FFT_SIZE);
appframe->getWaterfallDataThread()->getProcessor()->setHideDC(true);
spectrumVisualThread->getProcessor()->setHideDC(true);
}
@ -652,7 +753,11 @@ SpectrumVisualProcessor *CubicSDR::getSpectrumProcessor() {
}
SpectrumVisualProcessor *CubicSDR::getDemodSpectrumProcessor() {
if (demodVisualThread) {
return demodVisualThread->getProcessor();
} else {
return nullptr;
}
}
DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() {
@ -671,6 +776,10 @@ DemodulatorMgr &CubicSDR::getDemodMgr() {
return demodMgr;
}
BookmarkMgr &CubicSDR::getBookmarkMgr() {
return bookmarkMgr;
}
SDRPostThread *CubicSDR::getSDRPostThread() {
return sdrPostThread;
}
@ -704,6 +813,7 @@ void CubicSDR::removeDemodulator(DemodulatorInstance *demod) {
}
demod->setActive(false);
sdrPostThread->removeDemodulator(demod);
wxGetApp().getAppFrame()->notifyUpdateModemProperties();
}
std::vector<SDRDeviceInfo*>* CubicSDR::getDevices() {
@ -749,6 +859,7 @@ void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetM
switch (targetMode) {
case FrequencyDialog::FDIALOG_TARGET_DEFAULT:
case FrequencyDialog::FDIALOG_TARGET_FREQ:
title = demodMgr.getActiveDemodulator()?demodTitle:freqTitle;
break;
case FrequencyDialog::FDIALOG_TARGET_BANDWIDTH:
@ -806,6 +917,10 @@ bool CubicSDR::areDevicesReady() {
return devicesReady.load();
}
void CubicSDR::notifyMainUIOfDeviceChange() {
appframe->notifyDeviceChanged();
}
bool CubicSDR::areDevicesEnumerating() {
return !sdrEnum->isTerminated();
}

View File

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

View File

@ -1,6 +1,9 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#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
#ifdef _WIN32
@ -28,13 +31,31 @@ const char filePathSeparator =
#define BUF_SIZE (16384*6)
#define DEFAULT_SAMPLE_RATE 2500000
//
#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_BW 200000
#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 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 "wx/clipbrd.h"
@ -57,7 +60,7 @@ void DemodLabelDialog::OnChar(wxKeyEvent& event) {
else {
activeDemod->setDemodulatorUserLabel(L"");
}
wxGetApp().getBookmarkMgr().updateActiveList();
Close();
break;
case WXK_ESCAPE:

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once
#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 "wx/clipbrd.h"

View File

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

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once
#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> 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
std::atomic_bool stopping;
Timer gTimer;
@ -227,4 +233,5 @@ private:
//true when the thread has really ended, i.e run() from threadMain() has returned.
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 "CubicSDR.h"
@ -30,26 +33,10 @@ void ModemProperties::OnShow(wxShowEvent & /* event */) {
}
void ModemProperties::updateTheme() {
wxColour bgColor(
(unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.r * 255.0),
(unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.g * 255.0),
(unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.b * 255.0));
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));
wxColour bgColor(ThemeMgr::mgr.currentTheme->generalBackground);
wxColour textColor(ThemeMgr::mgr.currentTheme->text);
wxColour btn(ThemeMgr::mgr.currentTheme->button);
wxColour btnHl(ThemeMgr::mgr.currentTheme->buttonHighlight);
m_propertyGrid->SetEmptySpaceColour(bgColor);
m_propertyGrid->SetCellBackgroundColour(bgColor);
@ -122,10 +109,8 @@ void ModemProperties::initProperties(ModemArgInfoList newArgs, DemodulatorInstan
m_propertyGrid->Clear();
if (!demodInstance) {
Hide();
m_propertyGrid->Append(new wxPropertyCategory("Modem Settings"));
return;
} else {
Show();
}
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
#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 "CubicSDRDefs.h"
#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;
}
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;

View File

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

View File

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

View File

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

View File

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

View File

@ -1,15 +1,22 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include <DemodulatorMgr.h>
#include <sstream>
#include <algorithm>
#include "CubicSDR.h"
#include <string>
#include <sstream>
#include <algorithm>
#include "DemodulatorMgr.h"
#include "CubicSDR.h"
#if USE_HAMLIB
#include "RigThread.h"
#endif
#include "DataTree.h"
bool demodFreqCompare (DemodulatorInstance *i, DemodulatorInstance *j) { return (i->getFrequency()<j->getFrequency()); }
bool inactiveCompare (DemodulatorInstance *i, DemodulatorInstance *j) { return (i->isActive()<j->isActive()); }
@ -131,6 +138,8 @@ DemodulatorInstance *DemodulatorMgr::getFirstDemodulator() {
void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
wxGetApp().getBookmarkMgr().addRecent(demod);
std::vector<DemodulatorInstance *>::iterator i;
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);
}
#endif
wxGetApp().getBookmarkMgr().updateActiveList();
} else {
std::lock_guard < std::recursive_mutex > lock(demods_busy);
garbageCollect();
@ -368,3 +378,138 @@ ModemSettings DemodulatorMgr::getLastModemSettings(std::string modemType) {
void DemodulatorMgr::setLastModemSettings(std::string modemType, ModemSettings 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
#include <vector>
@ -6,6 +9,8 @@
#include "DemodulatorInstance.h"
class DataNode;
class DemodulatorMgr {
public:
DemodulatorMgr();
@ -54,6 +59,10 @@ public:
void updateLastState();
void setOutputDevices(std::map<int,RtAudio::DeviceInfo> devs);
void saveInstance(DataNode *node, DemodulatorInstance *inst);
DemodulatorInstance *loadInstance(DataNode *node);
private:
void garbageCollect();
@ -79,4 +88,5 @@ private:
std::recursive_mutex demods_busy;
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 <vector>

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once
#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 "CubicSDR.h"
#include <iomanip>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemAnalog.h"
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) {
return MIN_BANDWIDTH;
}
return sampleRate;
return (int)sampleRate;
}
ModemKit *ModemAnalog::buildKit(long long sampleRate, int audioSampleRate) {
@ -24,7 +27,7 @@ ModemKit *ModemAnalog::buildKit(long long sampleRate, int audioSampleRate) {
akit->sampleRate = sampleRate;
akit->audioSampleRate = audioSampleRate;
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;
}
@ -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->sampleRate = akit->audioSampleRate;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemFM.h"
ModemFM::ModemFM() : ModemAnalog() {
@ -30,7 +33,7 @@ void ModemFM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *au
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);
}

View File

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

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemFMStereo.h"
ModemFMStereo::ModemFMStereo() {
@ -27,7 +30,7 @@ int ModemFMStereo::checkSampleRate(long long sampleRate, int /* audioSampleRate
} else if (sampleRate < 1500) {
return 1500;
} 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]
kit->audioResampler = msresamp_rrrf_create(kit->audioResampleRatio, As);
kit->stereoResampler = msresamp_rrrf_create(kit->audioResampleRatio, As);
kit->audioResampler = msresamp_rrrf_create((float)kit->audioResampleRatio, As);
kit->stereoResampler = msresamp_rrrf_create((float)kit->audioResampleRatio, As);
// Stereo filters / shifters
double firStereoCutoff = 16000.0 / double(audioSampleRate);
float firStereoCutoff = 16000.0f / float(audioSampleRate);
// filter transition
float ft = 1000.0f / double(audioSampleRate);
float ft = 1000.0f / float(audioSampleRate);
// fractional timing offset
float mu = 0.0f;
@ -139,13 +142,13 @@ ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) {
kit->demph = _demph;
if (_demph) {
float f = (1.0f / (2.0f * M_PI * double(_demph) * 1e-6));
float t = 1.0f / (2.0f * M_PI * f);
t = 1.0f / (2.0f * float(audioSampleRate) * tan(1.0f / (2.0f * float(audioSampleRate) * t)));
double f = (1.0 / (2.0 * M_PI * double(_demph) * 1e-6));
double t = 1.0 / (2.0 * M_PI * f);
t = 1.0 / (2.0 * double(audioSampleRate) * tan(1.0 / (2.0 * double(audioSampleRate) * t)));
float tb = (1.0f + 2.0f * t * float(audioSampleRate));
float b_demph[2] = { 1.0f / tb, 1.0f / tb };
float a_demph[2] = { 1.0f, (1.0f - 2.0f * t * float(audioSampleRate)) / tb };
double tb = (1.0 + 2.0 * t * double(audioSampleRate));
float b_demph[2] = { (float)(1.0 / tb), (float)(1.0 / 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->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;
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.capacity() < audio_out_size) {
@ -199,7 +202,7 @@ void ModemFMStereo::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInp
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.capacity() < bufSize) {
@ -249,7 +252,7 @@ void ModemFMStereo::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInp
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;
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
#include "Modem.h"

View File

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

View File

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

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemLSB.h"
ModemLSB::ModemLSB() : ModemAnalog() {
@ -9,7 +12,7 @@ ModemLSB::ModemLSB() : ModemAnalog() {
ssbFilt = iirfilt_crcf_create_lowpass(6, 0.25);
#endif
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);
useSignalOutput(true);
}
@ -38,9 +41,9 @@ int ModemLSB::checkSampleRate(long long sampleRate, int /* audioSampleRate */) {
return MIN_BANDWIDTH;
}
if (sampleRate % 2 == 0) {
return sampleRate;
return (int)sampleRate;
}
return sampleRate+1;
return (int)(sampleRate+1);
}
int ModemLSB::getDefaultSampleRate() {

View File

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

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemNBFM.h"
ModemNBFM::ModemNBFM() : ModemAnalog() {
@ -30,7 +33,7 @@ void ModemNBFM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *
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);
}

View File

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

View File

@ -1,3 +1,6 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#include "ModemUSB.h"
ModemUSB::ModemUSB() : ModemAnalog() {
@ -9,7 +12,7 @@ ModemUSB::ModemUSB() : ModemAnalog() {
ssbFilt = iirfilt_crcf_create_lowpass(6, 0.25);
#endif
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);
useSignalOutput(true);
}
@ -38,9 +41,9 @@ int ModemUSB::checkSampleRate(long long sampleRate, int /* audioSampleRate */) {
return MIN_BANDWIDTH;
}
if (sampleRate % 2 == 0) {
return sampleRate;
return (int)sampleRate;
}
return sampleRate+1;
return (int)(sampleRate+1);
}
int ModemUSB::getDefaultSampleRate() {

View File

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

View File

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

View File

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

View File

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

View File

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

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