Rename fdmdv2 to freedv.
commit
a362d8ebe7
|
@ -0,0 +1,487 @@
|
|||
#
|
||||
# FreeDV - HF Digital Voice for Radio Amateurs
|
||||
#
|
||||
# CMake configuration contributed by Richard Shaw (KF5OIM)
|
||||
# Please report questions, comments, problems, or patches to the freetel
|
||||
# mailing list: https://lists.sourceforge.net/lists/listinfo/freetel-codec2
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
# Prevent in-source builds to protect automake/autoconf config.
|
||||
# If an in-source build is attempted, you will still need to clean up a few
|
||||
# files manually.
|
||||
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
||||
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
||||
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||
message(FATAL_ERROR "In-source builds in ${CMAKE_BINARY_DIR} are not "
|
||||
"allowed, please remove ./CMakeCache.txt and ./CMakeFiles/, create a "
|
||||
"separate build directory and run cmake from there.")
|
||||
endif("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||
|
||||
# Set local module path.
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
project(FreeDV)
|
||||
|
||||
#
|
||||
# Set FreeDV version and generate src/version.h
|
||||
#
|
||||
set(FREEDV_VERSION_MAJOR 0)
|
||||
set(FREEDV_VERSION_MINOR 99)
|
||||
set(FREEDV_VERSION_PATCH FALSE)
|
||||
set(FREEDV_VERSION ${FREEDV_VERSION_MAJOR}.${FREEDV_VERSION_MINOR})
|
||||
if(FREEDV_VERSION_PATCH)
|
||||
set(FREEDV_VERSION ${FREEDV_VERSION}.${FREEDV_VERSION_PATCH})
|
||||
endif()
|
||||
set(FREEDV_VERSION_SUFFIX "Beta")
|
||||
if(FREEDV_VERSION_SUFFIX)
|
||||
set(FREEDV_VERSION_STRING "${FREEDV_VERSION} ${FREEDV_VERSION_SUFFIX}")
|
||||
endif()
|
||||
message(STATUS "FreeDV version: ${FREEDV_VERSION_STRING}")
|
||||
configure_file(cmake/version.h.in src/version.h @ONLY)
|
||||
|
||||
# Set default build type
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
message(STATUS "Build type not specified, defaulting to ${CMAKE_BUILD_TYPE}")
|
||||
endif(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
|
||||
# Work around for not using a svn working copy.
|
||||
add_definitions(-D_NO_AUTOTOOLS_)
|
||||
find_program(SVNVERSION_PATH svnversion)
|
||||
if(SVNVERSION_PATH)
|
||||
execute_process(COMMAND ${SVNVERSION_PATH} .
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
RESULT_VARIABLE SVN_REVISION_RESULT
|
||||
OUTPUT_VARIABLE SVN_CURRENT_REVISION
|
||||
ERROR_QUIET
|
||||
)
|
||||
else()
|
||||
set(SVN_REVISION_RESULT 1)
|
||||
endif()
|
||||
if(SVN_REVISION_RESULT EQUAL 0)
|
||||
string(STRIP ${SVN_CURRENT_REVISION} SVN_REVISION)
|
||||
add_definitions(-DSVN_REVISION="${SVN_REVISION}")
|
||||
else()
|
||||
add_definitions(-DSVN_REVISION="Unversioned directory")
|
||||
endif()
|
||||
|
||||
|
||||
# Set default build flags.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
|
||||
#
|
||||
# Setup cmake options
|
||||
#
|
||||
set(CMAKE_VERBOSE_MAKEFILE TRUE CACHE BOOL "Verbose makefile.")
|
||||
set(USE_STATIC_DEPS FALSE CACHE BOOL
|
||||
"Download and build static libraries instead of system libraries.")
|
||||
set(USE_STATIC_PORTAUDIO FALSE CACHE BOOL
|
||||
"Download and build static portaudio instead of the system library.")
|
||||
set(USE_STATIC_SNDFILE FALSE CACHE BOOL
|
||||
"Download and build static sndfile instead of the system library.")
|
||||
set(USE_STATIC_SAMPLERATE FALSE CACHE BOOL
|
||||
"Download and build static samplerate instead of the system library.")
|
||||
set(USE_STATIC_SOX FALSE CACHE BOOL
|
||||
"Download and build static sox instead of the system library.")
|
||||
set(USE_STATIC_CODEC2 TRUE CACHE BOOL
|
||||
"Download and build static codec2 instead of the system library.")
|
||||
set(USE_STATIC_SPEEXDSP TRUE CACHE BOOL
|
||||
"Download and build static speex instead of the system library.")
|
||||
set(BOOTSTRAP_WXWIDGETS FALSE CACHE BOOL
|
||||
"Download and build static wxWidgets instead of the system library.")
|
||||
|
||||
if(USE_STATIC_DEPS)
|
||||
set(USE_STATIC_PORTAUDIO TRUE FORCE)
|
||||
set(USE_STATIC_SNDFILE TRUE FORCE)
|
||||
set(USE_STATIC_SAMPLERATE TRUE FORCE)
|
||||
set(USE_STATIC_SOX TRUE FORCE)
|
||||
set(USE_STATIC_CODEC2 TRUE FORCE)
|
||||
endif(USE_STATIC_DEPS)
|
||||
|
||||
#
|
||||
# Pull in external wxWidgets target if performing static build.
|
||||
#
|
||||
if(BOOTSTRAP_WXWIDGETS)
|
||||
message(STATUS "Adding wxWidgets build target...")
|
||||
include(cmake/BuildWxWidgets.cmake)
|
||||
endif(BOOTSTRAP_WXWIDGETS)
|
||||
|
||||
#
|
||||
# Perform bootstrap build of wxWidgets
|
||||
#
|
||||
if(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
|
||||
message(STATUS "Will perform bootstrap build of wxWidgets.
|
||||
After make step completes, re-run cmake and make again to perform FreeDV build.")
|
||||
#
|
||||
# Continue normal build if not bootstrapping wxWidgets or is already built.
|
||||
#
|
||||
else(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
|
||||
|
||||
|
||||
#
|
||||
# Various hacks and work arounds for building under MinGW.
|
||||
#
|
||||
if(MINGW)
|
||||
message(STATUS "System is MinGW.")
|
||||
# Setup HOST variable.
|
||||
include(cmake/MinGW.cmake)
|
||||
# This sets up the exe icon for windows under mingw.
|
||||
set(RES_FILES "")
|
||||
set(RES_FILES "${CMAKE_SOURCE_DIR}/contrib/freedv.rc")
|
||||
set(CMAKE_RC_COMPILER_INIT windres)
|
||||
enable_language(RC)
|
||||
set(CMAKE_RC_COMPILE_OBJECT
|
||||
"<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
|
||||
# These are DLOPEN'ed and can't be automatically pulled in by dependency.
|
||||
foreach(RUNTIME
|
||||
hamlib-adat.dll
|
||||
hamlib-alinco.dll
|
||||
hamlib-amsat.dll
|
||||
hamlib-aor.dll
|
||||
hamlib-ars.dll
|
||||
hamlib-celestron.dll
|
||||
hamlib-drake.dll
|
||||
hamlib-dummy.dll
|
||||
hamlib-easycomm.dll
|
||||
hamlib-flexradio.dll
|
||||
hamlib-fodtrack.dll
|
||||
hamlib-gs232a.dll
|
||||
hamlib-heathkit.dll
|
||||
hamlib-icom.dll
|
||||
hamlib-jrc.dll
|
||||
hamlib-kachina.dll
|
||||
hamlib-kenwood.dll
|
||||
hamlib-kit.dll
|
||||
hamlib-lowe.dll
|
||||
hamlib-m2.dll
|
||||
hamlib-pcr.dll
|
||||
hamlib-prm80.dll
|
||||
hamlib-racal.dll
|
||||
hamlib-rft.dll
|
||||
hamlib-rotorez.dll
|
||||
hamlib-rs.dll
|
||||
hamlib-sartek.dll
|
||||
hamlib-skanti.dll
|
||||
hamlib-spid.dll
|
||||
hamlib-tapr.dll
|
||||
hamlib-tentec.dll
|
||||
hamlib-ts7400.dll
|
||||
hamlib-tuner.dll
|
||||
hamlib-uniden.dll
|
||||
hamlib-winradio.dll
|
||||
hamlib-wj.dll
|
||||
hamlib-yaesu.dll)
|
||||
message(STATUS "Checking for ${RUNTIME}")
|
||||
find_library(${RUNTIME}_LIB ${RUNTIME}
|
||||
PATH_SUFFIXES hamlib)
|
||||
message(STATUS "runtime found: ${${RUNTIME}_LIB}")
|
||||
list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${${RUNTIME}_LIB})
|
||||
endforeach()
|
||||
include(InstallRequiredSystemLibraries)
|
||||
endif(MINGW)
|
||||
|
||||
# Math library is automatic on MinGW
|
||||
if(UNIX)
|
||||
set(CMAKE_REQUIRED_INCLUDES math.h)
|
||||
set(CMAKE_REQUIRED_LIBRARIES m)
|
||||
endif(UNIX)
|
||||
|
||||
# Find some standard headers and functions.
|
||||
include(CheckIncludeFiles)
|
||||
check_include_files("limits.h" HAVE_LIMITS_H)
|
||||
check_include_files("stddef.h" HAVE_STDDEF_H)
|
||||
check_include_files("stdlib.h" HAVE_STDLIB_H)
|
||||
check_include_files("string.h" HAVE_STRING_H)
|
||||
|
||||
include(CheckTypeSize)
|
||||
check_type_size("int" SIZEOF_INT)
|
||||
|
||||
include(CheckFunctionExists)
|
||||
check_function_exists(floor HAVE_FLOOR)
|
||||
check_function_exists(memset HAVE_MEMSET)
|
||||
check_function_exists(pow HAVE_POW)
|
||||
check_function_exists(sqrt HAVE_SQRT)
|
||||
|
||||
# fdmdv2_main.h requires patching to find config.h as it current looks in the
|
||||
# source directory and the generated file goes in the binary directory.
|
||||
configure_file ("${PROJECT_SOURCE_DIR}/cmake/config.h.in"
|
||||
"${PROJECT_BINARY_DIR}/config.h" )
|
||||
include_directories(${PROJECT_BINARY_DIR})
|
||||
add_definitions(-DHAVE_CONFIG_H)
|
||||
|
||||
# Pthread Library
|
||||
find_package(Threads REQUIRED)
|
||||
message(STATUS "Threads library flags: ${CMAKE_THREAD_LIBS_INIT}")
|
||||
|
||||
#
|
||||
# Find codec2
|
||||
#
|
||||
if(NOT USE_STATIC_CODEC2)
|
||||
message(STATUS "Looking for codec2...")
|
||||
find_package(codec2 CONFIG QUIET)
|
||||
if(codec2_FOUND)
|
||||
get_target_property(CODEC2_LIBRARY codec2 LOCATION)
|
||||
message(STATUS " codec2 library: ${CODEC2_LIBRARY}")
|
||||
message(STATUS " codec2 headers: ${codec2_INCLUDE_DIRS}")
|
||||
else()
|
||||
# Try to find manually
|
||||
find_path(CODEC2_INCLUDE_DIRS codec2.h
|
||||
PATH_SUFFIXES codec2)
|
||||
find_library(CODEC2_LIBRARY NAMES codec2)
|
||||
if(CODEC2_LIBRARY AND CODEC2_INCLUDE_DIRS)
|
||||
message(STATUS " codec2 library: ${CODEC2_LIBRARY}")
|
||||
message(STATUS " codec2 headers: ${CODEC2_INCLUDE_DIRS}")
|
||||
list(APPEND FREEDV_LINK_LIBS ${CODEC2_LIBRARY})
|
||||
include_directories(${CODEC2_INCLUDE_DIRS})
|
||||
else()
|
||||
message(FATAL_ERROR "codec2 library not found.
|
||||
Linux:
|
||||
Codec2 may not be in your distribution so build yourself or use the cmake option to build statically into FreeDV.
|
||||
Windws:
|
||||
It's easiest to use the cmake option: USE_STATIC_CODEC2"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
else(NOT USE_STATIC_CODEC2)
|
||||
message(STATUS "Will attempt static build of codec2.")
|
||||
include(cmake/BuildCodec2.cmake)
|
||||
endif(NOT USE_STATIC_CODEC2)
|
||||
|
||||
#
|
||||
# Find or build portaudio Library
|
||||
#
|
||||
if(NOT USE_STATIC_PORTAUDIO)
|
||||
message(STATUS "Looking for portaudio...")
|
||||
find_package(Portaudio REQUIRED)
|
||||
if(PORTAUDIO_FOUND)
|
||||
message(STATUS " portaudio library: ${PORTAUDIO_LIBRARIES}")
|
||||
message(STATUS " portaudio headers: ${PORTAUDIO_INCLUDE_DIRS}")
|
||||
list(APPEND FREEDV_LINK_LIBS ${PORTAUDIO_LIBRARIES})
|
||||
include_directories(${PORTAUDIO_INCLUDE_DIRS})
|
||||
else()
|
||||
message(FATAL_ERROR "portaudio library not found.
|
||||
On Linux systems try installing:
|
||||
portaudio-devel (RPM based systems)
|
||||
libportaudio-dev (DEB based systems)
|
||||
On Windows it's easiest to use the cmake option: USE_STATIC_PORTAUDIO"
|
||||
)
|
||||
endif()
|
||||
if(NOT ${PORTAUDIO_VERSION} EQUAL 19)
|
||||
message(WARNING "Portaudio versions other than 19 are known to have issues. You have been warned!")
|
||||
endif()
|
||||
else(NOT USE_STATIC_PORTAUDIO)
|
||||
message(STATUS "Will attempt static build of portaudio.")
|
||||
include(cmake/BuildPortaudio.cmake)
|
||||
endif(NOT USE_STATIC_PORTAUDIO)
|
||||
|
||||
#
|
||||
# Hamlib library
|
||||
#
|
||||
message(STATUS "Looking for hamlib...")
|
||||
find_path(HAMLIB_INCLUDE_DIR hamlib/rig.h)
|
||||
find_library(HAMLIB_LIBRARY hamlib)
|
||||
message(STATUS "Hamlib library: ${HAMLIB_LIBRARY}")
|
||||
message(STATUS "Hamlib headers: ${HAMLIB_INCLUDE_DIR}")
|
||||
if(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
|
||||
message(STATUS "Hamlib library found.")
|
||||
include_directories(${HAMLIB_INCLUDE_DIR})
|
||||
list(APPEND FREEDV_LINK_LIBS ${HAMLIB_LIBRARY})
|
||||
else(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
|
||||
message(FATAL_ERROR "hamlib not found.
|
||||
On Linux systems try installing:
|
||||
hamlib-devel (RPM based systems)
|
||||
libhamlib-dev (DEB based systems)"
|
||||
)
|
||||
endif(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
|
||||
|
||||
|
||||
#
|
||||
# Samplerate Library
|
||||
#
|
||||
if(NOT USE_STATIC_SAMPLERATE)
|
||||
message(STATUS "Looking for samplerate...")
|
||||
find_library(LIBSAMPLERATE samplerate)
|
||||
find_path(LIBSAMPLERATE_INCLUDE_DIR samplerate.h)
|
||||
message(STATUS " samplerate library: ${LIBSAMPLERATE}")
|
||||
message(STATUS " samplerate headers: ${LIBSAMPLERATE_INCLUDE_DIR}")
|
||||
if(LIBSAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
|
||||
list(APPEND FREEDV_LINK_LIBS ${LIBSAMPLERATE})
|
||||
include_directories(${LIBSAMPLERATE_INCLUDE_DIR})
|
||||
else(LIBSTAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
|
||||
message(FATAL_ERROR "samplerate library not found.
|
||||
On Linux systems try installing:
|
||||
samplerate-devel (RPM based systems)
|
||||
libsamplerate-dev (DEB based systems)
|
||||
On Windows it's easiest to use the cmake option: USE_STATIC_SAMPLERATE"
|
||||
)
|
||||
endif(LIBSAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
|
||||
else(NOT USE_STATIC_SAMPLERATE)
|
||||
message(STATUS "Will attempt static build of samplerate.")
|
||||
include(cmake/BuildSamplerate.cmake)
|
||||
endif(NOT USE_STATIC_SAMPLERATE)
|
||||
|
||||
#
|
||||
# Find sox library
|
||||
#
|
||||
if(NOT USE_STATIC_SOX)
|
||||
message(STATUS "Looking for sox...")
|
||||
find_library(LIBSOX_LIBRARY sox)
|
||||
find_path(LIBSOX_INCLUDE_DIR NAMES sox/sox.h sox.h)
|
||||
message(STATUS " sox library: ${LIBSOX_LIBRARY}")
|
||||
message(STATUS " sox headers: ${LIBSOX_INCLUDE_DIR}")
|
||||
if(LIBSOX_LIBRARY AND LIBSOX_INCLUDE_DIR)
|
||||
list(APPEND FREEDV_LINK_LIBS ${LIBSOX_LIBRARY})
|
||||
include_directories(${LIBSOX_INCLUDE_DIR})
|
||||
else(LIBSOX_LIBRARY AND LIBSOX_INCLUDE_DIR)
|
||||
message(FATAL_ERROR "sox library not found.
|
||||
On Linux systems try installing:
|
||||
sox-devel (RPM based systems)
|
||||
libsox-dev (DEB based systems)
|
||||
On Windows it's easiest to use the cmake option: USE_STATIC_SOX"
|
||||
)
|
||||
endif(LIBSOX_LIBRARY AND LIBSOX_INCLUDE_DIR)
|
||||
else(NOT USE_STATIC_SOX)
|
||||
message(STATUS "Will attempt static build of sox.")
|
||||
include(cmake/BuildSox.cmake)
|
||||
endif(NOT USE_STATIC_SOX)
|
||||
|
||||
#
|
||||
# sndfile Library
|
||||
#
|
||||
if(NOT USE_STATIC_SNDFILE)
|
||||
message(STATUS "Looking for sndfile...")
|
||||
find_library(LIBSNDFILE sndfile)
|
||||
find_path(LIBSNDFILE_INCLUDE_DIR sndfile.h)
|
||||
message(STATUS " sndfile library: ${LIBSNDFILE}")
|
||||
message(STATUS " sndfile headers: ${LIBSNDFILE_INCLUDE_DIR}")
|
||||
if(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
|
||||
list(APPEND FREEDV_LINK_LIBS ${LIBSNDFILE})
|
||||
else(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
|
||||
message(FATAL_ERROR "sndfile library not found.
|
||||
On Linux systems try installing:
|
||||
libsndfile-devel (RPM based systems)
|
||||
libsndfile-dev (DEB based systems)
|
||||
On Windows it's easiest to use the cmake option: USE_STATIC_SNDFILE"
|
||||
)
|
||||
endif(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
|
||||
else(NOT USE_STATIC_SNDFILE)
|
||||
message(STATUS "Will attempt static build of sndfile.")
|
||||
include(cmake/BuildSndfile.cmake)
|
||||
endif(NOT USE_STATIC_SNDFILE)
|
||||
|
||||
#
|
||||
# Find wxWidgets
|
||||
#
|
||||
if(NOT BOOTSTRAP_WXWIDGETS)
|
||||
set(WXCONFIG "" CACHE FILEPATH "Location of wx-config binary.")
|
||||
set(WXRC "" CACHE FILEPATH "Location of wxrc binary.")
|
||||
endif(NOT BOOTSTRAP_WXWIDGETS)
|
||||
#if(BOOTSTRAP_WXWIDGETS)
|
||||
# set(WXCONFIG "${CMAKE_BINARY_DIR}/external/dist/bin/wx-config")
|
||||
# set(WXRC "${CMAKE_BINARY_DIR}/external/dist/bin/wxrc")
|
||||
# list(APPEND FREEDV_STATIC_DEPS wxWidgets)
|
||||
#endif(BOOTSTRAP_WXWIDGETS)
|
||||
message(STATUS "Looking for wxWidgets...")
|
||||
if(WXCONFIG)
|
||||
message(STATUS "wx-config: ${WXCONFIG}")
|
||||
set(wxWidgets_CONFIG_EXECUTABLE ${WXCONFIG})
|
||||
endif(WXCONFIG)
|
||||
if(WXRC)
|
||||
message(STATUS "wxrc: ${WXRC}")
|
||||
set(wxWidgets_wxrc_EXECUTABLE ${WXRC})
|
||||
endif(WXRC)
|
||||
set(WX_VERSION_MIN 3.0.0)
|
||||
find_package(wxWidgets REQUIRED core base aui html net adv)
|
||||
execute_process(COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}" --version
|
||||
OUTPUT_VARIABLE WX_VERSION)
|
||||
string(STRIP ${WX_VERSION} WX_VERSION)
|
||||
if(WX_VERSION VERSION_EQUAL ${WX_VERSION_MIN}
|
||||
OR WX_VERSION VERSION_GREATER ${WX_VERSION_MIN})
|
||||
message(STATUS "wxWidgets version: ${WX_VERSION}")
|
||||
else()
|
||||
message(FATAL_ERROR "wxWidgets must be installed on your system.
|
||||
Please check that wx-config is in path, the directory
|
||||
where wxWidgets libraries are installed (returned by
|
||||
'wx-config --libs' or 'wx-config --static --libs' command)
|
||||
is in LD_LIBRARY_PATH or equivalent variable and
|
||||
wxWidgets version is ${WX_VERSION_MIN} or above.")
|
||||
endif()
|
||||
if(wxWidgets_FOUND)
|
||||
include("${wxWidgets_USE_FILE}")
|
||||
list(APPEND FREEDV_LINK_LIBS ${wxWidgets_LIBRARIES})
|
||||
endif(wxWidgets_FOUND)
|
||||
|
||||
#
|
||||
# Find speex library
|
||||
#
|
||||
if(NOT USE_STATIC_SPEEXDSP)
|
||||
message(STATUS "Looking for Speex DSP library.")
|
||||
find_path(SPEEXDSP_INCLUDE_DIR speex/speex.h)
|
||||
find_library(SPEEXDSP_LIBRARY speexdsp)
|
||||
message(STATUS " Speex DSP headers: ${SPEEXDSP_INCLUDE_DIR}")
|
||||
message(STATUS " Speex DSP library: ${SPEEXDSP_LIBRARY}")
|
||||
if(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
|
||||
include_directories(${SPEEXDSP_INCLUDE_DIR})
|
||||
list(APPEND FREEDV_LINK_LIBS ${SPEEXDSP_LIBRARY})
|
||||
else(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
|
||||
message(FATAL_ERROR "Speex DSP library not found!")
|
||||
endif(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
|
||||
else()
|
||||
message(STATUS "Will attempt static build of speex.")
|
||||
include(cmake/BuildSpeex.cmake)
|
||||
endif()
|
||||
|
||||
#Freedv
|
||||
add_subdirectory(src)
|
||||
|
||||
# Icons and desktop file
|
||||
add_subdirectory(contrib)
|
||||
|
||||
message(STATUS "Build type will be: ${CMAKE_BUILD_TYPE}")
|
||||
|
||||
#
|
||||
# Cpack NSIS configuration for Windows.
|
||||
#
|
||||
if(WIN32)
|
||||
# Detect if we're doing a 32-bit or 64-bit windows build.
|
||||
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
|
||||
set(CMAKE_CL_64 TRUE)
|
||||
endif()
|
||||
if(NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
|
||||
set(CPACK_STRIP_FILES TRUE)
|
||||
endif()
|
||||
configure_file(cmake/GetDependencies.cmake.in cmake/GetDependencies.cmake
|
||||
@ONLY
|
||||
)
|
||||
install(SCRIPT ${CMAKE_BINARY_DIR}/cmake/GetDependencies.cmake)
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "HF Digital Voice for Radio Amateurs")
|
||||
set(CPACK_PACKAGE_VENDOR "CMake")
|
||||
#set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${FREEDV_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${FREEDV_VERSION_MINOR})
|
||||
# CPack expects a patch level version so set it here and override if we
|
||||
# are actually setting one.
|
||||
set(CPACK_PACKAGE_VERSION_PATCH 0)
|
||||
if(FREEDV_VERSION_PATCH)
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${FREEDV_VERSION_PATCH})
|
||||
endif()
|
||||
if(FREEDV_VERSION_SUFFIX)
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "${CPACK_PACKAGE_VERSION_PATCH}-${FREEDV_VERSION_SUFFIX}")
|
||||
endif()
|
||||
# There is a bug in NSI that does not handle full unix paths properly. Make
|
||||
# sure there is at least one set of four (4) backlasshes.
|
||||
#set(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp")
|
||||
set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\freedv.exe")
|
||||
set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
|
||||
set(CPACK_NSIS_PACKAGE_NAME "FreeDV")
|
||||
set(CPACK_NSIS_URL_INFO_ABOUT "http://freedv.org")
|
||||
set(CPACK_NSIS_MODIFY_PATH OFF)
|
||||
set(CPACK_NSIS_MENU_LINKS "http://freedv.org" "FreeDV Homepage")
|
||||
include(CPack)
|
||||
endif(WIN32)
|
||||
|
||||
endif(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
|
|
@ -0,0 +1,502 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 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.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest 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.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
|
@ -0,0 +1,275 @@
|
|||
==================================
|
||||
Building and installing on Linux
|
||||
==================================
|
||||
|
||||
Quickstart 1
|
||||
-----------
|
||||
|
||||
Builds static versions of wxWidgets, portaudio, codec2-dev, which are commonly
|
||||
missing on many Linux systems, or of the wrong (older) version.
|
||||
|
||||
1/ Assuming the fdmdv2-dev source is checked out into ~/fdmdv2-dev:
|
||||
|
||||
$ sudo apt-get install libgtk2.0-dev libhamlib-dev libsamplerate-dev libasound2-dev libao-dev libgsm1-dev
|
||||
$ cd fdmdv2-dev
|
||||
$ mkdir build_linux
|
||||
$ cd build_linux
|
||||
$ cmake -DBOOTSTRAP_WXWIDGETS=TRUE ~/fdmdv2-dev
|
||||
$ make
|
||||
|
||||
2/ Then you can configure FreeDV using your local codec-dev, something like:
|
||||
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug -DBOOTSTRAP_WXWIDGETS=TRUE -DCODEC2_INCLUDE_DIRS=/path/to/codec2-dev/src -DCODEC2_LIBRARY=/path/to/codec2-dev/build_linux/src/libcodec2.so -DUSE_STATIC_CODEC2=FALSE -DUSE_STATIC_PORTAUDIO=TRUE -DUSE_STATIC_SOX=TRUE ../
|
||||
|
||||
3/ OR build a local copy of codec2-dev:
|
||||
|
||||
$ cmake -DBOOTSTRAP_WXWIDGETS=TRUE -DUSE_STATIC_CODEC2=TRUE -DUSE_STATIC_PORTAUDIO=TRUE -DUSE_STATIC_SOX=TRUE ../
|
||||
|
||||
4/ Build and run FreeDV:
|
||||
|
||||
$ make
|
||||
$ ./src/freedv
|
||||
|
||||
Quickstart 2
|
||||
------------
|
||||
|
||||
1/ Assuming you have all the dependant libraries:
|
||||
|
||||
$ cd /path/to/fdmdv2
|
||||
$ mkdir build_linux
|
||||
$ cd build_linux
|
||||
$ cmake ../ (defaults to /usr/local, use CMAKE_INSTALL_PREFIX to override)
|
||||
(if no errors)
|
||||
$ make
|
||||
(as root)
|
||||
$ make install
|
||||
|
||||
|
||||
=======================================================
|
||||
Building for Windows on Ubuntu Linux (Cross compiling)
|
||||
=======================================================
|
||||
|
||||
1/ Install the cross compiling toolchain:
|
||||
|
||||
$ sudo apt-get install mingw-w64
|
||||
|
||||
2/ Patch cmake using: http://www.cmake.org/gitweb?p=stage/cmake.git;a=patch;h=33286235048495ceafb636d549d9a4e8891967ae
|
||||
|
||||
3/ Checkout a fresh copy of codec2-dev and build for Windows, pointing to the generate_codebook built by a linux build of generate_codebook, using this cmake line
|
||||
|
||||
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../fdmdv2-dev/cmake/Toolchain-Ubuntu-mingw32.cmake -DUNITTEST=FALSE -DGENERATE_CODEBOOK=/home/david/codec2-dev/build_linux/src/generate_codebook
|
||||
|
||||
4/ Build WxWidgets
|
||||
|
||||
$ cd /path/to/fdmdv2-dev
|
||||
$ mkdir build_windows
|
||||
$ cd build_windows
|
||||
$ cmake -DBOOTSTRAP_WXWIDGETS=TRUE .. -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-Ubuntu-mingw32.cmake -DCMAKE_BUILD_TYPE=Debug
|
||||
$ make
|
||||
|
||||
5/ Download and install the Windows version of Hamlib:
|
||||
|
||||
$ wget http://internode.dl.sourceforge.net/project/hamlib/hamlib/1.2.15.3/hamlib-win32-1.2.15.3.zip
|
||||
$ unzip hamlib-win32-1.2.15.3.zip
|
||||
|
||||
6/ Build All the libraries and FreeDV:
|
||||
|
||||
$ cmake -DBOOTSTRAP_WXWIDGETS=TRUE -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-Ubuntu-mingw32.cmake -DUSE_STATIC_PORTAUDIO=TRUE -DUSE_STATIC_SNDFILE=TRUE -DUSE_STATIC_SAMPLERATE=TRUE -DUSE_STATIC_SOX=TRUE -DUSE_STATIC_CODEC2=FALSE -DCODEC2_INCLUDE_DIRS=/home/david/tmp/codec2-dev/src -DCODEC2_LIBRARY=/home/david/tmp/codec2-dev/build_windows/src/libcodec2.dll.a -DHAMLIB_INCLUDE_DIR=hamlib-win32-1.2.15.3/include -DHAMLIB_LIBRARY=hamlib-win32-1.2.15.3/lib/gcc/libhamlib.dll.a -DCMAKE_BUILD_TYPE=Debug ..
|
||||
$ make
|
||||
|
||||
====================================
|
||||
Building and installing on Windows
|
||||
====================================
|
||||
|
||||
The windows build is similar to linux and follows the same basic workflow,
|
||||
however, while codec2 and FreeDV (fdmdv2) build well on windows, some of the
|
||||
dependencies do not. For that reson current windows releases are cross-compiled
|
||||
from linux.
|
||||
|
||||
Only MinGW is supported. While it is likely possible to perform a pure MinGW
|
||||
build, installing MSYS2 will make your life easier.
|
||||
|
||||
CMake may not automatically detect that you're in the MSYS environment. If this
|
||||
occurs you need to pass cmake the proper generator:
|
||||
|
||||
cmake -G"MSYS Makefiles" [other options] </path/to/source>
|
||||
|
||||
===============================
|
||||
Bootstrapping wxWidgets build
|
||||
===============================
|
||||
|
||||
If wxWidgets (>= 3.0) is not available then one option is to have CMake boot-
|
||||
strap the build for FreeDV.
|
||||
|
||||
This is required because the tool wx-config is used to get the correct compiler
|
||||
and linker flags of the wxWidgets components needed by FreeDV. Since this is
|
||||
normally done at configure time, not during "make", it is not possible for CMake
|
||||
or have this information prior to building wxWidgets.
|
||||
|
||||
In order to work around this issue you can "bootstrap" the wxWidgets build using
|
||||
the CMake option, "BOOTSTRAP_WXWIDGETS". wxWidgets will be built using static
|
||||
libraries.
|
||||
|
||||
NOTE: This forces "USE_STATIC_WXWIDGETS" to be true internally regarless of the
|
||||
value set manually.
|
||||
|
||||
(from any directory, but empty directory outside of the source is prefered.)
|
||||
$ cmake -DBOOTSTRAP_WXWIDGETS=TRUE /path/to/fdmdv2
|
||||
$ make
|
||||
(wxWidgets is downloaded and built)
|
||||
$ cmake .
|
||||
(wxWidgets build should be detected)
|
||||
$ make
|
||||
(if all goes well, as root)
|
||||
$ make install
|
||||
|
||||
====================================
|
||||
Building and installing on OSX
|
||||
====================================
|
||||
|
||||
====================================
|
||||
Building and installing on FreeBSD
|
||||
====================================
|
||||
|
||||
As per "Quickstart 2" above but change build_linux to build_freebsd
|
||||
|
||||
=======
|
||||
Editing
|
||||
=======
|
||||
|
||||
Please make sure your text editor does not insert tabs, and
|
||||
used indents of 4 spaces. The following .emacs code was used to
|
||||
configure emacs:
|
||||
|
||||
(setq-default indent-tabs-mode nil)
|
||||
|
||||
(add-hook 'c-mode-common-hook
|
||||
(function (lambda ()
|
||||
(setq c-basic-offset 4)
|
||||
)))
|
||||
|
||||
====
|
||||
TODO
|
||||
====
|
||||
|
||||
[ ] Open R&D questions
|
||||
+ Goal is to develop an open source DV mode that performs comparably to SSB
|
||||
[ ] Does 700 perform OK next to SSB?
|
||||
+ approx same tx pk level (hard to measure exactly)
|
||||
+ try some low SNR channels
|
||||
+ try some fast fading/nasty channels
|
||||
[ ] Is 700 speech quality acceptable?
|
||||
|
||||
[X] test frames
|
||||
[X] freedv API support
|
||||
[X] BER displayed on GUI for 700 and 1600
|
||||
[X] plot error patterns for 700 and 1600
|
||||
+ callback for error patterns, or poll via stats interface
|
||||
[X] plot error histograms for 700 and 1600
|
||||
+ map bit error to carrier, have done this in tcohpsk?
|
||||
+ how to reset histogram? On error reset?
|
||||
+ histogram screen ... new code?
|
||||
+ test with filter
|
||||
|
||||
[X] Bugs
|
||||
[X] resync issue
|
||||
[X] equalise power on 700 and 1600
|
||||
[X] research real and complex PAPR
|
||||
[X] waterfall and spectrum in analog mode
|
||||
[X] The waterfall in analog mode appears to quit working sometimes?
|
||||
|
||||
[X] On TX, intermittently PTT will cause signal to be heard in speakers. Toggle PTT or
|
||||
Stop/Start toggle and then starts working.
|
||||
[X] Squelch control on 1600 mode will not open up squelch to 0 (appears to be around 2 dB)
|
||||
[X] space bar keys PTT when entering text info box
|
||||
[X] checksum based txt reception
|
||||
+ only print if valid
|
||||
[X] IC7200 audio breakup
|
||||
[ ] short varicode doesn't work
|
||||
+ #ifdef-ed out for now
|
||||
+ cld be broken in freedv_api
|
||||
[X] On 700 audio sounds tinny and clicky when out of sync compared to 1600 why?
|
||||
+ clue: only when analog not pressed
|
||||
+ this was 7.5 to 8kHz interpolator bug
|
||||
[X] spectrum and waterfall scale changes when analog pressed
|
||||
[X] ocassional test frames error counter goes crazy
|
||||
[ ] old Waterfall AGC
|
||||
[ ] 700 syncs up to 1000Hz sine waves
|
||||
+ shouldn't trigger sync logic, will be a problem with carriers
|
||||
[ ] "clip" led, encourage people to adjust gain to hit that occ when speaking
|
||||
[ ] Win32 record from radio time
|
||||
|
||||
[ ] FreeDV 700 improvements
|
||||
[ ] bpf filter after clipping to remove clicks
|
||||
[ ] tcohpsk first, measure PAPR, impl loss
|
||||
[ ] error masking
|
||||
[ ] C version
|
||||
[ ] training off air? Switchable?
|
||||
[ ] excitation params
|
||||
[ ] training
|
||||
[ ] plotting other demod stats like ch ampl and phase ests
|
||||
[ ] profile with perf, different libresample routine
|
||||
[ ] check for occassional freedv 700 loss of sync
|
||||
+ scatter seems to jump
|
||||
[ ] switchable diversity (narrowband) option
|
||||
+ measure difference on a few channels
|
||||
+ blog
|
||||
|
||||
[X] win32
|
||||
[X] X-compile works
|
||||
[X] basic installer
|
||||
[X] Win32 installer
|
||||
+ Richard has taken care of this
|
||||
|
||||
[ ] Small fixes
|
||||
[X] Playfile bug
|
||||
[X] running again
|
||||
[X] bump ver number
|
||||
[X] long varicode default
|
||||
[X] option to _not_ require checksum, on by default
|
||||
[X] default squelch 2dB
|
||||
[X] scatter diagram tweaks
|
||||
+ e.g. meaningful plots on fading channels in real time
|
||||
[X] agc with hysteresis
|
||||
+ changed to log steps
|
||||
[X] longer persistance
|
||||
+ changed to 6 seconds
|
||||
[X] diversity addtions on 700
|
||||
+ still not real obvious on plot
|
||||
+ might be useful to make this switchable
|
||||
[X] scatter diagram different colours/carrier
|
||||
[X] remember what mode you were in
|
||||
[ ] cmd line file decode
|
||||
[ ] Waterfall direction
|
||||
[ ] documentation or use, walk through, you tube, blog posts
|
||||
|
||||
[ ] Web support for Presence/spotting hooks
|
||||
|
||||
=================
|
||||
USER GUIDE NOTES
|
||||
=================
|
||||
|
||||
TODO: Put this in a more usable form, video tutorials etc
|
||||
|
||||
1/ Error Histogram. Displays BER of each carrier when in "test frame"
|
||||
mode. As each QPSK carrier has 2 bits there are 2*Nc histogram
|
||||
points.
|
||||
|
||||
Ideally all carriers will have about the same BER (+/- 20% after 5000
|
||||
total bit errors). However problems can occur with filtering in the
|
||||
tx path. If one carrier has less power, then it will have a higher
|
||||
BER. The errors in this carrier will tend to dominate overall
|
||||
BER. For example if one carrier is attenuated due to SSB filter
|
||||
ripple in the tx path then the BER on that carrier will be higher.
|
||||
This is bad news for DV.
|
||||
|
||||
Suggested usage: Transmit FreeDV in test frame mode. Use a 2nd rx
|
||||
(or get a friend) to monitor your rx signal with FreeDV in test frame
|
||||
mode. Adjust your rx SNR to get a BER of a few % (e.g. reduce tx power,
|
||||
use a short antenna for the rx, point your beam away, adjust rx RF
|
||||
gain). Monitor the error histogram for a few minutes, until you have
|
||||
say 5000 total bit errors. You have a problem if the BER of any
|
||||
carrier is more than 20% different from the rest.
|
||||
|
||||
A typical issue will be one carrier at 1.0, the others at 0.5,
|
||||
indicating the poorer carrier BER is twice the larger.
|
|
@ -0,0 +1,23 @@
|
|||
set(SPEEXDSP_CMAKE_ARGS -DBUILD_SHARED_LIBS=FALSE -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/external/dist)
|
||||
|
||||
if(USE_STATIC_SPEEXDSP)
|
||||
list(APPEND SPEEXDSP_CMAKE_ARGS
|
||||
-DSPEEXDSP_LIBRARIES=${CMAKE_BINARY_DIR}/external/dist/lib/libspeexdsp.a
|
||||
-DSPEEXDSP_INCLUDE_DIR=${CMAKE_BINARY_DIR}/external/dist/include)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
set(CODEC2_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}")
|
||||
endif()
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(codec2
|
||||
SVN_REPOSITORY https://svn.code.sf.net/p/freetel/code/codec2-dev
|
||||
CMAKE_ARGS ${CODEC2_CMAKE_ARGS} ${SPEEXDSP_CMAKE_ARGS}
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
set(CODEC2_LIBRARIES
|
||||
${CMAKE_BINARY_DIR}/codec2-prefix/src/codec2-build/src/libcodec2.a)
|
||||
include_directories(${CMAKE_BINARY_DIR}/codec2-prefix/src/codec2/src)
|
||||
list(APPEND FREEDV_LINK_LIBS ${CODEC2_LIBRARIES})
|
||||
list(APPEND FREEDV_STATIC_DEPS codec2)
|
|
@ -0,0 +1,52 @@
|
|||
set(PORTAUDIO_TARBALL "pa_stable_v19_20111121")
|
||||
|
||||
# required linking libraries on linux. Not sure about windows.
|
||||
find_library(ALSA_LIBRARIES asound)
|
||||
|
||||
if(UNIX AND NOT ALSA_LIBRARIES)
|
||||
message(ERROR "Could not find alsa library which is required for portaudio.
|
||||
On Linux systems try installing:
|
||||
alsa-lib-devel (RPM based systems)
|
||||
libasound2-dev (DEB based systems)"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Make sure that configure knows what system we're using when cross-compiling.
|
||||
if(MINGW AND CMAKE_CROSSCOMPILING)
|
||||
include(cmake/MinGW.cmake)
|
||||
set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --enable-cxx --without-jack --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
|
||||
else()
|
||||
set(CONFIGURE_COMMAND ./configure --enable-cxx --without-jack --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
|
||||
endif()
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(portaudio
|
||||
URL http://www.portaudio.com/archives/${PORTAUDIO_TARBALL}.tgz
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_DIR external/dist
|
||||
CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
|
||||
BUILD_COMMAND $(MAKE)
|
||||
INSTALL_COMMAND $(MAKE) install
|
||||
)
|
||||
if(WIN32)
|
||||
set(PORTAUDIO_LIBRARIES
|
||||
${CMAKE_BINARY_DIR}/external/dist/lib/libportaudio.a
|
||||
${CMAKE_BINARY_DIR}/external/dist/lib/libportaudiocpp.a
|
||||
)
|
||||
else(WIN32)
|
||||
find_library(RT rt)
|
||||
find_library(ASOUND asound)
|
||||
set(PORTAUDIO_LIBRARIES
|
||||
${CMAKE_BINARY_DIR}/external/dist/lib/libportaudio.a
|
||||
${CMAKE_BINARY_DIR}/external/dist/lib/libportaudiocpp.a
|
||||
${RT}
|
||||
${ASOUND}
|
||||
)
|
||||
endif(WIN32)
|
||||
include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
|
||||
|
||||
# Add the portaudio library to the list of libraries that must be linked.
|
||||
list(APPEND FREEDV_LINK_LIBS ${PORTAUDIO_LIBRARIES})
|
||||
|
||||
# Setup a dependency so that this gets built before linking to freedv.
|
||||
list(APPEND FREEDV_STATIC_DEPS portaudio)
|
|
@ -0,0 +1,27 @@
|
|||
set(SAMPLERATE_TARBALL "libsamplerate-0.1.8")
|
||||
|
||||
if(MINGW AND CMAKE_CROSSCOMPILING)
|
||||
set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-sndfile)
|
||||
else()
|
||||
set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist)
|
||||
endif()
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(samplerate
|
||||
URL http://www.mega-nerd.com/SRC/${SAMPLERATE_TARBALL}.tar.gz
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_DIR external/dist
|
||||
CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
|
||||
BUILD_COMMAND $(MAKE)
|
||||
INSTALL_COMMAND $(MAKE) install
|
||||
)
|
||||
if(WIN32)
|
||||
set(SAMPLERATE_LIBRARIES
|
||||
${CMAKE_BINARY_DIR}/external/dist/lib/libsamplerate.a)
|
||||
else(WIN32)
|
||||
set(SAMPLERATE_LIBRARIES
|
||||
${CMAKE_BINARY_DIR}/external/dist/lib/libsamplerate.a)
|
||||
endif(WIN32)
|
||||
include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
|
||||
list(APPEND FREEDV_LINK_LIBS ${SAMPLERATE_LIBRARIES})
|
||||
list(APPEND FREEDV_STATIC_DEPS samplerate)
|
|
@ -0,0 +1,26 @@
|
|||
set(SNDFILE_TARBALL "libsndfile-1.0.25")
|
||||
|
||||
if(MINGW AND CMAKE_CROSSCOMPILING)
|
||||
set(CONFIGURE_COMMAND ./configure --host=${HOST} --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-external-libs --disable-shared)
|
||||
else()
|
||||
set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-external-libs --disable-shared --disable-external-libs)
|
||||
endif()
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(sndfile
|
||||
URL http://www.mega-nerd.com/libsndfile/files/${SNDFILE_TARBALL}.tar.gz
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_DIR external/dist
|
||||
CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
|
||||
BUILD_COMMAND $(MAKE) V=1
|
||||
INSTALL_COMMAND $(MAKE) install
|
||||
)
|
||||
if(MINGW)
|
||||
set(SNDFILE_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libsndfile.a)
|
||||
else()
|
||||
set(SNDFILE_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libsndfile.a)
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
|
||||
list(APPEND FREEDV_LINK_LIBS ${SNDFILE_LIBRARIES})
|
||||
list(APPEND FREEDV_STATIC_DEPS sndfile)
|
|
@ -0,0 +1,48 @@
|
|||
set(SOX_TARBALL "sox-14.4.1")
|
||||
|
||||
# required linking libraries on linux. Not sure about windows.
|
||||
find_library(ALSA_LIBRARIES asound)
|
||||
find_library(AO_LIBRARIES ao)
|
||||
find_library(GSM_LIBRARIES gsm)
|
||||
|
||||
if(UNIX AND NOT ALSA_LIBRARIES)
|
||||
message(ERROR "Could not find alsa library.
|
||||
On Linux systems try installing:
|
||||
alsa-lib-devel (RPM based systems)
|
||||
libasound2-dev (DEB based systems)"
|
||||
)
|
||||
endif(UNIX AND NOT ALSA_LIBRARIES)
|
||||
|
||||
if(UNIX AND NOT AO_LIBRARIES)
|
||||
message(ERROR "Could not find libao.
|
||||
On Linux systems try installing:
|
||||
libao-devel (RPM based systems)
|
||||
libao-dev (DEB based systems)"
|
||||
)
|
||||
endif(UNIX AND NOT AO_LIBRARIES)
|
||||
|
||||
if(MINGW AND CMAKE_CROSSCOMPILING)
|
||||
set(CONFIGURE_COMMAND ./configure --host=${HOST} --enable-shared=no --without-id3tag --without-png --disable-gomp --with-oggvorbis=no --with-oss=no --with-flac=no --with-amrnb=no --with-amrwb=no --with-mp3=no --with-wavpack=no --disable-dl-sndfile --with-pulseaudio=no --without-magic --with-gsm --prefix=${CMAKE_BINARY_DIR}/external/dist)
|
||||
else()
|
||||
set(CONFIGURE_COMMAND ./configure --enable-shared=no --without-id3tag --without-png --disable-gomp --with-oggvorbis=no --with-oss=no --with-flac=no --with-amrnb=no --with-amrwb=no --with-mp3=no --with-wavpack=no --disable-dl-sndfile --with-pulseaudio=no --without-magic --with-gsm --prefix=${CMAKE_BINARY_DIR}/external/dist)
|
||||
endif()
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(sox
|
||||
URL http://downloads.sourceforge.net/sox/${SOX_TARBALL}.tar.gz
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_DIR external/dist
|
||||
CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
|
||||
BUILD_COMMAND $(MAKE) V=1
|
||||
INSTALL_COMMAND $(MAKE) install
|
||||
)
|
||||
set(SOX_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libsox.a)
|
||||
if(UNIX)
|
||||
list(APPEND SOX_LIBRARIES ${ALSA_LIBRARIES} ${AO_LIBRARIES} ${GSM_LIBRARIES})
|
||||
endif()
|
||||
if(MINGW)
|
||||
list(APPEND SOX_LIBRARIES winmm)
|
||||
endif()
|
||||
include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
|
||||
list(APPEND FREEDV_LINK_LIBS ${SOX_LIBRARIES})
|
||||
list(APPEND FREEDV_STATIC_DEPS sox)
|
|
@ -0,0 +1,26 @@
|
|||
set(SPEEXDSP_TARBALL "speexdsp-1.2rc3.tar.gz")
|
||||
|
||||
if(MINGW AND CMAKE_CROSSCOMPILING)
|
||||
include(cmake/MinGW.cmake)
|
||||
set(CONFIGURE_COMMAND ./configure --host=${HOST} --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-examples)
|
||||
else()
|
||||
set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-examples)
|
||||
endif()
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(speex
|
||||
URL http://downloads.xiph.org/releases/speex/${SPEEXDSP_TARBALL}
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_DIR external/dist
|
||||
CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
|
||||
BUILD_COMMAND $(MAKE)
|
||||
INSTALL_COMMAND $(MAKE) install
|
||||
)
|
||||
|
||||
set(SPEEXDSP_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libspeexdsp.a)
|
||||
include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
|
||||
list(APPEND FREEDV_LINK_LIBS ${SPEEXDSP_LIBRARIES})
|
||||
list(APPEND FREEDV_STATIC_DEPS speex)
|
||||
if(USE_STATIC_CODEC2)
|
||||
add_dependencies(codec2 speex)
|
||||
endif()
|
|
@ -0,0 +1,43 @@
|
|||
set(WXWIDGETS_TARBALL "wxWidgets-3.0.2")
|
||||
|
||||
# If we're cross-compiling then we need to set the target host manually.
|
||||
if(MINGW AND CMAKE_CROSSCOMPILING)
|
||||
include(cmake/MinGW.cmake)
|
||||
endif()
|
||||
|
||||
# If not cross-compiling then use the built-in makefile, otherwise use standard configure.
|
||||
if(MINGW AND NOT CMAKE_CROSSCOMPILING)
|
||||
# set(CONFIGURE_COMMAND "true")
|
||||
# set(MAKE_COMMAND $(MAKE) -C build/msw -f makefile.gcc SHARED=0 UNICODE=1 BUILD=release PREFIX=${CMAKE_BINARY_DIR}/external/dist)
|
||||
set(CONFIGURE_COMMAND ./configure --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
|
||||
set(MAKE_COMMAND $(MAKE))
|
||||
endif()
|
||||
|
||||
if(MINGW AND CMAKE_CROSSCOMPILING)
|
||||
set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
|
||||
set(MAKE_COMMAND $(MAKE))
|
||||
endif()
|
||||
|
||||
if(NOT MINGW)
|
||||
set(CONFIGURE_COMMAND ./configure --host=${HOST} --target=${HOST} --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
|
||||
set(MAKE_COMMAND $(MAKE))
|
||||
endif()
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(wxWidgets
|
||||
URL http://downloads.sourceforge.net/wxwindows/${WXWIDGETS_TARBALL}.tar.bz2
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_DIR external/dist
|
||||
CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
|
||||
BUILD_COMMAND ${MAKE_COMMAND}
|
||||
INSTALL_COMMAND $(MAKE) install
|
||||
)
|
||||
|
||||
ExternalProject_Get_Property(wxWidgets install_dir)
|
||||
message(STATUS "wxWidgets install dir: ${install_dir}")
|
||||
if(NOT WXCONFIG)
|
||||
set(WXCONFIG "${install_dir}/bin/wx-config")
|
||||
endif()
|
||||
if(EXISTS ${WXCONFIG})
|
||||
set(BS_WX_DONE TRUE)
|
||||
endif()
|
|
@ -0,0 +1,107 @@
|
|||
# - Try to find Portaudio
|
||||
# Once done this will define
|
||||
#
|
||||
# PORTAUDIO_FOUND - system has Portaudio
|
||||
# PORTAUDIO_INCLUDE_DIRS - the Portaudio include directory
|
||||
# PORTAUDIO_LIBRARIES - Link these to use Portaudio
|
||||
# PORTAUDIO_DEFINITIONS - Compiler switches required for using Portaudio
|
||||
# PORTAUDIO_VERSION - Portaudio version
|
||||
#
|
||||
# Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(PORTAUDIO_FOUND TRUE)
|
||||
else (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
|
||||
if (NOT WIN32)
|
||||
include(FindPkgConfig)
|
||||
pkg_check_modules(PORTAUDIO2 portaudio-2.0)
|
||||
endif (NOT WIN32)
|
||||
|
||||
if (PORTAUDIO2_FOUND)
|
||||
set(PORTAUDIO_INCLUDE_DIRS
|
||||
${PORTAUDIO2_INCLUDE_DIRS}
|
||||
)
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(PORTAUDIO_LIBRARIES "${PORTAUDIO2_LIBRARY_DIRS}/lib${PORTAUDIO2_LIBRARIES}.dylib")
|
||||
else (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(PORTAUDIO_LIBRARIES
|
||||
${PORTAUDIO2_LIBRARIES}
|
||||
)
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(PORTAUDIO_VERSION
|
||||
19
|
||||
)
|
||||
set(PORTAUDIO_FOUND TRUE)
|
||||
else (PORTAUDIO2_FOUND)
|
||||
find_path(PORTAUDIO_INCLUDE_DIR
|
||||
NAMES
|
||||
portaudio.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
)
|
||||
|
||||
find_library(PORTAUDIO_LIBRARY
|
||||
NAMES
|
||||
portaudio
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
find_path(PORTAUDIO_LIBRARY_DIR
|
||||
NAMES
|
||||
portaudio
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
set(PORTAUDIO_INCLUDE_DIRS
|
||||
${PORTAUDIO_INCLUDE_DIR}
|
||||
)
|
||||
set(PORTAUDIO_LIBRARIES
|
||||
${PORTAUDIO_LIBRARY}
|
||||
)
|
||||
|
||||
set(PORTAUDIO_LIBRARY_DIRS
|
||||
${PORTAUDIO_LIBRARY_DIR}
|
||||
)
|
||||
|
||||
set(PORTAUDIO_VERSION
|
||||
18
|
||||
)
|
||||
|
||||
if (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
|
||||
set(PORTAUDIO_FOUND TRUE)
|
||||
endif (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
|
||||
|
||||
if (PORTAUDIO_FOUND)
|
||||
if (NOT Portaudio_FIND_QUIETLY)
|
||||
message(STATUS "Found Portaudio: ${PORTAUDIO_LIBRARIES}")
|
||||
endif (NOT Portaudio_FIND_QUIETLY)
|
||||
else (PORTAUDIO_FOUND)
|
||||
if (Portaudio_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find Portaudio")
|
||||
endif (Portaudio_FIND_REQUIRED)
|
||||
endif (PORTAUDIO_FOUND)
|
||||
endif (PORTAUDIO2_FOUND)
|
||||
|
||||
|
||||
# show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES)
|
||||
|
||||
endif (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# As this script is run in a new cmake instance, it does not have access to
|
||||
# the existing cache variables. Pass them in via the configure_file command.
|
||||
set(CMAKE_BINARY_DIR @CMAKE_BINARY_DIR@)
|
||||
set(CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@)
|
||||
set(UNIX @UNIX@)
|
||||
set(WIN32 @WIN32@)
|
||||
set(CMAKE_CROSSCOMPILING @CMAKE_CROSSCOMPILING@)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES @CMAKE_FIND_LIBRARY_SUFFIXES@)
|
||||
set(CMAKE_FIND_LIBRARY_PREFIXES @CMAKE_FIND_LIBRARY_PREFIXES@)
|
||||
set(CMAKE_SYSTEM_LIBRARY_PATH @CMAKE_SYSTEM_LIBRARY_PATH@)
|
||||
set(CMAKE_FIND_ROOT_PATH @CMAKE_FIND_ROOT_PATH@)
|
||||
|
||||
set(FREEDV_EXE ${CMAKE_BINARY_DIR}/src/freedv.exe)
|
||||
|
||||
include(GetPrerequisites)
|
||||
get_prerequisites("${FREEDV_EXE}" _deps 1 1 "" "${CMAKE_SYSTEM_LIBRARY_PATH}")
|
||||
foreach(_runtime ${_deps})
|
||||
message("Looking for ${_runtime}")
|
||||
find_library(RUNTIME_${_runtime} ${_runtime})
|
||||
message("${RUNTIME_${_runtime}}")
|
||||
if(RUNTIME_${_runtime})
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
|
||||
TYPE EXECUTABLE FILES "${RUNTIME_${_runtime}}")
|
||||
endif()
|
||||
endforeach()
|
|
@ -0,0 +1,8 @@
|
|||
# If we're cross-compiling then we need to set the target host manually.
|
||||
if(MINGW AND CMAKE_CROSSCOMPILING)
|
||||
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
|
||||
set(HOST x86_64-w64-mingw32)
|
||||
else()
|
||||
set(HOST i686-w64-mingw32)
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,25 @@
|
|||
# Sample toolchain file for building for Windows from an Ubuntu Linux system.
|
||||
#
|
||||
# Typical usage:
|
||||
# *) install cross compiler: `sudo apt-get install mingw-w64 g++-mingw-w64`
|
||||
# *) cd build
|
||||
# *) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-mingw32.cmake ..
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
set(TOOLCHAIN_PREFIX i686-w64-mingw32)
|
||||
|
||||
# cross compilers to use for C and C++
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
|
||||
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
|
||||
|
||||
# target environment on the build host system
|
||||
# set 1st to dir with the cross compiler's C/C++ headers/libs
|
||||
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
|
||||
|
||||
# modify default behavior of FIND_XXX() commands to
|
||||
# search for headers/libs in the target environment and
|
||||
# search for programs in the build host environment
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
|
@ -0,0 +1,19 @@
|
|||
/*--------------------------------------------------------------------------
|
||||
** This file is autogenerated from config.h.in
|
||||
** during the cmake configuration of your project. If you need to make changes
|
||||
** edit the original file NOT THIS FILE.
|
||||
** --------------------------------------------------------------------------*/
|
||||
#ifndef _CONFIGURATION_HEADER_GUARD_H_
|
||||
#define _CONFIGURATION_HEADER_GUARD_H_
|
||||
|
||||
#define SIZEOF_INT @SIZEOF_INT@
|
||||
#cmakedefine HAVE_LIMITS_H @HAVE_LIMITS_H@
|
||||
#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@
|
||||
#cmakedefine HAVE_STDDEF_H @HAVE_STDDEF_H@
|
||||
#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@
|
||||
#cmakedefine HAVE_STRING_H @HAVE_STRING_H@
|
||||
#cmakedefine HAVE_FLOOR @HAVE_FLOOR@
|
||||
#cmakedefine HAVE_MEMSET @HAVE_MEMSET@
|
||||
#cmakedefine HAVE_POW @HAVE_POW@
|
||||
#cmakedefine HAVE_SQRT @HAVE_SQRT@
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef FREEDV_VER_DOT_H
|
||||
#define FREEDV_VER_DOT_H 1
|
||||
|
||||
#define FREEDV_VERSION_MAJOR @FREEDV_VERSION_MAJOR@
|
||||
#define FREEDV_VERSION_MINOR @FREEDV_VERSION_MINOR@
|
||||
#define FREEDV_VERSION_PATCH @FREEDV_VERSION_PATCH@
|
||||
#define FREEDV_VERSION_SUFFIX "@FREEDV_VERSION_SUFFIX@"
|
||||
|
||||
#define FREEDV_VERSION "@FREEDV_VERSION_STRING@"
|
||||
|
||||
#endif //FREEDV_VER_DOT_H
|
|
@ -0,0 +1,22 @@
|
|||
# Install icons if we're on most *nix systems.
|
||||
if(UNIX AND NOT APPLE)
|
||||
set(ICON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor
|
||||
CACHE PATH "Prefix to use for installing icons.")
|
||||
install(FILES freedv48x48.png
|
||||
DESTINATION ${ICON_INSTALL_PREFIX}/48x48/apps
|
||||
RENAME freedv.png)
|
||||
install(FILES freedv64x64.png
|
||||
DESTINATION ${ICON_INSTALL_PREFIX}/64x64/apps
|
||||
RENAME freedv.png)
|
||||
install(FILES freedv128x128.png
|
||||
DESTINATION ${ICON_INSTALL_PREFIX}/128x128/apps
|
||||
RENAME freedv.png)
|
||||
install(FILES freedv256x256.png
|
||||
DESTINATION ${ICON_INSTALL_PREFIX}/256x256/apps
|
||||
RENAME freedv.png)
|
||||
|
||||
set(DESKTOP_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/applications
|
||||
CACHE PATH "Location to install desktop files.")
|
||||
install(FILES freedv.desktop
|
||||
DESTINATION ${DESKTOP_INSTALL_DIR})
|
||||
endif(UNIX AND NOT APPLE)
|
|
@ -0,0 +1,393 @@
|
|||
Attribution 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More_considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution 4.0 International Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution 4.0 International Public License ("Public License"). To the
|
||||
extent this Public License may be interpreted as a contract, You are
|
||||
granted the Licensed Rights in consideration of Your acceptance of
|
||||
these terms and conditions, and the Licensor grants You such rights in
|
||||
consideration of benefits the Licensor receives from making the
|
||||
Licensed Material available under these terms and conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
d. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
f. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
g. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
h. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
i. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
j. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
k. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
4. If You Share Adapted Material You produce, the Adapter's
|
||||
License You apply must not prevent recipients of the Adapted
|
||||
Material from complying with this Public License.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material; and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public licenses.
|
||||
Notwithstanding, Creative Commons may elect to apply one of its public
|
||||
licenses to material it publishes and in those instances will be
|
||||
considered the "Licensor." Except for the limited purpose of indicating
|
||||
that material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the public
|
||||
licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
|
@ -0,0 +1,8 @@
|
|||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=FreeDV
|
||||
Exec=freedv
|
||||
Icon=freedv
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Categories=GTK;GNOME;AudioVideo;Audio;HamRadio;
|
Binary file not shown.
After Width: | Height: | Size: 356 KiB |
|
@ -0,0 +1 @@
|
|||
id ICON "./freedv.ico"
|
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
|
@ -0,0 +1,13 @@
|
|||
Credits (code or ideas borrowed from):
|
||||
==============================================
|
||||
Dave Witten and David Rowe (obviously)
|
||||
Mel Whitten K0PFX (material and moral support)
|
||||
Bruce Perens (cheerleader, promotion and publicity)
|
||||
Mooneer Salem KG6AOV(Mac OSX Patch)
|
||||
Soeren Straarup OZ2DAK (FreeBSD Port)
|
||||
Don Mak
|
||||
Steve Nance (K5FR)
|
||||
Joel Stanley (Hamlib prototyping) and Mark Jessop (Mac OSX)
|
||||
James Ahlstrom (Quisk)
|
||||
FLDIGI
|
||||
All the folks on the digital voice google group...
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1 @@
|
|||
fsfs
|
|
@ -0,0 +1,38 @@
|
|||
### This file controls the configuration of the FSFS filesystem.
|
||||
|
||||
[memcached-servers]
|
||||
### These options name memcached servers used to cache internal FSFS
|
||||
### data. See http://www.danga.com/memcached/ for more information on
|
||||
### memcached. To use memcached with FSFS, run one or more memcached
|
||||
### servers, and specify each of them as an option like so:
|
||||
# first-server = 127.0.0.1:11211
|
||||
# remote-memcached = mymemcached.corp.example.com:11212
|
||||
### The option name is ignored; the value is of the form HOST:PORT.
|
||||
### memcached servers can be shared between multiple repositories;
|
||||
### however, if you do this, you *must* ensure that repositories have
|
||||
### distinct UUIDs and paths, or else cached data from one repository
|
||||
### might be used by another accidentally. Note also that memcached has
|
||||
### no authentication for reads or writes, so you must ensure that your
|
||||
### memcached servers are only accessible by trusted users.
|
||||
|
||||
[caches]
|
||||
### When a cache-related error occurs, normally Subversion ignores it
|
||||
### and continues, logging an error if the server is appropriately
|
||||
### configured (and ignoring it with file:// access). To make
|
||||
### Subversion never ignore cache errors, uncomment this line.
|
||||
# fail-stop = true
|
||||
|
||||
[rep-sharing]
|
||||
### To conserve space, the filesystem can optionally avoid storing
|
||||
### duplicate representations. This comes at a slight cost in
|
||||
### performance, as maintaining a database of shared representations can
|
||||
### increase commit times. The space savings are dependent upon the size
|
||||
### of the repository, the number of objects it contains and the amount of
|
||||
### duplication between them, usually a function of the branching and
|
||||
### merging process.
|
||||
###
|
||||
### The following parameter enables rep-sharing in the repository. It can
|
||||
### be switched on and off at will, but for best space-saving results
|
||||
### should be enabled consistently over the life of the repository.
|
||||
### rep-sharing is enabled by default.
|
||||
# enable-rep-sharing = true
|
|
@ -0,0 +1 @@
|
|||
0
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2012-08-21T18:27:59.389906Z
|
||||
END
|
|
@ -0,0 +1,13 @@
|
|||
K 10
|
||||
svn:author
|
||||
V 9
|
||||
OFA-Staff
|
||||
K 8
|
||||
svn:date
|
||||
V 27
|
||||
2012-08-21T18:28:08.741468Z
|
||||
K 7
|
||||
svn:log
|
||||
V 25
|
||||
Imported folder structure
|
||||
END
|
|
@ -0,0 +1,11 @@
|
|||
PLAIN
|
||||
END
|
||||
ENDREP
|
||||
id: 0.0.r0/17
|
||||
type: dir
|
||||
count: 0
|
||||
text: 0 0 4 4 2d2977d1c96f487abe4a1e202dd03b4e
|
||||
cpath: /
|
||||
|
||||
|
||||
17 107
|
|
@ -0,0 +1,49 @@
|
|||
id: 3-1.0.r1/0
|
||||
type: dir
|
||||
count: 0
|
||||
cpath: /tags
|
||||
copyroot: 0 /
|
||||
|
||||
id: 0-1.0.r1/62
|
||||
type: dir
|
||||
count: 0
|
||||
cpath: /trunk
|
||||
copyroot: 0 /
|
||||
|
||||
id: 2-1.0.r1/126
|
||||
type: dir
|
||||
count: 0
|
||||
cpath: /branches
|
||||
copyroot: 0 /
|
||||
|
||||
PLAIN
|
||||
K 8
|
||||
branches
|
||||
V 16
|
||||
dir 2-1.0.r1/126
|
||||
K 4
|
||||
tags
|
||||
V 14
|
||||
dir 3-1.0.r1/0
|
||||
K 5
|
||||
trunk
|
||||
V 15
|
||||
dir 0-1.0.r1/62
|
||||
END
|
||||
ENDREP
|
||||
id: 0.0.r1/306
|
||||
type: dir
|
||||
pred: 0.0.r0/17
|
||||
count: 1
|
||||
text: 1 194 99 99 7b6cc14dddba4e09be5255b475d1a0a8
|
||||
cpath: /
|
||||
copyroot: 0 /
|
||||
|
||||
_0.0.t0-0 add-dir false false /trunk
|
||||
|
||||
_2.0.t0-0 add-dir false false /branches
|
||||
|
||||
_3.0.t0-0 add-dir false false /tags
|
||||
|
||||
|
||||
306 431
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,44 @@
|
|||
set(FREEDV_SOURCES
|
||||
dlg_audiooptions.cpp
|
||||
dlg_filter.cpp
|
||||
dlg_options.cpp
|
||||
dlg_ptt.cpp
|
||||
fdmdv2_main.cpp
|
||||
fdmdv2_pa_wrapper.cpp
|
||||
fdmdv2_plot.cpp
|
||||
fdmdv2_plot_scalar.cpp
|
||||
fdmdv2_plot_scatter.cpp
|
||||
fdmdv2_plot_spectrum.cpp
|
||||
fdmdv2_plot_waterfall.cpp
|
||||
hamlib.cpp
|
||||
topFrame.cpp
|
||||
sox_biquad.c
|
||||
comp.h
|
||||
dlg_audiooptions.h
|
||||
dlg_filter.h
|
||||
dlg_options.h
|
||||
dlg_ptt.h
|
||||
fdmdv2_defines.h
|
||||
fdmdv2_main.h
|
||||
fdmdv2_pa_wrapper.h
|
||||
fdmdv2_plot.h
|
||||
fdmdv2_plot_scalar.h
|
||||
fdmdv2_plot_scatter.h
|
||||
fdmdv2_plot_spectrum.h
|
||||
fdmdv2_plot_waterfall.h
|
||||
hamlib.h
|
||||
sox_biquad.h
|
||||
sox.h
|
||||
topFrame.h
|
||||
version.h
|
||||
)
|
||||
|
||||
# WIN32 is needed for Windows GUI apps and is ignored for UNIX like systems.
|
||||
add_executable(freedv WIN32 ${FREEDV_SOURCES} ${RES_FILES})
|
||||
target_link_libraries(freedv ${FREEDV_LINK_LIBS})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(FREEDV_STATIC_DEPS)
|
||||
add_dependencies(freedv ${FREEDV_STATIC_DEPS})
|
||||
endif(FREEDV_STATIC_DEPS)
|
||||
install(TARGETS freedv
|
||||
RUNTIME DESTINATION bin)
|
|
@ -0,0 +1,52 @@
|
|||
# src/Makefile.win32
|
||||
# David Rowe 26 Oct 2012
|
||||
#
|
||||
# Makefile for Win32 on msys/Mingw to help David R get up to speed
|
||||
#
|
||||
# $ make -f Makefile.Win32
|
||||
|
||||
CODEC2_PATH=$(HOME)/codec2-dev
|
||||
INCLUDE_PATH=/usr/local/include
|
||||
|
||||
WX_CONFIG=wx-config
|
||||
WX_CPPFLAGS = $(shell $(WX_CONFIG) --cxxflags) -D__WXDEBUG__
|
||||
WX_LIBS = $(shell $(WX_CONFIG) --libs core, base, aui, adv, net)
|
||||
SVN_REVISION=$(shell svnversion)
|
||||
CODEC2_INC=$(CODEC2_PATH)/src
|
||||
CODEC2_LIB=$(CODEC2_PATH)/build_win32/src/
|
||||
|
||||
CPP_FLAGS = -D_NO_AUTOTOOLS_ -I$(INCLUDE_PATH) $(WX_CPPFLAGS) -I$(CODEC2_INC) -I../extern/include -I. -g -Wall -DSVN_REVISION=\"$(SVN_REVISION)\"
|
||||
LIBS = $(WX_LIBS) -L$(CODEC2_LIB) -lcodec2 -lm -lportaudiocpp -lportaudio -lpthread -lsndfile -lsamplerate -lhamlib -lsox -lspeexdsp
|
||||
|
||||
OBJS = topFrame.o \
|
||||
fdmdv2_main.o \
|
||||
fdmdv2_plot.o \
|
||||
fdmdv2_plot_scalar.o \
|
||||
fdmdv2_plot_scatter.o \
|
||||
fdmdv2_plot_spectrum.o \
|
||||
fdmdv2_plot_waterfall.o \
|
||||
fdmdv2_pa_wrapper.o \
|
||||
dlg_audiooptions.o \
|
||||
dlg_ptt.o \
|
||||
dlg_options.o \
|
||||
dlg_filter.o \
|
||||
sox_biquad.o \
|
||||
hamlib.o \
|
||||
../../codec2-dev/src/golay23.o
|
||||
|
||||
HDRS = version.h dlg_audiooptions.h dlg_ptt.h dlg_filter.h fdmdv2_main.h fdmdv2_defines.h fdmdv2_plot.h fdmdv2_plot_scalar.h fdmdv2_plot_waterfall.h fdmdv2_plot_scatter.h fdmdv2_plot_spectrum.h fdmdv2_pa_wrapper.h topFrame.h dlg_audiooptions.h topFrame.h varicode.h ../../codec2-dev/src/golay23.h hamlib.h
|
||||
|
||||
all: freedv
|
||||
|
||||
freedv: $(OBJS)
|
||||
g++ -o freedv $(OBJS) $(CPP_FLAGS) $(LIBS)
|
||||
|
||||
%.o: %.cpp $(HDRS) Makefile.win32
|
||||
g++ $(CPP_FLAGS) -c $< -o $@
|
||||
|
||||
%.o: %.c $(HDRS) Makefile.win32
|
||||
gcc $(CPP_FLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f *.o fdmdv2
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: comp.h
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 24/08/09
|
||||
|
||||
Complex number definition.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2009 David Rowe
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1, as
|
||||
published by the Free Software Foundation. This program is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __COMP__
|
||||
#define __COMP__
|
||||
|
||||
/* Complex number */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float real;
|
||||
float imag;
|
||||
} COMP;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,176 @@
|
|||
//=========================================================================
|
||||
// Name: AudioInfoDisplay.h
|
||||
// Purpose: Declares simple wxWidgets application with GUI
|
||||
// created using wxFormBuilder.
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//=========================================================================
|
||||
#ifndef __AudioOptsDialog__
|
||||
#define __AudioOptsDialog__
|
||||
|
||||
#include "fdmdv2_main.h"
|
||||
|
||||
#define ID_AUDIO_OPTIONS 1000
|
||||
#define AUDIO_IN 0
|
||||
#define AUDIO_OUT 1
|
||||
|
||||
#include "portaudio.h"
|
||||
#ifdef WIN32
|
||||
#if PA_USE_ASIO
|
||||
#include "pa_asio.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "codec2_fifo.h"
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// AudioInfoDisplay
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class AudioInfoDisplay
|
||||
{
|
||||
public:
|
||||
wxListCtrl* m_listDevices;
|
||||
int direction;
|
||||
wxTextCtrl* m_textDevice;
|
||||
wxComboBox* m_cbSampleRate;
|
||||
};
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// class AudioOptsDialog
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class AudioOptsDialog : public wxDialog
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
PaError pa_err;
|
||||
bool m_isPaInitialized;
|
||||
|
||||
int rxInAudioDeviceNum;
|
||||
int rxOutAudioDeviceNum;
|
||||
int txInAudioDeviceNum;
|
||||
int txOutAudioDeviceNum;
|
||||
|
||||
void buildTestControls(PlotScalar **plotScalar, wxButton **btnTest,
|
||||
wxPanel *parentPanel, wxBoxSizer *bSizer, wxString buttonLabel);
|
||||
void plotDeviceInputForAFewSecs(int devNum, PlotScalar *plotScalar);
|
||||
void plotDeviceOutputForAFewSecs(int devNum, PlotScalar *plotScalar);
|
||||
|
||||
int buildListOfSupportedSampleRates(wxComboBox *cbSampleRate, int devNum, int in_out);
|
||||
void populateParams(AudioInfoDisplay);
|
||||
void showAPIInfo();
|
||||
int setTextCtrlIfDevNumValid(wxTextCtrl *textCtrl, wxListCtrl *listCtrl, int devNum);
|
||||
void Pa_Init(void);
|
||||
void OnDeviceSelect(wxComboBox *cbSampleRate,
|
||||
wxTextCtrl *textCtrl,
|
||||
int *devNum,
|
||||
wxListCtrl *listCtrlDevices,
|
||||
int index,
|
||||
int in_out);
|
||||
|
||||
AudioInfoDisplay m_RxInDevices;
|
||||
AudioInfoDisplay m_RxOutDevices;
|
||||
AudioInfoDisplay m_TxInDevices;
|
||||
AudioInfoDisplay m_TxOutDevices;
|
||||
wxPanel* m_panel1;
|
||||
wxNotebook* m_notebook1;
|
||||
|
||||
wxPanel* m_panelRx;
|
||||
|
||||
wxListCtrl* m_listCtrlRxInDevices;
|
||||
wxStaticText* m_staticText51;
|
||||
wxTextCtrl* m_textCtrlRxIn;
|
||||
wxStaticText* m_staticText6;
|
||||
wxComboBox* m_cbSampleRateRxIn;
|
||||
|
||||
wxButton* m_btnRxInTest;
|
||||
PlotScalar* m_plotScalarRxIn;
|
||||
|
||||
wxListCtrl* m_listCtrlRxOutDevices;
|
||||
wxStaticText* m_staticText9;
|
||||
wxTextCtrl* m_textCtrlRxOut;
|
||||
wxStaticText* m_staticText10;
|
||||
wxComboBox* m_cbSampleRateRxOut;
|
||||
|
||||
wxButton* m_btnRxOutTest;
|
||||
PlotScalar* m_plotScalarRxOut;
|
||||
|
||||
wxPanel* m_panelTx;
|
||||
|
||||
wxListCtrl* m_listCtrlTxInDevices;
|
||||
wxStaticText* m_staticText12;
|
||||
wxTextCtrl* m_textCtrlTxIn;
|
||||
wxStaticText* m_staticText11;
|
||||
wxComboBox* m_cbSampleRateTxIn;
|
||||
|
||||
wxButton* m_btnTxInTest;
|
||||
PlotScalar* m_plotScalarTxIn;
|
||||
|
||||
wxListCtrl* m_listCtrlTxOutDevices;
|
||||
wxStaticText* m_staticText81;
|
||||
wxTextCtrl* m_textCtrlTxOut;
|
||||
wxStaticText* m_staticText71;
|
||||
wxComboBox* m_cbSampleRateTxOut;
|
||||
|
||||
wxButton* m_btnTxOutTest;
|
||||
PlotScalar* m_plotScalarTxOut;
|
||||
|
||||
wxPanel* m_panelAPI;
|
||||
|
||||
wxStaticText* m_staticText7;
|
||||
wxStaticText* m_textStringVer;
|
||||
wxStaticText* m_staticText8;
|
||||
wxStaticText* m_textIntVer;
|
||||
wxStaticText* m_staticText5;
|
||||
wxStaticText* m_textCDevCount;
|
||||
wxStaticText* m_staticText4;
|
||||
wxStaticText* m_textAPICount;
|
||||
wxButton* m_btnRefresh;
|
||||
wxStdDialogButtonSizer* m_sdbSizer1;
|
||||
wxButton* m_sdbSizer1OK;
|
||||
wxButton* m_sdbSizer1Apply;
|
||||
wxButton* m_sdbSizer1Cancel;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
//virtual void OnActivateApp( wxActivateEvent& event ) { event.Skip(); }
|
||||
// virtual void OnCloseFrame( wxCloseEvent& event ) { event.Skip(); }
|
||||
|
||||
void OnRxInDeviceSelect( wxListEvent& event );
|
||||
|
||||
void OnRxInTest( wxCommandEvent& event );
|
||||
void OnRxOutTest( wxCommandEvent& event );
|
||||
void OnTxInTest( wxCommandEvent& event );
|
||||
void OnTxOutTest( wxCommandEvent& event );
|
||||
|
||||
void OnRxOutDeviceSelect( wxListEvent& event );
|
||||
void OnTxInDeviceSelect( wxListEvent& event );
|
||||
void OnTxOutDeviceSelect( wxListEvent& event );
|
||||
void OnRefreshClick( wxCommandEvent& event );
|
||||
void OnApplyAudioParameters( wxCommandEvent& event );
|
||||
void OnCancelAudioParameters( wxCommandEvent& event );
|
||||
void OnOkAudioParameters( wxCommandEvent& event );
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
void OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||
void OnHibernate( wxActivateEvent& event ) { event.Skip(); }
|
||||
void OnIconize( wxIconizeEvent& event ) { event.Skip(); }
|
||||
void OnInitDialog( wxInitDialogEvent& event );
|
||||
|
||||
public:
|
||||
|
||||
AudioOptsDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Audio Config"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 300,300 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~AudioOptsDialog();
|
||||
int ExchangeData(int inout);
|
||||
};
|
||||
#endif //__AudioOptsDialog__
|
|
@ -0,0 +1,786 @@
|
|||
//==========================================================================
|
||||
// Name: dlg_filter.cpp
|
||||
// Purpose: Dialog for controlling Codec audio filtering
|
||||
// Date: Nov 25 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#include "dlg_filter.h"
|
||||
|
||||
#define SLIDER_MAX 100
|
||||
#define SLIDER_LENGTH 100
|
||||
|
||||
#define FILTER_MIN_MAG_DB -20.0
|
||||
#define FILTER_MAX_MAG_DB 20.0
|
||||
|
||||
#define MAX_FREQ_BASS 600.00
|
||||
#define MAX_FREQ_TREBLE 3900.00
|
||||
#define MAX_FREQ_DEF 3000.00
|
||||
|
||||
#define MIN_GAIN -20
|
||||
#define MAX_GAIN 20
|
||||
|
||||
#define MAX_LOG10_Q 1.0
|
||||
#define MIN_LOG10_Q -1.0
|
||||
|
||||
// DFT parameters
|
||||
|
||||
#define IMP_AMP 2000.0 // amplitude of impulse
|
||||
#define NIMP 50 // number of samples in impulse response
|
||||
#define F_STEP_DFT 10.0 // frequency steps to sample spectrum
|
||||
#define F_MAG_N (int)(MAX_F_HZ/F_STEP_DFT) // number of frequency steps
|
||||
|
||||
extern struct freedv *g_pfreedv;
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class FilterDlg
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
FilterDlg::FilterDlg(wxWindow* parent, bool running, bool *newMicInFilter, bool *newSpkOutFilter,
|
||||
wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
|
||||
{
|
||||
m_running = running;
|
||||
m_newMicInFilter = newMicInFilter;
|
||||
m_newSpkOutFilter = newSpkOutFilter;
|
||||
|
||||
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
|
||||
|
||||
wxBoxSizer* bSizer30;
|
||||
bSizer30 = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
// LPC Post Filter --------------------------------------------------------
|
||||
|
||||
wxStaticBoxSizer* lpcpfs = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("LPC Post Filter")), wxHORIZONTAL);
|
||||
|
||||
wxBoxSizer* left = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_codec2LPCPostFilterEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
|
||||
left->Add(m_codec2LPCPostFilterEnable);
|
||||
|
||||
m_codec2LPCPostFilterBassBoost = new wxCheckBox(this, wxID_ANY, _("0-1 kHz 3dB Boost"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
left->Add(m_codec2LPCPostFilterBassBoost);
|
||||
lpcpfs->Add(left, 0, wxALL, 5);
|
||||
|
||||
newLPCPFControl(&m_codec2LPCPostFilterBeta, &m_staticTextBeta, lpcpfs, "Beta");
|
||||
newLPCPFControl(&m_codec2LPCPostFilterGamma, &m_staticTextGamma, lpcpfs, "Gamma");
|
||||
|
||||
m_LPCPostFilterDefault = new wxButton(this, wxID_ANY, wxT("Default"));
|
||||
lpcpfs->Add(m_LPCPostFilterDefault, 0, wxALL|wxALIGN_CENTRE_HORIZONTAL|wxALIGN_CENTRE_VERTICAL, 5);
|
||||
|
||||
bSizer30->Add(lpcpfs, 0, wxALL, 0);
|
||||
|
||||
// Speex pre-processor --------------------------------------------------
|
||||
|
||||
wxStaticBoxSizer* sbSizer_speexpp;
|
||||
wxStaticBox *sb_speexpp = new wxStaticBox(this, wxID_ANY, _("Speex Mic Audio Pre-Processor"));
|
||||
sbSizer_speexpp = new wxStaticBoxSizer(sb_speexpp, wxVERTICAL);
|
||||
|
||||
m_ckboxSpeexpp = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
sb_speexpp->SetToolTip(_("Enable noise supression, dereverberation, AGC of mic signal"));
|
||||
sbSizer_speexpp->Add(m_ckboxSpeexpp, wxALIGN_LEFT, 2);
|
||||
|
||||
bSizer30->Add(sbSizer_speexpp, 0, wxALL, 0);
|
||||
|
||||
// EQ Filters -----------------------------------------------------------
|
||||
|
||||
wxStaticBoxSizer* eqMicInSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Mic In Equaliser")), wxVERTICAL);
|
||||
wxBoxSizer* eqMicInSizer1 = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* eqMicInSizer2 = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_MicInBass = newEQ(eqMicInSizer1, "Bass" , MAX_FREQ_BASS, disableQ);
|
||||
m_MicInTreble = newEQ(eqMicInSizer1, "Treble", MAX_FREQ_TREBLE, disableQ);
|
||||
eqMicInSizer->Add(eqMicInSizer1);
|
||||
|
||||
m_MicInEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
|
||||
eqMicInSizer2->Add(m_MicInEnable,0,wxALIGN_CENTRE_VERTICAL|wxRIGHT,10);
|
||||
m_MicInMid = newEQ(eqMicInSizer2, "Mid" , MAX_FREQ_DEF, enableQ);
|
||||
m_MicInDefault = new wxButton(this, wxID_ANY, wxT("Default"));
|
||||
eqMicInSizer2->Add(m_MicInDefault,0,wxALIGN_CENTRE_VERTICAL|wxLEFT,20);
|
||||
eqMicInSizer->Add(eqMicInSizer2);
|
||||
|
||||
wxStaticBoxSizer* eqSpkOutSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Speaker Out Equaliser")), wxVERTICAL);
|
||||
wxBoxSizer* eqSpkOutSizer1 = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* eqSpkOutSizer2 = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_SpkOutBass = newEQ(eqSpkOutSizer1, "Bass" , MAX_FREQ_BASS, disableQ);
|
||||
m_SpkOutTreble = newEQ(eqSpkOutSizer1, "Treble", MAX_FREQ_TREBLE, disableQ);
|
||||
eqSpkOutSizer->Add(eqSpkOutSizer1);
|
||||
|
||||
m_SpkOutEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
|
||||
eqSpkOutSizer2->Add(m_SpkOutEnable,0,wxALIGN_CENTRE_VERTICAL|wxRIGHT,10);
|
||||
m_SpkOutMid = newEQ(eqSpkOutSizer2, "Mid" , MAX_FREQ_DEF, enableQ);
|
||||
m_SpkOutDefault = new wxButton(this, wxID_ANY, wxT("Default"));
|
||||
eqSpkOutSizer2->Add(m_SpkOutDefault,0,wxALIGN_CENTRE_VERTICAL|wxLEFT,20);
|
||||
eqSpkOutSizer->Add(eqSpkOutSizer2);
|
||||
|
||||
bSizer30->Add(eqMicInSizer, 0, wxALL, 0);
|
||||
bSizer30->Add(eqSpkOutSizer, 0, wxALL, 0);
|
||||
|
||||
// Storgage for spectrum magnitude plots ------------------------------------
|
||||
|
||||
m_MicInMagdB = new float[F_MAG_N];
|
||||
for(int i=0; i<F_MAG_N; i++)
|
||||
m_MicInMagdB[i] = 0.0;
|
||||
|
||||
m_SpkOutMagdB = new float[F_MAG_N];
|
||||
for(int i=0; i<F_MAG_N; i++)
|
||||
m_SpkOutMagdB[i] = 0.0;
|
||||
|
||||
// Spectrum Plots -----------------------------------------------------------
|
||||
|
||||
long nb_style = wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS;
|
||||
m_auiNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(-1,200), nb_style);
|
||||
m_auiNotebook->SetFont(wxFont(8, 70, 90, 90, false, wxEmptyString));
|
||||
|
||||
bSizer30->Add(m_auiNotebook, 0, wxEXPAND|wxALL, 3);
|
||||
|
||||
m_MicInFreqRespPlot = new PlotSpectrum((wxFrame*) m_auiNotebook, m_MicInMagdB, F_MAG_N, FILTER_MIN_MAG_DB, FILTER_MAX_MAG_DB);
|
||||
m_auiNotebook->AddPage(m_MicInFreqRespPlot, _("Microphone In Equaliser"));
|
||||
|
||||
m_SpkOutFreqRespPlot = new PlotSpectrum((wxFrame*)m_auiNotebook, m_SpkOutMagdB, F_MAG_N, FILTER_MIN_MAG_DB, FILTER_MAX_MAG_DB);
|
||||
m_auiNotebook->AddPage(m_SpkOutFreqRespPlot, _("Speaker Out Equaliser"));
|
||||
|
||||
// OK - Cancel buttons at the bottom --------------------------
|
||||
|
||||
wxBoxSizer* bSizer31 = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_sdbSizer5OK = new wxButton(this, wxID_OK);
|
||||
bSizer31->Add(m_sdbSizer5OK, 0, wxALL, 2);
|
||||
|
||||
m_sdbSizer5Cancel = new wxButton(this, wxID_CANCEL);
|
||||
bSizer31->Add(m_sdbSizer5Cancel, 0, wxALL, 2);
|
||||
|
||||
bSizer30->Add(bSizer31, 0, wxALIGN_RIGHT|wxALL, 0);
|
||||
|
||||
this->SetSizer(bSizer30);
|
||||
this->Layout();
|
||||
|
||||
this->Centre(wxBOTH);
|
||||
|
||||
// Connect Events -------------------------------------------------------
|
||||
|
||||
this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(FilterDlg::OnInitDialog));
|
||||
|
||||
m_codec2LPCPostFilterEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnEnable), NULL, this);
|
||||
m_codec2LPCPostFilterBassBoost->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnBassBoost), NULL, this);
|
||||
m_codec2LPCPostFilterBeta->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnBetaScroll), NULL, this);
|
||||
m_codec2LPCPostFilterGamma->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnGammaScroll), NULL, this);
|
||||
m_LPCPostFilterDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnLPCPostFilterDefault), NULL, this);
|
||||
|
||||
m_ckboxSpeexpp->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpeexppEnable), NULL, this);
|
||||
|
||||
m_MicInBass.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassFreqScroll), NULL, this);
|
||||
m_MicInBass.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassGainScroll), NULL, this);
|
||||
m_MicInTreble.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleFreqScroll), NULL, this);
|
||||
m_MicInTreble.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleGainScroll), NULL, this);
|
||||
m_MicInMid.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidFreqScroll), NULL, this);
|
||||
m_MicInMid.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidGainScroll), NULL, this);
|
||||
m_MicInMid.sliderQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidQScroll), NULL, this);
|
||||
m_MicInEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnMicInEnable), NULL, this);
|
||||
m_MicInDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnMicInDefault), NULL, this);
|
||||
|
||||
m_SpkOutBass.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassFreqScroll), NULL, this);
|
||||
m_SpkOutBass.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassGainScroll), NULL, this);
|
||||
m_SpkOutTreble.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleFreqScroll), NULL, this);
|
||||
m_SpkOutTreble.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleGainScroll), NULL, this);
|
||||
m_SpkOutMid.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidFreqScroll), NULL, this);
|
||||
m_SpkOutMid.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidGainScroll), NULL, this);
|
||||
m_SpkOutMid.sliderQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidQScroll), NULL, this);
|
||||
m_SpkOutEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpkOutEnable), NULL, this);
|
||||
m_SpkOutDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnSpkOutDefault), NULL, this);
|
||||
|
||||
m_sdbSizer5Cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnCancel), NULL, this);
|
||||
m_sdbSizer5OK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnOK), NULL, this);
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ~FilterDlg()
|
||||
//-------------------------------------------------------------------------
|
||||
FilterDlg::~FilterDlg()
|
||||
{
|
||||
delete m_MicInMagdB;
|
||||
delete m_SpkOutMagdB;
|
||||
|
||||
// Disconnect Events
|
||||
|
||||
this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(FilterDlg::OnInitDialog));
|
||||
|
||||
m_codec2LPCPostFilterEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnEnable), NULL, this);
|
||||
m_codec2LPCPostFilterBassBoost->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnBassBoost), NULL, this);
|
||||
m_codec2LPCPostFilterBeta->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnBetaScroll), NULL, this);
|
||||
m_codec2LPCPostFilterGamma->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnGammaScroll), NULL, this);
|
||||
m_LPCPostFilterDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnLPCPostFilterDefault), NULL, this);
|
||||
|
||||
m_MicInBass.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassFreqScroll), NULL, this);
|
||||
m_MicInBass.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassGainScroll), NULL, this);
|
||||
m_MicInTreble.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleFreqScroll), NULL, this);
|
||||
m_MicInTreble.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleGainScroll), NULL, this);
|
||||
m_MicInMid.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidFreqScroll), NULL, this);
|
||||
m_MicInMid.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidGainScroll), NULL, this);
|
||||
m_MicInMid.sliderQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidQScroll), NULL, this);
|
||||
m_MicInEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnMicInEnable), NULL, this);
|
||||
m_MicInDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnMicInDefault), NULL, this);
|
||||
|
||||
m_SpkOutBass.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassFreqScroll), NULL, this);
|
||||
m_SpkOutBass.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassGainScroll), NULL, this);
|
||||
m_SpkOutTreble.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleFreqScroll), NULL, this);
|
||||
m_SpkOutTreble.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleGainScroll), NULL, this);
|
||||
m_SpkOutMid.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidFreqScroll), NULL, this);
|
||||
m_SpkOutMid.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidGainScroll), NULL, this);
|
||||
m_SpkOutMid.sliderQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidQScroll), NULL, this);
|
||||
m_SpkOutEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpkOutEnable), NULL, this);
|
||||
m_SpkOutDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnSpkOutDefault), NULL, this);
|
||||
|
||||
m_sdbSizer5Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnCancel), NULL, this);
|
||||
m_sdbSizer5OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnOK), NULL, this);
|
||||
}
|
||||
|
||||
void FilterDlg::newLPCPFControl(wxSlider **slider, wxStaticText **stValue, wxSizer *s, wxString controlName)
|
||||
{
|
||||
wxBoxSizer *bs = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxStaticText* st = new wxStaticText(this, wxID_ANY, controlName, wxDefaultPosition, wxSize(70,-1), wxALIGN_RIGHT);
|
||||
bs->Add(st, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 2);
|
||||
|
||||
*slider = new wxSlider(this, wxID_ANY, 0, 0, SLIDER_MAX, wxDefaultPosition, wxSize(SLIDER_LENGTH,wxDefaultCoord));
|
||||
bs->Add(*slider, 1, wxALIGN_CENTER_VERTICAL|wxALL, 2);
|
||||
|
||||
*stValue = new wxStaticText(this, wxID_ANY, wxT("0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
bs->Add(*stValue, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 2);
|
||||
|
||||
s->Add(bs, 0);
|
||||
}
|
||||
|
||||
void FilterDlg::newEQControl(wxSlider** slider, wxStaticText** value, wxStaticBoxSizer *bs, wxString controlName)
|
||||
{
|
||||
wxStaticText* label = new wxStaticText(this, wxID_ANY, controlName, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
|
||||
bs->Add(label, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 0);
|
||||
|
||||
*slider = new wxSlider(this, wxID_ANY, 0, 0, SLIDER_MAX, wxDefaultPosition, wxSize(SLIDER_LENGTH,wxDefaultCoord));
|
||||
bs->Add(*slider, 1, wxALIGN_CENTER_VERTICAL|wxALL, 0);
|
||||
|
||||
*value = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(40,-1), wxALIGN_LEFT);
|
||||
bs->Add(*value, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxRIGHT, 5);
|
||||
}
|
||||
|
||||
EQ FilterDlg::newEQ(wxSizer *bs, wxString eqName, float maxFreqHz, bool enableQ)
|
||||
{
|
||||
EQ eq;
|
||||
|
||||
wxStaticBoxSizer *bsEQ = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, eqName), wxHORIZONTAL);
|
||||
|
||||
newEQControl(&eq.sliderFreq, &eq.valueFreq, bsEQ, "Freq");
|
||||
eq.maxFreqHz = maxFreqHz;
|
||||
eq.sliderFreqId = eq.sliderFreq->GetId();
|
||||
|
||||
newEQControl(&eq.sliderGain, &eq.valueGain, bsEQ, "Gain");
|
||||
if (enableQ)
|
||||
newEQControl(&eq.sliderQ, &eq.valueQ, bsEQ, "Q");
|
||||
else
|
||||
eq.sliderQ = NULL;
|
||||
|
||||
bs->Add(bsEQ);
|
||||
|
||||
return eq;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ExchangeData()
|
||||
//-------------------------------------------------------------------------
|
||||
void FilterDlg::ExchangeData(int inout, bool storePersistent)
|
||||
{
|
||||
wxConfigBase *pConfig = wxConfigBase::Get();
|
||||
if(inout == EXCHANGE_DATA_IN)
|
||||
{
|
||||
// LPC Post filter
|
||||
|
||||
m_codec2LPCPostFilterEnable->SetValue(wxGetApp().m_codec2LPCPostFilterEnable);
|
||||
m_codec2LPCPostFilterBassBoost->SetValue(wxGetApp().m_codec2LPCPostFilterBassBoost);
|
||||
m_beta = wxGetApp().m_codec2LPCPostFilterBeta; setBeta();
|
||||
m_gamma = wxGetApp().m_codec2LPCPostFilterGamma; setGamma();
|
||||
|
||||
// Speex Pre-Processor
|
||||
|
||||
m_ckboxSpeexpp->SetValue(wxGetApp().m_speexpp_enable);
|
||||
|
||||
// Mic In Equaliser
|
||||
|
||||
m_MicInBass.freqHz = wxGetApp().m_MicInBassFreqHz;
|
||||
m_MicInBass.freqHz = limit(m_MicInBass.freqHz, 1.0, MAX_FREQ_BASS);
|
||||
setFreq(&m_MicInBass);
|
||||
m_MicInBass.gaindB = wxGetApp().m_MicInBassGaindB;
|
||||
m_MicInBass.gaindB = limit(m_MicInBass.gaindB, MIN_GAIN, MAX_GAIN);
|
||||
setGain(&m_MicInBass);
|
||||
|
||||
m_MicInTreble.freqHz = wxGetApp().m_MicInTrebleFreqHz;
|
||||
m_MicInTreble.freqHz = limit(m_MicInTreble.freqHz, 1.0, MAX_FREQ_TREBLE);
|
||||
setFreq(&m_MicInTreble);
|
||||
m_MicInTreble.gaindB = wxGetApp().m_MicInTrebleGaindB;
|
||||
m_MicInTreble.gaindB = limit(m_MicInTreble.gaindB, MIN_GAIN, MAX_GAIN);
|
||||
setGain(&m_MicInTreble);
|
||||
|
||||
m_MicInMid.freqHz = wxGetApp().m_MicInMidFreqHz;
|
||||
m_MicInMid.freqHz = limit(m_MicInMid.freqHz, 1.0, MAX_FREQ_TREBLE);
|
||||
setFreq(&m_MicInMid);
|
||||
m_MicInMid.gaindB = wxGetApp().m_MicInMidGaindB;
|
||||
m_MicInMid.gaindB = limit(m_MicInMid.gaindB, MIN_GAIN, MAX_GAIN);
|
||||
setGain(&m_MicInMid);
|
||||
m_MicInMid.Q = wxGetApp().m_MicInMidQ;
|
||||
m_MicInMid.Q = limit(m_MicInMid.Q, pow(10.0,MIN_LOG10_Q), pow(10.0, MAX_LOG10_Q));
|
||||
setQ(&m_MicInMid);
|
||||
|
||||
m_MicInEnable->SetValue(wxGetApp().m_MicInEQEnable);
|
||||
|
||||
plotMicInFilterSpectrum();
|
||||
|
||||
// Spk Out Equaliser
|
||||
|
||||
m_SpkOutBass.freqHz = wxGetApp().m_SpkOutBassFreqHz;
|
||||
m_SpkOutBass.freqHz = limit(m_SpkOutBass.freqHz, 1.0, MAX_FREQ_BASS);
|
||||
setFreq(&m_SpkOutBass);
|
||||
m_SpkOutBass.gaindB = wxGetApp().m_SpkOutBassGaindB;
|
||||
m_SpkOutBass.gaindB = limit(m_SpkOutBass.gaindB, MIN_GAIN, MAX_GAIN);
|
||||
setGain(&m_SpkOutBass);
|
||||
|
||||
m_SpkOutTreble.freqHz = wxGetApp().m_SpkOutTrebleFreqHz;
|
||||
m_SpkOutTreble.freqHz = limit(m_SpkOutTreble.freqHz, 1.0, MAX_FREQ_TREBLE);
|
||||
setFreq(&m_SpkOutTreble);
|
||||
m_SpkOutTreble.gaindB = wxGetApp().m_SpkOutTrebleGaindB;
|
||||
m_SpkOutTreble.gaindB = limit(m_SpkOutTreble.gaindB, MIN_GAIN, MAX_GAIN);
|
||||
setGain(&m_SpkOutTreble);
|
||||
|
||||
m_SpkOutMid.freqHz = wxGetApp().m_SpkOutMidFreqHz;
|
||||
m_SpkOutMid.freqHz = limit(m_SpkOutMid.freqHz, 1.0, MAX_FREQ_TREBLE);
|
||||
setFreq(&m_SpkOutMid);
|
||||
m_SpkOutMid.gaindB = wxGetApp().m_SpkOutMidGaindB;
|
||||
m_SpkOutMid.gaindB = limit(m_SpkOutMid.gaindB, MIN_GAIN, MAX_GAIN);
|
||||
setGain(&m_SpkOutMid);
|
||||
m_SpkOutMid.Q = wxGetApp().m_SpkOutMidQ;
|
||||
m_SpkOutMid.Q = limit(m_SpkOutMid.Q, pow(10.0,MIN_LOG10_Q), pow(10.0, MAX_LOG10_Q));
|
||||
setQ(&m_SpkOutMid);
|
||||
|
||||
m_SpkOutEnable->SetValue(wxGetApp().m_SpkOutEQEnable);
|
||||
|
||||
plotSpkOutFilterSpectrum();
|
||||
}
|
||||
if(inout == EXCHANGE_DATA_OUT)
|
||||
{
|
||||
// LPC Post filter
|
||||
|
||||
wxGetApp().m_codec2LPCPostFilterEnable = m_codec2LPCPostFilterEnable->GetValue();
|
||||
wxGetApp().m_codec2LPCPostFilterBassBoost = m_codec2LPCPostFilterBassBoost->GetValue();
|
||||
wxGetApp().m_codec2LPCPostFilterBeta = m_beta;
|
||||
wxGetApp().m_codec2LPCPostFilterGamma = m_gamma;
|
||||
|
||||
// Speex Pre-Processor
|
||||
|
||||
wxGetApp().m_speexpp_enable = m_ckboxSpeexpp->GetValue();
|
||||
|
||||
// Mic In Equaliser
|
||||
|
||||
wxGetApp().m_MicInBassFreqHz = m_MicInBass.freqHz;
|
||||
wxGetApp().m_MicInBassGaindB = m_MicInBass.gaindB;
|
||||
|
||||
wxGetApp().m_MicInTrebleFreqHz = m_MicInTreble.freqHz;
|
||||
wxGetApp().m_MicInTrebleGaindB = m_MicInTreble.gaindB;
|
||||
|
||||
wxGetApp().m_MicInMidFreqHz = m_MicInMid.freqHz;
|
||||
wxGetApp().m_MicInMidGaindB = m_MicInMid.gaindB;
|
||||
wxGetApp().m_MicInMidQ = m_MicInMid.Q;
|
||||
|
||||
// Spk Out Equaliser
|
||||
|
||||
wxGetApp().m_SpkOutBassFreqHz = m_SpkOutBass.freqHz;
|
||||
wxGetApp().m_SpkOutBassGaindB = m_SpkOutBass.gaindB;
|
||||
|
||||
wxGetApp().m_SpkOutTrebleFreqHz = m_SpkOutTreble.freqHz;
|
||||
wxGetApp().m_SpkOutTrebleGaindB = m_SpkOutTreble.gaindB;
|
||||
|
||||
wxGetApp().m_SpkOutMidFreqHz = m_SpkOutMid.freqHz;
|
||||
wxGetApp().m_SpkOutMidGaindB = m_SpkOutMid.gaindB;
|
||||
wxGetApp().m_SpkOutMidQ = m_SpkOutMid.Q;
|
||||
|
||||
if (storePersistent) {
|
||||
pConfig->Write(wxT("/Filter/codec2LPCPostFilterEnable"), wxGetApp().m_codec2LPCPostFilterEnable);
|
||||
pConfig->Write(wxT("/Filter/codec2LPCPostFilterBassBoost"), wxGetApp().m_codec2LPCPostFilterBassBoost);
|
||||
pConfig->Write(wxT("/Filter/codec2LPCPostFilterBeta"), (int)(m_beta*100.0));
|
||||
pConfig->Write(wxT("/Filter/codec2LPCPostFilterGamma"), (int)(m_gamma*100.0));
|
||||
|
||||
pConfig->Write(wxT("/Filter/speexpp_enable"), wxGetApp().m_speexpp_enable);
|
||||
|
||||
pConfig->Write(wxT("/Filter/MicInBassFreqHz"), (int)m_MicInBass.freqHz);
|
||||
pConfig->Write(wxT("/Filter/MicInBassGaindB"), (int)(10.0*m_MicInBass.gaindB));
|
||||
pConfig->Write(wxT("/Filter/MicInTrebleFreqHz"), (int)m_MicInTreble.freqHz);
|
||||
pConfig->Write(wxT("/Filter/MicInTrebleGaindB"), (int)(10.0*m_MicInTreble.gaindB));
|
||||
pConfig->Write(wxT("/Filter/MicInMidFreqHz"), (int)m_MicInMid.freqHz);
|
||||
pConfig->Write(wxT("/Filter/MicInMidGaindB"), (int)(10.0*m_MicInMid.gaindB));
|
||||
pConfig->Write(wxT("/Filter/MicInMidQ"), (int)(100.0*m_MicInMid.Q));
|
||||
|
||||
pConfig->Write(wxT("/Filter/SpkOutBassFreqHz"), (int)m_SpkOutBass.freqHz);
|
||||
pConfig->Write(wxT("/Filter/SpkOutBassGaindB"), (int)(10.0*m_SpkOutBass.gaindB));
|
||||
pConfig->Write(wxT("/Filter/SpkOutTrebleFreqHz"), (int)m_SpkOutTreble.freqHz);
|
||||
pConfig->Write(wxT("/Filter/SpkOutTrebleGaindB"), (int)(10.0*m_SpkOutTreble.gaindB));
|
||||
pConfig->Write(wxT("/Filter/SpkOutMidQ"), (int)(100.0*m_SpkOutMid.Q));
|
||||
pConfig->Write(wxT("/Filter/SpkOutMidFreqHz"), (int)m_SpkOutMid.freqHz);
|
||||
pConfig->Write(wxT("/Filter/SpkOutMidGaindB"), (int)(10.0*m_SpkOutMid.gaindB));
|
||||
|
||||
pConfig->Flush();
|
||||
}
|
||||
}
|
||||
delete wxConfigBase::Set((wxConfigBase *) NULL);
|
||||
}
|
||||
|
||||
float FilterDlg::limit(float value, float min, float max) {
|
||||
if (value < min) return min;
|
||||
if (value > max) return max;
|
||||
return value;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnCancel()
|
||||
//-------------------------------------------------------------------------
|
||||
void FilterDlg::OnCancel(wxCommandEvent& event)
|
||||
{
|
||||
this->EndModal(wxID_CANCEL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnDefault()
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
void FilterDlg::OnLPCPostFilterDefault(wxCommandEvent& event)
|
||||
{
|
||||
m_beta = CODEC2_LPC_PF_BETA; setBeta();
|
||||
m_gamma = CODEC2_LPC_PF_GAMMA; setGamma();
|
||||
m_codec2LPCPostFilterEnable->SetValue(true);
|
||||
m_codec2LPCPostFilterBassBoost->SetValue(true);
|
||||
}
|
||||
|
||||
void FilterDlg::OnMicInDefault(wxCommandEvent& event)
|
||||
{
|
||||
m_MicInBass.freqHz = 100.0;
|
||||
m_MicInBass.gaindB = 0.0;
|
||||
setFreq(&m_MicInBass); setGain(&m_MicInBass);
|
||||
|
||||
m_MicInTreble.freqHz = 3000.0;
|
||||
m_MicInTreble.gaindB = 0.0;
|
||||
setFreq(&m_MicInTreble); setGain(&m_MicInTreble);
|
||||
|
||||
m_MicInMid.freqHz = 1500.0;
|
||||
m_MicInMid.gaindB = 0.0;
|
||||
m_MicInMid.Q = 1.0;
|
||||
setFreq(&m_MicInMid); setGain(&m_MicInMid); setQ(&m_MicInMid);
|
||||
|
||||
plotMicInFilterSpectrum();
|
||||
}
|
||||
|
||||
void FilterDlg::OnSpkOutDefault(wxCommandEvent& event)
|
||||
{
|
||||
m_SpkOutBass.freqHz = 100.0;
|
||||
m_SpkOutBass.gaindB = 0.0;
|
||||
setFreq(&m_SpkOutBass); setGain(&m_SpkOutBass);
|
||||
|
||||
m_SpkOutTreble.freqHz = 3000.0;
|
||||
m_SpkOutTreble.gaindB = 0.0;
|
||||
setFreq(&m_SpkOutTreble); setGain(&m_SpkOutTreble);
|
||||
|
||||
m_SpkOutMid.freqHz = 1500.0;
|
||||
m_SpkOutMid.gaindB = 0.0;
|
||||
m_SpkOutMid.Q = 1.0;
|
||||
setFreq(&m_SpkOutMid); setGain(&m_SpkOutMid); setQ(&m_SpkOutMid);
|
||||
|
||||
plotSpkOutFilterSpectrum();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnOK()
|
||||
//-------------------------------------------------------------------------
|
||||
void FilterDlg::OnOK(wxCommandEvent& event)
|
||||
{
|
||||
//printf("FilterDlg::OnOK\n");
|
||||
ExchangeData(EXCHANGE_DATA_OUT, true);
|
||||
this->EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnClose()
|
||||
//-------------------------------------------------------------------------
|
||||
void FilterDlg::OnClose(wxCloseEvent& event)
|
||||
{
|
||||
this->EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnInitDialog()
|
||||
//-------------------------------------------------------------------------
|
||||
void FilterDlg::OnInitDialog(wxInitDialogEvent& event)
|
||||
{
|
||||
//printf("FilterDlg::OnInitDialog\n");
|
||||
ExchangeData(EXCHANGE_DATA_IN, false);
|
||||
//printf("m_beta: %f\n", m_beta);
|
||||
}
|
||||
|
||||
void FilterDlg::setBeta(void) {
|
||||
wxString buf;
|
||||
buf.Printf(wxT("%3.2f"), m_beta);
|
||||
m_staticTextBeta->SetLabel(buf);
|
||||
int slider = (int)(m_beta*SLIDER_MAX + 0.5);
|
||||
m_codec2LPCPostFilterBeta->SetValue(slider);
|
||||
}
|
||||
|
||||
void FilterDlg::setCodec2(void) {
|
||||
if (m_running) {
|
||||
assert(g_pfreedv->codec2 != NULL);
|
||||
codec2_set_lpc_post_filter(g_pfreedv->codec2,
|
||||
m_codec2LPCPostFilterEnable->GetValue(),
|
||||
m_codec2LPCPostFilterBassBoost->GetValue(),
|
||||
m_beta, m_gamma);
|
||||
}
|
||||
}
|
||||
|
||||
void FilterDlg::setGamma(void) {
|
||||
wxString buf;
|
||||
buf.Printf(wxT("%3.2f"), m_gamma);
|
||||
m_staticTextGamma->SetLabel(buf);
|
||||
int slider = (int)(m_gamma*SLIDER_MAX + 0.5);
|
||||
m_codec2LPCPostFilterGamma->SetValue(slider);
|
||||
}
|
||||
|
||||
void FilterDlg::OnEnable(wxScrollEvent& event) {
|
||||
setCodec2();
|
||||
}
|
||||
|
||||
void FilterDlg::OnBassBoost(wxScrollEvent& event) {
|
||||
setCodec2();
|
||||
}
|
||||
|
||||
void FilterDlg::OnBetaScroll(wxScrollEvent& event) {
|
||||
m_beta = (float)m_codec2LPCPostFilterBeta->GetValue()/SLIDER_MAX;
|
||||
setBeta();
|
||||
setCodec2();
|
||||
}
|
||||
|
||||
void FilterDlg::OnGammaScroll(wxScrollEvent& event) {
|
||||
m_gamma = (float)m_codec2LPCPostFilterGamma->GetValue()/SLIDER_MAX;
|
||||
setGamma();
|
||||
setCodec2();
|
||||
}
|
||||
|
||||
// immediately change enable flags rather using ExchangeData() so we can switch on and off at run time
|
||||
|
||||
void FilterDlg::OnSpeexppEnable(wxScrollEvent& event) {
|
||||
wxGetApp().m_speexpp_enable = m_ckboxSpeexpp->GetValue();
|
||||
}
|
||||
|
||||
void FilterDlg::OnMicInEnable(wxScrollEvent& event) {
|
||||
wxGetApp().m_MicInEQEnable = m_MicInEnable->GetValue();
|
||||
}
|
||||
|
||||
void FilterDlg::OnSpkOutEnable(wxScrollEvent& event) {
|
||||
wxGetApp().m_SpkOutEQEnable = m_SpkOutEnable->GetValue();
|
||||
//printf("wxGetApp().m_SpkOutEQEnable: %d\n", wxGetApp().m_SpkOutEQEnable);
|
||||
}
|
||||
|
||||
void FilterDlg::setFreq(EQ *eq)
|
||||
{
|
||||
wxString buf;
|
||||
buf.Printf(wxT("%3.0f"), eq->freqHz);
|
||||
eq->valueFreq->SetLabel(buf);
|
||||
int slider = (int)((eq->freqHz/eq->maxFreqHz)*SLIDER_MAX + 0.5);
|
||||
eq->sliderFreq->SetValue(slider);
|
||||
}
|
||||
|
||||
void FilterDlg::sliderToFreq(EQ *eq, bool micIn)
|
||||
{
|
||||
eq->freqHz = ((float)eq->sliderFreq->GetValue()/SLIDER_MAX)*eq->maxFreqHz;
|
||||
if (eq->freqHz < 1.0) eq->freqHz = 1.0; // sox doesn't like 0 Hz;
|
||||
setFreq(eq);
|
||||
if (micIn) {
|
||||
plotMicInFilterSpectrum();
|
||||
adjRunTimeMicInFilter();
|
||||
}
|
||||
else {
|
||||
plotSpkOutFilterSpectrum();
|
||||
adjRunTimeSpkOutFilter();
|
||||
}
|
||||
}
|
||||
|
||||
void FilterDlg::setGain(EQ *eq)
|
||||
{
|
||||
wxString buf;
|
||||
buf.Printf(wxT("%3.1f"), eq->gaindB);
|
||||
eq->valueGain->SetLabel(buf);
|
||||
int slider = (int)(((eq->gaindB-MIN_GAIN)/(MAX_GAIN-MIN_GAIN))*SLIDER_MAX + 0.5);
|
||||
eq->sliderGain->SetValue(slider);
|
||||
}
|
||||
|
||||
void FilterDlg::sliderToGain(EQ *eq, bool micIn)
|
||||
{
|
||||
float range = MAX_GAIN-MIN_GAIN;
|
||||
|
||||
eq->gaindB = MIN_GAIN + range*((float)eq->sliderGain->GetValue()/SLIDER_MAX);
|
||||
//printf("gaindB: %f\n", eq->gaindB);
|
||||
setGain(eq);
|
||||
if (micIn) {
|
||||
plotMicInFilterSpectrum();
|
||||
adjRunTimeMicInFilter();
|
||||
}
|
||||
else {
|
||||
plotSpkOutFilterSpectrum();
|
||||
adjRunTimeSpkOutFilter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FilterDlg::setQ(EQ *eq)
|
||||
{
|
||||
wxString buf;
|
||||
buf.Printf(wxT("%2.1f"), eq->Q);
|
||||
eq->valueQ->SetLabel(buf);
|
||||
|
||||
float log10_range = MAX_LOG10_Q - MIN_LOG10_Q;
|
||||
|
||||
int slider = (int)(((log10(eq->Q+1E-6)-MIN_LOG10_Q)/log10_range)*SLIDER_MAX + 0.5);
|
||||
eq->sliderQ->SetValue(slider);
|
||||
}
|
||||
|
||||
void FilterDlg::sliderToQ(EQ *eq, bool micIn)
|
||||
{
|
||||
float log10_range = MAX_LOG10_Q - MIN_LOG10_Q;
|
||||
|
||||
float sliderNorm = (float)eq->sliderQ->GetValue()/SLIDER_MAX;
|
||||
float log10Q = MIN_LOG10_Q + sliderNorm*(log10_range);
|
||||
eq->Q = pow(10.0, log10Q);
|
||||
//printf("log10Q: %f eq->Q: %f\n", log10Q, eq->Q);
|
||||
setQ(eq);
|
||||
if (micIn) {
|
||||
plotMicInFilterSpectrum();
|
||||
adjRunTimeMicInFilter();
|
||||
}
|
||||
else {
|
||||
plotSpkOutFilterSpectrum();
|
||||
adjRunTimeSpkOutFilter();
|
||||
}
|
||||
}
|
||||
|
||||
void FilterDlg::plotMicInFilterSpectrum(void) {
|
||||
plotFilterSpectrum(&m_MicInBass, &m_MicInMid, &m_MicInTreble, m_MicInFreqRespPlot, m_MicInMagdB);
|
||||
}
|
||||
|
||||
void FilterDlg::plotSpkOutFilterSpectrum(void) {
|
||||
plotFilterSpectrum(&m_SpkOutBass, &m_SpkOutMid, &m_SpkOutTreble, m_SpkOutFreqRespPlot, m_SpkOutMagdB);
|
||||
}
|
||||
|
||||
void FilterDlg::adjRunTimeMicInFilter(void) {
|
||||
// signal an adjustment in running filter coeffs
|
||||
|
||||
if (m_running) {
|
||||
ExchangeData(EXCHANGE_DATA_OUT, false);
|
||||
*m_newMicInFilter = true;
|
||||
}
|
||||
}
|
||||
|
||||
void FilterDlg::adjRunTimeSpkOutFilter(void) {
|
||||
// signal an adjustment in running filter coeffs
|
||||
|
||||
if (m_running) {
|
||||
ExchangeData(EXCHANGE_DATA_OUT, false);
|
||||
*m_newSpkOutFilter = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FilterDlg::plotFilterSpectrum(EQ *eqBass, EQ *eqMid, EQ *eqTreble, PlotSpectrum* freqRespPlot, float *magdB) {
|
||||
char *argBass[10];
|
||||
char *argTreble[10];
|
||||
char *argMid[10];
|
||||
char argstorage[10][80];
|
||||
float magBass[F_MAG_N];
|
||||
float magTreble[F_MAG_N];
|
||||
float magMid[F_MAG_N];
|
||||
int i;
|
||||
|
||||
for(i=0; i<10; i++) {
|
||||
argBass[i] = &argstorage[i][0];
|
||||
argTreble[i] = &argstorage[i][0];
|
||||
argMid[i] = &argstorage[i][0];
|
||||
}
|
||||
sprintf(argBass[0], "bass");
|
||||
sprintf(argBass[1], "%f", eqBass->gaindB+1E-6);
|
||||
sprintf(argBass[2], "%f", eqBass->freqHz);
|
||||
|
||||
calcFilterSpectrum(magBass, 2, argBass);
|
||||
|
||||
sprintf(argTreble[0], "treble");
|
||||
sprintf(argTreble[1], "%f", eqTreble->gaindB+1E-6);
|
||||
sprintf(argTreble[2], "%f", eqTreble->freqHz);
|
||||
|
||||
calcFilterSpectrum(magTreble, 2, argTreble);
|
||||
|
||||
sprintf(argTreble[0], "equalizer");
|
||||
sprintf(argTreble[1], "%f", eqMid->freqHz);
|
||||
sprintf(argTreble[2], "%f", eqMid->Q);
|
||||
sprintf(argTreble[3], "%f", eqMid->gaindB+1E-6);
|
||||
|
||||
calcFilterSpectrum(magMid, 3, argMid);
|
||||
|
||||
for(i=0; i<F_MAG_N; i++)
|
||||
magdB[i] = magBass[i] + magMid[i] + magTreble[i];
|
||||
freqRespPlot->m_newdata = true;
|
||||
freqRespPlot->Refresh();
|
||||
}
|
||||
|
||||
void FilterDlg::calcFilterSpectrum(float magdB[], int argc, char *argv[]) {
|
||||
void *sbq;
|
||||
short in[NIMP];
|
||||
short out[NIMP];
|
||||
COMP X[F_MAG_N];
|
||||
float f, w;
|
||||
int i, k;
|
||||
|
||||
// find impulse response -----------------------------------
|
||||
|
||||
for(i=0; i<NIMP; i++)
|
||||
in[i] = 0;
|
||||
in[0] = IMP_AMP;
|
||||
|
||||
//printf("argv[0]: %s argv[1]: %s\n", argv[0], argv[1]);
|
||||
sbq = sox_biquad_create(argc, (const char **)argv);
|
||||
|
||||
sox_biquad_filter(sbq, out, in, NIMP);
|
||||
//for(i=0; i<NIMP; i++)
|
||||
// printf("%d\n", out[i]);
|
||||
|
||||
sox_biquad_destroy(sbq);
|
||||
|
||||
//for(i=0; i<NIMP; i++)
|
||||
// out[i] = 0.0;
|
||||
//out[0] = IMP_AMP;
|
||||
|
||||
// calculate discrete time continous frequency Fourer transform
|
||||
// doing this from first principles rather than FFT for no good reason
|
||||
|
||||
for(f=0,i=0; f<MAX_F_HZ; f+=F_STEP_DFT,i++) {
|
||||
w = M_PI*f/(FS/2);
|
||||
X[i].real = 0.0; X[i].imag = 0.0;
|
||||
for(k=0; k<NIMP; k++) {
|
||||
X[i].real += ((float)out[k]/IMP_AMP) * cos(w*k);
|
||||
X[i].imag -= ((float)out[k]/IMP_AMP) * sin(w*k);
|
||||
}
|
||||
magdB[i] = 10.0*log10(X[i].real* X[i].real + X[i].imag*X[i].imag + 1E-12);
|
||||
//printf("f: %f X[%d] = %f %f magdB = %f\n", f, i, X[i].real, X[i].imag, magdB[i]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
//==========================================================================
|
||||
// Name: dlg_filter.h
|
||||
// Purpose: Dialog for controlling Codec audio filtering
|
||||
// Created: Nov 25 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
#ifndef __FILTER_DIALOG__
|
||||
#define __FILTER_DIALOG__
|
||||
|
||||
#include "fdmdv2_main.h"
|
||||
|
||||
enum {disableQ = false, enableQ = true};
|
||||
|
||||
typedef struct {
|
||||
wxSlider *sliderFreq;
|
||||
wxStaticText *valueFreq;
|
||||
wxSlider *sliderGain;
|
||||
wxStaticText *valueGain;
|
||||
wxSlider *sliderQ;
|
||||
wxStaticText *valueQ;
|
||||
|
||||
int sliderFreqId;
|
||||
int sliderGainId;
|
||||
int sliderQId;
|
||||
|
||||
float freqHz;
|
||||
float gaindB;
|
||||
float Q;
|
||||
|
||||
float maxFreqHz;
|
||||
} EQ;
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class FilterDlg
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class FilterDlg : public wxDialog
|
||||
{
|
||||
public:
|
||||
FilterDlg( wxWindow* parent, bool running, bool *newMicInFilter, bool *newSpkOutFilter,
|
||||
wxWindowID id = wxID_ANY, const wxString& title = _("Filter"),
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 800, 630 ),
|
||||
long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~FilterDlg();
|
||||
|
||||
void ExchangeData(int inout, bool storePersistent);
|
||||
|
||||
protected:
|
||||
// Handlers for events.
|
||||
void OnCancel(wxCommandEvent& event);
|
||||
void OnOK(wxCommandEvent& event);
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void OnInitDialog(wxInitDialogEvent& event);
|
||||
void OnLPCPostFilterDefault(wxCommandEvent& event);
|
||||
|
||||
void OnBetaScroll(wxScrollEvent& event);
|
||||
void OnGammaScroll(wxScrollEvent& event);
|
||||
void OnEnable(wxScrollEvent& event);
|
||||
void OnBassBoost(wxScrollEvent& event);
|
||||
|
||||
void OnSpeexppEnable(wxScrollEvent& event);
|
||||
|
||||
void OnMicInBassFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInBass, true); }
|
||||
void OnMicInBassGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInBass, true); }
|
||||
void OnMicInTrebleFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInTreble, true); }
|
||||
void OnMicInTrebleGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInTreble, true); }
|
||||
void OnMicInMidFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInMid, true); }
|
||||
void OnMicInMidGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInMid, true); }
|
||||
void OnMicInMidQScroll(wxScrollEvent& event) { sliderToQ(&m_MicInMid, true); }
|
||||
void OnMicInEnable(wxScrollEvent& event);
|
||||
void OnMicInDefault(wxCommandEvent& event);
|
||||
|
||||
void OnSpkOutBassFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutBass, false); }
|
||||
void OnSpkOutBassGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutBass, false); }
|
||||
void OnSpkOutTrebleFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutTreble, false); }
|
||||
void OnSpkOutTrebleGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutTreble, false); }
|
||||
void OnSpkOutMidFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutMid, false); }
|
||||
void OnSpkOutMidGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutMid, false); }
|
||||
void OnSpkOutMidQScroll(wxScrollEvent& event) { sliderToQ(&m_SpkOutMid, false); }
|
||||
void OnSpkOutEnable(wxScrollEvent& event);
|
||||
void OnSpkOutDefault(wxCommandEvent& event);
|
||||
|
||||
wxStaticText* m_staticText8;
|
||||
wxCheckBox* m_codec2LPCPostFilterEnable;
|
||||
wxStaticText* m_staticText9;
|
||||
wxCheckBox* m_codec2LPCPostFilterBassBoost;
|
||||
wxStaticText* m_staticText91;
|
||||
wxSlider* m_codec2LPCPostFilterBeta;
|
||||
wxStaticText* m_staticTextBeta;
|
||||
wxStaticText* m_staticText911;
|
||||
wxSlider* m_codec2LPCPostFilterGamma;
|
||||
wxStaticText* m_staticTextGamma;
|
||||
wxButton* m_LPCPostFilterDefault;
|
||||
|
||||
wxCheckBox* m_ckboxSpeexpp;
|
||||
|
||||
wxStdDialogButtonSizer* m_sdbSizer5;
|
||||
wxButton* m_sdbSizer5OK;
|
||||
wxButton* m_sdbSizer5Cancel;
|
||||
PlotSpectrum* m_MicInFreqRespPlot;
|
||||
PlotSpectrum* m_SpkOutFreqRespPlot;
|
||||
|
||||
wxCheckBox* m_MicInEnable;
|
||||
wxButton* m_MicInDefault;
|
||||
wxCheckBox* m_SpkOutEnable;
|
||||
wxButton* m_SpkOutDefault;
|
||||
|
||||
float *m_MicInMagdB;
|
||||
float *m_SpkOutMagdB;
|
||||
|
||||
private:
|
||||
bool m_running;
|
||||
float m_beta;
|
||||
float m_gamma;
|
||||
|
||||
void setBeta(void); // sets slider and static text from m_beta
|
||||
void setGamma(void); // sets slider and static text from m_gamma
|
||||
void setCodec2(void);
|
||||
|
||||
void newEQControl(wxSlider** slider, wxStaticText** value, wxStaticBoxSizer *bs, wxString controlName);
|
||||
EQ newEQ(wxSizer *bs, wxString eqName, float maxFreqHz, bool enableQ);
|
||||
void newLPCPFControl(wxSlider **slider, wxStaticText **stValue, wxSizer *sbs, wxString controlName);
|
||||
wxAuiNotebook *m_auiNotebook;
|
||||
void setFreq(EQ *eq);
|
||||
void setGain(EQ *eq);
|
||||
void setQ(EQ *eq);
|
||||
void sliderToFreq(EQ *eq, bool micIn);
|
||||
void sliderToGain(EQ *eq, bool micIn);
|
||||
void sliderToQ(EQ *eq, bool micIn);
|
||||
void plotFilterSpectrum(EQ *eqBass, EQ *eqMid, EQ* eqTreble, PlotSpectrum* freqRespPlot, float *magdB);
|
||||
void calcFilterSpectrum(float magdB[], int arc, char *argv[]);
|
||||
void plotMicInFilterSpectrum(void);
|
||||
void plotSpkOutFilterSpectrum(void);
|
||||
void adjRunTimeMicInFilter(void);
|
||||
void adjRunTimeSpkOutFilter(void);
|
||||
|
||||
EQ m_MicInBass;
|
||||
EQ m_MicInMid;
|
||||
EQ m_MicInTreble;
|
||||
|
||||
EQ m_SpkOutBass;
|
||||
EQ m_SpkOutMid;
|
||||
EQ m_SpkOutTreble;
|
||||
|
||||
float limit(float value, float min, float max);
|
||||
|
||||
bool *m_newMicInFilter;
|
||||
bool *m_newSpkOutFilter;
|
||||
|
||||
};
|
||||
|
||||
#endif // __FILTER_DIALOG__
|
|
@ -0,0 +1,363 @@
|
|||
//==========================================================================
|
||||
// Name: dlg_options.cpp
|
||||
// Purpose: Dialog for controlling misc FreeDV options
|
||||
// Date: May 24 2013
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
#include "dlg_options.h"
|
||||
extern bool g_modal;
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class OptionsDlg
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
OptionsDlg::OptionsDlg(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* bSizer30;
|
||||
bSizer30 = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
//------------------------------
|
||||
// Test Frames check box
|
||||
//------------------------------
|
||||
|
||||
wxStaticBoxSizer* sbSizer_testFrames;
|
||||
wxStaticBox *sb_testFrames = new wxStaticBox(this, wxID_ANY, _("Test Frames"));
|
||||
sbSizer_testFrames = new wxStaticBoxSizer(sb_testFrames, wxHORIZONTAL);
|
||||
|
||||
m_ckboxTestFrame = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
m_ckboxTestFrame->SetToolTip(_("Send frames of known bits instead of compressed voice"));
|
||||
sbSizer_testFrames->Add(m_ckboxTestFrame, 0, wxALIGN_LEFT, 0);
|
||||
|
||||
m_ckboxChannelNoise = new wxCheckBox(this, wxID_ANY, _("Channel Noise"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
m_ckboxChannelNoise->SetToolTip(_("Add simulated AWGN channel noise to received signal"));
|
||||
sbSizer_testFrames->Add(m_ckboxChannelNoise, 0, wxALIGN_LEFT, 0);
|
||||
|
||||
bSizer30->Add(sbSizer_testFrames,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
//------------------------------
|
||||
// FreeDV 700 Options
|
||||
//------------------------------
|
||||
|
||||
wxStaticBoxSizer* sbSizer_freedv700;
|
||||
wxStaticBox *sb_freedv700 = new wxStaticBox(this, wxID_ANY, _("FreeDV 700 Clipping"));
|
||||
sbSizer_freedv700 = new wxStaticBoxSizer(sb_freedv700, wxHORIZONTAL);
|
||||
|
||||
m_ckboxFreeDV700txClip = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
m_ckboxFreeDV700txClip->SetToolTip(_("Clip FreeDv 700 tx waveform to reduce Peak to Average Power Ratio (PAPR)"));
|
||||
sbSizer_freedv700->Add(m_ckboxFreeDV700txClip, 0, wxALIGN_LEFT, 0);
|
||||
|
||||
bSizer30->Add(sbSizer_freedv700,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
//------------------------------
|
||||
// Txt Msg Text Box
|
||||
//------------------------------
|
||||
|
||||
wxStaticBoxSizer* sbSizer_callSign;
|
||||
wxStaticBox *sb_textMsg = new wxStaticBox(this, wxID_ANY, _("Txt Msg"));
|
||||
sbSizer_callSign = new wxStaticBoxSizer(sb_textMsg, wxVERTICAL);
|
||||
|
||||
m_txtCtrlCallSign = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_txtCtrlCallSign->SetToolTip(_("Txt Msg you can send along with Voice"));
|
||||
sbSizer_callSign->Add(m_txtCtrlCallSign, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
bSizer30->Add(sbSizer_callSign,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
//------------------------------
|
||||
// Txt Encoding
|
||||
//------------------------------
|
||||
|
||||
wxStaticBoxSizer* sbSizer_encoding = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Text Encoding")), wxHORIZONTAL);
|
||||
|
||||
#ifdef SHORT_VARICODE
|
||||
m_rb_textEncoding1 = new wxRadioButton( this, wxID_ANY, wxT("Long varicode"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_rb_textEncoding1->SetValue(true);
|
||||
sbSizer_encoding->Add(m_rb_textEncoding1, 0, wxALIGN_LEFT|wxALL, 1);
|
||||
m_rb_textEncoding2 = new wxRadioButton( this, wxID_ANY, wxT("Short Varicode"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
sbSizer_encoding->Add(m_rb_textEncoding2, 0, wxALIGN_LEFT|wxALL, 1);
|
||||
#endif
|
||||
|
||||
m_ckboxEnableChecksum = new wxCheckBox(this, wxID_ANY, _("Use Checksum on Rx"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
sbSizer_encoding->Add(m_ckboxEnableChecksum, 0, wxALIGN_LEFT, 0);
|
||||
|
||||
bSizer30->Add(sbSizer_encoding,0, wxALL|wxEXPAND, 3);
|
||||
|
||||
//------------------------------
|
||||
// Event processing
|
||||
//------------------------------
|
||||
|
||||
wxStaticBoxSizer* sbSizer_events;
|
||||
wxStaticBox *sb_events = new wxStaticBox(this, wxID_ANY, _("Event Processing"));
|
||||
sbSizer_events = new wxStaticBoxSizer(sb_events, wxVERTICAL);
|
||||
|
||||
// event processing enable and spam timer
|
||||
|
||||
wxStaticBoxSizer* sbSizer_events_top;
|
||||
wxStaticBox* sb_events1 = new wxStaticBox(this, wxID_ANY, _(""));
|
||||
sbSizer_events_top = new wxStaticBoxSizer(sb_events1, wxHORIZONTAL);
|
||||
|
||||
m_ckbox_events = new wxCheckBox(this, wxID_ANY, _("Enable System Calls Syscall Spam Timer"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
sb_events->SetToolTip(_("Enable processing of events and generation of system calls"));
|
||||
sbSizer_events_top->Add(m_ckbox_events, 0, 0, 5);
|
||||
m_txt_spam_timer = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0, wxTextValidator(wxFILTER_DIGITS));
|
||||
m_txt_spam_timer->SetToolTip(_("Many matching events can cause a flood of syscalls. Set minimum time (seconds) between syscalls for each event here"));
|
||||
sbSizer_events_top->Add(m_txt_spam_timer, 0, 0, 5);
|
||||
m_rb_spam_timer = new wxRadioButton( this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
|
||||
m_rb_spam_timer->SetForegroundColour( wxColour(0, 255, 0 ) );
|
||||
sbSizer_events_top->Add(m_rb_spam_timer, 0, 0, 10);
|
||||
sbSizer_events->Add(sbSizer_events_top, 0, 0, 5);
|
||||
|
||||
// list of regexps
|
||||
|
||||
wxStaticBoxSizer* sbSizer_regexp = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Regular Expressions to Process Events")), wxHORIZONTAL);
|
||||
m_txt_events_regexp_match = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,100), wxTE_MULTILINE);
|
||||
m_txt_events_regexp_match->SetToolTip(_("Enter regular expressions to match events"));
|
||||
sbSizer_regexp->Add(m_txt_events_regexp_match, 1, wxEXPAND, 5);
|
||||
m_txt_events_regexp_replace = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,100), wxTE_MULTILINE);
|
||||
m_txt_events_regexp_replace->SetToolTip(_("Enter regular expressions to replace events"));
|
||||
sbSizer_regexp->Add(m_txt_events_regexp_replace, 1, wxEXPAND, 5);
|
||||
sbSizer_events->Add(sbSizer_regexp, 1, wxEXPAND, 5);
|
||||
|
||||
// log of events and responses
|
||||
|
||||
wxStaticBoxSizer* sbSizer_event_log = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Log of Events and Responses")), wxVERTICAL);
|
||||
wxBoxSizer* bSizer33 = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_txt_events_in = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,50), wxTE_MULTILINE | wxTE_READONLY);
|
||||
bSizer33->Add(m_txt_events_in, 1, wxEXPAND, 5);
|
||||
m_txt_events_out = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,50), wxTE_MULTILINE | wxTE_READONLY);
|
||||
bSizer33->Add(m_txt_events_out, 1, wxEXPAND, 5);
|
||||
sbSizer_event_log->Add(bSizer33, 1, wxEXPAND, 5);
|
||||
sbSizer_events->Add(sbSizer_event_log, 1, wxEXPAND, 5);
|
||||
|
||||
bSizer30->Add(sbSizer_events,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
//------------------------------
|
||||
// UDP control port
|
||||
//------------------------------
|
||||
|
||||
wxStaticBoxSizer* sbSizer_udp;
|
||||
wxStaticBox* sb_udp = new wxStaticBox(this, wxID_ANY, _("UDP Control Port"));
|
||||
sbSizer_udp = new wxStaticBoxSizer(sb_udp, wxHORIZONTAL);
|
||||
m_ckbox_udp_enable = new wxCheckBox(this, wxID_ANY, _("Enable UDP Control Port UDP Port Number:"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
sb_udp->SetToolTip(_("Enable control of FreeDV via UDP port"));
|
||||
sbSizer_udp->Add(m_ckbox_udp_enable, 0, wxALIGN_CENTER_HORIZONTAL, 5);
|
||||
m_txt_udp_port = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(50,-1), 0, wxTextValidator(wxFILTER_DIGITS));
|
||||
sbSizer_udp->Add(m_txt_udp_port, 0, wxALIGN_CENTER_HORIZONTAL, 5);
|
||||
|
||||
bSizer30->Add(sbSizer_udp,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
//------------------------------
|
||||
// OK - Cancel - Apply Buttons
|
||||
//------------------------------
|
||||
|
||||
wxBoxSizer* bSizer31 = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_sdbSizer5OK = new wxButton(this, wxID_OK);
|
||||
bSizer31->Add(m_sdbSizer5OK, 0, wxALL, 2);
|
||||
|
||||
m_sdbSizer5Cancel = new wxButton(this, wxID_CANCEL);
|
||||
bSizer31->Add(m_sdbSizer5Cancel, 0, wxALL, 2);
|
||||
|
||||
m_sdbSizer5Apply = new wxButton(this, wxID_APPLY);
|
||||
bSizer31->Add(m_sdbSizer5Apply, 0, wxALL, 2);
|
||||
|
||||
bSizer30->Add(bSizer31, 0, wxALIGN_RIGHT|wxALL, 0);
|
||||
|
||||
this->SetSizer(bSizer30);
|
||||
this->Layout();
|
||||
|
||||
this->Centre(wxBOTH);
|
||||
|
||||
// Connect Events -------------------------------------------------------
|
||||
|
||||
this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(OptionsDlg::OnInitDialog));
|
||||
|
||||
m_sdbSizer5OK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnOK), NULL, this);
|
||||
m_sdbSizer5Cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnCancel), NULL, this);
|
||||
m_sdbSizer5Apply->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnApply), NULL, this);
|
||||
|
||||
m_ckboxFreeDV700txClip->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700txClip), NULL, this);
|
||||
|
||||
event_in_serial = 0;
|
||||
event_out_serial = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ~OptionsDlg()
|
||||
//-------------------------------------------------------------------------
|
||||
OptionsDlg::~OptionsDlg()
|
||||
{
|
||||
|
||||
// Disconnect Events
|
||||
|
||||
this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(OptionsDlg::OnInitDialog));
|
||||
|
||||
m_sdbSizer5OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnOK), NULL, this);
|
||||
m_sdbSizer5Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnCancel), NULL, this);
|
||||
m_sdbSizer5Apply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnApply), NULL, this);
|
||||
m_ckboxFreeDV700txClip->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700txClip), NULL, this);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ExchangeData()
|
||||
//-------------------------------------------------------------------------
|
||||
void OptionsDlg::ExchangeData(int inout, bool storePersistent)
|
||||
{
|
||||
wxConfigBase *pConfig = wxConfigBase::Get();
|
||||
|
||||
if(inout == EXCHANGE_DATA_IN)
|
||||
{
|
||||
m_txtCtrlCallSign->SetValue(wxGetApp().m_callSign);
|
||||
m_ckboxTestFrame->SetValue(wxGetApp().m_testFrames);
|
||||
m_ckboxChannelNoise->SetValue(wxGetApp().m_channel_noise);
|
||||
|
||||
m_ckbox_events->SetValue(wxGetApp().m_events);
|
||||
m_txt_spam_timer->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_events_spam_timer));
|
||||
|
||||
m_txt_events_regexp_match->SetValue(wxGetApp().m_events_regexp_match);
|
||||
m_txt_events_regexp_replace->SetValue(wxGetApp().m_events_regexp_replace);
|
||||
|
||||
m_ckbox_udp_enable->SetValue(wxGetApp().m_udp_enable);
|
||||
m_txt_udp_port->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_udp_port));
|
||||
|
||||
#ifdef SHORT_VARICODE
|
||||
if (wxGetApp().m_textEncoding == 1)
|
||||
m_rb_textEncoding1->SetValue(true);
|
||||
if (wxGetApp().m_textEncoding == 2)
|
||||
m_rb_textEncoding2->SetValue(true);
|
||||
#endif
|
||||
m_ckboxEnableChecksum->SetValue(wxGetApp().m_enable_checksum);
|
||||
|
||||
m_ckboxFreeDV700txClip->SetValue(wxGetApp().m_FreeDV700txClip);
|
||||
}
|
||||
|
||||
if(inout == EXCHANGE_DATA_OUT)
|
||||
{
|
||||
wxGetApp().m_callSign = m_txtCtrlCallSign->GetValue();
|
||||
wxGetApp().m_testFrames = m_ckboxTestFrame->GetValue();
|
||||
wxGetApp().m_channel_noise = m_ckboxChannelNoise->GetValue();
|
||||
|
||||
wxGetApp().m_events = m_ckbox_events->GetValue();
|
||||
long spam_timer;
|
||||
m_txt_spam_timer->GetValue().ToLong(&spam_timer);
|
||||
wxGetApp().m_events_spam_timer = (int)spam_timer;
|
||||
|
||||
// make sure regexp lists are terminated by a \n
|
||||
|
||||
if (m_txt_events_regexp_match->GetValue().Last() != '\n') {
|
||||
m_txt_events_regexp_match->SetValue(m_txt_events_regexp_match->GetValue()+'\n');
|
||||
}
|
||||
if (m_txt_events_regexp_replace->GetValue().Last() != '\n') {
|
||||
m_txt_events_regexp_replace->SetValue(m_txt_events_regexp_replace->GetValue()+'\n');
|
||||
}
|
||||
wxGetApp().m_events_regexp_match = m_txt_events_regexp_match->GetValue();
|
||||
wxGetApp().m_events_regexp_replace = m_txt_events_regexp_replace->GetValue();
|
||||
|
||||
wxGetApp().m_udp_enable = m_ckbox_udp_enable->GetValue();
|
||||
long port;
|
||||
m_txt_udp_port->GetValue().ToLong(&port);
|
||||
wxGetApp().m_udp_port = (int)port;
|
||||
|
||||
#ifdef SHORT_VARICODE
|
||||
if (m_rb_textEncoding1->GetValue())
|
||||
wxGetApp().m_textEncoding = 1;
|
||||
if (m_rb_textEncoding2->GetValue())
|
||||
wxGetApp().m_textEncoding = 2;
|
||||
#endif
|
||||
wxGetApp().m_enable_checksum = m_ckboxEnableChecksum->GetValue();
|
||||
|
||||
wxGetApp().m_FreeDV700txClip = m_ckboxFreeDV700txClip->GetValue();
|
||||
|
||||
if (storePersistent) {
|
||||
pConfig->Write(wxT("/Data/CallSign"), wxGetApp().m_callSign);
|
||||
#ifdef SHORT_VARICODE
|
||||
pConfig->Write(wxT("/Data/TextEncoding"), wxGetApp().m_textEncoding);
|
||||
#endif
|
||||
pConfig->Write(wxT("/Data/EnableChecksumOnMsgRx"), wxGetApp().m_enable_checksum);
|
||||
|
||||
pConfig->Write(wxT("/Events/enable"), wxGetApp().m_events);
|
||||
pConfig->Write(wxT("/Events/spam_timer"), wxGetApp().m_events_spam_timer);
|
||||
pConfig->Write(wxT("/Events/regexp_match"), wxGetApp().m_events_regexp_match);
|
||||
pConfig->Write(wxT("/Events/regexp_replace"), wxGetApp().m_events_regexp_replace);
|
||||
|
||||
pConfig->Write(wxT("/UDP/enable"), wxGetApp().m_udp_enable);
|
||||
pConfig->Write(wxT("/UDP/port"), wxGetApp().m_udp_port);
|
||||
|
||||
pConfig->Write(wxT("/FreeDV700/txClip"), wxGetApp().m_FreeDV700txClip);
|
||||
|
||||
pConfig->Flush();
|
||||
}
|
||||
}
|
||||
delete wxConfigBase::Set((wxConfigBase *) NULL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnOK()
|
||||
//-------------------------------------------------------------------------
|
||||
void OptionsDlg::OnOK(wxCommandEvent& event)
|
||||
{
|
||||
ExchangeData(EXCHANGE_DATA_OUT, true);
|
||||
//this->EndModal(wxID_OK);
|
||||
g_modal = false;
|
||||
this->Show(false);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnCancel()
|
||||
//-------------------------------------------------------------------------
|
||||
void OptionsDlg::OnCancel(wxCommandEvent& event)
|
||||
{
|
||||
//this->EndModal(wxID_CANCEL);
|
||||
g_modal = false;
|
||||
this->Show(false);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnApply()
|
||||
//-------------------------------------------------------------------------
|
||||
void OptionsDlg::OnApply(wxCommandEvent& event)
|
||||
{
|
||||
ExchangeData(EXCHANGE_DATA_OUT, true);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnInitDialog()
|
||||
//-------------------------------------------------------------------------
|
||||
void OptionsDlg::OnInitDialog(wxInitDialogEvent& event)
|
||||
{
|
||||
ExchangeData(EXCHANGE_DATA_IN, false);
|
||||
}
|
||||
|
||||
// immediately change flags rather using ExchangeData() so we can switch on and off at run time
|
||||
|
||||
void OptionsDlg::OnFreeDV700txClip(wxScrollEvent& event) {
|
||||
wxGetApp().m_FreeDV700txClip = m_ckboxFreeDV700txClip->GetValue();
|
||||
}
|
||||
|
||||
|
||||
void OptionsDlg::updateEventLog(wxString event_in, wxString event_out) {
|
||||
wxString event_in_with_serial, event_out_with_serial;
|
||||
event_in_with_serial.Printf(_T("[%d] %s"), event_in_serial++, event_in);
|
||||
event_out_with_serial.Printf(_T("[%d] %s"), event_out_serial++, event_out);
|
||||
|
||||
m_txt_events_in->AppendText(event_in_with_serial+"\n");
|
||||
m_txt_events_out->AppendText(event_out_with_serial+"\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
//==========================================================================
|
||||
// Name: dlg_options.h
|
||||
// Purpose: Dialog for controlling misc FreeDV options
|
||||
// Created: Nov 25 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
#ifndef __OPTIONS_DIALOG__
|
||||
#define __OPTIONS_DIALOG__
|
||||
|
||||
#include "fdmdv2_main.h"
|
||||
#include "fdmdv2_defines.h"
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class OptionsDlg
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class OptionsDlg : public wxDialog
|
||||
{
|
||||
public:
|
||||
OptionsDlg( wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY, const wxString& title = _("Options"),
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(600,630),
|
||||
long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
~OptionsDlg();
|
||||
|
||||
void ExchangeData(int inout, bool storePersistent);
|
||||
void updateEventLog(wxString event_in, wxString event_out);
|
||||
|
||||
bool enableEventsChecked() {return m_ckbox_events->GetValue();}
|
||||
|
||||
void SetSpamTimerLight(bool state) {
|
||||
|
||||
// Colours don't work on Windows
|
||||
|
||||
if (state) {
|
||||
m_rb_spam_timer->SetForegroundColour( wxColour( 255,0 , 0 ) ); // red
|
||||
m_rb_spam_timer->SetValue(true);
|
||||
}
|
||||
else {
|
||||
m_rb_spam_timer->SetForegroundColour( wxColour( 0, 255, 0 ) ); // green
|
||||
m_rb_spam_timer->SetValue(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
// Handlers for events.
|
||||
void OnOK(wxCommandEvent& event);
|
||||
void OnCancel(wxCommandEvent& event);
|
||||
void OnApply(wxCommandEvent& event);
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void OnInitDialog(wxInitDialogEvent& event);
|
||||
|
||||
void OnFreeDV700txClip(wxScrollEvent& event);
|
||||
|
||||
wxTextCtrl *m_txtCtrlCallSign; // TODO: this should be renamed to tx_txtmsg, and rename all related incl persis strge
|
||||
wxCheckBox *m_ckboxTestFrame;
|
||||
wxCheckBox *m_ckboxChannelNoise;
|
||||
wxCheckBox *m_ckboxFreeDV700txClip;
|
||||
|
||||
wxRadioButton *m_rb_textEncoding1;
|
||||
wxRadioButton *m_rb_textEncoding2;
|
||||
wxCheckBox *m_ckboxEnableChecksum;
|
||||
|
||||
wxCheckBox *m_ckbox_events;
|
||||
wxTextCtrl *m_txt_events_regexp_match;
|
||||
wxTextCtrl *m_txt_events_regexp_replace;
|
||||
wxTextCtrl *m_txt_events_in;
|
||||
wxTextCtrl *m_txt_events_out;
|
||||
wxTextCtrl *m_txt_spam_timer;
|
||||
wxRadioButton *m_rb_spam_timer;
|
||||
|
||||
wxCheckBox *m_ckbox_udp_enable;
|
||||
wxTextCtrl *m_txt_udp_port;
|
||||
|
||||
wxButton* m_sdbSizer5OK;
|
||||
wxButton* m_sdbSizer5Cancel;
|
||||
wxButton* m_sdbSizer5Apply;
|
||||
|
||||
unsigned int event_in_serial, event_out_serial;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // __OPTIONS_DIALOG__
|
|
@ -0,0 +1,416 @@
|
|||
//==========================================================================
|
||||
// Name: dlg_ptt.cpp
|
||||
// Purpose: Subclasses dialog GUI for PTT Config. Creates simple
|
||||
// wxWidgets dialog GUI to select real/virtual Comm ports.
|
||||
// Date: May 11 2012
|
||||
// Authors: David Rowe, David Witten, Joel Stanley
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#include "dlg_ptt.h"
|
||||
#include "fdmdv2_main.h"
|
||||
|
||||
#ifdef __WIN32__
|
||||
#include <wx/msw/registry.h>
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
#include <glob.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class ComPortsDlg
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
ComPortsDlg::ComPortsDlg(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
|
||||
{
|
||||
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
this->SetSizer(mainSizer);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Half Duplex Flag for VOX PTT
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// DR: should this be on options dialog?
|
||||
|
||||
wxStaticBoxSizer* staticBoxSizer28 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("VOX PTT Settings")), wxHORIZONTAL);
|
||||
m_ckHalfDuplex = new wxCheckBox(this, wxID_ANY, _("Half Duplex"), wxDefaultPosition, wxSize(-1,-1), 0);
|
||||
staticBoxSizer28->Add(m_ckHalfDuplex, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
|
||||
m_ckLeftChannelVoxTone = new wxCheckBox(this, wxID_ANY, _("Left Channel Vox Tone"), wxDefaultPosition, wxSize(-1,-1), 0);
|
||||
staticBoxSizer28->Add(m_ckLeftChannelVoxTone, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
|
||||
|
||||
mainSizer->Add(staticBoxSizer28, 0, wxEXPAND, 5);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Hamlib for CAT PTT
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
wxStaticBoxSizer* staticBoxSizer18 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Hamlib Settings")), wxVERTICAL);
|
||||
|
||||
wxBoxSizer* gridSizer100 = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
/* Use Hamlib for PTT checkbox. */
|
||||
m_ckUseHamlibPTT = new wxCheckBox(this, wxID_ANY, _("Use Hamlib PTT"), wxDefaultPosition, wxSize(-1, -1), 0);
|
||||
m_ckUseHamlibPTT->SetValue(false);
|
||||
gridSizer100->Add(m_ckUseHamlibPTT, 0, wxALIGN_CENTER_VERTICAL, 0);
|
||||
|
||||
/* Hamlib Rig Type combobox. */
|
||||
gridSizer100->Add(new wxStaticText(this, wxID_ANY, _("Rig Model:"), wxDefaultPosition, wxDefaultSize, 0),
|
||||
0, wxALIGN_CENTER_VERTICAL | wxLEFT, 20);
|
||||
m_cbRigName = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(250, -1), 0, NULL, wxCB_DROPDOWN);
|
||||
/* TODO(Joel): this is a hack. At the least, need to gurantee that m_hamLib
|
||||
* exists. */
|
||||
wxGetApp().m_hamlib->populateComboBox(m_cbRigName);
|
||||
m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig);
|
||||
gridSizer100->Add(m_cbRigName, 0, wxALIGN_CENTER_VERTICAL, 0);
|
||||
|
||||
/* Hamlib Serial Port combobox. */
|
||||
gridSizer100->Add(new wxStaticText(this, wxID_ANY, _("Serial Device:"), wxDefaultPosition, wxDefaultSize, 0),
|
||||
0, wxALIGN_CENTER_VERTICAL | wxLEFT, 20);
|
||||
m_cbSerialPort = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
|
||||
gridSizer100->Add(m_cbSerialPort, 0, wxALIGN_CENTER_VERTICAL, 0);
|
||||
|
||||
staticBoxSizer18->Add(gridSizer100, 1);
|
||||
mainSizer->Add(staticBoxSizer18, 1);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Serial port PTT
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
wxStaticBoxSizer* staticBoxSizer17 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Serial Port Settings")), wxVERTICAL);
|
||||
mainSizer->Add(staticBoxSizer17, 1, wxEXPAND, 5);
|
||||
wxStaticBoxSizer* staticBoxSizer31 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("PTT Port")), wxVERTICAL);
|
||||
staticBoxSizer17->Add(staticBoxSizer31, 1, wxEXPAND, 5);
|
||||
|
||||
#ifdef __WXMSW__
|
||||
m_ckUseSerialPTT = new wxCheckBox(this, wxID_ANY, _("Use Serial Port PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
|
||||
m_ckUseSerialPTT->SetValue(false);
|
||||
staticBoxSizer31->Add(m_ckUseSerialPTT, 0, wxALIGN_LEFT, 20);
|
||||
|
||||
wxArrayString m_listCtrlPortsArr;
|
||||
m_listCtrlPorts = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxSize(-1,45), m_listCtrlPortsArr, wxLB_SINGLE | wxLB_SORT);
|
||||
staticBoxSizer31->Add(m_listCtrlPorts, 1, wxALIGN_CENTER, 0);
|
||||
#endif
|
||||
|
||||
#ifdef __WXGTK__
|
||||
wxBoxSizer* bSizer83;
|
||||
bSizer83 = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxGridSizer* gridSizer200 = new wxGridSizer(1, 3, 0, 0);
|
||||
|
||||
m_ckUseSerialPTT = new wxCheckBox(this, wxID_ANY, _("Use Serial Port PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
|
||||
m_ckUseSerialPTT->SetValue(false);
|
||||
gridSizer200->Add(m_ckUseSerialPTT, 1, wxALIGN_CENTER|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 2);
|
||||
|
||||
m_staticText12 = new wxStaticText(this, wxID_ANY, _("Serial Device: "), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_staticText12->Wrap(-1);
|
||||
gridSizer200->Add(m_staticText12, 1,wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 2);
|
||||
|
||||
m_cbCtlDevicePath = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
|
||||
gridSizer200->Add(m_cbCtlDevicePath, 1, wxEXPAND|wxALIGN_CENTER|wxALIGN_RIGHT, 2);
|
||||
|
||||
bSizer83->Add(gridSizer200, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 2);
|
||||
staticBoxSizer31->Add(bSizer83, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
|
||||
#endif
|
||||
|
||||
wxBoxSizer* boxSizer19 = new wxBoxSizer(wxVERTICAL);
|
||||
staticBoxSizer17->Add(boxSizer19, 1, wxEXPAND, 5);
|
||||
wxStaticBoxSizer* staticBoxSizer16 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Signal polarity")), wxHORIZONTAL);
|
||||
boxSizer19->Add(staticBoxSizer16, 1, wxEXPAND|wxALIGN_CENTER|wxALIGN_RIGHT, 5);
|
||||
|
||||
wxGridSizer* gridSizer17 = new wxGridSizer(2, 2, 0, 0);
|
||||
staticBoxSizer16->Add(gridSizer17, 1, wxEXPAND|wxALIGN_RIGHT, 5);
|
||||
|
||||
m_rbUseDTR = new wxRadioButton(this, wxID_ANY, _("Use DTR"), wxDefaultPosition, wxSize(-1,-1), 0);
|
||||
m_rbUseDTR->SetToolTip(_("Toggle DTR line for PTT"));
|
||||
m_rbUseDTR->SetValue(1);
|
||||
gridSizer17->Add(m_rbUseDTR, 0, wxALIGN_CENTER|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
|
||||
|
||||
m_ckDTRPos = new wxCheckBox(this, wxID_ANY, _("DTR = +V"), wxDefaultPosition, wxSize(-1,-1), 0);
|
||||
m_ckDTRPos->SetToolTip(_("Set Polarity of the DTR line"));
|
||||
m_ckDTRPos->SetValue(false);
|
||||
gridSizer17->Add(m_ckDTRPos, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
|
||||
|
||||
m_rbUseRTS = new wxRadioButton(this, wxID_ANY, _("Use RTS"), wxDefaultPosition, wxSize(-1,-1), 0);
|
||||
m_rbUseRTS->SetToolTip(_("Toggle the RTS pin for PTT"));
|
||||
m_rbUseRTS->SetValue(1);
|
||||
gridSizer17->Add(m_rbUseRTS, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
|
||||
|
||||
m_ckRTSPos = new wxCheckBox(this, wxID_ANY, _("RTS = +V"), wxDefaultPosition, wxSize(-1,-1), 0);
|
||||
m_ckRTSPos->SetValue(false);
|
||||
m_ckRTSPos->SetToolTip(_("Set Polarity of the RTS line"));
|
||||
gridSizer17->Add(m_ckRTSPos, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// OK - Cancel - Apply
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
wxBoxSizer* boxSizer12 = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_buttonOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxSize(-1,-1), 0);
|
||||
m_buttonOK->SetDefault();
|
||||
boxSizer12->Add(m_buttonOK, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
|
||||
|
||||
m_buttonCancel = new wxButton(this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0);
|
||||
boxSizer12->Add(m_buttonCancel, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
|
||||
|
||||
m_buttonApply = new wxButton(this, wxID_APPLY, _("Apply"), wxDefaultPosition, wxSize(-1,-1), 0);
|
||||
boxSizer12->Add(m_buttonApply, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
|
||||
|
||||
mainSizer->Add(boxSizer12, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM|wxALIGN_CENTER_HORIZONTAL, 5);
|
||||
|
||||
if ( GetSizer() )
|
||||
{
|
||||
GetSizer()->Fit(this);
|
||||
}
|
||||
Centre(wxBOTH);
|
||||
|
||||
// Connect events
|
||||
this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(ComPortsDlg::OnInitDialog), NULL, this);
|
||||
m_ckUseHamlibPTT->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseHamLibClicked), NULL, this);
|
||||
m_ckUseSerialPTT->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseSerialClicked), NULL, this);
|
||||
m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this);
|
||||
m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this);
|
||||
m_buttonApply->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ~ComPortsDlg()
|
||||
//-------------------------------------------------------------------------
|
||||
ComPortsDlg::~ComPortsDlg()
|
||||
{
|
||||
// Disconnect Events
|
||||
this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(ComPortsDlg::OnInitDialog), NULL, this);
|
||||
m_ckUseHamlibPTT->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseHamLibClicked), NULL, this);
|
||||
m_ckUseSerialPTT->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseSerialClicked), NULL, this);
|
||||
m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this);
|
||||
m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this);
|
||||
m_buttonApply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnInitDialog()
|
||||
//-------------------------------------------------------------------------
|
||||
void ComPortsDlg::OnInitDialog(wxInitDialogEvent& event)
|
||||
{
|
||||
populatePortList();
|
||||
ExchangeData(EXCHANGE_DATA_IN);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// populatePortList()
|
||||
//-------------------------------------------------------------------------
|
||||
void ComPortsDlg::populatePortList()
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
m_listCtrlPorts->Clear();
|
||||
m_cbSerialPort->Clear();
|
||||
wxArrayString aStr;
|
||||
wxRegKey key(wxRegKey::HKLM, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"));
|
||||
if(!key.Exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the number of subkeys and enumerate them.
|
||||
if(!key.Open(wxRegKey::Read))
|
||||
{
|
||||
return;
|
||||
}
|
||||
size_t subkeys;
|
||||
size_t values;
|
||||
if(!key.GetKeyInfo(&subkeys, NULL, &values, NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!key.HasValues())
|
||||
{
|
||||
return;
|
||||
}
|
||||
wxString key_name;
|
||||
long el = 1;
|
||||
key.GetFirstValue(key_name, el);
|
||||
wxString valType;
|
||||
wxString key_data;
|
||||
for(unsigned int i = 0; i < values; i++)
|
||||
{
|
||||
key.QueryValue(key_name, key_data);
|
||||
//wxPrintf("Value: %s Data: %s\n", key_name, key_data);
|
||||
aStr.Add(key_data, 1);
|
||||
key.GetNextValue(key_name, el);
|
||||
}
|
||||
}
|
||||
m_listCtrlPorts->Append(aStr);
|
||||
m_cbSerialPort->Append(aStr);
|
||||
#endif
|
||||
#ifdef __WXGTK__
|
||||
m_cbSerialPort->Clear();
|
||||
m_cbCtlDevicePath->Clear();
|
||||
#ifdef __FreeBSD__
|
||||
glob_t gl;
|
||||
if(glob("/dev/tty*", GLOB_MARK, NULL, &gl)==0) {
|
||||
for(unsigned int i=0; i<gl.gl_pathc; i++) {
|
||||
if(gl.gl_pathv[i][strlen(gl.gl_pathv[i])-1]=='/')
|
||||
continue;
|
||||
|
||||
/* Exclude pseudo TTYs */
|
||||
if(gl.gl_pathv[i][8] >= 'l' && gl.gl_pathv[i][8] <= 's')
|
||||
continue;
|
||||
if(gl.gl_pathv[i][8] >= 'L' && gl.gl_pathv[i][8] <= 'S')
|
||||
continue;
|
||||
|
||||
/* Exclude virtual TTYs */
|
||||
if(gl.gl_pathv[i][8] == 'v')
|
||||
continue;
|
||||
|
||||
/* Exclude initial-state and lock-state devices */
|
||||
if(strchr(gl.gl_pathv[i], '.') != NULL)
|
||||
continue;
|
||||
|
||||
m_cbSerialPort->Append(gl.gl_pathv[i]);
|
||||
m_cbCtlDevicePath->Append(gl.gl_pathv[i]);
|
||||
}
|
||||
globfree(&gl);
|
||||
}
|
||||
#else
|
||||
/* TODO(Joel): http://stackoverflow.com/questions/2530096/how-to-find-all-serial-devices-ttys-ttyusb-on-linux-without-opening-them */
|
||||
m_cbSerialPort->Append("/dev/ttyUSB0");
|
||||
m_cbSerialPort->Append("/dev/ttyUSB1");
|
||||
m_cbSerialPort->Append("/dev/ttyS0");
|
||||
m_cbSerialPort->Append("/dev/ttyS1");
|
||||
m_cbCtlDevicePath->Clear();
|
||||
m_cbCtlDevicePath->Append("/dev/ttyUSB0");
|
||||
m_cbCtlDevicePath->Append("/dev/ttyUSB1");
|
||||
m_cbCtlDevicePath->Append("/dev/ttyS0");
|
||||
m_cbCtlDevicePath->Append("/dev/ttyS1");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ExchangeData()
|
||||
//-------------------------------------------------------------------------
|
||||
void ComPortsDlg::ExchangeData(int inout)
|
||||
{
|
||||
wxConfigBase *pConfig = wxConfigBase::Get();
|
||||
wxString str;
|
||||
|
||||
if(inout == EXCHANGE_DATA_IN)
|
||||
{
|
||||
m_ckHalfDuplex->SetValue(wxGetApp().m_boolHalfDuplex);
|
||||
m_ckLeftChannelVoxTone->SetValue(wxGetApp().m_leftChannelVoxTone);
|
||||
|
||||
m_ckUseHamlibPTT->SetValue(wxGetApp().m_boolHamlibUseForPTT);
|
||||
m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig);
|
||||
m_cbSerialPort->SetValue(wxGetApp().m_strHamlibSerialPort);
|
||||
|
||||
m_ckUseSerialPTT->SetValue(wxGetApp().m_boolUseSerialPTT);
|
||||
str = wxGetApp().m_strRigCtrlPort;
|
||||
#ifdef __WXMSW__
|
||||
m_listCtrlPorts->SetStringSelection(str);
|
||||
#endif
|
||||
#ifdef __WXGTK__
|
||||
m_cbCtlDevicePath->SetValue(str);
|
||||
#endif
|
||||
m_rbUseRTS->SetValue(wxGetApp().m_boolUseRTS);
|
||||
m_ckRTSPos->SetValue(wxGetApp().m_boolRTSPos);
|
||||
m_rbUseDTR->SetValue(wxGetApp().m_boolUseDTR);
|
||||
m_ckDTRPos->SetValue(wxGetApp().m_boolDTRPos);
|
||||
}
|
||||
if(inout == EXCHANGE_DATA_OUT)
|
||||
{
|
||||
wxGetApp().m_boolHalfDuplex = m_ckHalfDuplex->GetValue();
|
||||
pConfig->Write(wxT("/Rig/HalfDuplex"), wxGetApp().m_boolHalfDuplex);
|
||||
wxGetApp().m_leftChannelVoxTone = m_ckLeftChannelVoxTone->GetValue();
|
||||
pConfig->Write(wxT("/Rig/leftChannelVoxTone"), wxGetApp().m_leftChannelVoxTone);
|
||||
|
||||
/* Hamlib settings. */
|
||||
|
||||
wxGetApp().m_boolHamlibUseForPTT = m_ckUseHamlibPTT->GetValue();
|
||||
wxGetApp().m_intHamlibRig = m_cbRigName->GetSelection();
|
||||
wxGetApp().m_strHamlibSerialPort = m_cbSerialPort->GetValue();
|
||||
|
||||
pConfig->Write(wxT("/Hamlib/UseForPTT"), wxGetApp().m_boolHamlibUseForPTT);
|
||||
pConfig->Write(wxT("/Hamlib/RigName"), wxGetApp().m_intHamlibRig);
|
||||
pConfig->Write(wxT("/Hamlib/SerialPort"), wxGetApp().m_strHamlibSerialPort);
|
||||
|
||||
/* Serial settings */
|
||||
|
||||
wxGetApp().m_boolUseSerialPTT = m_ckUseSerialPTT->IsChecked();
|
||||
#ifdef __WXMSW__
|
||||
wxGetApp().m_strRigCtrlPort = m_listCtrlPorts->GetStringSelection();
|
||||
#endif
|
||||
#ifdef __WXGTK__
|
||||
wxGetApp().m_strRigCtrlPort = m_cbCtlDevicePath->GetValue();
|
||||
#endif
|
||||
wxGetApp().m_boolUseRTS = m_rbUseRTS->GetValue();
|
||||
wxGetApp().m_boolRTSPos = m_ckRTSPos->IsChecked();
|
||||
wxGetApp().m_boolUseDTR = m_rbUseDTR->GetValue();
|
||||
wxGetApp().m_boolDTRPos = m_ckDTRPos->IsChecked();
|
||||
|
||||
pConfig->Write(wxT("/Rig/UseSerialPTT"), wxGetApp().m_boolUseSerialPTT);
|
||||
pConfig->Write(wxT("/Rig/Port"), wxGetApp().m_strRigCtrlPort);
|
||||
pConfig->Write(wxT("/Rig/UseRTS"), wxGetApp().m_boolUseRTS);
|
||||
pConfig->Write(wxT("/Rig/RTSPolarity"), wxGetApp().m_boolRTSPos);
|
||||
pConfig->Write(wxT("/Rig/UseDTR"), wxGetApp().m_boolUseDTR);
|
||||
pConfig->Write(wxT("/Rig/DTRPolarity"), wxGetApp().m_boolDTRPos);
|
||||
|
||||
pConfig->Flush();
|
||||
}
|
||||
delete wxConfigBase::Set((wxConfigBase *) NULL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// PTTUseHamLibClicked()
|
||||
//-------------------------------------------------------------------------
|
||||
void ComPortsDlg::PTTUseHamLibClicked(wxCommandEvent& event)
|
||||
{
|
||||
m_ckUseSerialPTT->SetValue(false);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// PTTUseSerialClicked()
|
||||
//-------------------------------------------------------------------------
|
||||
void ComPortsDlg::PTTUseSerialClicked(wxCommandEvent& event)
|
||||
{
|
||||
m_ckUseHamlibPTT->SetValue(false);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnApply()
|
||||
//-------------------------------------------------------------------------
|
||||
void ComPortsDlg::OnApply(wxCommandEvent& event)
|
||||
{
|
||||
ExchangeData(EXCHANGE_DATA_OUT);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnCancel()
|
||||
//-------------------------------------------------------------------------
|
||||
void ComPortsDlg::OnCancel(wxCommandEvent& event)
|
||||
{
|
||||
this->EndModal(wxID_CANCEL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnClose()
|
||||
//-------------------------------------------------------------------------
|
||||
void ComPortsDlg::OnOK(wxCommandEvent& event)
|
||||
{
|
||||
ExchangeData(EXCHANGE_DATA_OUT);
|
||||
this->EndModal(wxID_OK);
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
//==========================================================================
|
||||
// Name: dlg_ptt.h
|
||||
// Purpose: Subclasses dialog GUI for PTT Config.
|
||||
//
|
||||
// Created: May. 11, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#ifndef __COMPORTS_DIALOG__
|
||||
#define __COMPORTS_DIALOG__
|
||||
|
||||
#include "fdmdv2_main.h"
|
||||
#include "hamlib.h"
|
||||
#include <wx/settings.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/xrc/xh_bmp.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/listbox.h>
|
||||
#include <wx/radiobut.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/spinctrl.h>
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class ComPortsDlg
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class ComPortsDlg : public wxDialog
|
||||
{
|
||||
public:
|
||||
ComPortsDlg(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("PTT Config"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(450,300), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
|
||||
virtual ~ComPortsDlg();
|
||||
void ExchangeData(int inout);
|
||||
|
||||
protected:
|
||||
wxCheckBox* m_ckHalfDuplex;
|
||||
wxCheckBox* m_ckLeftChannelVoxTone;
|
||||
|
||||
/* Hamlib settings.*/
|
||||
|
||||
wxCheckBox *m_ckUseHamlibPTT;
|
||||
wxComboBox *m_cbRigName;
|
||||
wxComboBox *m_cbSerialPort;
|
||||
|
||||
Hamlib *m_hamlib;
|
||||
|
||||
/* Serial Settings */
|
||||
|
||||
wxListBox *m_listCtrlPorts;
|
||||
wxCheckBox *m_ckUseSerialPTT;
|
||||
wxStaticText *m_staticText12;
|
||||
wxComboBox *m_cbCtlDevicePath;
|
||||
wxRadioButton *m_rbUseDTR;
|
||||
wxCheckBox *m_ckRTSPos;
|
||||
wxRadioButton *m_rbUseRTS;
|
||||
wxCheckBox *m_ckDTRPos;
|
||||
|
||||
/* Ok - Cancel - Apply */
|
||||
|
||||
wxButton* m_buttonOK;
|
||||
wxButton* m_buttonCancel;
|
||||
wxButton* m_buttonApply;
|
||||
|
||||
|
||||
protected:
|
||||
void populatePortList();
|
||||
|
||||
void PTTUseHamLibClicked(wxCommandEvent& event);
|
||||
void PTTUseSerialClicked(wxCommandEvent& event);
|
||||
|
||||
void OnOK(wxCommandEvent& event);
|
||||
void OnCancel(wxCommandEvent& event);
|
||||
void OnApply(wxCommandEvent& event);
|
||||
virtual void OnInitDialog(wxInitDialogEvent& event);
|
||||
};
|
||||
|
||||
#endif // __COMPORTS_DIALOG__
|
|
@ -0,0 +1,102 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_defines.h
|
||||
// Purpose: Definitions used by plots derived from fdmdv2_plot class.
|
||||
// Created: August 27, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#ifndef __FDMDV2_DEFINES__
|
||||
#define __FDMDV2_DEFINES__
|
||||
|
||||
#include "wx/wx.h"
|
||||
#include "freedv_api.h"
|
||||
#include "freedv_api_internal.h"
|
||||
|
||||
// Spectrogram and Waterfall
|
||||
|
||||
#define MIN_MAG_DB -40.0 // min of spectrogram/waterfall magnitude axis
|
||||
#define MAX_MAG_DB 0.0 // max of spectrogram/waterfall magnitude axis
|
||||
#define STEP_MAG_DB 5.0 // magnitude axis step
|
||||
#define BETA 0.95 // constant for time averaging spectrum data
|
||||
#define MIN_F_HZ 0 // min freq on Waterfall and Spectrum
|
||||
#define MAX_F_HZ 3000 // max freq on Waterfall and Spectrum
|
||||
#define STEP_F_HZ 500 // major (e.g. text legend) freq step on Waterfall and Spectrum graticule
|
||||
#define STEP_MINOR_F_HZ 100 // minor (ticks) freq step on Waterfall and Spectrum graticule
|
||||
#define WATERFALL_SECS_Y 30 // number of seconds respresented by y axis of waterfall
|
||||
#define WATERFALL_SECS_STEP 5 // graticule y axis steps of waterfall
|
||||
#define DT 0.1 // time between real time graphing updates
|
||||
#define FS 8000 // FDMDV modem sample rate
|
||||
|
||||
// Scatter diagram
|
||||
|
||||
#define SCATTER_MEM_SECS 10
|
||||
// (symbols/frame)/(graphics update period) = symbols/s sent to scatter memory
|
||||
// memory (symbols) = secs of memory * symbols/sec
|
||||
#define SCATTER_MEM_SYMS_MAX ((int)(SCATTER_MEM_SECS*((FDMDV_NC_MAX+1)/DT)))
|
||||
|
||||
// Waveform plotting constants
|
||||
|
||||
#define WAVEFORM_PLOT_FS 400 // sample rate (points/s) of waveform plotted to screen
|
||||
#define WAVEFORM_PLOT_TIME 5 // length or entire waveform on screen
|
||||
#define WAVEFORM_PLOT_BUF ((int)(DT*WAVEFORM_PLOT_FS)) // number of new samples we plot per DT
|
||||
|
||||
// sample rate I/O & conversion constants
|
||||
|
||||
#define MAX_FPB 8096 // maximum value of portAudio framesPerBuffer
|
||||
#define PA_FPB 1024 // nominal value of portAudio framesPerBuffer
|
||||
#define SAMPLE_RATE 48000 // 48 kHz sampling rate rec. as we can trust accuracy of sound card
|
||||
#define N8 160 // processing buffer size at 8 kHz
|
||||
#define MEM8 (FDMDV_OS_TAPS/FDMDV_OS)
|
||||
#define N48 (N8*SAMPLE_RATE/FS) // processing buffer size at 48 kHz
|
||||
#define NUM_CHANNELS 2 // I think most sound cards prefer stereo we will convert to mono
|
||||
#define VOX_TONE_FREQ 1000.0 // optional left channel vox tone freq
|
||||
#define VOX_TONE_AMP 30000 // optional left channel vox tone amp
|
||||
|
||||
#define MAX_BITS_PER_CODEC_FRAME 64 // 1600 bit/s mode
|
||||
#define MAX_BYTES_PER_CODEC_FRAME (MAX_BITS_PER_CODEC_FRAME/8)
|
||||
#define MAX_BITS_PER_FDMDV_FRAME 40 // 2000 bit/s mode
|
||||
|
||||
// Squelch
|
||||
#define SQ_DEFAULT_SNR 2.0
|
||||
|
||||
// Level Gauge
|
||||
#define FROM_RADIO_MAX 0.8
|
||||
#define FROM_MIC_MAX 0.8
|
||||
#define LEVEL_BETA 0.99
|
||||
|
||||
// SNR
|
||||
#define SNRSLOW_BETA 0.5 // time constant for slow SNR for display
|
||||
|
||||
// Text messaging Data
|
||||
#define MAX_CALLSIGN 80
|
||||
#define MAX_EVENT_LOG 10
|
||||
#define MAX_EVENT_RULES 100
|
||||
|
||||
enum
|
||||
{
|
||||
ID_ROTATE_LEFT = wxID_HIGHEST + 1,
|
||||
ID_ROTATE_RIGHT,
|
||||
ID_RESIZE,
|
||||
ID_PAINT_BG
|
||||
};
|
||||
|
||||
// Codec 2 LPC Post Filter defaults, from codec-dev/src/quantise.c
|
||||
|
||||
#define CODEC2_LPC_PF_GAMMA 0.5
|
||||
#define CODEC2_LPC_PF_BETA 0.2
|
||||
|
||||
|
||||
#endif //__FDMDV2_DEFINES__
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,614 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_main.h
|
||||
//
|
||||
// Purpose: Declares simple wxWidgets application with GUI.
|
||||
// Created: Apr. 9, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#ifndef __FDMDV2_MAIN__
|
||||
#define __FDMDV2_MAIN__
|
||||
|
||||
#include "version.h"
|
||||
#ifndef _NO_AUTOTOOLS_
|
||||
#include "../config.h"
|
||||
#endif
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include <wx/tglbtn.h>
|
||||
#include <wx/app.h>
|
||||
//#include <wx/aboutdlg.h>
|
||||
#include "wx/rawbmp.h"
|
||||
#include "wx/file.h"
|
||||
#include "wx/filename.h"
|
||||
#include "wx/config.h"
|
||||
#include <wx/fileconf.h>
|
||||
#include "wx/graphics.h"
|
||||
#include "wx/mstream.h"
|
||||
#include "wx/wfstream.h"
|
||||
#include "wx/quantize.h"
|
||||
#include "wx/scopedptr.h"
|
||||
#include "wx/stopwatch.h"
|
||||
#include "wx/versioninfo.h"
|
||||
#include <wx/sound.h>
|
||||
#include <wx/url.h>
|
||||
#include <wx/sstream.h>
|
||||
#include <wx/listbox.h>
|
||||
#include <wx/textdlg.h>
|
||||
#include <wx/regex.h>
|
||||
#include <wx/socket.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include <hamlib.h>
|
||||
#include <stdint.h>
|
||||
#include <speex/speex_preprocess.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "codec2.h"
|
||||
#include "codec2_fdmdv.h"
|
||||
#include "codec2_fifo.h"
|
||||
#include "golay23.h"
|
||||
#include "modem_stats.h"
|
||||
|
||||
#include "topFrame.h"
|
||||
#include "dlg_ptt.h"
|
||||
#include "dlg_options.h"
|
||||
#include "fdmdv2_plot.h"
|
||||
#include "fdmdv2_plot_scalar.h"
|
||||
#include "fdmdv2_plot_scatter.h"
|
||||
#include "fdmdv2_plot_waterfall.h"
|
||||
#include "fdmdv2_plot_spectrum.h"
|
||||
#include "fdmdv2_pa_wrapper.h"
|
||||
#include "sndfile.h"
|
||||
#include "portaudio.h"
|
||||
#include "dlg_audiooptions.h"
|
||||
#include "dlg_filter.h"
|
||||
#include "dlg_options.h"
|
||||
#include "varicode.h"
|
||||
#include "sox_biquad.h"
|
||||
#include "comp_prim.h"
|
||||
|
||||
#define _USE_TIMER 1
|
||||
#define _USE_ONIDLE 1
|
||||
#define _DUMMY_DATA 1
|
||||
//#define _AUDIO_PASSTHROUGH 1
|
||||
#define _REFRESH_TIMER_PERIOD (DT*1000)
|
||||
//#define _USE_ABOUT_DIALOG 1
|
||||
|
||||
enum {
|
||||
ID_START = wxID_HIGHEST,
|
||||
ID_TIMER_WATERFALL,
|
||||
ID_TIMER_SPECTRUM,
|
||||
ID_TIMER_SCATTER,
|
||||
ID_TIMER_SCALAR
|
||||
};
|
||||
|
||||
#define EXCHANGE_DATA_IN 0
|
||||
#define EXCHANGE_DATA_OUT 1
|
||||
|
||||
#ifdef _WIN32
|
||||
#define COM_HANDLE_INVALID INVALID_HANDLE_VALUE
|
||||
typedef HANDLE com_handle_t;
|
||||
#else
|
||||
#define COM_HANDLE_INVALID -1
|
||||
typedef int com_handle_t;
|
||||
#endif
|
||||
|
||||
extern int g_nSoundCards;
|
||||
extern int g_soundCard1InDeviceNum;
|
||||
extern int g_soundCard1OutDeviceNum;
|
||||
extern int g_soundCard1SampleRate;
|
||||
extern int g_soundCard2InDeviceNum;
|
||||
extern int g_soundCard2OutDeviceNum;
|
||||
extern int g_soundCard2SampleRate;
|
||||
|
||||
class MainFrame;
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class MainApp
|
||||
//
|
||||
// @class $(Name)
|
||||
// @author $(User)
|
||||
// @date $(Date)
|
||||
// @file $(CurrentFileName).$(CurrentFileExt)
|
||||
// @brief
|
||||
//
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class MainApp : public wxApp
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
virtual int OnExit();
|
||||
|
||||
wxString m_strVendName;
|
||||
wxString m_StrAppName;
|
||||
|
||||
wxString m_textNumChOut;
|
||||
wxString m_textNumChIn;
|
||||
|
||||
wxString m_strRxInAudio;
|
||||
wxString m_strRxOutAudio;
|
||||
wxString m_textVoiceInput;
|
||||
wxString m_textVoiceOutput;
|
||||
wxString m_strSampleRate;
|
||||
wxString m_strBitrate;
|
||||
|
||||
// PTT -----------------------------------
|
||||
|
||||
bool m_boolHalfDuplex;
|
||||
|
||||
bool m_boolHamlibUseForPTT;
|
||||
unsigned int m_intHamlibRig;
|
||||
wxString m_strHamlibSerialPort;
|
||||
Hamlib *m_hamlib;
|
||||
|
||||
bool m_boolUseSerialPTT;
|
||||
wxString m_strRigCtrlPort;
|
||||
bool m_boolUseRTS;
|
||||
bool m_boolRTSPos;
|
||||
bool m_boolUseDTR;
|
||||
bool m_boolDTRPos;
|
||||
|
||||
// Play/Rec files
|
||||
|
||||
wxString m_playFileToMicInPath;
|
||||
wxString m_recFileFromRadioPath;
|
||||
unsigned int m_recFileFromRadioSecs;
|
||||
wxString m_playFileFromRadioPath;
|
||||
|
||||
// Options dialog
|
||||
|
||||
wxString m_callSign;
|
||||
bool m_events;
|
||||
int m_events_spam_timer;
|
||||
unsigned int m_textEncoding;
|
||||
bool m_enable_checksum;
|
||||
wxString m_events_regexp_match;
|
||||
wxString m_events_regexp_replace;
|
||||
|
||||
bool m_snrSlow;
|
||||
|
||||
// LPC Post Filter
|
||||
bool m_codec2LPCPostFilterEnable;
|
||||
bool m_codec2LPCPostFilterBassBoost;
|
||||
float m_codec2LPCPostFilterGamma;
|
||||
float m_codec2LPCPostFilterBeta;
|
||||
|
||||
// Speex Pre-Processor
|
||||
bool m_speexpp_enable;
|
||||
|
||||
// Mic In Equaliser
|
||||
float m_MicInBassFreqHz;
|
||||
float m_MicInBassGaindB;
|
||||
float m_MicInTrebleFreqHz;
|
||||
float m_MicInTrebleGaindB;
|
||||
float m_MicInMidFreqHz;
|
||||
float m_MicInMidGaindB;
|
||||
float m_MicInMidQ;
|
||||
bool m_MicInEQEnable;
|
||||
|
||||
// Spk Out Equaliser
|
||||
float m_SpkOutBassFreqHz;
|
||||
float m_SpkOutBassGaindB;
|
||||
float m_SpkOutTrebleFreqHz;
|
||||
float m_SpkOutTrebleGaindB;
|
||||
float m_SpkOutMidFreqHz;
|
||||
float m_SpkOutMidGaindB;
|
||||
float m_SpkOutMidQ;
|
||||
bool m_SpkOutEQEnable;
|
||||
|
||||
// Flags for displaying windows
|
||||
int m_show_wf;
|
||||
int m_show_spect;
|
||||
int m_show_scatter;
|
||||
int m_show_timing;
|
||||
int m_show_freq;
|
||||
int m_show_speech_in;
|
||||
int m_show_speech_out;
|
||||
int m_show_demod_in;
|
||||
int m_show_test_frame_errors;
|
||||
int m_show_test_frame_errors_hist;
|
||||
|
||||
// optional vox trigger tone
|
||||
bool m_leftChannelVoxTone;
|
||||
|
||||
// UDP control port
|
||||
bool m_udp_enable;
|
||||
int m_udp_port;
|
||||
|
||||
// notebook display after tx->rxtransition
|
||||
int m_rxNbookCtrl;
|
||||
|
||||
wxRect m_rTopWindow;
|
||||
|
||||
int m_framesPerBuffer;
|
||||
|
||||
bool loadConfig();
|
||||
bool saveConfig();
|
||||
|
||||
// misc
|
||||
|
||||
bool m_testFrames;
|
||||
bool m_channel_noise;
|
||||
float m_channel_snr_dB;
|
||||
|
||||
int FilterEvent(wxEvent& event);
|
||||
MainFrame *frame;
|
||||
|
||||
bool m_FreeDV700txClip;
|
||||
protected:
|
||||
};
|
||||
|
||||
// declare global static function wxGetApp()
|
||||
DECLARE_APP(MainApp)
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// paCallBackData
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
typedef struct
|
||||
{
|
||||
// libresample states for 48 to 8 kHz conversions
|
||||
|
||||
SRC_STATE *insrc1;
|
||||
SRC_STATE *outsrc1;
|
||||
SRC_STATE *insrc2;
|
||||
SRC_STATE *outsrc2;
|
||||
SRC_STATE *insrcsf;
|
||||
|
||||
// FIFOs attached to first sound card
|
||||
|
||||
struct FIFO *infifo1;
|
||||
struct FIFO *outfifo1;
|
||||
|
||||
// FIFOs attached to second sound card
|
||||
struct FIFO *infifo2;
|
||||
struct FIFO *outfifo2;
|
||||
|
||||
// FIFOs for rx process
|
||||
struct FIFO *rxinfifo;
|
||||
struct FIFO *rxoutfifo;
|
||||
|
||||
int inputChannels1, inputChannels2;
|
||||
|
||||
// EQ filter states
|
||||
void *sbqMicInBass;
|
||||
void *sbqMicInTreble;
|
||||
void *sbqMicInMid;
|
||||
void *sbqSpkOutBass;
|
||||
void *sbqSpkOutTreble;
|
||||
void *sbqSpkOutMid;
|
||||
|
||||
bool micInEQEnable;
|
||||
bool spkOutEQEnable;
|
||||
|
||||
// optional loud tone on left channel to reliably trigger vox
|
||||
bool leftChannelVoxTone;
|
||||
float voxTonePhase;
|
||||
|
||||
} paCallBackData;
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// panel with custom loop checkbox for play file dialog
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class MyExtraPlayFilePanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
MyExtraPlayFilePanel(wxWindow *parent);
|
||||
void setLoopPlayFileToMicIn(bool checked) { m_cb->SetValue(checked); }
|
||||
bool getLoopPlayFileToMicIn(void) { return m_cb->GetValue(); }
|
||||
private:
|
||||
wxCheckBox *m_cb;
|
||||
};
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// panel with custom Seconds-to-record control for record file dialog
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class MyExtraRecFilePanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
MyExtraRecFilePanel(wxWindow *parent);
|
||||
~MyExtraRecFilePanel()
|
||||
{
|
||||
wxLogDebug("Destructor\n");
|
||||
}
|
||||
void setSecondsToRecord(wxString value) { m_secondsToRecord->SetValue(value); }
|
||||
wxString getSecondsToRecord(void)
|
||||
{
|
||||
wxLogDebug("getSecondsToRecord: %s\n",m_secondsToRecord->GetValue());
|
||||
return m_secondsToRecord->GetValue();
|
||||
}
|
||||
private:
|
||||
wxTextCtrl *m_secondsToRecord;
|
||||
};
|
||||
|
||||
class txRxThread;
|
||||
class UDPThread;
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class MainFrame
|
||||
//
|
||||
// @class $(Name)
|
||||
// @author $(User)
|
||||
// @date $(Date)
|
||||
// @file $(CurrentFileName).$(CurrentFileExt)
|
||||
// @brief
|
||||
//
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class MainFrame : public TopFrame
|
||||
{
|
||||
public:
|
||||
MainFrame(wxWindow *parent);
|
||||
virtual ~MainFrame();
|
||||
|
||||
PlotSpectrum* m_panelSpectrum;
|
||||
PlotWaterfall* m_panelWaterfall;
|
||||
PlotScatter* m_panelScatter;
|
||||
PlotScalar* m_panelTimeOffset;
|
||||
PlotScalar* m_panelFreqOffset;
|
||||
PlotScalar* m_panelSpeechIn;
|
||||
PlotScalar* m_panelSpeechOut;
|
||||
PlotScalar* m_panelDemodIn;
|
||||
PlotScalar* m_panelTestFrameErrors;
|
||||
PlotScalar* m_panelTestFrameErrorsHist;
|
||||
|
||||
bool m_RxRunning;
|
||||
|
||||
PortAudioWrap *m_rxInPa;
|
||||
PortAudioWrap *m_rxOutPa;
|
||||
PortAudioWrap *m_txInPa;
|
||||
PortAudioWrap *m_txOutPa;
|
||||
|
||||
PaError m_rxErr;
|
||||
PaError m_txErr;
|
||||
|
||||
txRxThread* m_txRxThread;
|
||||
|
||||
bool OpenHamlibRig();
|
||||
void SetupSerialPort(void);
|
||||
void CloseSerialPort(void);
|
||||
void SerialPTTRx(void);
|
||||
|
||||
bool m_modal;
|
||||
|
||||
#ifdef _USE_TIMER
|
||||
wxTimer m_plotTimer;
|
||||
#endif
|
||||
|
||||
void destroy_fifos(void);
|
||||
void destroy_src(void);
|
||||
void autoDetectSoundCards(PortAudioWrap *pa);
|
||||
|
||||
static int rxCallback(
|
||||
const void *inBuffer,
|
||||
void *outBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo *outTime,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData
|
||||
);
|
||||
|
||||
static int txCallback(
|
||||
const void *inBuffer,
|
||||
void *outBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo *outTime,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData
|
||||
);
|
||||
|
||||
|
||||
void initPortAudioDevice(PortAudioWrap *pa, int inDevice, int outDevice,
|
||||
int soundCard, int sampleRate, int inputChannels);
|
||||
|
||||
void togglePTT(void);
|
||||
|
||||
wxIPV4address m_udp_addr;
|
||||
wxDatagramSocket *m_udp_sock;
|
||||
UDPThread *m_UDPThread;
|
||||
void startUDPThread(void);
|
||||
void stopUDPThread(void);
|
||||
int PollUDP();
|
||||
bool m_schedule_restore;
|
||||
|
||||
protected:
|
||||
|
||||
#ifdef _WIN32
|
||||
#define COM_HANDLE_INVALID INVALID_HANDLE_VALUE
|
||||
com_handle_t com_handle;
|
||||
#else
|
||||
#define COM_HANDLE_INVALID -1
|
||||
com_handle_t com_handle;
|
||||
#endif
|
||||
void raiseDTR(void);
|
||||
void lowerDTR(void);
|
||||
void raiseRTS(void);
|
||||
void lowerRTS(void);
|
||||
bool openComPort(const char *port);
|
||||
void closeComPort(void);
|
||||
|
||||
void setsnrBeta(bool snrSlow);
|
||||
|
||||
// protected event handlers
|
||||
virtual void OnCloseFrame(wxCloseEvent& event);
|
||||
void OnExitClick(wxCommandEvent& event);
|
||||
|
||||
void startTxStream();
|
||||
void startRxStream();
|
||||
void stopTxStream();
|
||||
void stopRxStream();
|
||||
void abortTxStream();
|
||||
void abortRxStream();
|
||||
|
||||
void OnTop(wxCommandEvent& event);
|
||||
void OnExit( wxCommandEvent& event );
|
||||
|
||||
void OnToolsAudio( wxCommandEvent& event );
|
||||
void OnToolsAudioUI( wxUpdateUIEvent& event );
|
||||
void OnToolsComCfg( wxCommandEvent& event );
|
||||
void OnToolsComCfgUI( wxUpdateUIEvent& event );
|
||||
void OnToolsFilter( wxCommandEvent& event );
|
||||
void OnToolsOptions(wxCommandEvent& event);
|
||||
void OnToolsOptionsUI(wxUpdateUIEvent& event);
|
||||
|
||||
void OnPlayFileToMicIn( wxCommandEvent& event );
|
||||
void OnRecFileFromRadio( wxCommandEvent& event );
|
||||
void OnPlayFileFromRadio( wxCommandEvent& event );
|
||||
|
||||
void OnHelpCheckUpdates( wxCommandEvent& event );
|
||||
void OnHelpCheckUpdatesUI( wxUpdateUIEvent& event );
|
||||
void OnHelpAbout( wxCommandEvent& event );
|
||||
void OnCmdSliderScroll( wxScrollEvent& event );
|
||||
// void OnSliderScrollBottom( wxScrollEvent& event );
|
||||
// void OnCmdSliderScrollChanged( wxScrollEvent& event );
|
||||
// void OnSliderScrollTop( wxScrollEvent& event );
|
||||
void OnCheckSQClick( wxCommandEvent& event );
|
||||
void OnCheckSNRClick( wxCommandEvent& event );
|
||||
|
||||
// Toggle Buttons
|
||||
void OnTogBtnSplitClick(wxCommandEvent& event);
|
||||
void OnTogBtnAnalogClick(wxCommandEvent& event);
|
||||
void OnTogBtnRxID( wxCommandEvent& event );
|
||||
void OnTogBtnTxID( wxCommandEvent& event );
|
||||
void OnTogBtnPTT( wxCommandEvent& event );
|
||||
void OnTogBtnOnOff( wxCommandEvent& event );
|
||||
|
||||
void OnCallSignReset( wxCommandEvent& event );
|
||||
void OnBerReset( wxCommandEvent& event );
|
||||
|
||||
//System Events
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnSize( wxSizeEvent& event );
|
||||
void OnUpdateUI( wxUpdateUIEvent& event );
|
||||
void OnDeleteConfig(wxCommandEvent&);
|
||||
#ifdef _USE_TIMER
|
||||
void OnTimer(wxTimerEvent &evt);
|
||||
#endif
|
||||
#ifdef _USE_ONIDLE
|
||||
void OnIdle(wxIdleEvent &evt);
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool m_useMemory;
|
||||
wxTextCtrl* m_tc;
|
||||
int m_zoom;
|
||||
float m_snrBeta;
|
||||
|
||||
// Callsign/text messaging
|
||||
char m_callsign[MAX_CALLSIGN];
|
||||
char *m_pcallsign;
|
||||
unsigned int m_checksumGood;
|
||||
unsigned int m_checksumBad;
|
||||
|
||||
// Events
|
||||
void processTxtEvent(char event[]);
|
||||
class OptionsDlg *optionsDlg;
|
||||
wxTimer spamTimer[MAX_EVENT_RULES];
|
||||
|
||||
// level Gauge
|
||||
float m_maxLevel;
|
||||
|
||||
// flags to indicate when new EQ filters need to be designed
|
||||
|
||||
bool m_newMicInFilter;
|
||||
bool m_newSpkOutFilter;
|
||||
|
||||
void* designAnEQFilter(const char filterType[], float freqHz, float gaindB, float Q = 0.0);
|
||||
void designEQFilters(paCallBackData *cb);
|
||||
void deleteEQFilters(paCallBackData *cb);
|
||||
};
|
||||
|
||||
void txRxProcessing();
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// class txRxThread - experimental tx/rx processing thread
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class txRxThread : public wxThread
|
||||
{
|
||||
public:
|
||||
txRxThread(void) : wxThread(wxTHREAD_JOINABLE) { m_run = 1; }
|
||||
|
||||
// thread execution starts here
|
||||
void *Entry()
|
||||
{
|
||||
while (m_run)
|
||||
{
|
||||
txRxProcessing();
|
||||
wxThread::Sleep(20);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// called when the thread exits - whether it terminates normally or is
|
||||
// stopped with Delete() (but not when it is Kill()ed!)
|
||||
void OnExit() { }
|
||||
|
||||
public:
|
||||
bool m_run;
|
||||
};
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// class UDPThread - waits for UDP messages
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class UDPThread : public wxThread
|
||||
{
|
||||
public:
|
||||
UDPThread(void) : wxThread(wxTHREAD_JOINABLE) { m_run = 1; }
|
||||
|
||||
// thread execution starts here
|
||||
void *Entry();
|
||||
|
||||
// called when the thread exits - whether it terminates normally or is
|
||||
// stopped with Delete() (but not when it is Kill()ed!)
|
||||
void OnExit() { }
|
||||
|
||||
public:
|
||||
MainFrame *mf;
|
||||
bool m_run;
|
||||
};
|
||||
|
||||
void resample_for_plot(struct FIFO *plotFifo, short buf[], int length, int fs);
|
||||
|
||||
int resample(SRC_STATE *src,
|
||||
short output_short[],
|
||||
short input_short[],
|
||||
int output_sample_rate,
|
||||
int input_sample_rate,
|
||||
int length_output_short, // maximum output array length in samples
|
||||
int length_input_short
|
||||
);
|
||||
void txRxProcessing();
|
||||
void per_frame_rx_processing(
|
||||
FIFO *output_fifo, // decoded speech samples
|
||||
FIFO *input_fifo // modem samples input to demod
|
||||
);
|
||||
|
||||
// FreeDv API calls this when there is a test frame that needs a-plottin'
|
||||
|
||||
void my_freedv_put_error_pattern(void *state, short error_pattern[], int sz_error_pattern);
|
||||
|
||||
// FreeDv API calls these puppies when it needs/receives a text char
|
||||
|
||||
char my_get_next_tx_char(void *callback_state);
|
||||
void my_put_next_rx_char(void *callback_state, char c);
|
||||
|
||||
#endif //__FDMDV2_MAIN__
|
|
@ -0,0 +1,324 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_pa_wrapper.cpp
|
||||
// Purpose: Implements a wrapper class around the PortAudio library.
|
||||
// Created: August 12, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#include "fdmdv2_pa_wrapper.h"
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// PortAudioWrap()
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
PortAudioWrap::PortAudioWrap()
|
||||
{
|
||||
m_pStream = NULL;
|
||||
m_pUserData = NULL;
|
||||
m_samplerate = 0;
|
||||
m_framesPerBuffer = 0;
|
||||
m_statusFlags = 0;
|
||||
m_pStreamCallback = NULL;
|
||||
m_pStreamFinishedCallback = NULL;
|
||||
m_pTimeInfo = 0;
|
||||
m_newdata = false;
|
||||
|
||||
// loadData();
|
||||
}
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// ~PortAudioWrap()
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
PortAudioWrap::~PortAudioWrap()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// streamOpen()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::streamOpen()
|
||||
{
|
||||
return Pa_OpenStream(
|
||||
&m_pStream,
|
||||
m_inputBuffer.device == paNoDevice ? NULL : &m_inputBuffer,
|
||||
m_outputBuffer.device == paNoDevice ? NULL : &m_outputBuffer,
|
||||
m_samplerate,
|
||||
m_framesPerBuffer,
|
||||
m_statusFlags,
|
||||
*m_pStreamCallback,
|
||||
m_pUserData
|
||||
);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// streamStart()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::streamStart()
|
||||
{
|
||||
return Pa_StartStream(m_pStream);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// streamClose()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::streamClose()
|
||||
{
|
||||
if(isOpen())
|
||||
{
|
||||
PaError rv = Pa_CloseStream(m_pStream);
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
{
|
||||
return paNoError;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// terminate()
|
||||
//----------------------------------------------------------------
|
||||
void PortAudioWrap::terminate()
|
||||
{
|
||||
if(Pa_IsStreamStopped(m_pStream) != paNoError)
|
||||
{
|
||||
Pa_StopStream(m_pStream);
|
||||
}
|
||||
Pa_Terminate();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// stop()
|
||||
//----------------------------------------------------------------
|
||||
void PortAudioWrap::stop()
|
||||
{
|
||||
Pa_StopStream(m_pStream);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// abort()
|
||||
//----------------------------------------------------------------
|
||||
void PortAudioWrap::abort()
|
||||
{
|
||||
Pa_AbortStream(m_pStream);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// isStopped()
|
||||
//----------------------------------------------------------------
|
||||
bool PortAudioWrap::isStopped() const
|
||||
{
|
||||
PaError ret = Pa_IsStreamStopped(m_pStream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// isActive()
|
||||
//----------------------------------------------------------------
|
||||
bool PortAudioWrap::isActive() const
|
||||
{
|
||||
PaError ret = Pa_IsStreamActive(m_pStream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// isOpen()
|
||||
//----------------------------------------------------------------
|
||||
bool PortAudioWrap::isOpen() const
|
||||
{
|
||||
return (m_pStream != NULL);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// getDefaultInputDevice()
|
||||
//----------------------------------------------------------------
|
||||
PaDeviceIndex PortAudioWrap::getDefaultInputDevice()
|
||||
{
|
||||
return Pa_GetDefaultInputDevice();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// getDefaultOutputDevice()
|
||||
//----------------------------------------------------------------
|
||||
PaDeviceIndex PortAudioWrap::getDefaultOutputDevice()
|
||||
{
|
||||
return Pa_GetDefaultOutputDevice();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setInputChannelCount()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setInputChannelCount(int count)
|
||||
{
|
||||
m_inputBuffer.channelCount = count;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// getInputChannelCount()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::getInputChannelCount()
|
||||
{
|
||||
return m_inputBuffer.channelCount;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setInputSampleFormat()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setInputSampleFormat(PaSampleFormat format)
|
||||
{
|
||||
m_inputBuffer.sampleFormat = format;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setInputLatency()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setInputLatency(PaTime latency)
|
||||
{
|
||||
m_inputBuffer.suggestedLatency = latency;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setInputHostApiStreamInfo()
|
||||
//----------------------------------------------------------------
|
||||
void PortAudioWrap::setInputHostApiStreamInfo(void *info)
|
||||
{
|
||||
m_inputBuffer.hostApiSpecificStreamInfo = info;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// getInputDefaultLowLatency()
|
||||
//----------------------------------------------------------------
|
||||
PaTime PortAudioWrap::getInputDefaultLowLatency()
|
||||
{
|
||||
return Pa_GetDeviceInfo(m_inputBuffer.device)->defaultLowInputLatency;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setOutputChannelCount()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setOutputChannelCount(int count)
|
||||
{
|
||||
m_outputBuffer.channelCount = count;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// getOutputChannelCount()
|
||||
//----------------------------------------------------------------
|
||||
const int PortAudioWrap::getOutputChannelCount()
|
||||
{
|
||||
return m_outputBuffer.channelCount;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// getDeviceName()
|
||||
//----------------------------------------------------------------
|
||||
const char *PortAudioWrap::getDeviceName(PaDeviceIndex dev)
|
||||
{
|
||||
const PaDeviceInfo *info;
|
||||
info = Pa_GetDeviceInfo(dev);
|
||||
return info->name;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setOutputSampleFormat()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setOutputSampleFormat(PaSampleFormat format)
|
||||
{
|
||||
m_outputBuffer.sampleFormat = format;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setOutputLatency()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setOutputLatency(PaTime latency)
|
||||
{
|
||||
m_outputBuffer.suggestedLatency = latency;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setOutputHostApiStreamInfo()
|
||||
//----------------------------------------------------------------
|
||||
void PortAudioWrap::setOutputHostApiStreamInfo(void *info)
|
||||
{
|
||||
m_outputBuffer.hostApiSpecificStreamInfo = info;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// getOutputDefaultLowLatency()
|
||||
//----------------------------------------------------------------
|
||||
PaTime PortAudioWrap::getOutputDefaultLowLatency()
|
||||
{
|
||||
return Pa_GetDeviceInfo(m_outputBuffer.device)->defaultLowOutputLatency;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setFramesPerBuffer()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setFramesPerBuffer(unsigned long size)
|
||||
{
|
||||
m_framesPerBuffer = size;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setSampleRate()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setSampleRate(unsigned long rate)
|
||||
{
|
||||
m_samplerate = rate;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setStreamFlags()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setStreamFlags(PaStreamFlags flags)
|
||||
{
|
||||
m_statusFlags = flags;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setInputDevice()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setInputDevice(PaDeviceIndex index)
|
||||
{
|
||||
m_inputBuffer.device = index;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setOutputDevice()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setOutputDevice(PaDeviceIndex index)
|
||||
{
|
||||
m_outputBuffer.device = index;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setCallback()
|
||||
//----------------------------------------------------------------
|
||||
PaError PortAudioWrap::setCallback(PaStreamCallback *callback)
|
||||
{
|
||||
m_pStreamCallback = callback;
|
||||
return paNoError;
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_pa_wrapper.h
|
||||
// Purpose: Defines a wrapper class around PortAudio
|
||||
// Created: August 12, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "fdmdv2_defines.h"
|
||||
#include "codec2_fdmdv.h"
|
||||
#include "codec2.h"
|
||||
#include "portaudio.h"
|
||||
|
||||
#define PA_SAMPLE_TYPE paInt16 //paFloat32
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
|
||||
typedef float SAMPLE;
|
||||
|
||||
class PortAudioWrap
|
||||
{
|
||||
public:
|
||||
PortAudioWrap();
|
||||
~PortAudioWrap();
|
||||
|
||||
// float m_av_mag[FDMDV_NSPEC];
|
||||
|
||||
private:
|
||||
PaStream *m_pStream;
|
||||
void *m_pUserData;
|
||||
PaStreamCallback *m_pStreamCallback;
|
||||
PaStreamFinishedCallback *m_pStreamFinishedCallback;
|
||||
const PaStreamCallbackTimeInfo *m_pTimeInfo;
|
||||
struct FDMDV *m_pFDMDV_state;
|
||||
PaStreamParameters m_inputBuffer;
|
||||
PaStreamParameters m_outputBuffer;
|
||||
int m_samplerate;
|
||||
unsigned long m_framesPerBuffer;
|
||||
PaStreamCallbackFlags m_statusFlags;
|
||||
bool m_newdata;
|
||||
|
||||
public:
|
||||
|
||||
void averageData(float mag_dB[]);
|
||||
|
||||
int getDeviceCount() { return Pa_GetDeviceCount(); }
|
||||
PaDeviceIndex getDefaultInputDevice();
|
||||
PaDeviceIndex getDefaultOutputDevice();
|
||||
PaStreamParameters *getDeviceInfo(PaDeviceIndex idx);
|
||||
|
||||
PaError setFramesPerBuffer(unsigned long size);
|
||||
PaError setSampleRate(unsigned long size);
|
||||
|
||||
PaError setStreamFlags(PaStreamFlags flags);
|
||||
PaError setCallback(PaStreamCallback *m_pStreamCallback);
|
||||
PaError setStreamCallback(PaStream *stream, PaStreamCallback* callback) { m_pStreamCallback = callback; return 0;}
|
||||
PaError setStreamFinishedCallback(PaStream *stream, PaStreamFinishedCallback* m_pStreamFinishedCallback);
|
||||
|
||||
void setInputBuffer(const PaStreamParameters& inputBuffer) {this->m_inputBuffer = inputBuffer;}
|
||||
PaError setInputDevice(PaDeviceIndex dev);
|
||||
PaError setInputChannelCount(int count);
|
||||
int getInputChannelCount();
|
||||
PaError setInputSampleFormat(PaSampleFormat format);
|
||||
PaError setInputSampleRate(PaSampleFormat format);
|
||||
PaError setInputLatency(PaTime latency);
|
||||
void setInputHostApiStreamInfo(void *info = NULL);
|
||||
PaTime getInputDefaultLowLatency();
|
||||
const char *getDeviceName(PaDeviceIndex dev);
|
||||
|
||||
PaError setOutputDevice(PaDeviceIndex dev);
|
||||
PaError setOutputChannelCount(int count);
|
||||
const int getOutputChannelCount();
|
||||
PaError setOutputSampleFormat(PaSampleFormat format);
|
||||
PaError setOutputLatency(PaTime latency);
|
||||
void setOutputHostApiStreamInfo(void *info = NULL);
|
||||
PaTime getOutputDefaultLowLatency();
|
||||
|
||||
void setFdmdvState(FDMDV* fdmdv_state) {this->m_pFDMDV_state = fdmdv_state;}
|
||||
void setOutputBuffer(const PaStreamParameters& outputBuffer) {this->m_outputBuffer = outputBuffer;}
|
||||
void setTimeInfo(PaStreamCallbackTimeInfo* timeInfo) {this->m_pTimeInfo = timeInfo;}
|
||||
void setUserData(void* userData) {this->m_pUserData = userData;}
|
||||
unsigned long getFramesPerBuffer() const {return m_framesPerBuffer;}
|
||||
const PaStreamParameters& getInputBuffer() const {return m_inputBuffer;}
|
||||
const PaStreamParameters& getOutputBuffer() const {return m_outputBuffer;}
|
||||
const PaStreamCallbackFlags& getStatusFlags() const {return m_statusFlags;}
|
||||
|
||||
FDMDV* getFdmdvState() {return m_pFDMDV_state;}
|
||||
int getSamplerate() const {return m_samplerate;}
|
||||
PaStream* getStream() {return m_pStream;}
|
||||
void *getUserData() {return m_pUserData;}
|
||||
bool getDataAvail() {return m_newdata;}
|
||||
PaError streamStart();
|
||||
PaError streamClose();
|
||||
PaError streamOpen();
|
||||
void terminate();
|
||||
void stop();
|
||||
void abort();
|
||||
bool isOpen() const;
|
||||
bool isStopped() const;
|
||||
bool isActive() const;
|
||||
// void loadData();
|
||||
};
|
|
@ -0,0 +1,283 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_plot.cpp
|
||||
// Purpose: Implements simple wxWidgets application with GUI.
|
||||
// Created: Apr. 9, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#include <string.h>
|
||||
#include "fdmdv2_plot.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(PlotPanel, wxPanel)
|
||||
EVT_PAINT (PlotPanel::OnPaint)
|
||||
EVT_MOTION (PlotPanel::OnMouseMove)
|
||||
EVT_LEFT_DOWN (PlotPanel::OnMouseLeftDown)
|
||||
EVT_LEFT_UP (PlotPanel::OnMouseLeftUp)
|
||||
EVT_RIGHT_DOWN (PlotPanel::OnMouseRightDown)
|
||||
EVT_MOUSEWHEEL (PlotPanel::OnMouseWheelMoved)
|
||||
EVT_SIZE (PlotPanel::OnSize)
|
||||
EVT_SHOW (PlotPanel::OnShow)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class PlotPanel(wxFrame* parent) : wxPanel(parent)
|
||||
//
|
||||
// @class $(Name)
|
||||
// @author $(User)
|
||||
// @date $(Date)
|
||||
// @file $(CurrentFileName).$(CurrentFileExt)
|
||||
// @brief
|
||||
//
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
PlotPanel::PlotPanel(wxFrame* parent) : wxPanel(parent)
|
||||
{
|
||||
m_pNoteBook = (wxAuiNotebook *) parent;
|
||||
m_pTopFrame = (MainFrame *)m_pNoteBook->GetParent();
|
||||
m_zoomFactor = 1.0;
|
||||
m_pBmp = NULL;
|
||||
m_pPix = NULL;
|
||||
m_firstPass = true;
|
||||
m_line_color = 0;
|
||||
m_newdata = false;
|
||||
m_clip = false;
|
||||
m_use_bitmap = true;
|
||||
m_rubberBand = false;
|
||||
m_mouseDown = false;
|
||||
m_penShortDash = wxPen(wxColor(0xA0, 0xA0, 0xA0), 1, wxPENSTYLE_SHORT_DASH);
|
||||
m_penDotDash = wxPen(wxColor(0xD0, 0xD0, 0xD0), 1, wxPENSTYLE_DOT_DASH);
|
||||
m_penSolid = wxPen(wxColor(0x00, 0x00, 0x00), 1, wxPENSTYLE_SOLID);
|
||||
SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
SetLabelSize(10.0);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ~PlotPanel()
|
||||
//-------------------------------------------------------------------------
|
||||
PlotPanel::~PlotPanel()
|
||||
{
|
||||
if(m_pBmp != NULL)
|
||||
{
|
||||
delete m_pBmp;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// GetLabelSize()
|
||||
//-------------------------------------------------------------------------
|
||||
double PlotPanel::GetLabelSize()
|
||||
{
|
||||
return m_label_size;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// SetLabelSize()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::SetLabelSize(double size)
|
||||
{
|
||||
m_label_size = size;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnShow()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::OnShow(wxShowEvent& event)
|
||||
{
|
||||
this->Refresh();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnErase()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::OnErase(wxEraseEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnSize()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::OnSize(wxSizeEvent& event)
|
||||
{
|
||||
m_rCtrlPrev = m_rCtrl;
|
||||
m_rCtrl = GetClientRect();
|
||||
if(m_use_bitmap)
|
||||
{
|
||||
if(!m_oImage.IsOk())
|
||||
{
|
||||
m_oImage.Create(m_rCtrl.GetWidth(), m_rCtrl.GetHeight(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oImage.Rescale(m_rCtrl.GetWidth(), m_rCtrl.GetHeight());
|
||||
}
|
||||
m_pBmp = new wxBitmap(m_oImage, wxBITMAP_SCREEN_DEPTH);
|
||||
m_firstPass = true;
|
||||
}
|
||||
this->Refresh();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnMouseMove()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::OnMouseMove(wxMouseEvent& event)
|
||||
{
|
||||
// if(m_mouseDown)
|
||||
// {
|
||||
// paintNow();
|
||||
// }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnMouseLeftDown()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::OnMouseLeftDown(wxMouseEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnMouseRightDown()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::OnMouseRightDown(wxMouseEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnMouseWheelMoved()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::OnMouseWheelMoved(wxMouseEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnMouseLeftUp()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::OnMouseLeftUp(wxMouseEvent& event)
|
||||
{
|
||||
m_mouseDown = false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// SetZoomFactor()
|
||||
//-------------------------------------------------------------------------
|
||||
double PlotPanel::SetZoomFactor(double zf)
|
||||
{
|
||||
if((zf > 0) && (zf < 5.0))
|
||||
{
|
||||
m_zoomFactor = zf;
|
||||
}
|
||||
return zf;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// GetZoomFactor()
|
||||
//-------------------------------------------------------------------------
|
||||
double PlotPanel::GetZoomFactor(double zf)
|
||||
{
|
||||
return m_zoomFactor;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// draw()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::draw(wxAutoBufferedPaintDC& pDC)
|
||||
{
|
||||
printf("PlotPanel::draw()");
|
||||
wxMemoryDC m_mDC;
|
||||
m_mDC.SelectObject(*m_pBmp);
|
||||
m_rCtrl = GetClientRect();
|
||||
m_rGrid = m_rCtrl;
|
||||
|
||||
m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
|
||||
m_rGrid.Offset(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER);
|
||||
|
||||
pDC.Clear();
|
||||
m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
|
||||
if(m_firstPass)
|
||||
{
|
||||
m_firstPass = false;
|
||||
m_mDC.FloodFill(0, 0, VERY_LTGREY_COLOR);
|
||||
|
||||
// Draw a filled rectangle with aborder
|
||||
wxBrush ltGraphBkgBrush = wxBrush(DARK_BLUE_COLOR);
|
||||
m_mDC.SetBrush(ltGraphBkgBrush);
|
||||
m_mDC.SetPen(wxPen(BLACK_COLOR, 0));
|
||||
m_mDC.DrawRectangle(m_rPlot);
|
||||
}
|
||||
if(m_newdata)
|
||||
{
|
||||
m_newdata = false;
|
||||
int t = m_rPlot.GetTop();
|
||||
int l = m_rPlot.GetLeft();
|
||||
// int r = m_rPlot.GetRight();
|
||||
int h = m_rPlot.GetHeight();
|
||||
int w = m_rPlot.GetWidth();
|
||||
pDC.Blit(l, t, w, h, &m_mDC, l, t);
|
||||
}
|
||||
drawGraticule(pDC);
|
||||
m_mDC.SetBrush(wxNullBrush);
|
||||
m_mDC.SelectObject(wxNullBitmap);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// drawGraticule()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::drawGraticule(wxAutoBufferedPaintDC& pDC)
|
||||
{
|
||||
int p;
|
||||
char buf[15];
|
||||
wxString s;
|
||||
|
||||
// Vertical gridlines
|
||||
pDC.SetPen(m_penShortDash);
|
||||
for(p = (PLOT_BORDER + XLEFT_OFFSET + GRID_INCREMENT); p < ((m_rGrid.GetWidth() - XLEFT_OFFSET) + GRID_INCREMENT); p += GRID_INCREMENT)
|
||||
{
|
||||
pDC.DrawLine(p, (m_rGrid.GetHeight() + PLOT_BORDER), p, PLOT_BORDER);
|
||||
}
|
||||
// Horizontal gridlines
|
||||
pDC.SetPen(m_penDotDash);
|
||||
for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT)
|
||||
{
|
||||
pDC.DrawLine(PLOT_BORDER + XLEFT_OFFSET, (p + PLOT_BORDER), (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), (p + PLOT_BORDER));
|
||||
}
|
||||
// Label the X-Axis
|
||||
pDC.SetPen(wxPen(GREY_COLOR, 1));
|
||||
for(p = GRID_INCREMENT; p < (m_rGrid.GetWidth() - YBOTTOM_OFFSET); p += GRID_INCREMENT)
|
||||
{
|
||||
sprintf(buf, "%1.1f Hz",(double)(p / 10));
|
||||
pDC.DrawText(buf, p - PLOT_BORDER + XLEFT_OFFSET, m_rGrid.GetHeight() + YBOTTOM_OFFSET/2);
|
||||
}
|
||||
// Label the Y-Axis
|
||||
//for(p = GRID_INCREMENT; p < (h - YBOTTOM_OFFSET); p += GRID_INCREMENT)
|
||||
for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT)
|
||||
{
|
||||
sprintf(buf, "%1.0f", (double)((m_rGrid.GetHeight() - p) * -10));
|
||||
pDC.DrawText(buf, XLEFT_TEXT_OFFSET, p);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// paintEvent()
|
||||
//
|
||||
// Called by the system of by wxWidgets when the panel needs
|
||||
// to be redrawn. You can also trigger this call by calling
|
||||
// Refresh()/Update().
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotPanel::OnPaint(wxPaintEvent & evt)
|
||||
{
|
||||
wxAutoBufferedPaintDC pdc(this);
|
||||
draw(pdc);
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_plot.h
|
||||
// Purpose: Declares simple wxWidgets application with GUI
|
||||
// Created: Apr. 10, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
//#include "fdmdv2_main.h"
|
||||
#ifndef __FDMDV2_PLOT__
|
||||
#define __FDMDV2_PLOT__
|
||||
#include <wx/wx.h>
|
||||
#include <wx/aui/auibook.h>
|
||||
#include <wx/rawbmp.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/dcbuffer.h>
|
||||
|
||||
#define MAX_ZOOM 7
|
||||
#define MAX_BMP_X (400 * MAX_ZOOM)
|
||||
#define MAX_BMP_Y (400 * MAX_ZOOM)
|
||||
#define DATA_LINE_HEIGHT 10
|
||||
#define TEXT_BASELINE_OFFSET_Y -5
|
||||
|
||||
|
||||
#define wxUSE_FILEDLG 1
|
||||
#define wxUSE_LIBPNG 1
|
||||
#define wxUSE_LIBJPEG 1
|
||||
#define wxUSE_GIF 1
|
||||
#define wxUSE_PCX 1
|
||||
#define wxUSE_LIBTIFF 1
|
||||
|
||||
#define PLOT_BORDER 12
|
||||
#define XLEFT_OFFSET 40
|
||||
#define XLEFT_TEXT_OFFSET 6
|
||||
#define YBOTTOM_OFFSET 20
|
||||
#define YBOTTOM_TEXT_OFFSET 15
|
||||
#define GRID_INCREMENT 50
|
||||
|
||||
#define BLACK_COLOR wxColor(0x00, 0x00, 0x00)
|
||||
#define GREY_COLOR wxColor(0x80, 0x80, 0x80)
|
||||
#define DARK_GREY_COLOR wxColor(0x40, 0x40, 0x40)
|
||||
#define MEDIUM_GREY_COLOR wxColor(0xC0, 0xC0, 0xC0)
|
||||
#define LIGHT_GREY_COLOR wxColor(0xE0, 0xE0, 0xE0)
|
||||
#define VERY_LTGREY_COLOR wxColor(0xF8, 0xF8, 0xF8)
|
||||
#define WHITE_COLOR wxColor(0xFF, 0xFF, 0xFF)
|
||||
|
||||
#define DARK_BLUE_COLOR wxColor(0x00, 0x00, 0x60)
|
||||
#define BLUE_COLOR wxColor(0x00, 0x00, 0xFF)
|
||||
#define LIGHT_BLUE_COLOR wxColor(0x80, 0x80, 0xFF)
|
||||
|
||||
#define RED_COLOR wxColor(0xFF, 0x5E, 0x5E)
|
||||
#define LIGHT_RED_COLOR wxColor(0xFF, 0xE0, 0xE0)
|
||||
#define DARK_RED_COLOR wxColor(0xFF, 0x00, 0x00)
|
||||
#define PINK_COLOR wxColor(0xFF, 0x80, 0xFF)
|
||||
|
||||
#define LIGHT_GREEN_COLOR wxColor(0xE3, 0xFF, 0xE0)
|
||||
#define GREEN_COLOR wxColor(0x95, 0xFF, 0x8A)
|
||||
#define DARK_GREEN_COLOR wxColor(0x20, 0xFF, 0x08)
|
||||
#define VERY_GREEN_COLOR wxColor(0x00, 0xFF, 0x00)
|
||||
|
||||
#define YELLOW_COLOR wxColor(0xFF, 0xFF, 0x5E)
|
||||
#define LIGHT_YELLOW_COLOR wxColor(0xFF, 0xFF, 0xB5)
|
||||
#define DARK_YELLOW_COLOR wxColor(0xFF, 0xFF, 0x08)
|
||||
|
||||
class MainFrame;
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class PlotPanel
|
||||
//
|
||||
// @class $(Name)
|
||||
// @author $(User)
|
||||
// @date $(Date)
|
||||
// @file $(CurrentFileName).$(CurrentFileExt)
|
||||
// @brief
|
||||
//
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class PlotPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
PlotPanel(wxFrame* parent);
|
||||
~PlotPanel();
|
||||
wxPen m_penShortDash;
|
||||
wxPen m_penDotDash;
|
||||
wxPen m_penSolid;
|
||||
wxRect m_rCtrlPrev;
|
||||
wxRect m_rCtrl;
|
||||
wxRect m_rGrid;
|
||||
wxRect m_rPlot;
|
||||
MainFrame *m_pTopFrame;
|
||||
wxAuiNotebook *m_pNoteBook;
|
||||
double m_label_size;
|
||||
wxSize m_Bufsz;
|
||||
bool m_newdata;
|
||||
wxImage m_oImage;
|
||||
wxBitmap *m_pBmp;
|
||||
wxNativePixelData *m_pPix;
|
||||
|
||||
// some useful events
|
||||
void OnMouseMove(wxMouseEvent& event);
|
||||
virtual void OnMouseLeftDown(wxMouseEvent& event);
|
||||
void OnMouseLeftUp(wxMouseEvent& event);
|
||||
virtual void OnMouseRightDown(wxMouseEvent& event);
|
||||
void OnMouseWheelMoved(wxMouseEvent& event);
|
||||
void OnClose(wxCloseEvent& event ){ event.Skip(); }
|
||||
void OnSize( wxSizeEvent& event );
|
||||
void OnErase(wxEraseEvent& event);
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
//void OnUpdateUI( wxUpdateUIEvent& event ){ event.Skip(); }
|
||||
|
||||
void paintEvent(wxPaintEvent & evt);
|
||||
virtual void draw(wxAutoBufferedPaintDC& pdc);
|
||||
virtual void drawGraticule(wxAutoBufferedPaintDC& pdc);
|
||||
virtual double SetZoomFactor(double zf);
|
||||
virtual double GetZoomFactor(double zf);
|
||||
virtual void OnShow(wxShowEvent& event);
|
||||
virtual double GetLabelSize();
|
||||
virtual void SetLabelSize(double size);
|
||||
|
||||
protected:
|
||||
int m_x;
|
||||
int m_y;
|
||||
int m_left;
|
||||
int m_top;
|
||||
int m_prev_w;
|
||||
int m_prev_h;
|
||||
int m_prev_x;
|
||||
int m_prev_y;
|
||||
bool m_use_bitmap;
|
||||
bool m_clip;
|
||||
bool m_rubberBand;
|
||||
bool m_mouseDown;
|
||||
bool m_firstPass;
|
||||
double m_zoomFactor;
|
||||
int m_greyscale;
|
||||
int m_line_color;
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
#endif //__FDMDV2_PLOT__
|
|
@ -0,0 +1,281 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_plot_scalar.cpp
|
||||
// Purpose: Plots scalar amplitude against time
|
||||
// Created: June 22, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#include <string.h>
|
||||
#include "wx/wx.h"
|
||||
#include "fdmdv2_main.h"
|
||||
#include "fdmdv2_plot_scalar.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(PlotScalar, PlotPanel)
|
||||
EVT_PAINT (PlotScalar::OnPaint)
|
||||
EVT_MOTION (PlotScalar::OnMouseMove)
|
||||
EVT_MOUSEWHEEL (PlotScalar::OnMouseWheelMoved)
|
||||
EVT_SIZE (PlotScalar::OnSize)
|
||||
EVT_SHOW (PlotScalar::OnShow)
|
||||
// EVT_ERASE_BACKGROUND(PlotScalar::OnErase)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// PlotScalar()
|
||||
//----------------------------------------------------------------
|
||||
PlotScalar::PlotScalar(wxFrame* parent,
|
||||
int channels, // number on channels to plot
|
||||
float t_secs, // time covered by entire x axis in seconds
|
||||
float sample_period_secs, // time between each sample in seconds
|
||||
float a_min, // min ampltude of samples being plotted
|
||||
float a_max, // max ampltude of samples being plotted
|
||||
float graticule_t_step, // time step of x (time) axis graticule in seconds
|
||||
float graticule_a_step, // step of amplitude axis graticule
|
||||
const char a_fmt[], // printf format string for amplitude axis labels
|
||||
int mini // true for mini-plot - don't draw graticule
|
||||
): PlotPanel(parent)
|
||||
{
|
||||
int i;
|
||||
|
||||
m_rCtrl = GetClientRect();
|
||||
|
||||
m_channels = channels;
|
||||
m_t_secs = t_secs;
|
||||
m_sample_period_secs = sample_period_secs;
|
||||
m_a_min = a_min;
|
||||
m_a_max = a_max;
|
||||
m_graticule_t_step = graticule_t_step;
|
||||
m_graticule_a_step = graticule_a_step;
|
||||
assert(strlen(a_fmt) < 15);
|
||||
strcpy(m_a_fmt, a_fmt);
|
||||
m_mini = mini;
|
||||
|
||||
// work out number of samples we will store and allocate storage
|
||||
|
||||
m_samples = m_t_secs/m_sample_period_secs;
|
||||
m_mem = new float[m_samples*m_channels];
|
||||
|
||||
for(i = 0; i < m_samples*m_channels; i++)
|
||||
{
|
||||
m_mem[i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// ~PlotScalar()
|
||||
//----------------------------------------------------------------
|
||||
PlotScalar::~PlotScalar()
|
||||
{
|
||||
delete m_mem;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// add_new_sample()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScalar::add_new_sample(int channel, float sample)
|
||||
{
|
||||
int i;
|
||||
int offset = channel*m_samples;
|
||||
|
||||
assert(channel < m_channels);
|
||||
|
||||
for(i = 0; i < m_samples-1; i++)
|
||||
{
|
||||
m_mem[offset+i] = m_mem[offset+i+1];
|
||||
}
|
||||
m_mem[offset+m_samples-1] = sample;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// add_new_samples()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScalar::add_new_short_samples(int channel, short samples[], int length, float scale_factor)
|
||||
{
|
||||
int i;
|
||||
int offset = channel*m_samples;
|
||||
|
||||
assert(channel < m_channels);
|
||||
|
||||
for(i = 0; i < m_samples-length; i++)
|
||||
m_mem[offset+i] = m_mem[offset+i+length];
|
||||
for(; i < m_samples; i++)
|
||||
m_mem[offset+i] = (float)*samples++/scale_factor;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// draw()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScalar::draw(wxAutoBufferedPaintDC& dc)
|
||||
{
|
||||
float index_to_px;
|
||||
float a_to_py;
|
||||
int i;
|
||||
int x, y;
|
||||
int prev_x, prev_y;
|
||||
float a;
|
||||
|
||||
m_rCtrl = GetClientRect();
|
||||
m_rGrid = m_rCtrl;
|
||||
if (!m_mini)
|
||||
m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
|
||||
|
||||
//printf("h %d w %d\n", m_rCtrl.GetWidth(), m_rCtrl.GetHeight());
|
||||
//printf("h %d w %d\n", m_rGrid.GetWidth(), m_rGrid.GetHeight());
|
||||
|
||||
// black background
|
||||
|
||||
dc.Clear();
|
||||
if (m_mini)
|
||||
m_rPlot = wxRect(0, 0, m_rGrid.GetWidth(), m_rGrid.GetHeight());
|
||||
else
|
||||
m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
|
||||
|
||||
wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
|
||||
dc.SetBrush(ltGraphBkgBrush);
|
||||
dc.SetPen(wxPen(BLACK_COLOR, 0));
|
||||
dc.DrawRectangle(m_rPlot);
|
||||
|
||||
index_to_px = (float)m_rGrid.GetWidth()/m_samples;
|
||||
a_to_py = (float)m_rGrid.GetHeight()/(m_a_max - m_a_min);
|
||||
|
||||
wxPen pen;
|
||||
pen.SetColour(DARK_GREEN_COLOR);
|
||||
pen.SetWidth(1);
|
||||
dc.SetPen(pen);
|
||||
|
||||
// draw all samples
|
||||
|
||||
prev_x = prev_y = 0; // stop warning
|
||||
|
||||
// plot each channel
|
||||
|
||||
int offset;
|
||||
for(offset=0; offset<m_channels*m_samples; offset+=m_samples) {
|
||||
|
||||
for(i = 0; i < m_samples; i++) {
|
||||
x = index_to_px * i;
|
||||
a = m_mem[offset+i];
|
||||
if (a < m_a_min) a = m_a_min;
|
||||
if (a > m_a_max) a = m_a_max;
|
||||
|
||||
// invert y axis and offset by minimum
|
||||
|
||||
y = m_rGrid.GetHeight() - a_to_py * a + m_a_min*a_to_py;
|
||||
|
||||
// put inside plot window
|
||||
|
||||
if (!m_mini) {
|
||||
x += PLOT_BORDER + XLEFT_OFFSET;
|
||||
y += PLOT_BORDER;
|
||||
}
|
||||
|
||||
if (i)
|
||||
dc.DrawLine(x, y, prev_x, prev_y);
|
||||
prev_x = x; prev_y = y;
|
||||
}
|
||||
}
|
||||
|
||||
drawGraticule(dc);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// drawGraticule()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotScalar::drawGraticule(wxAutoBufferedPaintDC& dc)
|
||||
{
|
||||
float t, a;
|
||||
int x, y, text_w, text_h;
|
||||
char buf[15];
|
||||
wxString s;
|
||||
float sec_to_px;
|
||||
float a_to_py;
|
||||
|
||||
wxBrush ltGraphBkgBrush;
|
||||
ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
|
||||
ltGraphBkgBrush.SetColour(*wxBLACK);
|
||||
dc.SetBrush(ltGraphBkgBrush);
|
||||
dc.SetPen(wxPen(BLACK_COLOR, 1));
|
||||
|
||||
sec_to_px = (float)m_rGrid.GetWidth()/m_t_secs;
|
||||
a_to_py = (float)m_rGrid.GetHeight()/(m_a_max - m_a_min);
|
||||
|
||||
// upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
|
||||
// lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(),
|
||||
// PLOT_BORDER + m_rGrid.GetHeight())
|
||||
|
||||
// Vertical gridlines
|
||||
|
||||
dc.SetPen(m_penShortDash);
|
||||
for(t=0; t<=m_t_secs; t+=m_graticule_t_step) {
|
||||
x = t*sec_to_px;
|
||||
if (m_mini) {
|
||||
dc.DrawLine(x, m_rGrid.GetHeight(), x, 0);
|
||||
}
|
||||
else {
|
||||
x += PLOT_BORDER + XLEFT_OFFSET;
|
||||
dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
|
||||
}
|
||||
if (!m_mini) {
|
||||
sprintf(buf, "%2.1fs", t);
|
||||
GetTextExtent(buf, &text_w, &text_h);
|
||||
dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
// Horizontal gridlines
|
||||
|
||||
dc.SetPen(m_penDotDash);
|
||||
for(a=m_a_min; a<m_a_max; a+=m_graticule_a_step) {
|
||||
y = m_rGrid.GetHeight() - a*a_to_py + m_a_min*a_to_py;
|
||||
if (m_mini) {
|
||||
dc.DrawLine(0, y, m_rGrid.GetWidth(), y);
|
||||
}
|
||||
else {
|
||||
y += PLOT_BORDER;
|
||||
dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y,
|
||||
(m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
|
||||
}
|
||||
if (!m_mini) {
|
||||
sprintf(buf, m_a_fmt, a);
|
||||
GetTextExtent(buf, &text_w, &text_h);
|
||||
dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// OnPaint()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScalar::OnPaint(wxPaintEvent& event)
|
||||
{
|
||||
wxAutoBufferedPaintDC dc(this);
|
||||
draw(dc);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// OnSize()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScalar::OnSize(wxSizeEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// OnShow()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScalar::OnShow(wxShowEvent& event)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_plot_scalar.h
|
||||
// Purpose: Defines a scalar plot derivative of fdmdv2_plot.
|
||||
// Created: June 22, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#ifndef __FDMDV2_PLOT_SCALAR__
|
||||
#define __FDMDV2_PLOT_SCALAR__
|
||||
|
||||
#include "fdmdv2_plot.h"
|
||||
#include "fdmdv2_defines.h"
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class PlotScalar
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class PlotScalar: public PlotPanel
|
||||
{
|
||||
public:
|
||||
|
||||
PlotScalar(wxFrame* parent,
|
||||
int channels,
|
||||
float t_secs,
|
||||
float sample_period_secs,
|
||||
float a_min,
|
||||
float a_max,
|
||||
float graticule_t_step,
|
||||
float graticule_a_step,
|
||||
const char a_fmt[],
|
||||
int mini
|
||||
);
|
||||
~PlotScalar();
|
||||
void add_new_sample(int channel, float sample);
|
||||
void add_new_short_samples(int channel, short samples[], int length, float scale_factor);
|
||||
|
||||
protected:
|
||||
|
||||
int m_channels;
|
||||
float m_t_secs;
|
||||
float m_sample_period_secs;
|
||||
float m_a_min;
|
||||
float m_a_max;
|
||||
float m_graticule_t_step;
|
||||
float m_graticule_a_step;
|
||||
char m_a_fmt[15];
|
||||
int m_mini;
|
||||
int m_samples;
|
||||
float *m_mem;
|
||||
|
||||
void draw(wxAutoBufferedPaintDC& dc);
|
||||
void drawGraticule(wxAutoBufferedPaintDC& dc);
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnSize(wxSizeEvent& event);
|
||||
void OnShow(wxShowEvent& event);
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#endif // __FDMDV2_PLOT_SCALAR__
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_plot_scatter.cpp
|
||||
// Purpose: A scatter plot derivative of fdmdv2_plot.
|
||||
// Created: June 24, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#include <string.h>
|
||||
#include "wx/wx.h"
|
||||
#include "fdmdv2_plot_scatter.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(PlotScatter, PlotPanel)
|
||||
EVT_PAINT (PlotScatter::OnPaint)
|
||||
EVT_MOTION (PlotScatter::OnMouseMove)
|
||||
EVT_MOUSEWHEEL (PlotScatter::OnMouseWheelMoved)
|
||||
EVT_SIZE (PlotScatter::OnSize)
|
||||
EVT_SHOW (PlotScatter::OnShow)
|
||||
// EVT_ERASE_BACKGROUND(PlotScatter::OnErase)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// PlotScatter
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
PlotScatter::PlotScatter(wxFrame* parent) : PlotPanel(parent)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i < SCATTER_MEM_SYMS_MAX; i++)
|
||||
{
|
||||
m_mem[i].real = 0.0;
|
||||
m_mem[i].imag = 0.0;
|
||||
}
|
||||
|
||||
m_filter_max_xy = 0.1;
|
||||
|
||||
// defaults so we start off with something sensible
|
||||
|
||||
Nsym = 14+1;
|
||||
scatterMemSyms = ((int)(SCATTER_MEM_SECS*(Nsym/DT)));
|
||||
assert(scatterMemSyms <= SCATTER_MEM_SYMS_MAX);
|
||||
|
||||
}
|
||||
|
||||
// changing number of carriers changes number of symbols to plot
|
||||
void PlotScatter::setNc(int Nc) {
|
||||
Nsym = Nc+1;
|
||||
assert(Nsym <= (FDMDV_NC_MAX+1));
|
||||
scatterMemSyms = ((int)(SCATTER_MEM_SECS*(Nsym/DT)));
|
||||
assert(scatterMemSyms <= SCATTER_MEM_SYMS_MAX);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// draw()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScatter::draw(wxAutoBufferedPaintDC& dc)
|
||||
{
|
||||
float x_scale;
|
||||
float y_scale;
|
||||
int i;
|
||||
int x;
|
||||
int y;
|
||||
wxColour sym_to_colour[] = {wxColor(0,0,255),
|
||||
wxColor(0,255,0),
|
||||
wxColor(0,255,255),
|
||||
wxColor(255,0,0),
|
||||
wxColor(255,0,255),
|
||||
wxColor(255,255,0),
|
||||
wxColor(255,255,255),
|
||||
wxColor(0,0,255),
|
||||
wxColor(0,255,0),
|
||||
wxColor(0,255,255),
|
||||
wxColor(255,0,0),
|
||||
wxColor(255,0,255),
|
||||
wxColor(255,255,0),
|
||||
wxColor(255,255,255),
|
||||
wxColor(0,0,255),
|
||||
wxColor(0,255,0),
|
||||
wxColor(0,255,255),
|
||||
wxColor(255,0,0),
|
||||
wxColor(255,0,255)
|
||||
};
|
||||
|
||||
m_rCtrl = GetClientRect();
|
||||
m_rGrid = m_rCtrl;
|
||||
m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
|
||||
|
||||
// black background
|
||||
|
||||
dc.Clear();
|
||||
m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
|
||||
wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
|
||||
dc.SetBrush(ltGraphBkgBrush);
|
||||
dc.SetPen(wxPen(BLACK_COLOR, 0));
|
||||
dc.DrawRectangle(m_rPlot);
|
||||
|
||||
wxPen pen;
|
||||
pen.SetWidth(1); // note this is ignored by DrawPoint
|
||||
|
||||
// automatically scale, first measure the maximum value
|
||||
|
||||
float max_xy = 1E-12;
|
||||
float real,imag;
|
||||
for(i=0; i< scatterMemSyms; i++) {
|
||||
real = fabs(m_mem[i].real);
|
||||
imag = fabs(m_mem[i].imag);
|
||||
if (real > max_xy)
|
||||
max_xy = real;
|
||||
if (imag > max_xy)
|
||||
max_xy = imag;
|
||||
}
|
||||
|
||||
// smooth it out and set a lower limit to prevent didev by 0 issues
|
||||
|
||||
m_filter_max_xy = BETA*m_filter_max_xy + (1 - BETA)*2.5*max_xy;
|
||||
if (m_filter_max_xy < 0.001)
|
||||
m_filter_max_xy = 0.001;
|
||||
|
||||
// quantise to log steps to prevent scatter scaling bobbing about too
|
||||
// much as scaling varies
|
||||
|
||||
float quant_m_filter_max_xy = exp(floor(0.5+log(m_filter_max_xy)));
|
||||
//printf("max_xy: %f m_filter_max_xy: %f quant_m_filter_max_xy: %f\n", max_xy, m_filter_max_xy, quant_m_filter_max_xy);
|
||||
|
||||
x_scale = (float)m_rGrid.GetWidth()/quant_m_filter_max_xy;
|
||||
y_scale = (float)m_rGrid.GetHeight()/quant_m_filter_max_xy;
|
||||
|
||||
// draw all samples
|
||||
|
||||
for(i = 0; i < scatterMemSyms; i++)
|
||||
{
|
||||
x = x_scale * m_mem[i].real + m_rGrid.GetWidth()/2;
|
||||
y = y_scale * m_mem[i].imag + m_rGrid.GetHeight()/2;
|
||||
x += PLOT_BORDER + XLEFT_OFFSET;
|
||||
y += PLOT_BORDER;
|
||||
pen.SetColour(sym_to_colour[i%Nsym]);
|
||||
dc.SetPen(pen);
|
||||
dc.DrawPoint(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// add_new_samples()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScatter::add_new_samples(COMP samples[])
|
||||
{
|
||||
int i,j;
|
||||
|
||||
// shift memory
|
||||
|
||||
for(i = 0; i < scatterMemSyms - Nsym; i++)
|
||||
{
|
||||
m_mem[i] = m_mem[i+Nsym];
|
||||
}
|
||||
|
||||
// new samples
|
||||
|
||||
for(j=0; i < scatterMemSyms; i++,j++)
|
||||
{
|
||||
m_mem[i] = samples[j];
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// OnPaint()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScatter::OnPaint(wxPaintEvent& event)
|
||||
{
|
||||
wxAutoBufferedPaintDC dc(this);
|
||||
draw(dc);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// OnSize()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScatter::OnSize(wxSizeEvent& event)
|
||||
{
|
||||
// todo: clear screen
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// OnShow()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScatter::OnShow(wxShowEvent& event)
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_plot_scatter.h
|
||||
// Purpose: A scatter plot derivative of fdmdv2_plot.
|
||||
// Created: June 24, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#ifndef __FDMDV2_PLOT_SCATTER__
|
||||
#define __FDMDV2_PLOT_SCATTER__
|
||||
|
||||
#include "comp.h"
|
||||
#include "fdmdv2_plot.h"
|
||||
#include "fdmdv2_defines.h"
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class PlotScatter
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class PlotScatter : public PlotPanel
|
||||
{
|
||||
public:
|
||||
PlotScatter(wxFrame* parent);
|
||||
~PlotScatter(){};
|
||||
void add_new_samples(COMP samples[]);
|
||||
void setNc(int Nc);
|
||||
|
||||
protected:
|
||||
COMP m_mem[SCATTER_MEM_SYMS_MAX];
|
||||
COMP m_new_samples[FDMDV_NC_MAX+1];
|
||||
|
||||
void draw(wxAutoBufferedPaintDC& dc);
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnSize(wxSizeEvent& event);
|
||||
void OnShow(wxShowEvent& event);
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
private:
|
||||
int Nsym;
|
||||
int scatterMemSyms;
|
||||
float m_filter_max_xy;
|
||||
};
|
||||
|
||||
#endif //__FDMDV2_PLOT_SCATTER__
|
|
@ -0,0 +1,266 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_plot_waterfall.cpp
|
||||
// Purpose: Implements a waterfall plot derivative of fdmdv2_plot.
|
||||
// Created: June 23, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#include <string.h>
|
||||
#include "wx/wx.h"
|
||||
|
||||
#include "fdmdv2_main.h"
|
||||
|
||||
extern float g_avmag[]; // average mag data passed to draw()
|
||||
void fdmdv2_clickTune(float frequency); // callback to pass new click freq
|
||||
|
||||
BEGIN_EVENT_TABLE(PlotSpectrum, PlotPanel)
|
||||
EVT_MOTION (PlotSpectrum::OnMouseMove)
|
||||
EVT_LEFT_DOWN (PlotSpectrum::OnMouseLeftDown)
|
||||
EVT_LEFT_UP (PlotSpectrum::OnMouseLeftUp)
|
||||
EVT_MOUSEWHEEL (PlotSpectrum::OnMouseWheelMoved)
|
||||
EVT_PAINT (PlotSpectrum::OnPaint)
|
||||
EVT_SHOW (PlotSpectrum::OnShow)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class PlotSpectrum
|
||||
//
|
||||
// @class $(Name)
|
||||
// @author $(User)
|
||||
// @date $(Date)
|
||||
// @file $(CurrentFileName).$(CurrentFileExt)
|
||||
// @brief
|
||||
//
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
PlotSpectrum::PlotSpectrum(wxFrame* parent, float *magdB, int n_magdB,
|
||||
float min_mag_db, float max_mag_db, bool clickTune): PlotPanel(parent)
|
||||
{
|
||||
m_greyscale = 0;
|
||||
m_Bufsz = GetMaxClientSize();
|
||||
m_newdata = false;
|
||||
m_firstPass = true;
|
||||
m_line_color = 0;
|
||||
SetLabelSize(10.0);
|
||||
|
||||
m_magdB = magdB;
|
||||
m_n_magdB = n_magdB; // number of points in magdB that covers 0 ... MAX_F_HZ of spectrum
|
||||
m_max_mag_db = max_mag_db;
|
||||
m_min_mag_db = min_mag_db;
|
||||
m_rxFreq = 0.0;
|
||||
m_clickTune = clickTune;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// ~PlotSpectrum()
|
||||
//----------------------------------------------------------------
|
||||
PlotSpectrum::~PlotSpectrum()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// OnSize()
|
||||
//----------------------------------------------------------------
|
||||
void PlotSpectrum::OnSize(wxSizeEvent& event) {
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// OnPaint()
|
||||
//----------------------------------------------------------------
|
||||
void PlotSpectrum::OnPaint(wxPaintEvent& event)
|
||||
{
|
||||
wxAutoBufferedPaintDC dc(this);
|
||||
draw(dc);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// OnShow()
|
||||
//----------------------------------------------------------------
|
||||
void PlotSpectrum::OnShow(wxShowEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// draw()
|
||||
//----------------------------------------------------------------
|
||||
void PlotSpectrum::draw(wxAutoBufferedPaintDC& dc)
|
||||
{
|
||||
m_rCtrl = GetClientRect();
|
||||
|
||||
// m_rGrid is coords of inner window we actually plot to. We deflate it a bit
|
||||
// to leave room for axis labels. We need to work this out every time we draw
|
||||
// as OnSize() may not be called before OnPaint(), for example when a new tab
|
||||
// is selected
|
||||
|
||||
m_rGrid = m_rCtrl;
|
||||
m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
|
||||
|
||||
dc.Clear();
|
||||
|
||||
// black background
|
||||
|
||||
m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
|
||||
wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
|
||||
dc.SetBrush(ltGraphBkgBrush);
|
||||
dc.SetPen(wxPen(BLACK_COLOR, 0));
|
||||
dc.DrawRectangle(m_rPlot);
|
||||
|
||||
// draw spectrum
|
||||
|
||||
int x, y, prev_x, prev_y, index;
|
||||
float index_to_px, mag_dB_to_py, mag;
|
||||
|
||||
m_newdata = false;
|
||||
|
||||
wxPen pen;
|
||||
pen.SetColour(DARK_GREEN_COLOR);
|
||||
pen.SetWidth(1);
|
||||
dc.SetPen(pen);
|
||||
|
||||
index_to_px = (float)m_rGrid.GetWidth()/m_n_magdB;
|
||||
mag_dB_to_py = (float)m_rGrid.GetHeight()/(m_max_mag_db - m_min_mag_db);
|
||||
|
||||
prev_x = PLOT_BORDER + XLEFT_OFFSET;
|
||||
prev_y = PLOT_BORDER;
|
||||
for(index = 0; index < m_n_magdB; index++)
|
||||
{
|
||||
x = index*index_to_px;
|
||||
mag = m_magdB[index];
|
||||
if (mag > m_max_mag_db) mag = m_max_mag_db;
|
||||
if (mag < m_min_mag_db) mag = m_min_mag_db;
|
||||
y = -(mag - m_max_mag_db) * mag_dB_to_py;
|
||||
|
||||
x += PLOT_BORDER + XLEFT_OFFSET;
|
||||
y += PLOT_BORDER;
|
||||
|
||||
if (index)
|
||||
dc.DrawLine(x, y, prev_x, prev_y);
|
||||
prev_x = x; prev_y = y;
|
||||
}
|
||||
|
||||
// and finally draw Graticule
|
||||
|
||||
drawGraticule(dc);
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// drawGraticule()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotSpectrum::drawGraticule(wxAutoBufferedPaintDC& dc)
|
||||
{
|
||||
int x, y, text_w, text_h;
|
||||
char buf[15];
|
||||
wxString s;
|
||||
float f, mag, freq_hz_to_px, mag_dB_to_py;
|
||||
|
||||
wxBrush ltGraphBkgBrush;
|
||||
ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
|
||||
ltGraphBkgBrush.SetColour(*wxBLACK);
|
||||
dc.SetBrush(ltGraphBkgBrush);
|
||||
dc.SetPen(wxPen(BLACK_COLOR, 1));
|
||||
|
||||
freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
|
||||
mag_dB_to_py = (float)m_rGrid.GetHeight()/(m_max_mag_db - m_min_mag_db);
|
||||
|
||||
// upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
|
||||
// lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(),
|
||||
// PLOT_BORDER + m_rGrid.GetHeight())
|
||||
|
||||
// Check if small screen size means text will overlap
|
||||
|
||||
int textXStep = STEP_F_HZ*freq_hz_to_px;
|
||||
int textYStep = STEP_MAG_DB*mag_dB_to_py;
|
||||
sprintf(buf, "%4.0fHz", (float)MAX_F_HZ - STEP_F_HZ);
|
||||
GetTextExtent(buf, &text_w, &text_h);
|
||||
int overlappedText = (text_w > textXStep) || (text_h > textYStep);
|
||||
//printf("text_w: %d textXStep: %d text_h: %d textYStep: %d overlappedText: %d\n", text_w, textXStep,
|
||||
// text_h, textYStep, overlappedText);
|
||||
|
||||
// Vertical gridlines
|
||||
|
||||
for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ) {
|
||||
x = f*freq_hz_to_px;
|
||||
x += PLOT_BORDER + XLEFT_OFFSET;
|
||||
|
||||
dc.SetPen(m_penShortDash);
|
||||
dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
|
||||
dc.SetPen(wxPen(BLACK_COLOR, 1));
|
||||
dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
|
||||
|
||||
sprintf(buf, "%4.0fHz", f);
|
||||
GetTextExtent(buf, &text_w, &text_h);
|
||||
if (!overlappedText)
|
||||
dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
|
||||
}
|
||||
|
||||
dc.SetPen(wxPen(BLACK_COLOR, 1));
|
||||
for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ)
|
||||
{
|
||||
x = f*freq_hz_to_px;
|
||||
x += PLOT_BORDER + XLEFT_OFFSET;
|
||||
dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
|
||||
}
|
||||
|
||||
// Horizontal gridlines
|
||||
|
||||
dc.SetPen(m_penDotDash);
|
||||
for(mag=m_min_mag_db; mag<=m_max_mag_db; mag+=STEP_MAG_DB) {
|
||||
y = -(mag - m_max_mag_db) * mag_dB_to_py;
|
||||
y += PLOT_BORDER;
|
||||
dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y,
|
||||
(m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
|
||||
sprintf(buf, "%3.0fdB", mag);
|
||||
GetTextExtent(buf, &text_w, &text_h);
|
||||
if (!overlappedText)
|
||||
dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
|
||||
}
|
||||
|
||||
// red rx tuning line
|
||||
|
||||
if (m_rxFreq != 0.0) {
|
||||
dc.SetPen(wxPen(RED_COLOR, 2));
|
||||
x = m_rxFreq*freq_hz_to_px;
|
||||
x += PLOT_BORDER + XLEFT_OFFSET;
|
||||
//printf("m_rxFreq %f x %d\n", m_rxFreq, x);
|
||||
dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnMouseDown()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotSpectrum::OnMouseLeftDown(wxMouseEvent& event)
|
||||
{
|
||||
m_mouseDown = true;
|
||||
wxClientDC dc(this);
|
||||
|
||||
wxPoint pt(event.GetLogicalPosition(dc));
|
||||
|
||||
// map x coord to edges of actual plot
|
||||
pt.x -= PLOT_BORDER + XLEFT_OFFSET;
|
||||
pt.y -= PLOT_BORDER;
|
||||
|
||||
// valid click if inside of plot
|
||||
if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0) && m_clickTune) {
|
||||
float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
|
||||
float clickFreq = (float)pt.x/freq_hz_to_px;
|
||||
|
||||
// see PlotWaterfall::OnMouseDown()
|
||||
|
||||
fdmdv2_clickTune(clickFreq);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_plot_spectrum.h
|
||||
// Purpose: Defines a spectrum plot derived from fdmdv2_plot class.
|
||||
// Created: June 22, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#ifndef __FDMDV2_PLOT_SPECTRUM__
|
||||
#define __FDMDV2_PLOT_SPECTRUM__
|
||||
|
||||
#include "fdmdv2_plot.h"
|
||||
#include "fdmdv2_defines.h"
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class Waterfall
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class PlotSpectrum : public PlotPanel
|
||||
{
|
||||
public:
|
||||
PlotSpectrum(wxFrame* parent, float *magdB, int n_magdB,
|
||||
float min_mag_db=MIN_MAG_DB, float max_mag_db=MAX_MAG_DB, bool clickTune=true);
|
||||
~PlotSpectrum();
|
||||
void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; }
|
||||
void setFreqScale(int n_magdB) { m_n_magdB = n_magdB; }
|
||||
|
||||
protected:
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnSize(wxSizeEvent& event);
|
||||
void OnShow(wxShowEvent& event);
|
||||
void drawGraticule(wxAutoBufferedPaintDC& dc);
|
||||
void draw(wxAutoBufferedPaintDC& dc);
|
||||
void OnMouseLeftDown(wxMouseEvent& event);
|
||||
|
||||
private:
|
||||
float m_rxFreq;
|
||||
float m_max_mag_db;
|
||||
float m_min_mag_db;
|
||||
float *m_magdB;
|
||||
int m_n_magdB;
|
||||
bool m_clickTune;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#endif //__FDMDV2_PLOT_SPECTRUM__
|
|
@ -0,0 +1,483 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_plot_waterfall.cpp
|
||||
// Purpose: Implements a waterfall plot derivative of fdmdv2_plot.
|
||||
// Created: June 22, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#include <string.h>
|
||||
#include "wx/wx.h"
|
||||
#include "fdmdv2_main.h"
|
||||
|
||||
extern float g_avmag[]; // av mag spec passed in to draw()
|
||||
void fdmdv2_clickTune(float frequency); // callback to pass new click freq
|
||||
|
||||
BEGIN_EVENT_TABLE(PlotWaterfall, PlotPanel)
|
||||
EVT_PAINT (PlotWaterfall::OnPaint)
|
||||
EVT_MOTION (PlotWaterfall::OnMouseMove)
|
||||
EVT_LEFT_DOWN (PlotWaterfall::OnMouseLeftDown)
|
||||
EVT_RIGHT_DOWN (PlotWaterfall::OnMouseRightDown)
|
||||
EVT_LEFT_UP (PlotWaterfall::OnMouseLeftUp)
|
||||
EVT_MOUSEWHEEL (PlotWaterfall::OnMouseWheelMoved)
|
||||
EVT_SIZE (PlotWaterfall::OnSize)
|
||||
EVT_SHOW (PlotWaterfall::OnShow)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class WaterfallPlot
|
||||
//
|
||||
// @class WaterfallPlot
|
||||
// @author David Witten
|
||||
// @date $(Date)
|
||||
// @file $(CurrentFileName).$(CurrentFileExt)
|
||||
// @brief
|
||||
//
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
PlotWaterfall::PlotWaterfall(wxFrame* parent, bool graticule, int colour): PlotPanel(parent)
|
||||
{
|
||||
|
||||
for(int i = 0; i < 255; i++)
|
||||
{
|
||||
m_heatmap_lut[i] = heatmap((float)i, 0.0, 255.0);
|
||||
}
|
||||
m_graticule = graticule;
|
||||
m_colour = colour;
|
||||
m_Bufsz = GetMaxClientSize();
|
||||
m_newdata = false;
|
||||
m_firstPass = true;
|
||||
m_line_color = 0;
|
||||
m_modem_stats_max_f_hz = MODEM_STATS_MAX_F_HZ;
|
||||
|
||||
SetLabelSize(10.0);
|
||||
|
||||
m_pBmp = NULL;
|
||||
m_max_mag = MAX_MAG_DB;
|
||||
m_min_mag = MIN_MAG_DB;
|
||||
}
|
||||
|
||||
// When the window size gets set we can work outthe size of the window
|
||||
// we plot in and allocate a bit map of the correct size
|
||||
void PlotWaterfall::OnSize(wxSizeEvent& event)
|
||||
{
|
||||
// resize bit map
|
||||
|
||||
delete m_pBmp;
|
||||
|
||||
m_rCtrl = GetClientRect();
|
||||
|
||||
// m_rGrid is coords of inner window we actually plot to. We deflate it a bit
|
||||
// to leave room for axis labels.
|
||||
|
||||
m_rGrid = m_rCtrl;
|
||||
m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
|
||||
|
||||
// we want a bit map the size of m_rGrid
|
||||
|
||||
m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
|
||||
|
||||
m_dT = DT;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// paintEvent()
|
||||
//
|
||||
// @class $(Name)
|
||||
// @author $(User)
|
||||
// @date $(Date)
|
||||
// @file $(CurrentFileName).$(CurrentFileExt)
|
||||
// @brief
|
||||
//
|
||||
// Called by the system of by wxWidgets when the panel needs
|
||||
// to be redrawn. You can also trigger this call by calling
|
||||
// Refresh()/Update().
|
||||
//----------------------------------------------------------------
|
||||
void PlotWaterfall::OnPaint(wxPaintEvent & evt)
|
||||
{
|
||||
wxAutoBufferedPaintDC dc(this);
|
||||
draw(dc);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// OnShow()
|
||||
//----------------------------------------------------------------
|
||||
void PlotWaterfall::OnShow(wxShowEvent& event)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// ~PlotWaterfall()
|
||||
//----------------------------------------------------------------
|
||||
PlotWaterfall::~PlotWaterfall()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// heatmap()
|
||||
// map val to a rgb colour
|
||||
// from http://eddiema.ca/2011/01/21/c-sharp-heatmaps/
|
||||
//----------------------------------------------------------------
|
||||
unsigned PlotWaterfall::heatmap(float val, float min, float max)
|
||||
{
|
||||
unsigned r = 0;
|
||||
unsigned g = 0;
|
||||
unsigned b = 0;
|
||||
|
||||
val = (val - min) / (max - min);
|
||||
if(val <= 0.2)
|
||||
{
|
||||
b = (unsigned)((val / 0.2) * 255);
|
||||
}
|
||||
else if(val > 0.2 && val <= 0.7)
|
||||
{
|
||||
b = (unsigned)((1.0 - ((val - 0.2) / 0.5)) * 255);
|
||||
}
|
||||
if(val >= 0.2 && val <= 0.6)
|
||||
{
|
||||
g = (unsigned)(((val - 0.2) / 0.4) * 255);
|
||||
}
|
||||
else if(val > 0.6 && val <= 0.9)
|
||||
{
|
||||
g = (unsigned)((1.0 - ((val - 0.6) / 0.3)) * 255);
|
||||
}
|
||||
if(val >= 0.5)
|
||||
{
|
||||
r = (unsigned)(((val - 0.5) / 0.5) * 255);
|
||||
}
|
||||
//printf("%f %x %x %x\n", val, r, g, b);
|
||||
return (b << 16) + (g << 8) + r;
|
||||
}
|
||||
|
||||
bool PlotWaterfall::checkDT(void)
|
||||
{
|
||||
// Check dY is > 1 pixel before proceeding. For small screens
|
||||
// and large WATERFALL_SECS_Y we might have less than one
|
||||
// block per pixel. In this case increase m_dT and perform draw
|
||||
// less often
|
||||
|
||||
float px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
|
||||
float dy = m_dT * px_per_sec;
|
||||
|
||||
if (dy < 1.0) {
|
||||
m_dT += DT;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// draw()
|
||||
//----------------------------------------------------------------
|
||||
void PlotWaterfall::draw(wxAutoBufferedPaintDC& dc)
|
||||
{
|
||||
|
||||
m_rCtrl = GetClientRect();
|
||||
|
||||
// m_rGrid is coords of inner window we actually plot to. We deflate it a bit
|
||||
// to leave room for axis labels.
|
||||
|
||||
m_rGrid = m_rCtrl;
|
||||
m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
|
||||
|
||||
if (m_pBmp == NULL)
|
||||
{
|
||||
// we want a bit map the size of m_rGrid
|
||||
m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
|
||||
}
|
||||
|
||||
dc.Clear();
|
||||
|
||||
if(m_newdata)
|
||||
{
|
||||
m_newdata = false;
|
||||
plotPixelData();
|
||||
dc.DrawBitmap(*m_pBmp, PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER);
|
||||
m_dT = DT;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// no data to plot so just erase to black. Blue looks nicer
|
||||
// but is same colour as low amplitude signal
|
||||
|
||||
// Bug on Linux: When Stop is pressed this code doesn't erase
|
||||
// the lower 25% of the Waterfall Window
|
||||
|
||||
m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
|
||||
wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
|
||||
dc.SetBrush(ltGraphBkgBrush);
|
||||
dc.SetPen(wxPen(BLACK_COLOR, 0));
|
||||
dc.DrawRectangle(m_rPlot);
|
||||
}
|
||||
drawGraticule(dc);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// drawGraticule()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC& dc)
|
||||
{
|
||||
int x, y, text_w, text_h;
|
||||
char buf[15];
|
||||
wxString s;
|
||||
float f, time, freq_hz_to_px, time_s_to_py;
|
||||
|
||||
wxBrush ltGraphBkgBrush;
|
||||
ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
|
||||
ltGraphBkgBrush.SetColour(*wxBLACK);
|
||||
dc.SetBrush(ltGraphBkgBrush);
|
||||
dc.SetPen(wxPen(BLACK_COLOR, 1));
|
||||
|
||||
freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
|
||||
time_s_to_py = (float)m_rGrid.GetHeight()/WATERFALL_SECS_Y;
|
||||
|
||||
// upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
|
||||
// lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(),
|
||||
// PLOT_BORDER + m_rGrid.GetHeight())
|
||||
|
||||
// Check if small screen size means text will overlap
|
||||
|
||||
int textXStep = STEP_F_HZ*freq_hz_to_px;
|
||||
int textYStep = WATERFALL_SECS_STEP*time_s_to_py;
|
||||
sprintf(buf, "%4.0fHz", (float)MAX_F_HZ - STEP_F_HZ);
|
||||
GetTextExtent(buf, &text_w, &text_h);
|
||||
int overlappedText = (text_w > textXStep) || (text_h > textYStep);
|
||||
|
||||
// Major Vertical gridlines and legend
|
||||
//dc.SetPen(m_penShortDash);
|
||||
for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ)
|
||||
{
|
||||
x = f*freq_hz_to_px;
|
||||
x += PLOT_BORDER + XLEFT_OFFSET;
|
||||
|
||||
if (m_graticule)
|
||||
dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
|
||||
else
|
||||
dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
|
||||
|
||||
sprintf(buf, "%4.0fHz", f);
|
||||
GetTextExtent(buf, &text_w, &text_h);
|
||||
if (!overlappedText)
|
||||
dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
|
||||
}
|
||||
|
||||
for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ)
|
||||
{
|
||||
x = f*freq_hz_to_px;
|
||||
x += PLOT_BORDER + XLEFT_OFFSET;
|
||||
dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
|
||||
}
|
||||
|
||||
// Horizontal gridlines
|
||||
dc.SetPen(m_penDotDash);
|
||||
for(time=0; time<=WATERFALL_SECS_Y; time+=WATERFALL_SECS_STEP) {
|
||||
y = m_rGrid.GetHeight() - time*time_s_to_py;
|
||||
y += PLOT_BORDER;
|
||||
|
||||
if (m_graticule)
|
||||
dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y,
|
||||
(m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
|
||||
sprintf(buf, "%3.0fs", time);
|
||||
GetTextExtent(buf, &text_w, &text_h);
|
||||
if (!overlappedText)
|
||||
dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
|
||||
}
|
||||
|
||||
// red rx tuning line
|
||||
dc.SetPen(wxPen(RED_COLOR, 2));
|
||||
x = m_rxFreq*freq_hz_to_px;
|
||||
x += PLOT_BORDER + XLEFT_OFFSET;
|
||||
//printf("m_rxFreq %f x %d\n", m_rxFreq, x);
|
||||
dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// plotPixelData()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotWaterfall::plotPixelData()
|
||||
{
|
||||
float spec_index_per_px;
|
||||
float intensity_per_dB;
|
||||
float px_per_sec;
|
||||
int index;
|
||||
float dy;
|
||||
int dy_blocks;
|
||||
int b;
|
||||
int px;
|
||||
int py;
|
||||
int intensity;
|
||||
|
||||
/*
|
||||
Design Notes:
|
||||
|
||||
The height in pixels represents WATERFALL_SECS_Y of data. Every DT
|
||||
seconds we get a vector of MODEM_STATS_NSPEC spectrum samples which we use
|
||||
to update the last row. The height of each row is dy pixels, which
|
||||
maps to DT seconds. We call each dy high rectangle of pixels a
|
||||
block.
|
||||
|
||||
*/
|
||||
|
||||
// determine dy, the height of one "block"
|
||||
px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
|
||||
dy = m_dT * px_per_sec;
|
||||
|
||||
// number of dy high blocks in spectrogram
|
||||
dy_blocks = m_rGrid.GetHeight()/ dy;
|
||||
|
||||
// update min and max amplitude estimates
|
||||
float max_mag = MIN_MAG_DB;
|
||||
|
||||
int min_fft_bin=((float)200/m_modem_stats_max_f_hz)*MODEM_STATS_NSPEC;
|
||||
int max_fft_bin=((float)2800/m_modem_stats_max_f_hz)*MODEM_STATS_NSPEC;
|
||||
|
||||
for(int i=min_fft_bin; i<max_fft_bin; i++)
|
||||
{
|
||||
if (g_avmag[i] > max_mag)
|
||||
{
|
||||
max_mag = g_avmag[i];
|
||||
}
|
||||
}
|
||||
|
||||
m_max_mag = BETA*m_max_mag + (1 - BETA)*max_mag;
|
||||
m_min_mag = max_mag - 20.0;
|
||||
//printf("max_mag: %f m_max_mag: %f\n", max_mag, m_max_mag);
|
||||
//intensity_per_dB = (float)256 /(MAX_MAG_DB - MIN_MAG_DB);
|
||||
intensity_per_dB = (float)256 /(m_max_mag - m_min_mag);
|
||||
spec_index_per_px = ((float)(MAX_F_HZ)/(float)m_modem_stats_max_f_hz)*(float)MODEM_STATS_NSPEC / (float) m_rGrid.GetWidth();
|
||||
|
||||
/*
|
||||
printf("h %d w %d px_per_sec %d dy %d dy_blocks %d spec_index_per_px: %f\n",
|
||||
m_rGrid.GetHeight(), m_rGrid.GetWidth(), px_per_sec,
|
||||
dy, dy_blocks, spec_index_per_px);
|
||||
*/
|
||||
|
||||
// Shift previous bit map up one row of blocks ----------------------------
|
||||
wxNativePixelData data(*m_pBmp);
|
||||
wxNativePixelData::Iterator bitMapStart(data);
|
||||
wxNativePixelData::Iterator p = bitMapStart;
|
||||
|
||||
for(b = 0; b < dy_blocks - 1; b++)
|
||||
{
|
||||
wxNativePixelData::Iterator psrc = bitMapStart;
|
||||
wxNativePixelData::Iterator pdest = bitMapStart;
|
||||
pdest.OffsetY(data, dy * b);
|
||||
psrc.OffsetY(data, dy * (b+1));
|
||||
|
||||
// copy one line of blocks
|
||||
|
||||
for(py = 0; py < dy; py++)
|
||||
{
|
||||
wxNativePixelData::Iterator pdestRowStart = pdest;
|
||||
wxNativePixelData::Iterator psrcRowStart = psrc;
|
||||
|
||||
for(px = 0; px < m_rGrid.GetWidth(); px++)
|
||||
{
|
||||
pdest.Red() = psrc.Red();
|
||||
pdest.Green() = psrc.Green();
|
||||
pdest.Blue() = psrc.Blue();
|
||||
pdest++;
|
||||
psrc++;
|
||||
}
|
||||
pdest = pdestRowStart;
|
||||
pdest.OffsetY(data, 1);
|
||||
psrc = psrcRowStart;
|
||||
psrc.OffsetY(data, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw last line of blocks using latest amplitude data ------------------
|
||||
p = bitMapStart;
|
||||
p.OffsetY(data, dy *(dy_blocks - 1));
|
||||
for(py = 0; py < dy; py++)
|
||||
{
|
||||
wxNativePixelData::Iterator rowStart = p;
|
||||
|
||||
for(px = 0; px < m_rGrid.GetWidth(); px++)
|
||||
{
|
||||
index = px * spec_index_per_px;
|
||||
assert(index < MODEM_STATS_NSPEC);
|
||||
|
||||
intensity = intensity_per_dB * (g_avmag[index] - m_min_mag);
|
||||
if(intensity > 255) intensity = 255;
|
||||
if (intensity < 0) intensity = 0;
|
||||
//printf("%d %f %d \n", index, g_avmag[index], intensity);
|
||||
|
||||
switch (m_colour) {
|
||||
case 0:
|
||||
p.Red() = m_heatmap_lut[intensity] & 0xff;
|
||||
p.Green() = (m_heatmap_lut[intensity] >> 8) & 0xff;
|
||||
p.Blue() = (m_heatmap_lut[intensity] >> 16) & 0xff;
|
||||
break;
|
||||
case 1:
|
||||
p.Red() = intensity;
|
||||
p.Green() = intensity;
|
||||
p.Blue() = intensity;
|
||||
break;
|
||||
case 2:
|
||||
p.Red() = intensity;
|
||||
p.Green() = intensity;
|
||||
if (intensity < 127)
|
||||
p.Blue() = intensity*2;
|
||||
else
|
||||
p.Blue() = 255;
|
||||
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
p = rowStart;
|
||||
p.OffsetY(data, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnMouseLeftDown()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotWaterfall::OnMouseLeftDown(wxMouseEvent& event)
|
||||
{
|
||||
m_mouseDown = true;
|
||||
wxClientDC dc(this);
|
||||
|
||||
wxPoint pt(event.GetLogicalPosition(dc));
|
||||
|
||||
// map x coord to edges of actual plot
|
||||
pt.x -= PLOT_BORDER + XLEFT_OFFSET;
|
||||
pt.y -= PLOT_BORDER;
|
||||
|
||||
// valid click if inside of plot
|
||||
if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0))
|
||||
{
|
||||
float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
|
||||
float clickFreq = (float)pt.x/freq_hz_to_px;
|
||||
|
||||
// communicate back to other threads
|
||||
fdmdv2_clickTune(clickFreq);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OnMouseRightDown()
|
||||
//-------------------------------------------------------------------------
|
||||
void PlotWaterfall::OnMouseRightDown(wxMouseEvent& event)
|
||||
{
|
||||
m_colour++;
|
||||
if (m_colour == 3)
|
||||
m_colour = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
//==========================================================================
|
||||
// Name: fdmdv2_plot_waterfall.h
|
||||
// Purpose: Defines a waterfall plot derivative of fdmdv2_plot.
|
||||
// Created: June 22, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#ifndef __FDMDV2_PLOT_WATERFALL__
|
||||
#define __FDMDV2_PLOT_WATERFALL__
|
||||
|
||||
#include "fdmdv2_plot.h"
|
||||
#include "fdmdv2_defines.h"
|
||||
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
// Class PlotWaterfall
|
||||
//
|
||||
// @class $(Name)
|
||||
// @author $(User)
|
||||
// @date $(Date)
|
||||
// @file $(CurrentFileName).$(CurrentFileExt)
|
||||
// @brief
|
||||
//
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
|
||||
class PlotWaterfall : public PlotPanel
|
||||
{
|
||||
public:
|
||||
PlotWaterfall(wxFrame* parent, bool graticule, int colour);
|
||||
~PlotWaterfall();
|
||||
bool checkDT(void);
|
||||
void setGreyscale(bool greyscale) { m_greyscale = greyscale; }
|
||||
void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; }
|
||||
void setFs(int fs) { m_modem_stats_max_f_hz = fs/2; }
|
||||
|
||||
protected:
|
||||
unsigned m_heatmap_lut[256];
|
||||
|
||||
unsigned heatmap(float val, float min, float max);
|
||||
|
||||
void OnPaint(wxPaintEvent & evt);
|
||||
void OnSize(wxSizeEvent& event);
|
||||
void OnShow(wxShowEvent& event);
|
||||
void drawGraticule(wxAutoBufferedPaintDC& dc);
|
||||
void draw(wxAutoBufferedPaintDC& dc);
|
||||
void plotPixelData();
|
||||
void OnMouseLeftDown(wxMouseEvent& event);
|
||||
void OnMouseRightDown(wxMouseEvent& event);
|
||||
|
||||
private:
|
||||
float m_dT;
|
||||
float m_rxFreq;
|
||||
bool m_graticule;
|
||||
float m_min_mag;
|
||||
float m_max_mag;
|
||||
int m_colour;
|
||||
int m_modem_stats_max_f_hz;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#endif //__FDMDV2_PLOT_WATERFALL__
|
|
@ -0,0 +1,127 @@
|
|||
//==========================================================================
|
||||
// Name: hamlib.cpp
|
||||
//
|
||||
// Purpose: Hamlib integration for FreeDV
|
||||
// Created: May 2013
|
||||
// Authors: Joel Stanley
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#include <hamlib.h>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef std::vector<const struct rig_caps *> riglist_t;
|
||||
|
||||
static bool rig_cmp(const struct rig_caps *rig1, const struct rig_caps *rig2);
|
||||
static int build_list(const struct rig_caps *rig, rig_ptr_t);
|
||||
|
||||
Hamlib::Hamlib() : m_rig(NULL) {
|
||||
/* Stop hamlib from spewing info to stderr. */
|
||||
rig_set_debug(RIG_DEBUG_NONE);
|
||||
|
||||
/* Create sorted list of rigs. */
|
||||
rig_load_all_backends();
|
||||
rig_list_foreach(build_list, &m_rigList);
|
||||
sort(m_rigList.begin(), m_rigList.end(), rig_cmp);
|
||||
|
||||
/* Reset debug output. */
|
||||
rig_set_debug(RIG_DEBUG_VERBOSE);
|
||||
|
||||
m_rig = NULL;
|
||||
}
|
||||
|
||||
Hamlib::~Hamlib() {
|
||||
if(m_rig)
|
||||
close();
|
||||
}
|
||||
|
||||
static int build_list(const struct rig_caps *rig, rig_ptr_t rigList) {
|
||||
((riglist_t *)rigList)->push_back(rig);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool rig_cmp(const struct rig_caps *rig1, const struct rig_caps *rig2) {
|
||||
/* Compare manufacturer. */
|
||||
int r = strcasecmp(rig1->mfg_name, rig2->mfg_name);
|
||||
if (r != 0)
|
||||
return r < 0;
|
||||
|
||||
/* Compare model. */
|
||||
r = strcasecmp(rig1->model_name, rig2->model_name);
|
||||
if (r != 0)
|
||||
return r < 0;
|
||||
|
||||
/* Compare rig ID. */
|
||||
return rig1->rig_model < rig2->rig_model;
|
||||
}
|
||||
|
||||
void Hamlib::populateComboBox(wxComboBox *cb) {
|
||||
|
||||
riglist_t::const_iterator rig = m_rigList.begin();
|
||||
for (; rig !=m_rigList.end(); rig++) {
|
||||
char name[128];
|
||||
snprintf(name, 128, "%s %s", (*rig)->mfg_name, (*rig)->model_name);
|
||||
cb->Append(name);
|
||||
}
|
||||
}
|
||||
|
||||
bool Hamlib::connect(unsigned int rig_index, const char *serial_port) {
|
||||
/* Look up model from index. */
|
||||
if (rig_index >= m_rigList.size()) {
|
||||
return false;
|
||||
}
|
||||
printf("rig: %s %s (%d)\n", m_rigList[rig_index]->mfg_name,
|
||||
m_rigList[rig_index]->model_name, m_rigList[rig_index]->rig_model);
|
||||
|
||||
if(m_rig) {
|
||||
printf("Closing old hamlib instance!\n");
|
||||
close();
|
||||
}
|
||||
|
||||
/* Initialise, configure and open. */
|
||||
m_rig = rig_init(m_rigList[rig_index]->rig_model);
|
||||
/* TODO: Also use baud rate from the screen. */
|
||||
if (!m_rig)
|
||||
return false;
|
||||
token_t token = rig_token_lookup(m_rig, "rig_pathname");
|
||||
if (rig_set_conf(m_rig, token, serial_port) != RIG_OK) {
|
||||
return false;
|
||||
}
|
||||
if (rig_open(m_rig) == RIG_OK) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Hamlib::ptt(bool press) {
|
||||
if(!m_rig)
|
||||
return false;
|
||||
/* TODO(Joel): make ON_DATA and ON configurable. */
|
||||
ptt_t on = press ? RIG_PTT_ON : RIG_PTT_OFF;
|
||||
/* TODO(Joel): what should the VFO option be? */
|
||||
return rig_set_ptt(m_rig, RIG_VFO_CURR, on) == RIG_OK;
|
||||
}
|
||||
|
||||
void Hamlib::close(void) {
|
||||
if(m_rig) {
|
||||
rig_close(m_rig);
|
||||
rig_cleanup(m_rig);
|
||||
m_rig = NULL;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef HAMLIB_H
|
||||
#define HAMLIB_H
|
||||
|
||||
extern "C" {
|
||||
#include <hamlib/rig.h>
|
||||
}
|
||||
#include <wx/combobox.h>
|
||||
#include <vector>
|
||||
|
||||
class Hamlib {
|
||||
|
||||
public:
|
||||
Hamlib();
|
||||
~Hamlib();
|
||||
void populateComboBox(wxComboBox *cb);
|
||||
bool connect(unsigned int rig_index, const char *serial_port);
|
||||
bool ptt(bool press);
|
||||
void close(void);
|
||||
|
||||
typedef std::vector<const struct rig_caps *> riglist_t;
|
||||
|
||||
private:
|
||||
RIG *m_rig;
|
||||
/* Sorted list of rigs. */
|
||||
riglist_t m_rigList;
|
||||
};
|
||||
|
||||
#endif /*HAMLIB_H*/
|
|
@ -0,0 +1,129 @@
|
|||
//==========================================================================
|
||||
// Name: sox_biquad.h
|
||||
// Purpose: Interface into Sox Biquad filters
|
||||
// Created: Dec 1, 2012
|
||||
// Authors: David Rowe
|
||||
//
|
||||
// To test:
|
||||
// $ gcc sox_biquad.c -o sox_biquad -DSOX_BIQUAD_UNITTEST -Wall \
|
||||
// /path/to/sox-14.4.0/src/.libs/libsox.a -lm -lsndfile
|
||||
// $ ./sox_biquad
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "sox.h"
|
||||
|
||||
#include "sox_biquad.h"
|
||||
|
||||
|
||||
#define N_MAX 1024
|
||||
|
||||
int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf,
|
||||
sox_sample_t *obuf, size_t *isamp, size_t *osamp);
|
||||
|
||||
void sox_biquad_start(void)
|
||||
{
|
||||
int r = sox_init();
|
||||
assert(r == SOX_SUCCESS);
|
||||
}
|
||||
|
||||
void sox_biquad_finish(void)
|
||||
{
|
||||
sox_quit();
|
||||
}
|
||||
|
||||
/*
|
||||
Effect must be implemented by biquads.c in sox, arguments are just
|
||||
like sox command line, for example:
|
||||
|
||||
char *argv[10];
|
||||
argv[0] = "highpass"; argv[1]="1000"; argc=1;
|
||||
*/
|
||||
|
||||
void *sox_biquad_create(int argc, const char *argv[])
|
||||
{
|
||||
int ret;
|
||||
sox_effect_t *e;
|
||||
int (*start)(sox_effect_t *); /* function pointer to effect start func */
|
||||
|
||||
e = sox_create_effect(sox_find_effect(argv[0])); assert(e != NULL);
|
||||
ret = sox_effect_options(e, argc, (char * const*)&argv[1]);
|
||||
assert(ret == SOX_SUCCESS);
|
||||
|
||||
start = e->handler.start;
|
||||
e->in_signal.rate = 8000; /* locked at FS=8000 Hz */
|
||||
ret = start(e); assert(ret == SOX_SUCCESS);
|
||||
|
||||
return (void *)e;
|
||||
}
|
||||
|
||||
void sox_biquad_destroy(void *sbq) {
|
||||
sox_effect_t *e = (sox_effect_t *)sbq;
|
||||
free(e);
|
||||
}
|
||||
|
||||
void sox_biquad_filter(void *sbq, short out[], short in[], int n)
|
||||
{
|
||||
sox_effect_t *e = (sox_effect_t *)sbq;
|
||||
sox_sample_t ibuf[N_MAX];
|
||||
sox_sample_t obuf[N_MAX];
|
||||
size_t isamp, osamp;
|
||||
unsigned int clips;
|
||||
SOX_SAMPLE_LOCALS;
|
||||
int i;
|
||||
|
||||
assert(n <= N_MAX);
|
||||
|
||||
clips = 0;
|
||||
for(i=0; i<n; i++)
|
||||
ibuf[i] = SOX_SIGNED_16BIT_TO_SAMPLE(in[i], clips);
|
||||
isamp = osamp = (unsigned int)n;
|
||||
lsx_biquad_flow(e, ibuf, obuf, &isamp, &osamp);
|
||||
for(i=0; i<n; i++)
|
||||
out[i] = SOX_SAMPLE_TO_SIGNED_16BIT(obuf[i], clips);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SOX_BIQUAD_UNITTEST
|
||||
#define N 20
|
||||
int main(void) {
|
||||
void *sbq;
|
||||
char *argv[10];
|
||||
short in[N];
|
||||
short out[N];
|
||||
int i, argc;;
|
||||
|
||||
for(i=0; i<N; i++)
|
||||
in[i] = 0;
|
||||
in[0] = 8000;
|
||||
|
||||
sox_biquad_start();
|
||||
argv[0] = "highpass"; argv[1]="1000"; argc=1;
|
||||
sbq = sox_biquad_create(argc, argv);
|
||||
|
||||
sox_biquad_filter(sbq, out, in, N);
|
||||
for(i=0; i<N; i++)
|
||||
printf("%d\n", out[i]);
|
||||
|
||||
sox_biquad_destroy(sbq);
|
||||
sox_biquad_finish();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
//==========================================================================
|
||||
// Name: sox_biquad.h
|
||||
// Purpose: Interface into Sox Biquad filters
|
||||
// Created: Dec 1, 2012
|
||||
// Authors: David Rowe
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
#ifndef __SOX_BIQUAD__
|
||||
#define __SOX_BIQUAD__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
#endif
|
||||
|
||||
void sox_biquad_start(void);
|
||||
void sox_biquad_finish(void);
|
||||
void *sox_biquad_create(int argc, const char *argv[]);
|
||||
void sox_biquad_destroy(void *sbq);
|
||||
void sox_biquad_filter(void *sbq, short out[], short in[], int n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,553 @@
|
|||
//==========================================================================
|
||||
// Name: topFrame.cpp
|
||||
//
|
||||
// Purpose: Implements simple wxWidgets application with GUI.
|
||||
// Created: Apr. 9, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#include "topFrame.h"
|
||||
|
||||
extern int g_playFileToMicInEventId;
|
||||
extern int g_recFileFromRadioEventId;
|
||||
extern int g_playFileFromRadioEventId;
|
||||
|
||||
//=========================================================================
|
||||
// Code that lays out the main application window
|
||||
//=========================================================================
|
||||
TopFrame::TopFrame(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style)
|
||||
{
|
||||
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
|
||||
this->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
|
||||
this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
|
||||
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
|
||||
this->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
|
||||
this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
|
||||
//=====================================================
|
||||
// Menubar Setup
|
||||
m_menubarMain = new wxMenuBar(wxMB_DOCKABLE);
|
||||
file = new wxMenu();
|
||||
|
||||
wxMenuItem* m_menuItemOnTop;
|
||||
m_menuItemOnTop = new wxMenuItem(file, wxID_ANY, wxString(_("On Top")) , _("Always Top Window"), wxITEM_NORMAL);
|
||||
file->Append(m_menuItemOnTop);
|
||||
|
||||
wxMenuItem* m_menuItemExit;
|
||||
m_menuItemExit = new wxMenuItem(file, ID_EXIT, wxString(_("E&xit")) , _("Exit Program"), wxITEM_NORMAL);
|
||||
file->Append(m_menuItemExit);
|
||||
|
||||
m_menubarMain->Append(file, _("&File"));
|
||||
|
||||
tools = new wxMenu();
|
||||
wxMenuItem* m_menuItemAudio;
|
||||
m_menuItemAudio = new wxMenuItem(tools, wxID_ANY, wxString(_("&Audio Config")) , wxEmptyString, wxITEM_NORMAL);
|
||||
tools->Append(m_menuItemAudio);
|
||||
|
||||
wxMenuItem* m_menuItemRigCtrlCfg;
|
||||
m_menuItemRigCtrlCfg = new wxMenuItem(tools, wxID_ANY, wxString(_("&PTT Config")) , wxEmptyString, wxITEM_NORMAL);
|
||||
tools->Append(m_menuItemRigCtrlCfg);
|
||||
|
||||
wxMenuItem* m_menuItemOptions;
|
||||
m_menuItemOptions = new wxMenuItem(tools, wxID_ANY, wxString(_("Options")) , wxEmptyString, wxITEM_NORMAL);
|
||||
tools->Append(m_menuItemOptions);
|
||||
|
||||
wxMenuItem* m_menuItemFilter;
|
||||
m_menuItemFilter = new wxMenuItem(tools, wxID_ANY, wxString(_("&Filter")) , wxEmptyString, wxITEM_NORMAL);
|
||||
tools->Append(m_menuItemFilter);
|
||||
|
||||
wxMenuItem* m_menuItemPlayFileToMicIn;
|
||||
m_menuItemPlayFileToMicIn = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Play File - Mic In")) , wxEmptyString, wxITEM_NORMAL);
|
||||
g_playFileToMicInEventId = m_menuItemPlayFileToMicIn->GetId();
|
||||
tools->Append(m_menuItemPlayFileToMicIn);
|
||||
|
||||
wxMenuItem* m_menuItemRecFileFromRadio;
|
||||
m_menuItemRecFileFromRadio = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Record File - From Radio")) , wxEmptyString, wxITEM_NORMAL);
|
||||
g_recFileFromRadioEventId = m_menuItemRecFileFromRadio->GetId();
|
||||
tools->Append(m_menuItemRecFileFromRadio);
|
||||
|
||||
wxMenuItem* m_menuItemPlayFileFromRadio;
|
||||
m_menuItemPlayFileFromRadio = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Play File - From Radio")) , wxEmptyString, wxITEM_NORMAL);
|
||||
g_playFileFromRadioEventId = m_menuItemPlayFileFromRadio->GetId();
|
||||
tools->Append(m_menuItemPlayFileFromRadio);
|
||||
m_menubarMain->Append(tools, _("&Tools"));
|
||||
|
||||
help = new wxMenu();
|
||||
wxMenuItem* m_menuItemHelpUpdates;
|
||||
m_menuItemHelpUpdates = new wxMenuItem(help, wxID_ANY, wxString(_("Check for Updates")) , wxEmptyString, wxITEM_NORMAL);
|
||||
help->Append(m_menuItemHelpUpdates);
|
||||
m_menuItemHelpUpdates->Enable(false);
|
||||
|
||||
wxMenuItem* m_menuItemAbout;
|
||||
m_menuItemAbout = new wxMenuItem(help, ID_ABOUT, wxString(_("&About")) , _("About this program"), wxITEM_NORMAL);
|
||||
help->Append(m_menuItemAbout);
|
||||
|
||||
m_menubarMain->Append(help, _("&Help"));
|
||||
|
||||
this->SetMenuBar(m_menubarMain);
|
||||
|
||||
wxBoxSizer* bSizer1;
|
||||
bSizer1 = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
//=====================================================
|
||||
// Left side
|
||||
//=====================================================
|
||||
wxBoxSizer* leftSizer;
|
||||
leftSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxStaticBoxSizer* snrSizer;
|
||||
snrSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("SNR")), wxVERTICAL);
|
||||
|
||||
//------------------------------
|
||||
// S/N ratio Guage (vert. bargraph)
|
||||
//------------------------------
|
||||
m_gaugeSNR = new wxGauge(this, wxID_ANY, 25, wxDefaultPosition, wxSize(15,135), wxGA_SMOOTH|wxGA_VERTICAL);
|
||||
m_gaugeSNR->SetToolTip(_("Displays signal to noise ratio in dB."));
|
||||
snrSizer->Add(m_gaugeSNR, 1, wxALIGN_CENTER_HORIZONTAL|wxALL, 10);
|
||||
|
||||
//------------------------------
|
||||
// Box for S/N ratio (Numeric)
|
||||
//------------------------------
|
||||
m_textSNR = new wxStaticText(this, wxID_ANY, wxT(" 0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
||||
snrSizer->Add(m_textSNR, 0, wxALIGN_CENTER_HORIZONTAL, 1);
|
||||
|
||||
//------------------------------
|
||||
// S/N ratio slow Checkbox
|
||||
//------------------------------
|
||||
m_ckboxSNR = new wxCheckBox(this, wxID_ANY, _("Slow"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
m_ckboxSNR->SetToolTip(_("Smooth but slow SNR estimation"));
|
||||
snrSizer->Add(m_ckboxSNR, 0, wxALIGN_CENTER_HORIZONTAL, 5);
|
||||
|
||||
leftSizer->Add(snrSizer, 2, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxALL, 1);
|
||||
|
||||
//------------------------------
|
||||
// Sync Indicator box
|
||||
//------------------------------
|
||||
wxStaticBoxSizer* sbSizer3_33;
|
||||
sbSizer3_33 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Sync")), wxVERTICAL);
|
||||
|
||||
m_rbSync = new wxRadioButton( this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
|
||||
m_rbSync->SetForegroundColour( wxColour( 255, 0, 0 ) );
|
||||
sbSizer3_33->Add(m_rbSync, 0, wxALIGN_CENTER|wxALL, 1);
|
||||
leftSizer->Add(sbSizer3_33,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
//------------------------------
|
||||
// BER Frames box
|
||||
//------------------------------
|
||||
|
||||
wxStaticBoxSizer* sbSizer_ber;
|
||||
sbSizer_ber = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Bit Error Rate")), wxVERTICAL);
|
||||
|
||||
m_BtnBerReset = new wxButton(this, wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
sbSizer_ber->Add(m_BtnBerReset, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
|
||||
|
||||
m_textBits = new wxStaticText(this, wxID_ANY, wxT("Bits: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
sbSizer_ber->Add(m_textBits, 0, wxALIGN_LEFT, 1);
|
||||
m_textErrors = new wxStaticText(this, wxID_ANY, wxT("Errs: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
sbSizer_ber->Add(m_textErrors, 0, wxALIGN_LEFT, 1);
|
||||
m_textBER = new wxStaticText(this, wxID_ANY, wxT("BER: 0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
sbSizer_ber->Add(m_textBER, 0, wxALIGN_LEFT, 1);
|
||||
|
||||
leftSizer->Add(sbSizer_ber,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
//------------------------------
|
||||
// Signal Level(vert. bargraph)
|
||||
//------------------------------
|
||||
wxStaticBoxSizer* levelSizer;
|
||||
levelSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Level")), wxVERTICAL);
|
||||
|
||||
m_textLevel = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(60,-1), wxALIGN_CENTRE);
|
||||
m_textLevel->SetForegroundColour(wxColour(255,0,0));
|
||||
levelSizer->Add(m_textLevel, 0, wxALIGN_LEFT, 1);
|
||||
|
||||
m_gaugeLevel = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxSize(15,135), wxGA_SMOOTH|wxGA_VERTICAL);
|
||||
m_gaugeLevel->SetToolTip(_("Peak of From Radio in Rx, or peak of From Mic in Tx mode. If Red you should reduce your levels"));
|
||||
levelSizer->Add(m_gaugeLevel, 1, wxALIGN_CENTER_HORIZONTAL|wxALL, 10);
|
||||
|
||||
leftSizer->Add(levelSizer, 2, wxALIGN_CENTER|wxALL|wxEXPAND, 1);
|
||||
|
||||
bSizer1->Add(leftSizer, 0, wxALL|wxEXPAND, 5);
|
||||
|
||||
//=====================================================
|
||||
// Center Section
|
||||
//=====================================================
|
||||
wxBoxSizer* centerSizer;
|
||||
centerSizer = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer* upperSizer;
|
||||
upperSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
//=====================================================
|
||||
// Tabbed Notebook control containing display graphs
|
||||
//=====================================================
|
||||
//m_auiNbookCtrl = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_BOTTOM|wxAUI_NB_DEFAULT_STYLE);
|
||||
//long style = wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_CLOSE_ON_ACTIVE_TAB | wxAUI_NB_MIDDLE_CLICK_CLOSE;
|
||||
long nb_style = wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS;
|
||||
m_auiNbookCtrl = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, nb_style);
|
||||
// This line sets the fontsize for the tabs on the notebook control
|
||||
m_auiNbookCtrl->SetFont(wxFont(8, 70, 90, 90, false, wxEmptyString));
|
||||
|
||||
upperSizer->Add(m_auiNbookCtrl, 1, wxALIGN_TOP|wxEXPAND, 1);
|
||||
centerSizer->Add(upperSizer, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALIGN_TOP|wxEXPAND, 0);
|
||||
|
||||
// lower middle used for user ID
|
||||
|
||||
wxBoxSizer* lowerSizer;
|
||||
lowerSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_BtnCallSignReset = new wxButton(this, wxID_ANY, _("Clear"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
lowerSizer->Add(m_BtnCallSignReset, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
|
||||
|
||||
wxBoxSizer* bSizer15;
|
||||
bSizer15 = new wxBoxSizer(wxVERTICAL);
|
||||
m_txtCtrlCallSign = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
|
||||
m_txtCtrlCallSign->SetToolTip(_("Call Sign of transmitting station will appear here"));
|
||||
bSizer15->Add(m_txtCtrlCallSign, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5);
|
||||
lowerSizer->Add(bSizer15, 1, wxEXPAND, 5);
|
||||
|
||||
wxStaticBoxSizer* sbSizer_Checksum = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Checksums")), wxHORIZONTAL);
|
||||
|
||||
wxStaticText *goodLabel = new wxStaticText(this, wxID_ANY, wxT("Good: "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
||||
sbSizer_Checksum->Add(goodLabel, 0, 0, 2);
|
||||
m_txtChecksumGood = new wxStaticText(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxSize(30,-1), wxALIGN_CENTRE);
|
||||
sbSizer_Checksum->Add(m_txtChecksumGood, 0, 0, 2);
|
||||
|
||||
wxStaticText *badLabel = new wxStaticText(this, wxID_ANY, wxT("Bad: "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
||||
sbSizer_Checksum->Add(badLabel, 0, 0, 1);
|
||||
m_txtChecksumBad = new wxStaticText(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxSize(30,-1), wxALIGN_CENTRE);
|
||||
sbSizer_Checksum->Add(m_txtChecksumBad, 0, 0, 1);
|
||||
|
||||
lowerSizer->Add(sbSizer_Checksum, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
|
||||
|
||||
//=====================================================
|
||||
// These are the buttons that autosend the userid (?)
|
||||
//=====================================================
|
||||
|
||||
// DR 4 Dec - taken off for screen for Beta release to avoid questions on their use until
|
||||
// we implement this feature
|
||||
#ifdef UNIMPLEMENTED
|
||||
wxBoxSizer* bSizer141;
|
||||
bSizer141 = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
// TxID
|
||||
//---------
|
||||
m_togTxID = new wxToggleButton(this, wxID_ANY, _("TxID"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_togTxID->SetToolTip(_("Send Tx ID information"));
|
||||
bSizer141->Add(m_togTxID, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
|
||||
|
||||
// RxID
|
||||
//---------
|
||||
m_togRxID = new wxToggleButton(this, wxID_ANY, _("RxID"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_togRxID->SetToolTip(_("Enable reception of ID information"));
|
||||
bSizer141->Add(m_togRxID, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_LEFT|wxALL|wxFIXED_MINSIZE, 5);
|
||||
|
||||
lowerSizer->Add(bSizer141, 0, wxALIGN_RIGHT, 5);
|
||||
#endif
|
||||
|
||||
centerSizer->Add(lowerSizer, 0, wxALIGN_BOTTOM|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 2);
|
||||
bSizer1->Add(centerSizer, 4, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 1);
|
||||
|
||||
//=====================================================
|
||||
// Right side
|
||||
//=====================================================
|
||||
wxBoxSizer* rightSizer;
|
||||
rightSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
//=====================================================
|
||||
// Squelch Slider Control
|
||||
//=====================================================
|
||||
wxStaticBoxSizer* sbSizer3;
|
||||
sbSizer3 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Squelch")), wxVERTICAL);
|
||||
|
||||
m_sliderSQ = new wxSlider(this, wxID_ANY, 0, 0, 40, wxDefaultPosition, wxSize(-1,80), wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_VERTICAL);
|
||||
m_sliderSQ->SetToolTip(_("Set Squelch level in dB."));
|
||||
|
||||
sbSizer3->Add(m_sliderSQ, 1, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
|
||||
//------------------------------
|
||||
// Squelch Level static text box
|
||||
//------------------------------
|
||||
m_textSQ = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
||||
|
||||
sbSizer3->Add(m_textSQ, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
|
||||
//------------------------------
|
||||
// Squelch Toggle Checkbox
|
||||
//------------------------------
|
||||
m_ckboxSQ = new wxCheckBox(this, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
|
||||
sbSizer3->Add(m_ckboxSQ, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
rightSizer->Add(sbSizer3, 2, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 0);
|
||||
|
||||
//rightSizer->Add(sbSizer3_33,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
/* new --- */
|
||||
|
||||
//------------------------------
|
||||
// Mode box
|
||||
//------------------------------
|
||||
wxStaticBoxSizer* sbSizer_mode;
|
||||
sbSizer_mode = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Mode")), wxVERTICAL);
|
||||
|
||||
#ifdef DISABLED_FEATURE
|
||||
m_rb1400old = new wxRadioButton( this, wxID_ANY, wxT("1400 V0.91"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
|
||||
sbSizer_mode->Add(m_rb1400old, 0, wxALIGN_LEFT|wxALL, 1);
|
||||
m_rb1400 = new wxRadioButton( this, wxID_ANY, wxT("1400"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
sbSizer_mode->Add(m_rb1400, 0, wxALIGN_LEFT|wxALL, 1);
|
||||
#endif
|
||||
m_rb700 = new wxRadioButton( this, wxID_ANY, wxT("700"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
|
||||
sbSizer_mode->Add(m_rb700, 0, wxALIGN_LEFT|wxALL, 1);
|
||||
m_rb700b = new wxRadioButton( this, wxID_ANY, wxT("700B"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
sbSizer_mode->Add(m_rb700b, 0, wxALIGN_LEFT|wxALL, 1);
|
||||
m_rb1600 = new wxRadioButton( this, wxID_ANY, wxT("1600"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
sbSizer_mode->Add(m_rb1600, 0, wxALIGN_LEFT|wxALL, 1);
|
||||
m_rb1600->SetValue(true);
|
||||
#ifdef DISABLED_FEATURE
|
||||
m_rb1600Wide = new wxRadioButton( this, wxID_ANY, wxT("1600 Wide"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
sbSizer_mode->Add(m_rb1600Wide, 0, wxALIGN_LEFT|wxALL, 1);
|
||||
m_rb2000 = new wxRadioButton( this, wxID_ANY, wxT("2000"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
sbSizer_mode->Add(m_rb2000, 0, wxALIGN_LEFT|wxALL, 1);
|
||||
#endif
|
||||
|
||||
rightSizer->Add(sbSizer_mode,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
|
||||
#ifdef MOVED_TO_OPTIONS_DIALOG
|
||||
/* new --- */
|
||||
|
||||
//------------------------------
|
||||
// Test Frames box
|
||||
//------------------------------
|
||||
|
||||
wxStaticBoxSizer* sbSizer_testFrames;
|
||||
sbSizer_testFrames = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Test Frames")), wxVERTICAL);
|
||||
|
||||
m_ckboxTestFrame = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
sbSizer_testFrames->Add(m_ckboxTestFrame, 0, wxALIGN_LEFT, 0);
|
||||
|
||||
rightSizer->Add(sbSizer_testFrames,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
|
||||
#endif
|
||||
|
||||
//=====================================================
|
||||
// Control Toggles box
|
||||
//=====================================================
|
||||
wxStaticBoxSizer* sbSizer5;
|
||||
sbSizer5 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Control")), wxVERTICAL);
|
||||
wxBoxSizer* bSizer1511;
|
||||
bSizer1511 = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
//-------------------------------
|
||||
// Stop/Stop signal processing (rx and tx)
|
||||
//-------------------------------
|
||||
m_togBtnOnOff = new wxToggleButton(this, wxID_ANY, _("Start"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_togBtnOnOff->SetToolTip(_("Begin/End receiving data."));
|
||||
bSizer1511->Add(m_togBtnOnOff, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
|
||||
sbSizer5->Add(bSizer1511, 0, wxEXPAND, 1);
|
||||
|
||||
#ifdef UNIMPLEMENTED
|
||||
//------------------------------
|
||||
// Toggle Loopback button for RX
|
||||
//------------------------------
|
||||
wxBoxSizer* bSizer15113;
|
||||
bSizer15113 = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer* bSizer15111;
|
||||
bSizer15111 = new wxBoxSizer(wxVERTICAL);
|
||||
wxSize wxSz = wxSize(44, 30);
|
||||
m_togBtnLoopRx = new wxToggleButton(this, wxID_ANY, _("Loop\nRX"), wxDefaultPosition, wxSz, 0);
|
||||
m_togBtnLoopRx->SetFont(wxFont(6, 70, 90, 90, false, wxEmptyString));
|
||||
m_togBtnLoopRx->SetToolTip(_("Loopback Receive audio data."));
|
||||
|
||||
bSizer15111->Add(m_togBtnLoopRx, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
|
||||
|
||||
//sbSizer5->Add(bSizer15111, 0, wxEXPAND, 1);
|
||||
bSizer15113->Add(bSizer15111, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
|
||||
|
||||
//------------------------------
|
||||
// Toggle Loopback button for Tx
|
||||
//------------------------------
|
||||
wxBoxSizer* bSizer15112;
|
||||
bSizer15112 = new wxBoxSizer(wxVERTICAL);
|
||||
m_togBtnLoopTx = new wxToggleButton(this, wxID_ANY, _("Loop\nTX"), wxDefaultPosition, wxSz, 0);
|
||||
m_togBtnLoopTx->SetFont(wxFont(6, 70, 90, 90, false, wxEmptyString));
|
||||
m_togBtnLoopTx->SetToolTip(_("Loopback Transmit audio data."));
|
||||
|
||||
bSizer15112->Add(m_togBtnLoopTx, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
|
||||
bSizer15113->Add(bSizer15112, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
|
||||
|
||||
sbSizer5->Add(bSizer15113, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
|
||||
#endif
|
||||
|
||||
//------------------------------
|
||||
// Split Frequency Mode Toggle
|
||||
//------------------------------
|
||||
wxBoxSizer* bSizer151;
|
||||
bSizer151 = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_togBtnSplit = new wxToggleButton(this, wxID_ANY, _("Split"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_togBtnSplit->SetToolTip(_("Toggle split frequency mode."));
|
||||
|
||||
bSizer151->Add(m_togBtnSplit, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
|
||||
sbSizer5->Add(bSizer151, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 1);
|
||||
wxBoxSizer* bSizer13;
|
||||
bSizer13 = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
//------------------------------
|
||||
// Analog Passthrough Toggle
|
||||
//------------------------------
|
||||
m_togBtnAnalog = new wxToggleButton(this, wxID_ANY, _("Analog"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_togBtnAnalog->SetToolTip(_("Toggle analog/digital operation."));
|
||||
bSizer13->Add(m_togBtnAnalog, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
|
||||
sbSizer5->Add(bSizer13, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
|
||||
|
||||
// not implemented on fdmdv2
|
||||
#ifdef ALC
|
||||
//------------------------------
|
||||
// Toggle for ALC
|
||||
//------------------------------
|
||||
wxBoxSizer* bSizer14;
|
||||
bSizer14 = new wxBoxSizer(wxVERTICAL);
|
||||
m_togBtnALC = new wxToggleButton(this, wxID_ANY, _("ALC"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_togBtnALC->SetToolTip(_("Toggle automatic level control mode."));
|
||||
|
||||
bSizer14->Add(m_togBtnALC, 0, wxALL, 1);
|
||||
sbSizer5->Add(bSizer14, 0, wxALIGN_CENTER|wxALIGN_CENTER_HORIZONTAL|wxALL, 1);
|
||||
#endif
|
||||
|
||||
//------------------------------
|
||||
// Toggle Transmit/Receive relays
|
||||
//------------------------------
|
||||
wxBoxSizer* bSizer11;
|
||||
bSizer11 = new wxBoxSizer(wxVERTICAL);
|
||||
m_btnTogPTT = new wxToggleButton(this, wxID_ANY, _("PTT"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_btnTogPTT->SetToolTip(_("Push to Talk - Switch between Receive and Transmit - you can also use the space bar "));
|
||||
bSizer11->Add(m_btnTogPTT, 1, wxALIGN_CENTER|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
|
||||
sbSizer5->Add(bSizer11, 2, wxEXPAND, 1);
|
||||
rightSizer->Add(sbSizer5, 2, wxALIGN_CENTER|wxALL|wxEXPAND, 3);
|
||||
bSizer1->Add(rightSizer, 0, wxALL|wxEXPAND, 3);
|
||||
this->SetSizer(bSizer1);
|
||||
this->Layout();
|
||||
m_statusBar1 = this->CreateStatusBar(3, wxST_SIZEGRIP, wxID_ANY);
|
||||
|
||||
//=====================================================
|
||||
// End of layout
|
||||
//=====================================================
|
||||
|
||||
//-------------------
|
||||
// Connect Events
|
||||
//-------------------
|
||||
this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(TopFrame::topFrame_OnClose));
|
||||
this->Connect(wxEVT_PAINT, wxPaintEventHandler(TopFrame::topFrame_OnPaint));
|
||||
this->Connect(wxEVT_SIZE, wxSizeEventHandler(TopFrame::topFrame_OnSize));
|
||||
this->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::topFrame_OnUpdateUI));
|
||||
|
||||
this->Connect(m_menuItemExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnExit));
|
||||
this->Connect(m_menuItemOnTop->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnTop));
|
||||
|
||||
this->Connect(m_menuItemAudio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsAudio));
|
||||
this->Connect(m_menuItemAudio->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsAudioUI));
|
||||
this->Connect(m_menuItemFilter->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsFilter));
|
||||
this->Connect(m_menuItemFilter->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsFilterUI));
|
||||
this->Connect(m_menuItemRigCtrlCfg->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsComCfg));
|
||||
this->Connect(m_menuItemRigCtrlCfg->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsComCfgUI));
|
||||
this->Connect(m_menuItemOptions->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsOptions));
|
||||
this->Connect(m_menuItemOptions->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsOptionsUI));
|
||||
|
||||
this->Connect(m_menuItemPlayFileToMicIn->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileToMicIn));
|
||||
this->Connect(m_menuItemRecFileFromRadio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnRecFileFromRadio));
|
||||
this->Connect(m_menuItemPlayFileFromRadio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileFromRadio));
|
||||
|
||||
this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpCheckUpdates));
|
||||
this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
|
||||
this->Connect(m_menuItemAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpAbout));
|
||||
//m_togRxID->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnRxID), NULL, this);
|
||||
//m_togTxID->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnTxID), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_LINEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_PAGEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnSliderScrollBottom), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScrollChanged), NULL, this);
|
||||
m_sliderSQ->Connect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnSliderScrollTop), NULL, this);
|
||||
m_ckboxSQ->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSQClick), NULL, this);
|
||||
|
||||
m_ckboxSNR->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSNRClick), NULL, this);
|
||||
|
||||
m_togBtnOnOff->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnOnOff), NULL, this);
|
||||
m_togBtnSplit->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnSplitClick), NULL, this);
|
||||
m_togBtnAnalog->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnAnalogClick), NULL, this);
|
||||
#ifdef ALC
|
||||
m_togBtnALC->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnALCClick), NULL, this);
|
||||
#endif
|
||||
m_btnTogPTT->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnPTT), NULL, this);
|
||||
|
||||
m_BtnCallSignReset->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnCallSignReset), NULL, this);
|
||||
m_BtnBerReset->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnBerReset), NULL, this);
|
||||
}
|
||||
|
||||
TopFrame::~TopFrame()
|
||||
{
|
||||
//-------------------
|
||||
// Disconnect Events
|
||||
//-------------------
|
||||
this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(TopFrame::topFrame_OnClose));
|
||||
this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(TopFrame::topFrame_OnPaint));
|
||||
this->Disconnect(wxEVT_SIZE, wxSizeEventHandler(TopFrame::topFrame_OnSize));
|
||||
this->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::topFrame_OnUpdateUI));
|
||||
this->Disconnect(ID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnExit));
|
||||
this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsAudio));
|
||||
this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsAudioUI));
|
||||
this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsFilter));
|
||||
this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsFilterUI));
|
||||
this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsComCfg));
|
||||
this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsComCfgUI));
|
||||
this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsOptions));
|
||||
this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsOptionsUI));
|
||||
|
||||
this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileToMicIn));
|
||||
this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnRecFileFromRadio));
|
||||
this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileFromRadio));
|
||||
|
||||
this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpCheckUpdates));
|
||||
this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
|
||||
this->Disconnect(ID_ABOUT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpAbout));
|
||||
//m_togRxID->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnRxID), NULL, this);
|
||||
//m_togTxID->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnTxID), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_LINEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_PAGEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnSliderScrollBottom), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScrollChanged), NULL, this);
|
||||
m_sliderSQ->Disconnect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnSliderScrollTop), NULL, this);
|
||||
m_ckboxSQ->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSQClick), NULL, this);
|
||||
|
||||
m_togBtnOnOff->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnOnOff), NULL, this);
|
||||
m_togBtnSplit->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnSplitClick), NULL, this);
|
||||
m_togBtnAnalog->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnAnalogClick), NULL, this);
|
||||
#ifdef ALC
|
||||
m_togBtnALC->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnALCClick), NULL, this);
|
||||
#endif
|
||||
m_btnTogPTT->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnPTT), NULL, this);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
//==========================================================================
|
||||
// Name: topFrame.h
|
||||
//
|
||||
// Purpose: Implements simple wxWidgets application with GUI.
|
||||
// Created: Apr. 9, 2012
|
||||
// Authors: David Rowe, David Witten
|
||||
//
|
||||
// License:
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License version 2.1,
|
||||
// as published by the Free Software Foundation. This program is
|
||||
// distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//==========================================================================
|
||||
#ifndef __TOPFRAME_H__
|
||||
#define __TOPFRAME_H__
|
||||
|
||||
#include "version.h"
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/menu.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/gauge.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/aui/auibook.h>
|
||||
#include <wx/tglbtn.h>
|
||||
#include <wx/slider.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/statusbr.h>
|
||||
#include <wx/frame.h>
|
||||
#include <wx/statbmp.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/radiobut.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/listbox.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/listctrl.h>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ID_OPEN 1000
|
||||
#define ID_SAVE 1001
|
||||
#define ID_CLOSE 1002
|
||||
#define ID_EXIT 1003
|
||||
#define ID_COPY 1004
|
||||
#define ID_CUT 1005
|
||||
#define ID_PASTE 1006
|
||||
#define ID_OPTIONS 1007
|
||||
#define ID_ABOUT 1008
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class TopFrame
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class TopFrame : public wxFrame
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxMenuBar* m_menubarMain;
|
||||
wxMenu* file;
|
||||
wxMenu* edit;
|
||||
wxMenu* tools;
|
||||
wxMenu* help;
|
||||
wxGauge* m_gaugeSNR;
|
||||
wxStaticText* m_textSNR;
|
||||
wxCheckBox* m_ckboxSNR;
|
||||
wxGauge* m_gaugeLevel;
|
||||
wxStaticText* m_textLevel;
|
||||
|
||||
wxButton* m_BtnCallSignReset;
|
||||
wxTextCtrl* m_txtCtrlCallSign;
|
||||
wxStaticText* m_txtChecksumGood;
|
||||
wxStaticText* m_txtChecksumBad;
|
||||
|
||||
wxSlider* m_sliderSQ;
|
||||
wxCheckBox* m_ckboxSQ;
|
||||
wxStaticText* m_textSQ;
|
||||
wxStatusBar* m_statusBar1;
|
||||
|
||||
wxButton* m_BtnBerReset;
|
||||
wxStaticText *m_textBits;
|
||||
wxStaticText *m_textErrors;
|
||||
wxStaticText *m_textBER;
|
||||
|
||||
wxRadioButton *m_rbSync;
|
||||
wxRadioButton *m_rb1400old;
|
||||
wxRadioButton *m_rb1400;
|
||||
wxRadioButton *m_rb700;
|
||||
wxRadioButton *m_rb700b;
|
||||
wxRadioButton *m_rb1600;
|
||||
wxRadioButton *m_rb2000;
|
||||
wxRadioButton *m_rb1600Wide;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void topFrame_OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||
virtual void topFrame_OnPaint( wxPaintEvent& event ) { event.Skip(); }
|
||||
virtual void topFrame_OnSize( wxSizeEvent& event ) { event.Skip(); }
|
||||
virtual void topFrame_OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
|
||||
virtual void OnExit( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnTop( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnToolsAudio( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnToolsAudioUI( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnToolsFilter( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnToolsFilterUI( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnToolsOptions( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnToolsUDP( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnToolsOptionsUI( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnToolsComCfg( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnToolsComCfgUI( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnPlayFileToMicIn( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnRecFileFromRadio( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnPlayFileFromRadio( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
virtual void OnHelpCheckUpdates( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnHelpCheckUpdatesUI( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnHelpAbout( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnTogBtnRxID( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnTogBtnTxID( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnCmdSliderScroll( wxScrollEvent& event ) { event.Skip(); }
|
||||
virtual void OnSliderScrollBottom( wxScrollEvent& event ) { event.Skip(); }
|
||||
virtual void OnCmdSliderScrollChanged( wxScrollEvent& event ) { event.Skip(); }
|
||||
virtual void OnSliderScrollTop( wxScrollEvent& event ) { event.Skip(); }
|
||||
virtual void OnCheckSQClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnCheckSNRClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
virtual void OnTogBtnLoopRx( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnTogBtnLoopTx( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnTogBtnOnOff( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnTogBtnSplitClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnTogBtnAnalogClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnTogBtnALCClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnTogBtnPTT( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
virtual void OnTogBtnSplitClickUI(wxUpdateUIEvent& event) { event.Skip(); }
|
||||
virtual void OnTogBtnAnalogClickUI(wxUpdateUIEvent& event) { event.Skip(); }
|
||||
virtual void OnTogBtnALCClickUI(wxUpdateUIEvent& event) { event.Skip(); }
|
||||
virtual void OnTogBtnRxIDUI(wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnTogBtnTxIDUI(wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnTogBtnPTT_UI(wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnTogBtnOnOffUI(wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
|
||||
virtual void OnCallSignReset( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBerReset( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
public:
|
||||
wxToggleButton* m_togRxID;
|
||||
wxToggleButton* m_togTxID;
|
||||
wxToggleButton* m_togBtnOnOff;
|
||||
wxToggleButton* m_togBtnSplit;
|
||||
wxToggleButton* m_togBtnAnalog;
|
||||
wxToggleButton* m_togBtnALC;
|
||||
wxToggleButton* m_btnTogPTT;
|
||||
wxToggleButton* m_togBtnLoopRx;
|
||||
wxToggleButton* m_togBtnLoopTx;
|
||||
wxAuiNotebook* m_auiNbookCtrl;
|
||||
|
||||
TopFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("FreeDV ") + _(FREEDV_VERSION), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(561,300 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
|
||||
|
||||
~TopFrame();
|
||||
};
|
||||
|
||||
#endif //__TOPFRAME_H__
|
Loading…
Reference in New Issue