mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-19 02:21:55 -05:00
Merge pull request #8 from cjcliffe/dynamic_demod
Dynamic demod, x86-64 switch and std::thread
This commit is contained in:
commit
0e2984ab18
@ -1,5 +1,7 @@
|
|||||||
cmake_minimum_required (VERSION 2.8)
|
cmake_minimum_required (VERSION 2.8)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
|
||||||
|
|
||||||
macro(configure_files srcDir destDir)
|
macro(configure_files srcDir destDir)
|
||||||
message(STATUS "Configuring directory ${destDir}")
|
message(STATUS "Configuring directory ${destDir}")
|
||||||
make_directory(${destDir})
|
make_directory(${destDir})
|
||||||
@ -50,8 +52,9 @@ SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR})
|
|||||||
|
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
|
|
||||||
|
|
||||||
|
find_package(wxWidgets REQUIRED gl core base)
|
||||||
set(wxWidgets_CONFIGURATION mswu)
|
set(wxWidgets_CONFIGURATION mswu)
|
||||||
find_package(wxWidgets COMPONENTS gl core base REQUIRED)
|
|
||||||
include(${wxWidgets_USE_FILE})
|
include(${wxWidgets_USE_FILE})
|
||||||
|
|
||||||
# include_directories ( ${PROJECT_SOURCE_DIR}/../CubicVR-2/build/include )
|
# include_directories ( ${PROJECT_SOURCE_DIR}/../CubicVR-2/build/include )
|
||||||
@ -59,15 +62,16 @@ include(${wxWidgets_USE_FILE})
|
|||||||
|
|
||||||
|
|
||||||
if (DEFINED WIN32)
|
if (DEFINED WIN32)
|
||||||
include_directories ( ${PROJECT_SOURCE_DIR}/external/fftw-3.3.4-dll32 ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release )
|
set(wxWidgets_USE_STATIC ON)
|
||||||
link_directories ( ${PROJECT_SOURCE_DIR}/external/fftw-3.3.4-dll32 ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/x32 )
|
include_directories ( ${PROJECT_SOURCE_DIR}/external/fftw-3.3.4-dll64 ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release )
|
||||||
|
link_directories ( ${PROJECT_SOURCE_DIR}/external/fftw-3.3.4-dll64 ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/x64 )
|
||||||
set(FFTW_LIB fftw3-3)
|
set(FFTW_LIB fftw3-3)
|
||||||
|
|
||||||
include_directories ( ${PROJECT_SOURCE_DIR}/external/portaudio/include )
|
include_directories ( ${PROJECT_SOURCE_DIR}/external/portaudio/include )
|
||||||
link_directories ( ${PROJECT_SOURCE_DIR}/external/portaudio/libs )
|
link_directories ( ${PROJECT_SOURCE_DIR}/external/portaudio/libs/64 )
|
||||||
SET (PORTAUDIO_LIBRARY portaudio.dll winmm)
|
SET (PORTAUDIO_LIBRARY libportaudio_x86.dll winmm)
|
||||||
|
|
||||||
link_directories ( ${PROJECT_SOURCE_DIR}/external/liquid-dsp/lib )
|
link_directories ( ${PROJECT_SOURCE_DIR}/external/liquid-dsp/lib/64 )
|
||||||
include_directories ( ${PROJECT_SOURCE_DIR}/external/liquid-dsp/include )
|
include_directories ( ${PROJECT_SOURCE_DIR}/external/liquid-dsp/include )
|
||||||
else (DEFINED WIN32)
|
else (DEFINED WIN32)
|
||||||
set(RTLSDR_INCLUDE "/opt/local/include" CACHE FILEPATH "RTL-SDR Include Path")
|
set(RTLSDR_INCLUDE "/opt/local/include" CACHE FILEPATH "RTL-SDR Include Path")
|
||||||
@ -84,19 +88,14 @@ endif (DEFINED WIN32)
|
|||||||
|
|
||||||
SET (cubicsdr_sources
|
SET (cubicsdr_sources
|
||||||
src/CubicSDR.cpp
|
src/CubicSDR.cpp
|
||||||
src/SDRThread.cpp
|
|
||||||
src/PrimaryGLContext.cpp
|
|
||||||
src/AppFrame.cpp
|
src/AppFrame.cpp
|
||||||
src/SDRThreadQueue.cpp
|
src/sdr/SDRThread.cpp
|
||||||
src/SDRThreadTask.cpp
|
src/demod/DemodulatorThread.cpp
|
||||||
src/DemodulatorThread.cpp
|
src/demod/DemodulatorMgr.cpp
|
||||||
src/DemodulatorThreadQueue.cpp
|
src/audio/AudioThread.cpp
|
||||||
src/DemodulatorThreadTask.cpp
|
src/util/Gradient.cpp
|
||||||
src/AudioThread.cpp
|
src/util/Timer.cpp
|
||||||
src/AudioThreadQueue.cpp
|
src/visual/PrimaryGLContext.cpp
|
||||||
src/AudioThreadTask.cpp
|
|
||||||
src/Gradient.cpp
|
|
||||||
src/Timer.cpp
|
|
||||||
src/visual/ScopeCanvas.cpp
|
src/visual/ScopeCanvas.cpp
|
||||||
src/visual/ScopeContext.cpp
|
src/visual/ScopeContext.cpp
|
||||||
src/visual/SpectrumCanvas.cpp
|
src/visual/SpectrumCanvas.cpp
|
||||||
@ -106,21 +105,17 @@ SET (cubicsdr_sources
|
|||||||
)
|
)
|
||||||
|
|
||||||
SET (cubicsdr_headers
|
SET (cubicsdr_headers
|
||||||
src/CubicSDR.h
|
|
||||||
src/SDRThread.h
|
|
||||||
src/PrimaryGLContext.h
|
|
||||||
src/AppFrame.h
|
|
||||||
src/CubicSDRDefs.h
|
src/CubicSDRDefs.h
|
||||||
src/SDRThreadQueue.h
|
src/CubicSDR.h
|
||||||
src/SDRThreadTask.h
|
src/AppFrame.h
|
||||||
src/DemodulatorThread.h
|
src/sdr/SDRThread.h
|
||||||
src/DemodulatorThreadQueue.h
|
src/demod/DemodulatorThread.h
|
||||||
src/DemodulatorThreadTask.h
|
src/demod/DemodulatorMgr.h
|
||||||
src/AudioThread.h
|
src/audio/AudioThread.h
|
||||||
src/AudioThreadQueue.h
|
src/util/Gradient.h
|
||||||
src/AudioThreadTask.h
|
src/util/Timer.h
|
||||||
src/Gradient.h
|
src/util/ThreadQueue.h
|
||||||
src/Timer.h
|
src/visual/PrimaryGLContext.h
|
||||||
src/visual/ScopeCanvas.h
|
src/visual/ScopeCanvas.h
|
||||||
src/visual/ScopeContext.h
|
src/visual/ScopeContext.h
|
||||||
src/visual/SpectrumCanvas.h
|
src/visual/SpectrumCanvas.h
|
||||||
@ -129,9 +124,18 @@ SET (cubicsdr_headers
|
|||||||
src/visual/WaterfallContext.h
|
src/visual/WaterfallContext.h
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories ( ${PROJECT_SOURCE_DIR}/src/visual
|
include_directories ( ${PROJECT_SOURCE_DIR}/src/sdr
|
||||||
|
${PROJECT_SOURCE_DIR}/src/demod
|
||||||
|
${PROJECT_SOURCE_DIR}/src/audio
|
||||||
|
${PROJECT_SOURCE_DIR}/src/util
|
||||||
|
${PROJECT_SOURCE_DIR}/src/visual
|
||||||
${PROJECT_SOURCE_DIR}/src )
|
${PROJECT_SOURCE_DIR}/src )
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(
|
||||||
|
-std=c++0x # or -std=c++11
|
||||||
|
-pthread
|
||||||
|
)
|
||||||
|
|
||||||
#configure_files(${PROJECT_SOURCE_DIR}/shaders ${PROJECT_BINARY_DIR}/shaders COPYONLY)
|
#configure_files(${PROJECT_SOURCE_DIR}/shaders ${PROJECT_BINARY_DIR}/shaders COPYONLY)
|
||||||
#configure_files(${PROJECT_SOURCE_DIR}/png ${PROJECT_BINARY_DIR}/png COPYONLY)
|
#configure_files(${PROJECT_SOURCE_DIR}/png ${PROJECT_BINARY_DIR}/png COPYONLY)
|
||||||
|
|
||||||
|
161
cmake/Modules/CMakeParseArguments.cmake
Normal file
161
cmake/Modules/CMakeParseArguments.cmake
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#.rst:
|
||||||
|
# CMakeParseArguments
|
||||||
|
# -------------------
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords>
|
||||||
|
# <multi_value_keywords> args...)
|
||||||
|
#
|
||||||
|
# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions
|
||||||
|
# for parsing the arguments given to that macro or function. It
|
||||||
|
# processes the arguments and defines a set of variables which hold the
|
||||||
|
# values of the respective options.
|
||||||
|
#
|
||||||
|
# The <options> argument contains all options for the respective macro,
|
||||||
|
# i.e. keywords which can be used when calling the macro without any
|
||||||
|
# value following, like e.g. the OPTIONAL keyword of the install()
|
||||||
|
# command.
|
||||||
|
#
|
||||||
|
# The <one_value_keywords> argument contains all keywords for this macro
|
||||||
|
# which are followed by one value, like e.g. DESTINATION keyword of the
|
||||||
|
# install() command.
|
||||||
|
#
|
||||||
|
# The <multi_value_keywords> argument contains all keywords for this
|
||||||
|
# macro which can be followed by more than one value, like e.g. the
|
||||||
|
# TARGETS or FILES keywords of the install() command.
|
||||||
|
#
|
||||||
|
# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
|
||||||
|
# keywords listed in <options>, <one_value_keywords> and
|
||||||
|
# <multi_value_keywords> a variable composed of the given <prefix>
|
||||||
|
# followed by "_" and the name of the respective keyword. These
|
||||||
|
# variables will then hold the respective value from the argument list.
|
||||||
|
# For the <options> keywords this will be TRUE or FALSE.
|
||||||
|
#
|
||||||
|
# All remaining arguments are collected in a variable
|
||||||
|
# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see
|
||||||
|
# whether your macro was called with unrecognized parameters.
|
||||||
|
#
|
||||||
|
# As an example here a my_install() macro, which takes similar arguments
|
||||||
|
# as the real install() command:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# function(MY_INSTALL)
|
||||||
|
# set(options OPTIONAL FAST)
|
||||||
|
# set(oneValueArgs DESTINATION RENAME)
|
||||||
|
# set(multiValueArgs TARGETS CONFIGURATIONS)
|
||||||
|
# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
|
||||||
|
# "${multiValueArgs}" ${ARGN} )
|
||||||
|
# ...
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Assume my_install() has been called like this:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# After the cmake_parse_arguments() call the macro will have set the
|
||||||
|
# following variables:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# MY_INSTALL_OPTIONAL = TRUE
|
||||||
|
# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
|
||||||
|
# MY_INSTALL_DESTINATION = "bin"
|
||||||
|
# MY_INSTALL_RENAME = "" (was not used)
|
||||||
|
# MY_INSTALL_TARGETS = "foo;bar"
|
||||||
|
# MY_INSTALL_CONFIGURATIONS = "" (was not used)
|
||||||
|
# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# You can then continue and process these variables.
|
||||||
|
#
|
||||||
|
# Keywords terminate lists of values, e.g. if directly after a
|
||||||
|
# one_value_keyword another recognized keyword follows, this is
|
||||||
|
# interpreted as the beginning of the new option. E.g.
|
||||||
|
# my_install(TARGETS foo DESTINATION OPTIONAL) would result in
|
||||||
|
# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION
|
||||||
|
# would be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
# (To distribute this file outside of CMake, substitute the full
|
||||||
|
# License text for the above reference.)
|
||||||
|
|
||||||
|
|
||||||
|
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
|
||||||
|
|
||||||
|
|
||||||
|
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
|
||||||
|
# first set all result variables to empty/FALSE
|
||||||
|
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
|
||||||
|
set(${prefix}_${arg_name})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
foreach(option ${_optionNames})
|
||||||
|
set(${prefix}_${option} FALSE)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(${prefix}_UNPARSED_ARGUMENTS)
|
||||||
|
|
||||||
|
set(insideValues FALSE)
|
||||||
|
set(currentArgName)
|
||||||
|
|
||||||
|
# now iterate over all arguments and fill the result variables
|
||||||
|
foreach(currentArg ${ARGN})
|
||||||
|
list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||||
|
list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||||
|
list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||||
|
|
||||||
|
if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
|
||||||
|
if(insideValues)
|
||||||
|
if("${insideValues}" STREQUAL "SINGLE")
|
||||||
|
set(${prefix}_${currentArgName} ${currentArg})
|
||||||
|
set(insideValues FALSE)
|
||||||
|
elseif("${insideValues}" STREQUAL "MULTI")
|
||||||
|
list(APPEND ${prefix}_${currentArgName} ${currentArg})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
if(NOT ${optionIndex} EQUAL -1)
|
||||||
|
set(${prefix}_${currentArg} TRUE)
|
||||||
|
set(insideValues FALSE)
|
||||||
|
elseif(NOT ${singleArgIndex} EQUAL -1)
|
||||||
|
set(currentArgName ${currentArg})
|
||||||
|
set(${prefix}_${currentArgName})
|
||||||
|
set(insideValues "SINGLE")
|
||||||
|
elseif(NOT ${multiArgIndex} EQUAL -1)
|
||||||
|
set(currentArgName ${currentArg})
|
||||||
|
set(${prefix}_${currentArgName})
|
||||||
|
set(insideValues "MULTI")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# propagate the result variables to the caller:
|
||||||
|
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
|
||||||
|
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
|
||||||
|
endforeach()
|
||||||
|
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
|
||||||
|
|
||||||
|
endfunction()
|
382
cmake/Modules/FindPackageHandleStandardArgs.cmake
Normal file
382
cmake/Modules/FindPackageHandleStandardArgs.cmake
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
#.rst:
|
||||||
|
# FindPackageHandleStandardArgs
|
||||||
|
# -----------------------------
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> ... )
|
||||||
|
#
|
||||||
|
# This function is intended to be used in FindXXX.cmake modules files.
|
||||||
|
# It handles the REQUIRED, QUIET and version-related arguments to
|
||||||
|
# find_package(). It also sets the <packagename>_FOUND variable. The
|
||||||
|
# package is considered found if all variables <var1>... listed contain
|
||||||
|
# valid results, e.g. valid filepaths.
|
||||||
|
#
|
||||||
|
# There are two modes of this function. The first argument in both
|
||||||
|
# modes is the name of the Find-module where it is called (in original
|
||||||
|
# casing).
|
||||||
|
#
|
||||||
|
# The first simple mode looks like this:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name>
|
||||||
|
# (DEFAULT_MSG|"Custom failure message") <var1>...<varN> )
|
||||||
|
#
|
||||||
|
# If the variables <var1> to <varN> are all valid, then
|
||||||
|
# <UPPERCASED_NAME>_FOUND will be set to TRUE. If DEFAULT_MSG is given
|
||||||
|
# as second argument, then the function will generate itself useful
|
||||||
|
# success and error messages. You can also supply a custom error
|
||||||
|
# message for the failure case. This is not recommended.
|
||||||
|
#
|
||||||
|
# The second mode is more powerful and also supports version checking:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME
|
||||||
|
# [FOUND_VAR <resultVar>]
|
||||||
|
# [REQUIRED_VARS <var1>...<varN>]
|
||||||
|
# [VERSION_VAR <versionvar>]
|
||||||
|
# [HANDLE_COMPONENTS]
|
||||||
|
# [CONFIG_MODE]
|
||||||
|
# [FAIL_MESSAGE "Custom failure message"] )
|
||||||
|
#
|
||||||
|
# In this mode, the name of the result-variable can be set either to
|
||||||
|
# either <UPPERCASED_NAME>_FOUND or <OriginalCase_Name>_FOUND using the
|
||||||
|
# FOUND_VAR option. Other names for the result-variable are not
|
||||||
|
# allowed. So for a Find-module named FindFooBar.cmake, the two
|
||||||
|
# possible names are FooBar_FOUND and FOOBAR_FOUND. It is recommended
|
||||||
|
# to use the original case version. If the FOUND_VAR option is not
|
||||||
|
# used, the default is <UPPERCASED_NAME>_FOUND.
|
||||||
|
#
|
||||||
|
# As in the simple mode, if <var1> through <varN> are all valid,
|
||||||
|
# <packagename>_FOUND will be set to TRUE. After REQUIRED_VARS the
|
||||||
|
# variables which are required for this package are listed. Following
|
||||||
|
# VERSION_VAR the name of the variable can be specified which holds the
|
||||||
|
# version of the package which has been found. If this is done, this
|
||||||
|
# version will be checked against the (potentially) specified required
|
||||||
|
# version used in the find_package() call. The EXACT keyword is also
|
||||||
|
# handled. The default messages include information about the required
|
||||||
|
# version and the version which has been actually found, both if the
|
||||||
|
# version is ok or not. If the package supports components, use the
|
||||||
|
# HANDLE_COMPONENTS option to enable handling them. In this case,
|
||||||
|
# find_package_handle_standard_args() will report which components have
|
||||||
|
# been found and which are missing, and the <packagename>_FOUND variable
|
||||||
|
# will be set to FALSE if any of the required components (i.e. not the
|
||||||
|
# ones listed after OPTIONAL_COMPONENTS) are missing. Use the option
|
||||||
|
# CONFIG_MODE if your FindXXX.cmake module is a wrapper for a
|
||||||
|
# find_package(... NO_MODULE) call. In this case VERSION_VAR will be
|
||||||
|
# set to <NAME>_VERSION and the macro will automatically check whether
|
||||||
|
# the Config module was found. Via FAIL_MESSAGE a custom failure
|
||||||
|
# message can be specified, if this is not used, the default message
|
||||||
|
# will be displayed.
|
||||||
|
#
|
||||||
|
# Example for mode 1:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# find_package_handle_standard_args(LibXml2 DEFAULT_MSG
|
||||||
|
# LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and
|
||||||
|
# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to
|
||||||
|
# TRUE. If it is not found and REQUIRED was used, it fails with
|
||||||
|
# FATAL_ERROR, independent whether QUIET was used or not. If it is
|
||||||
|
# found, success will be reported, including the content of <var1>. On
|
||||||
|
# repeated Cmake runs, the same message won't be printed again.
|
||||||
|
#
|
||||||
|
# Example for mode 2:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# find_package_handle_standard_args(LibXslt
|
||||||
|
# FOUND_VAR LibXslt_FOUND
|
||||||
|
# REQUIRED_VARS LibXslt_LIBRARIES LibXslt_INCLUDE_DIRS
|
||||||
|
# VERSION_VAR LibXslt_VERSION_STRING)
|
||||||
|
#
|
||||||
|
# In this case, LibXslt is considered to be found if the variable(s)
|
||||||
|
# listed after REQUIRED_VAR are all valid, i.e. LibXslt_LIBRARIES and
|
||||||
|
# LibXslt_INCLUDE_DIRS in this case. The result will then be stored in
|
||||||
|
# LibXslt_FOUND . Also the version of LibXslt will be checked by using
|
||||||
|
# the version contained in LibXslt_VERSION_STRING. Since no
|
||||||
|
# FAIL_MESSAGE is given, the default messages will be printed.
|
||||||
|
#
|
||||||
|
# Another example for mode 2:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
|
||||||
|
# find_package_handle_standard_args(Automoc4 CONFIG_MODE)
|
||||||
|
#
|
||||||
|
# In this case, FindAutmoc4.cmake wraps a call to find_package(Automoc4
|
||||||
|
# NO_MODULE) and adds an additional search directory for automoc4. Here
|
||||||
|
# the result will be stored in AUTOMOC4_FOUND. The following
|
||||||
|
# FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper
|
||||||
|
# success/error message.
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2007-2009 Kitware, Inc.
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
# (To distribute this file outside of CMake, substitute the full
|
||||||
|
# License text for the above reference.)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
|
||||||
|
|
||||||
|
# internal helper macro
|
||||||
|
macro(_FPHSA_FAILURE_MESSAGE _msg)
|
||||||
|
if (${_NAME}_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR "${_msg}")
|
||||||
|
else ()
|
||||||
|
if (NOT ${_NAME}_FIND_QUIETLY)
|
||||||
|
message(STATUS "${_msg}")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
# internal helper macro to generate the failure message when used in CONFIG_MODE:
|
||||||
|
macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
|
||||||
|
# <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
|
||||||
|
if(${_NAME}_CONFIG)
|
||||||
|
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
|
||||||
|
else()
|
||||||
|
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
|
||||||
|
# List them all in the error message:
|
||||||
|
if(${_NAME}_CONSIDERED_CONFIGS)
|
||||||
|
set(configsText "")
|
||||||
|
list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
|
||||||
|
math(EXPR configsCount "${configsCount} - 1")
|
||||||
|
foreach(currentConfigIndex RANGE ${configsCount})
|
||||||
|
list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
|
||||||
|
list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
|
||||||
|
set(configsText "${configsText} ${filename} (version ${version})\n")
|
||||||
|
endforeach()
|
||||||
|
if (${_NAME}_NOT_FOUND_MESSAGE)
|
||||||
|
set(configsText "${configsText} Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n")
|
||||||
|
endif()
|
||||||
|
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}")
|
||||||
|
|
||||||
|
else()
|
||||||
|
# Simple case: No Config-file was found at all:
|
||||||
|
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
|
||||||
|
|
||||||
|
# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in
|
||||||
|
# new extended or in the "old" mode:
|
||||||
|
set(options CONFIG_MODE HANDLE_COMPONENTS)
|
||||||
|
set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR)
|
||||||
|
set(multiValueArgs REQUIRED_VARS)
|
||||||
|
set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
|
||||||
|
list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
|
||||||
|
|
||||||
|
if(${INDEX} EQUAL -1)
|
||||||
|
set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
|
||||||
|
set(FPHSA_REQUIRED_VARS ${ARGN})
|
||||||
|
set(FPHSA_VERSION_VAR)
|
||||||
|
else()
|
||||||
|
|
||||||
|
CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
|
||||||
|
|
||||||
|
if(FPHSA_UNPARSED_ARGUMENTS)
|
||||||
|
message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT FPHSA_FAIL_MESSAGE)
|
||||||
|
set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# now that we collected all arguments, process them
|
||||||
|
|
||||||
|
if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
|
||||||
|
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package()
|
||||||
|
# when it successfully found the config-file, including version checking:
|
||||||
|
if(FPHSA_CONFIG_MODE)
|
||||||
|
list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
|
||||||
|
list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
|
||||||
|
set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT FPHSA_REQUIRED_VARS)
|
||||||
|
message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
|
||||||
|
|
||||||
|
string(TOUPPER ${_NAME} _NAME_UPPER)
|
||||||
|
string(TOLOWER ${_NAME} _NAME_LOWER)
|
||||||
|
|
||||||
|
if(FPHSA_FOUND_VAR)
|
||||||
|
if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$")
|
||||||
|
set(_FOUND_VAR ${FPHSA_FOUND_VAR})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# collect all variables which were not found, so they can be printed, so the
|
||||||
|
# user knows better what went wrong (#6375)
|
||||||
|
set(MISSING_VARS "")
|
||||||
|
set(DETAILS "")
|
||||||
|
# check if all passed variables are valid
|
||||||
|
unset(${_FOUND_VAR})
|
||||||
|
foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
|
||||||
|
if(NOT ${_CURRENT_VAR})
|
||||||
|
set(${_FOUND_VAR} FALSE)
|
||||||
|
set(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}")
|
||||||
|
else()
|
||||||
|
set(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if(NOT "${${_FOUND_VAR}}" STREQUAL "FALSE")
|
||||||
|
set(${_FOUND_VAR} TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# component handling
|
||||||
|
unset(FOUND_COMPONENTS_MSG)
|
||||||
|
unset(MISSING_COMPONENTS_MSG)
|
||||||
|
|
||||||
|
if(FPHSA_HANDLE_COMPONENTS)
|
||||||
|
foreach(comp ${${_NAME}_FIND_COMPONENTS})
|
||||||
|
if(${_NAME}_${comp}_FOUND)
|
||||||
|
|
||||||
|
if(NOT DEFINED FOUND_COMPONENTS_MSG)
|
||||||
|
set(FOUND_COMPONENTS_MSG "found components: ")
|
||||||
|
endif()
|
||||||
|
set(FOUND_COMPONENTS_MSG "${FOUND_COMPONENTS_MSG} ${comp}")
|
||||||
|
|
||||||
|
else()
|
||||||
|
|
||||||
|
if(NOT DEFINED MISSING_COMPONENTS_MSG)
|
||||||
|
set(MISSING_COMPONENTS_MSG "missing components: ")
|
||||||
|
endif()
|
||||||
|
set(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}")
|
||||||
|
|
||||||
|
if(${_NAME}_FIND_REQUIRED_${comp})
|
||||||
|
set(${_FOUND_VAR} FALSE)
|
||||||
|
set(MISSING_VARS "${MISSING_VARS} ${comp}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
|
||||||
|
set(DETAILS "${DETAILS}[c${COMPONENT_MSG}]")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# version handling:
|
||||||
|
set(VERSION_MSG "")
|
||||||
|
set(VERSION_OK TRUE)
|
||||||
|
set(VERSION ${${FPHSA_VERSION_VAR}})
|
||||||
|
|
||||||
|
# check with DEFINED here as the requested or found version may be "0"
|
||||||
|
if (DEFINED ${_NAME}_FIND_VERSION)
|
||||||
|
if(DEFINED ${FPHSA_VERSION_VAR})
|
||||||
|
|
||||||
|
if(${_NAME}_FIND_VERSION_EXACT) # exact version required
|
||||||
|
# count the dots in the version string
|
||||||
|
string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${VERSION}")
|
||||||
|
# add one dot because there is one dot more than there are components
|
||||||
|
string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS)
|
||||||
|
if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT)
|
||||||
|
# Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT
|
||||||
|
# is at most 4 here. Therefore a simple lookup table is used.
|
||||||
|
if (${_NAME}_FIND_VERSION_COUNT EQUAL 1)
|
||||||
|
set(_VERSION_REGEX "[^.]*")
|
||||||
|
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2)
|
||||||
|
set(_VERSION_REGEX "[^.]*\\.[^.]*")
|
||||||
|
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3)
|
||||||
|
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*")
|
||||||
|
else ()
|
||||||
|
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
|
||||||
|
endif ()
|
||||||
|
string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${VERSION}")
|
||||||
|
unset(_VERSION_REGEX)
|
||||||
|
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD)
|
||||||
|
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
|
||||||
|
set(VERSION_OK FALSE)
|
||||||
|
else ()
|
||||||
|
set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
|
||||||
|
endif ()
|
||||||
|
unset(_VERSION_HEAD)
|
||||||
|
else ()
|
||||||
|
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL VERSION)
|
||||||
|
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
|
||||||
|
set(VERSION_OK FALSE)
|
||||||
|
else ()
|
||||||
|
set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
unset(_VERSION_DOTS)
|
||||||
|
|
||||||
|
else() # minimum version specified:
|
||||||
|
if (${_NAME}_FIND_VERSION VERSION_GREATER VERSION)
|
||||||
|
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
|
||||||
|
set(VERSION_OK FALSE)
|
||||||
|
else ()
|
||||||
|
set(VERSION_MSG "(found suitable version \"${VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")")
|
||||||
|
endif ()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
else()
|
||||||
|
|
||||||
|
# if the package was not found, but a version was given, add that to the output:
|
||||||
|
if(${_NAME}_FIND_VERSION_EXACT)
|
||||||
|
set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
|
||||||
|
else()
|
||||||
|
set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
else ()
|
||||||
|
if(VERSION)
|
||||||
|
set(VERSION_MSG "(found version \"${VERSION}\")")
|
||||||
|
endif()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if(VERSION_OK)
|
||||||
|
set(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]")
|
||||||
|
else()
|
||||||
|
set(${_FOUND_VAR} FALSE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# print the result:
|
||||||
|
if (${_FOUND_VAR})
|
||||||
|
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
|
||||||
|
else ()
|
||||||
|
|
||||||
|
if(FPHSA_CONFIG_MODE)
|
||||||
|
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
|
||||||
|
else()
|
||||||
|
if(NOT VERSION_OK)
|
||||||
|
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
|
||||||
|
else()
|
||||||
|
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(${_FOUND_VAR} ${${_FOUND_VAR}} PARENT_SCOPE)
|
||||||
|
|
||||||
|
endfunction()
|
57
cmake/Modules/FindPackageMessage.cmake
Normal file
57
cmake/Modules/FindPackageMessage.cmake
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#.rst:
|
||||||
|
# FindPackageMessage
|
||||||
|
# ------------------
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FIND_PACKAGE_MESSAGE(<name> "message for user" "find result details")
|
||||||
|
#
|
||||||
|
# This macro is intended to be used in FindXXX.cmake modules files. It
|
||||||
|
# will print a message once for each unique find result. This is useful
|
||||||
|
# for telling the user where a package was found. The first argument
|
||||||
|
# specifies the name (XXX) of the package. The second argument
|
||||||
|
# specifies the message to display. The third argument lists details
|
||||||
|
# about the find result so that if they change the message will be
|
||||||
|
# displayed again. The macro also obeys the QUIET argument to the
|
||||||
|
# find_package command.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# if(X11_FOUND)
|
||||||
|
# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}"
|
||||||
|
# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
|
||||||
|
# else()
|
||||||
|
# ...
|
||||||
|
# endif()
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2008-2009 Kitware, Inc.
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
# (To distribute this file outside of CMake, substitute the full
|
||||||
|
# License text for the above reference.)
|
||||||
|
|
||||||
|
function(FIND_PACKAGE_MESSAGE pkg msg details)
|
||||||
|
# Avoid printing a message repeatedly for the same find result.
|
||||||
|
if(NOT ${pkg}_FIND_QUIETLY)
|
||||||
|
string(REPLACE "\n" "" details "${details}")
|
||||||
|
set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg})
|
||||||
|
if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
|
||||||
|
# The message has not yet been printed.
|
||||||
|
message(STATUS "${msg}")
|
||||||
|
|
||||||
|
# Save the find details in the cache to avoid printing the same
|
||||||
|
# message again.
|
||||||
|
set("${DETAILS_VAR}" "${details}"
|
||||||
|
CACHE INTERNAL "Details about finding ${pkg}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
1082
cmake/Modules/FindwxWidgets.cmake
Normal file
1082
cmake/Modules/FindwxWidgets.cmake
Normal file
File diff suppressed because it is too large
Load Diff
414
external/fftw-3.3.4-dll64/fftw3.h
vendored
Normal file
414
external/fftw-3.3.4-dll64/fftw3.h
vendored
Normal file
@ -0,0 +1,414 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003, 2007-14 Matteo Frigo
|
||||||
|
* Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
|
||||||
|
*
|
||||||
|
* The following statement of license applies *only* to this header file,
|
||||||
|
* and *not* to the other files distributed with FFTW or derived therefrom:
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************** NOTE TO USERS *********************************
|
||||||
|
*
|
||||||
|
* THIS IS A HEADER FILE, NOT A MANUAL
|
||||||
|
*
|
||||||
|
* If you want to know how to use FFTW, please read the manual,
|
||||||
|
* online at http://www.fftw.org/doc/ and also included with FFTW.
|
||||||
|
* For a quick start, see the manual's tutorial section.
|
||||||
|
*
|
||||||
|
* (Reading header files to learn how to use a library is a habit
|
||||||
|
* stemming from code lacking a proper manual. Arguably, it's a
|
||||||
|
* *bad* habit in most cases, because header files can contain
|
||||||
|
* interfaces that are not part of the public, stable API.)
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef FFTW3_H
|
||||||
|
#define FFTW3_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/* If <complex.h> is included, use the C99 complex type. Otherwise
|
||||||
|
define a type bit-compatible with C99 complex */
|
||||||
|
#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
|
||||||
|
# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
|
||||||
|
#else
|
||||||
|
# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FFTW_CONCAT(prefix, name) prefix ## name
|
||||||
|
#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name)
|
||||||
|
#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name)
|
||||||
|
#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name)
|
||||||
|
#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name)
|
||||||
|
|
||||||
|
/* IMPORTANT: for Windows compilers, you should add a line
|
||||||
|
*/
|
||||||
|
#define FFTW_DLL
|
||||||
|
/*
|
||||||
|
here and in kernel/ifftw.h if you are compiling/using FFTW as a
|
||||||
|
DLL, in order to do the proper importing/exporting, or
|
||||||
|
alternatively compile with -DFFTW_DLL or the equivalent
|
||||||
|
command-line flag. This is not necessary under MinGW/Cygwin, where
|
||||||
|
libtool does the imports/exports automatically. */
|
||||||
|
#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__))
|
||||||
|
/* annoying Windows syntax for shared-library declarations */
|
||||||
|
# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */
|
||||||
|
# define FFTW_EXTERN extern __declspec(dllexport)
|
||||||
|
# else /* user is calling FFTW; import symbol */
|
||||||
|
# define FFTW_EXTERN extern __declspec(dllimport)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define FFTW_EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum fftw_r2r_kind_do_not_use_me {
|
||||||
|
FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2,
|
||||||
|
FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6,
|
||||||
|
FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fftw_iodim_do_not_use_me {
|
||||||
|
int n; /* dimension size */
|
||||||
|
int is; /* input stride */
|
||||||
|
int os; /* output stride */
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <stddef.h> /* for ptrdiff_t */
|
||||||
|
struct fftw_iodim64_do_not_use_me {
|
||||||
|
ptrdiff_t n; /* dimension size */
|
||||||
|
ptrdiff_t is; /* input stride */
|
||||||
|
ptrdiff_t os; /* output stride */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *);
|
||||||
|
typedef int (*fftw_read_char_func_do_not_use_me)(void *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
huge second-order macro that defines prototypes for all API
|
||||||
|
functions. We expand this macro for each supported precision
|
||||||
|
|
||||||
|
X: name-mangling macro
|
||||||
|
R: real data type
|
||||||
|
C: complex data type
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FFTW_DEFINE_API(X, R, C) \
|
||||||
|
\
|
||||||
|
FFTW_DEFINE_COMPLEX(R, C); \
|
||||||
|
\
|
||||||
|
typedef struct X(plan_s) *X(plan); \
|
||||||
|
\
|
||||||
|
typedef struct fftw_iodim_do_not_use_me X(iodim); \
|
||||||
|
typedef struct fftw_iodim64_do_not_use_me X(iodim64); \
|
||||||
|
\
|
||||||
|
typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \
|
||||||
|
\
|
||||||
|
typedef fftw_write_char_func_do_not_use_me X(write_char_func); \
|
||||||
|
typedef fftw_read_char_func_do_not_use_me X(read_char_func); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(execute)(const X(plan) p); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \
|
||||||
|
C *in, C *out, int sign, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \
|
||||||
|
C *in, C *out, int sign, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \
|
||||||
|
C *in, C *out, int sign, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \
|
||||||
|
int howmany, \
|
||||||
|
C *in, const int *inembed, \
|
||||||
|
int istride, int idist, \
|
||||||
|
C *out, const int *onembed, \
|
||||||
|
int ostride, int odist, \
|
||||||
|
int sign, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
C *in, C *out, \
|
||||||
|
int sign, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
R *ri, R *ii, R *ro, R *io, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \
|
||||||
|
const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
C *in, C *out, \
|
||||||
|
int sign, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \
|
||||||
|
const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
R *ri, R *ii, R *ro, R *io, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \
|
||||||
|
FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \
|
||||||
|
R *ro, R *io); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \
|
||||||
|
int howmany, \
|
||||||
|
R *in, const int *inembed, \
|
||||||
|
int istride, int idist, \
|
||||||
|
C *out, const int *onembed, \
|
||||||
|
int ostride, int odist, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \
|
||||||
|
R *in, C *out, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \
|
||||||
|
R *in, C *out, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \
|
||||||
|
int n2, \
|
||||||
|
R *in, C *out, unsigned flags); \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \
|
||||||
|
int howmany, \
|
||||||
|
C *in, const int *inembed, \
|
||||||
|
int istride, int idist, \
|
||||||
|
R *out, const int *onembed, \
|
||||||
|
int ostride, int odist, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \
|
||||||
|
C *in, R *out, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \
|
||||||
|
C *in, R *out, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \
|
||||||
|
int n2, \
|
||||||
|
C *in, R *out, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
R *in, C *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
C *in, R *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \
|
||||||
|
int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
R *in, R *ro, R *io, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \
|
||||||
|
int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
R *ri, R *ii, R *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \
|
||||||
|
const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
R *in, C *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \
|
||||||
|
const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
C *in, R *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \
|
||||||
|
int rank, const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
R *in, R *ro, R *io, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \
|
||||||
|
int rank, const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
R *ri, R *ii, R *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \
|
||||||
|
FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \
|
||||||
|
R *in, R *ro, R *io); \
|
||||||
|
FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \
|
||||||
|
R *ri, R *ii, R *out); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \
|
||||||
|
int howmany, \
|
||||||
|
R *in, const int *inembed, \
|
||||||
|
int istride, int idist, \
|
||||||
|
R *out, const int *onembed, \
|
||||||
|
int ostride, int odist, \
|
||||||
|
const X(r2r_kind) *kind, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \
|
||||||
|
const X(r2r_kind) *kind, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \
|
||||||
|
X(r2r_kind) kind, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \
|
||||||
|
X(r2r_kind) kind0, X(r2r_kind) kind1, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \
|
||||||
|
R *in, R *out, X(r2r_kind) kind0, \
|
||||||
|
X(r2r_kind) kind1, X(r2r_kind) kind2, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
R *in, R *out, \
|
||||||
|
const X(r2r_kind) *kind, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
R *in, R *out, \
|
||||||
|
const X(r2r_kind) *kind, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(destroy_plan)(X(plan) p); \
|
||||||
|
FFTW_EXTERN void X(forget_wisdom)(void); \
|
||||||
|
FFTW_EXTERN void X(cleanup)(void); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(set_timelimit)(double t); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \
|
||||||
|
FFTW_EXTERN int X(init_threads)(void); \
|
||||||
|
FFTW_EXTERN void X(cleanup_threads)(void); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \
|
||||||
|
FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \
|
||||||
|
FFTW_EXTERN char *X(export_wisdom_to_string)(void); \
|
||||||
|
FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \
|
||||||
|
void *data); \
|
||||||
|
FFTW_EXTERN int X(import_system_wisdom)(void); \
|
||||||
|
FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \
|
||||||
|
FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \
|
||||||
|
FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \
|
||||||
|
FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \
|
||||||
|
FFTW_EXTERN void X(print_plan)(const X(plan) p); \
|
||||||
|
FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void *X(malloc)(size_t n); \
|
||||||
|
FFTW_EXTERN R *X(alloc_real)(size_t n); \
|
||||||
|
FFTW_EXTERN C *X(alloc_complex)(size_t n); \
|
||||||
|
FFTW_EXTERN void X(free)(void *p); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(flops)(const X(plan) p, \
|
||||||
|
double *add, double *mul, double *fmas); \
|
||||||
|
FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \
|
||||||
|
FFTW_EXTERN double X(cost)(const X(plan) p); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN int X(alignment_of)(R *p); \
|
||||||
|
FFTW_EXTERN const char X(version)[]; \
|
||||||
|
FFTW_EXTERN const char X(cc)[]; \
|
||||||
|
FFTW_EXTERN const char X(codelet_optim)[];
|
||||||
|
|
||||||
|
|
||||||
|
/* end of FFTW_DEFINE_API macro */
|
||||||
|
|
||||||
|
FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
|
||||||
|
FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
|
||||||
|
FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
|
||||||
|
|
||||||
|
/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64
|
||||||
|
for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */
|
||||||
|
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \
|
||||||
|
&& !(defined(__ICC) || defined(__INTEL_COMPILER)) \
|
||||||
|
&& (defined(__i386__) || defined(__x86_64__) || defined(__ia64__))
|
||||||
|
# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
|
||||||
|
/* note: __float128 is a typedef, which is not supported with the _Complex
|
||||||
|
keyword in gcc, so instead we use this ugly __attribute__ version.
|
||||||
|
However, we can't simply pass the __attribute__ version to
|
||||||
|
FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer
|
||||||
|
types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */
|
||||||
|
# undef FFTW_DEFINE_COMPLEX
|
||||||
|
# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C
|
||||||
|
# endif
|
||||||
|
FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FFTW_FORWARD (-1)
|
||||||
|
#define FFTW_BACKWARD (+1)
|
||||||
|
|
||||||
|
#define FFTW_NO_TIMELIMIT (-1.0)
|
||||||
|
|
||||||
|
/* documented flags */
|
||||||
|
#define FFTW_MEASURE (0U)
|
||||||
|
#define FFTW_DESTROY_INPUT (1U << 0)
|
||||||
|
#define FFTW_UNALIGNED (1U << 1)
|
||||||
|
#define FFTW_CONSERVE_MEMORY (1U << 2)
|
||||||
|
#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */
|
||||||
|
#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */
|
||||||
|
#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */
|
||||||
|
#define FFTW_ESTIMATE (1U << 6)
|
||||||
|
#define FFTW_WISDOM_ONLY (1U << 21)
|
||||||
|
|
||||||
|
/* undocumented beyond-guru flags */
|
||||||
|
#define FFTW_ESTIMATE_PATIENT (1U << 7)
|
||||||
|
#define FFTW_BELIEVE_PCOST (1U << 8)
|
||||||
|
#define FFTW_NO_DFT_R2HC (1U << 9)
|
||||||
|
#define FFTW_NO_NONTHREADED (1U << 10)
|
||||||
|
#define FFTW_NO_BUFFERING (1U << 11)
|
||||||
|
#define FFTW_NO_INDIRECT_OP (1U << 12)
|
||||||
|
#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */
|
||||||
|
#define FFTW_NO_RANK_SPLITS (1U << 14)
|
||||||
|
#define FFTW_NO_VRANK_SPLITS (1U << 15)
|
||||||
|
#define FFTW_NO_VRECURSE (1U << 16)
|
||||||
|
#define FFTW_NO_SIMD (1U << 17)
|
||||||
|
#define FFTW_NO_SLOW (1U << 18)
|
||||||
|
#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19)
|
||||||
|
#define FFTW_ALLOW_PRUNING (1U << 20)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* FFTW3_H */
|
BIN
external/fftw-3.3.4-dll64/libfftw3-3.a
vendored
Normal file
BIN
external/fftw-3.3.4-dll64/libfftw3-3.a
vendored
Normal file
Binary file not shown.
1013
external/fftw-3.3.4-dll64/libfftw3-3.def
vendored
Normal file
1013
external/fftw-3.3.4-dll64/libfftw3-3.def
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
external/fftw-3.3.4-dll64/libfftw3-3.dll
vendored
Normal file
BIN
external/fftw-3.3.4-dll64/libfftw3-3.dll
vendored
Normal file
Binary file not shown.
BIN
external/liquid-dsp/lib/64/4.7/libliquid.a
vendored
Normal file
BIN
external/liquid-dsp/lib/64/4.7/libliquid.a
vendored
Normal file
Binary file not shown.
1871
external/liquid-dsp/lib/64/4.7/libliquid.def
vendored
Normal file
1871
external/liquid-dsp/lib/64/4.7/libliquid.def
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
external/liquid-dsp/lib/64/4.7/libliquid.dll
vendored
Normal file
BIN
external/liquid-dsp/lib/64/4.7/libliquid.dll
vendored
Normal file
Binary file not shown.
BIN
external/liquid-dsp/lib/64/libliquid.a
vendored
Normal file
BIN
external/liquid-dsp/lib/64/libliquid.a
vendored
Normal file
Binary file not shown.
1871
external/liquid-dsp/lib/64/libliquid.def
vendored
Normal file
1871
external/liquid-dsp/lib/64/libliquid.def
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
external/liquid-dsp/lib/64/libliquid.dll
vendored
Normal file
BIN
external/liquid-dsp/lib/64/libliquid.dll
vendored
Normal file
Binary file not shown.
104
external/portaudio/include/pa_allocation.h
vendored
104
external/portaudio/include/pa_allocation.h
vendored
@ -1,104 +0,0 @@
|
|||||||
#ifndef PA_ALLOCATION_H
|
|
||||||
#define PA_ALLOCATION_H
|
|
||||||
/*
|
|
||||||
* $Id: pa_allocation.h 1339 2008-02-15 07:50:33Z rossb $
|
|
||||||
* Portable Audio I/O Library allocation context header
|
|
||||||
* memory allocation context for tracking allocation groups
|
|
||||||
*
|
|
||||||
* Based on the Open Source API proposed by Ross Bencina
|
|
||||||
* Copyright (c) 1999-2008 Ross Bencina, Phil Burk
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
|
|
||||||
@brief Allocation Group prototypes. An Allocation Group makes it easy to
|
|
||||||
allocate multiple blocks of memory and free them all at once.
|
|
||||||
|
|
||||||
An allocation group is useful for keeping track of multiple blocks
|
|
||||||
of memory which are allocated at the same time (such as during initialization)
|
|
||||||
and need to be deallocated at the same time. The allocation group maintains
|
|
||||||
a list of allocated blocks, and can free all allocations at once. This
|
|
||||||
can be usefull for cleaning up after a partially initialized object fails.
|
|
||||||
|
|
||||||
The allocation group implementation is built on top of the lower
|
|
||||||
level allocation functions defined in pa_util.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
long linkCount;
|
|
||||||
struct PaUtilAllocationGroupLink *linkBlocks;
|
|
||||||
struct PaUtilAllocationGroupLink *spareLinks;
|
|
||||||
struct PaUtilAllocationGroupLink *allocations;
|
|
||||||
}PaUtilAllocationGroup;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Create an allocation group.
|
|
||||||
*/
|
|
||||||
PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void );
|
|
||||||
|
|
||||||
/** Destroy an allocation group, but not the memory allocated through the group.
|
|
||||||
*/
|
|
||||||
void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group );
|
|
||||||
|
|
||||||
/** Allocate a block of memory though an allocation group.
|
|
||||||
*/
|
|
||||||
void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size );
|
|
||||||
|
|
||||||
/** Free a block of memory that was previously allocated though an allocation
|
|
||||||
group. Calling this function is a relatively time consuming operation.
|
|
||||||
Under normal circumstances clients should call PaUtil_FreeAllAllocations to
|
|
||||||
free all allocated blocks simultaneously.
|
|
||||||
@see PaUtil_FreeAllAllocations
|
|
||||||
*/
|
|
||||||
void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer );
|
|
||||||
|
|
||||||
/** Free all blocks of memory which have been allocated through the allocation
|
|
||||||
group. This function doesn't destroy the group itself.
|
|
||||||
*/
|
|
||||||
void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group );
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* PA_ALLOCATION_H */
|
|
263
external/portaudio/include/pa_converters.h
vendored
263
external/portaudio/include/pa_converters.h
vendored
@ -1,263 +0,0 @@
|
|||||||
#ifndef PA_CONVERTERS_H
|
|
||||||
#define PA_CONVERTERS_H
|
|
||||||
/*
|
|
||||||
* $Id: pa_converters.h 1097 2006-08-26 08:27:53Z rossb $
|
|
||||||
* Portable Audio I/O Library sample conversion mechanism
|
|
||||||
*
|
|
||||||
* Based on the Open Source API proposed by Ross Bencina
|
|
||||||
* Copyright (c) 1999-2002 Phil Burk, Ross Bencina
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
|
|
||||||
@brief Conversion functions used to convert buffers of samples from one
|
|
||||||
format to another.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "portaudio.h" /* for PaSampleFormat */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
struct PaUtilTriangularDitherGenerator;
|
|
||||||
|
|
||||||
|
|
||||||
/** Choose an available sample format which is most appropriate for
|
|
||||||
representing the requested format. If the requested format is not available
|
|
||||||
higher quality formats are considered before lower quality formates.
|
|
||||||
@param availableFormats A variable containing the logical OR of all available
|
|
||||||
formats.
|
|
||||||
@param format The desired format.
|
|
||||||
@return The most appropriate available format for representing the requested
|
|
||||||
format.
|
|
||||||
*/
|
|
||||||
PaSampleFormat PaUtil_SelectClosestAvailableFormat(
|
|
||||||
PaSampleFormat availableFormats, PaSampleFormat format );
|
|
||||||
|
|
||||||
|
|
||||||
/* high level conversions functions for use by implementations */
|
|
||||||
|
|
||||||
|
|
||||||
/** The generic sample converter prototype. Sample converters convert count
|
|
||||||
samples from sourceBuffer to destinationBuffer. The actual type of the data
|
|
||||||
pointed to by these parameters varys for different converter functions.
|
|
||||||
@param destinationBuffer A pointer to the first sample of the destination.
|
|
||||||
@param destinationStride An offset between successive destination samples
|
|
||||||
expressed in samples (not bytes.) It may be negative.
|
|
||||||
@param sourceBuffer A pointer to the first sample of the source.
|
|
||||||
@param sourceStride An offset between successive source samples
|
|
||||||
expressed in samples (not bytes.) It may be negative.
|
|
||||||
@param count The number of samples to convert.
|
|
||||||
@param ditherState State information used to calculate dither. Converters
|
|
||||||
that do not perform dithering will ignore this parameter, in which case
|
|
||||||
NULL or invalid dither state may be passed.
|
|
||||||
*/
|
|
||||||
typedef void PaUtilConverter(
|
|
||||||
void *destinationBuffer, signed int destinationStride,
|
|
||||||
void *sourceBuffer, signed int sourceStride,
|
|
||||||
unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator );
|
|
||||||
|
|
||||||
|
|
||||||
/** Find a sample converter function for the given source and destinations
|
|
||||||
formats and flags (clip and dither.)
|
|
||||||
@return
|
|
||||||
A pointer to a PaUtilConverter which will perform the requested
|
|
||||||
conversion, or NULL if the given format conversion is not supported.
|
|
||||||
For conversions where clipping or dithering is not necessary, the
|
|
||||||
clip and dither flags are ignored and a non-clipping or dithering
|
|
||||||
version is returned.
|
|
||||||
If the source and destination formats are the same, a function which
|
|
||||||
copies data of the appropriate size will be returned.
|
|
||||||
*/
|
|
||||||
PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat,
|
|
||||||
PaSampleFormat destinationFormat, PaStreamFlags flags );
|
|
||||||
|
|
||||||
|
|
||||||
/** The generic buffer zeroer prototype. Buffer zeroers copy count zeros to
|
|
||||||
destinationBuffer. The actual type of the data pointed to varys for
|
|
||||||
different zeroer functions.
|
|
||||||
@param destinationBuffer A pointer to the first sample of the destination.
|
|
||||||
@param destinationStride An offset between successive destination samples
|
|
||||||
expressed in samples (not bytes.) It may be negative.
|
|
||||||
@param count The number of samples to zero.
|
|
||||||
*/
|
|
||||||
typedef void PaUtilZeroer(
|
|
||||||
void *destinationBuffer, signed int destinationStride, unsigned int count );
|
|
||||||
|
|
||||||
|
|
||||||
/** Find a buffer zeroer function for the given destination format.
|
|
||||||
@return
|
|
||||||
A pointer to a PaUtilZeroer which will perform the requested
|
|
||||||
zeroing.
|
|
||||||
*/
|
|
||||||
PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
/* low level functions and data structures which may be used for
|
|
||||||
substituting conversion functions */
|
|
||||||
|
|
||||||
|
|
||||||
/** The type used to store all sample conversion functions.
|
|
||||||
@see paConverters;
|
|
||||||
*/
|
|
||||||
typedef struct{
|
|
||||||
PaUtilConverter *Float32_To_Int32;
|
|
||||||
PaUtilConverter *Float32_To_Int32_Dither;
|
|
||||||
PaUtilConverter *Float32_To_Int32_Clip;
|
|
||||||
PaUtilConverter *Float32_To_Int32_DitherClip;
|
|
||||||
|
|
||||||
PaUtilConverter *Float32_To_Int24;
|
|
||||||
PaUtilConverter *Float32_To_Int24_Dither;
|
|
||||||
PaUtilConverter *Float32_To_Int24_Clip;
|
|
||||||
PaUtilConverter *Float32_To_Int24_DitherClip;
|
|
||||||
|
|
||||||
PaUtilConverter *Float32_To_Int16;
|
|
||||||
PaUtilConverter *Float32_To_Int16_Dither;
|
|
||||||
PaUtilConverter *Float32_To_Int16_Clip;
|
|
||||||
PaUtilConverter *Float32_To_Int16_DitherClip;
|
|
||||||
|
|
||||||
PaUtilConverter *Float32_To_Int8;
|
|
||||||
PaUtilConverter *Float32_To_Int8_Dither;
|
|
||||||
PaUtilConverter *Float32_To_Int8_Clip;
|
|
||||||
PaUtilConverter *Float32_To_Int8_DitherClip;
|
|
||||||
|
|
||||||
PaUtilConverter *Float32_To_UInt8;
|
|
||||||
PaUtilConverter *Float32_To_UInt8_Dither;
|
|
||||||
PaUtilConverter *Float32_To_UInt8_Clip;
|
|
||||||
PaUtilConverter *Float32_To_UInt8_DitherClip;
|
|
||||||
|
|
||||||
PaUtilConverter *Int32_To_Float32;
|
|
||||||
PaUtilConverter *Int32_To_Int24;
|
|
||||||
PaUtilConverter *Int32_To_Int24_Dither;
|
|
||||||
PaUtilConverter *Int32_To_Int16;
|
|
||||||
PaUtilConverter *Int32_To_Int16_Dither;
|
|
||||||
PaUtilConverter *Int32_To_Int8;
|
|
||||||
PaUtilConverter *Int32_To_Int8_Dither;
|
|
||||||
PaUtilConverter *Int32_To_UInt8;
|
|
||||||
PaUtilConverter *Int32_To_UInt8_Dither;
|
|
||||||
|
|
||||||
PaUtilConverter *Int24_To_Float32;
|
|
||||||
PaUtilConverter *Int24_To_Int32;
|
|
||||||
PaUtilConverter *Int24_To_Int16;
|
|
||||||
PaUtilConverter *Int24_To_Int16_Dither;
|
|
||||||
PaUtilConverter *Int24_To_Int8;
|
|
||||||
PaUtilConverter *Int24_To_Int8_Dither;
|
|
||||||
PaUtilConverter *Int24_To_UInt8;
|
|
||||||
PaUtilConverter *Int24_To_UInt8_Dither;
|
|
||||||
|
|
||||||
PaUtilConverter *Int16_To_Float32;
|
|
||||||
PaUtilConverter *Int16_To_Int32;
|
|
||||||
PaUtilConverter *Int16_To_Int24;
|
|
||||||
PaUtilConverter *Int16_To_Int8;
|
|
||||||
PaUtilConverter *Int16_To_Int8_Dither;
|
|
||||||
PaUtilConverter *Int16_To_UInt8;
|
|
||||||
PaUtilConverter *Int16_To_UInt8_Dither;
|
|
||||||
|
|
||||||
PaUtilConverter *Int8_To_Float32;
|
|
||||||
PaUtilConverter *Int8_To_Int32;
|
|
||||||
PaUtilConverter *Int8_To_Int24;
|
|
||||||
PaUtilConverter *Int8_To_Int16;
|
|
||||||
PaUtilConverter *Int8_To_UInt8;
|
|
||||||
|
|
||||||
PaUtilConverter *UInt8_To_Float32;
|
|
||||||
PaUtilConverter *UInt8_To_Int32;
|
|
||||||
PaUtilConverter *UInt8_To_Int24;
|
|
||||||
PaUtilConverter *UInt8_To_Int16;
|
|
||||||
PaUtilConverter *UInt8_To_Int8;
|
|
||||||
|
|
||||||
PaUtilConverter *Copy_8_To_8; /* copy without any conversion */
|
|
||||||
PaUtilConverter *Copy_16_To_16; /* copy without any conversion */
|
|
||||||
PaUtilConverter *Copy_24_To_24; /* copy without any conversion */
|
|
||||||
PaUtilConverter *Copy_32_To_32; /* copy without any conversion */
|
|
||||||
} PaUtilConverterTable;
|
|
||||||
|
|
||||||
|
|
||||||
/** A table of pointers to all required converter functions.
|
|
||||||
PaUtil_SelectConverter() uses this table to lookup the appropriate
|
|
||||||
conversion functions. The fields of this structure are initialized
|
|
||||||
with default conversion functions. Fields may be NULL, indicating that
|
|
||||||
no conversion function is available. User code may substitue optimised
|
|
||||||
conversion functions by assigning different function pointers to
|
|
||||||
these fields.
|
|
||||||
|
|
||||||
@note
|
|
||||||
If the PA_NO_STANDARD_CONVERTERS preprocessor variable is defined,
|
|
||||||
PortAudio's standard converters will not be compiled, and all fields
|
|
||||||
of this structure will be initialized to NULL. In such cases, users
|
|
||||||
should supply their own conversion functions if the require PortAudio
|
|
||||||
to open a stream that requires sample conversion.
|
|
||||||
|
|
||||||
@see PaUtilConverterTable, PaUtilConverter, PaUtil_SelectConverter
|
|
||||||
*/
|
|
||||||
extern PaUtilConverterTable paConverters;
|
|
||||||
|
|
||||||
|
|
||||||
/** The type used to store all buffer zeroing functions.
|
|
||||||
@see paZeroers;
|
|
||||||
*/
|
|
||||||
typedef struct{
|
|
||||||
PaUtilZeroer *ZeroU8; /* unsigned 8 bit, zero == 128 */
|
|
||||||
PaUtilZeroer *Zero8;
|
|
||||||
PaUtilZeroer *Zero16;
|
|
||||||
PaUtilZeroer *Zero24;
|
|
||||||
PaUtilZeroer *Zero32;
|
|
||||||
} PaUtilZeroerTable;
|
|
||||||
|
|
||||||
|
|
||||||
/** A table of pointers to all required zeroer functions.
|
|
||||||
PaUtil_SelectZeroer() uses this table to lookup the appropriate
|
|
||||||
conversion functions. The fields of this structure are initialized
|
|
||||||
with default conversion functions. User code may substitue optimised
|
|
||||||
conversion functions by assigning different function pointers to
|
|
||||||
these fields.
|
|
||||||
|
|
||||||
@note
|
|
||||||
If the PA_NO_STANDARD_ZEROERS preprocessor variable is defined,
|
|
||||||
PortAudio's standard zeroers will not be compiled, and all fields
|
|
||||||
of this structure will be initialized to NULL. In such cases, users
|
|
||||||
should supply their own zeroing functions for the sample sizes which
|
|
||||||
they intend to use.
|
|
||||||
|
|
||||||
@see PaUtilZeroerTable, PaUtilZeroer, PaUtil_SelectZeroer
|
|
||||||
*/
|
|
||||||
extern PaUtilZeroerTable paZeroers;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* PA_CONVERTERS_H */
|
|
72
external/portaudio/include/pa_cpuload.h
vendored
72
external/portaudio/include/pa_cpuload.h
vendored
@ -1,72 +0,0 @@
|
|||||||
#ifndef PA_CPULOAD_H
|
|
||||||
#define PA_CPULOAD_H
|
|
||||||
/*
|
|
||||||
* $Id: pa_cpuload.h 1097 2006-08-26 08:27:53Z rossb $
|
|
||||||
* Portable Audio I/O Library CPU Load measurement functions
|
|
||||||
* Portable CPU load measurement facility.
|
|
||||||
*
|
|
||||||
* Based on the Open Source API proposed by Ross Bencina
|
|
||||||
* Copyright (c) 2002 Ross Bencina
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
|
|
||||||
@brief Functions to assist in measuring the CPU utilization of a callback
|
|
||||||
stream. Used to implement the Pa_GetStreamCpuLoad() function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
double samplingPeriod;
|
|
||||||
double measurementStartTime;
|
|
||||||
double averageLoad;
|
|
||||||
} PaUtilCpuLoadMeasurer; /**< @todo need better name than measurer */
|
|
||||||
|
|
||||||
void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate );
|
|
||||||
void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer );
|
|
||||||
void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed );
|
|
||||||
void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer );
|
|
||||||
double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer );
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* PA_CPULOAD_H */
|
|
149
external/portaudio/include/pa_debugprint.h
vendored
149
external/portaudio/include/pa_debugprint.h
vendored
@ -1,149 +0,0 @@
|
|||||||
#ifndef PA_LOG_H
|
|
||||||
#define PA_LOG_H
|
|
||||||
/*
|
|
||||||
* Log file redirector function
|
|
||||||
* Copyright (c) 1999-2006 Ross Bencina, Phil Burk
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PaUtil_DebugPrint( const char *format, ... );
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
The basic format for log messages is described below. If you need to
|
|
||||||
add any log messages, please follow this format.
|
|
||||||
|
|
||||||
Function entry (void function):
|
|
||||||
|
|
||||||
"FunctionName called.\n"
|
|
||||||
|
|
||||||
Function entry (non void function):
|
|
||||||
|
|
||||||
"FunctionName called:\n"
|
|
||||||
"\tParam1Type param1: param1Value\n"
|
|
||||||
"\tParam2Type param2: param2Value\n" (etc...)
|
|
||||||
|
|
||||||
|
|
||||||
Function exit (no return value):
|
|
||||||
|
|
||||||
"FunctionName returned.\n"
|
|
||||||
|
|
||||||
Function exit (simple return value):
|
|
||||||
|
|
||||||
"FunctionName returned:\n"
|
|
||||||
"\tReturnType: returnValue\n"
|
|
||||||
|
|
||||||
If the return type is an error code, the error text is displayed in ()
|
|
||||||
|
|
||||||
If the return type is not an error code, but has taken a special value
|
|
||||||
because an error occurred, then the reason for the error is shown in []
|
|
||||||
|
|
||||||
If the return type is a struct ptr, the struct is dumped.
|
|
||||||
|
|
||||||
See the code below for examples
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** PA_DEBUG() provides a simple debug message printing facility. The macro
|
|
||||||
passes it's argument to a printf-like function called PaUtil_DebugPrint()
|
|
||||||
which prints to stderr and always flushes the stream after printing.
|
|
||||||
Because preprocessor macros cannot directly accept variable length argument
|
|
||||||
lists, calls to the macro must include an additional set of parenthesis, eg:
|
|
||||||
PA_DEBUG(("errorno: %d", 1001 ));
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef PA_ENABLE_DEBUG_OUTPUT
|
|
||||||
#define PA_DEBUG(x) PaUtil_DebugPrint x ;
|
|
||||||
#else
|
|
||||||
#define PA_DEBUG(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef PA_LOG_API_CALLS
|
|
||||||
#define PA_LOGAPI(x) PaUtil_DebugPrint x
|
|
||||||
|
|
||||||
#define PA_LOGAPI_ENTER(functionName) PaUtil_DebugPrint( functionName " called.\n" )
|
|
||||||
|
|
||||||
#define PA_LOGAPI_ENTER_PARAMS(functionName) PaUtil_DebugPrint( functionName " called:\n" )
|
|
||||||
|
|
||||||
#define PA_LOGAPI_EXIT(functionName) PaUtil_DebugPrint( functionName " returned.\n" )
|
|
||||||
|
|
||||||
#define PA_LOGAPI_EXIT_PAERROR( functionName, result ) \
|
|
||||||
PaUtil_DebugPrint( functionName " returned:\n" ); \
|
|
||||||
PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )
|
|
||||||
|
|
||||||
#define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) \
|
|
||||||
PaUtil_DebugPrint( functionName " returned:\n" ); \
|
|
||||||
PaUtil_DebugPrint("\t" resultFormatString "\n", result )
|
|
||||||
|
|
||||||
#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) \
|
|
||||||
PaUtil_DebugPrint( functionName " returned:\n" ); \
|
|
||||||
if( result > 0 ) \
|
|
||||||
PaUtil_DebugPrint("\t" positiveResultFormatString "\n", result ); \
|
|
||||||
else \
|
|
||||||
PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )
|
|
||||||
#else
|
|
||||||
#define PA_LOGAPI(x)
|
|
||||||
#define PA_LOGAPI_ENTER(functionName)
|
|
||||||
#define PA_LOGAPI_ENTER_PARAMS(functionName)
|
|
||||||
#define PA_LOGAPI_EXIT(functionName)
|
|
||||||
#define PA_LOGAPI_EXIT_PAERROR( functionName, result )
|
|
||||||
#define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result )
|
|
||||||
#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (*PaUtilLogCallback ) (const char *log);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Install user provided log function
|
|
||||||
*/
|
|
||||||
void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* PA_LOG_H */
|
|
106
external/portaudio/include/pa_dither.h
vendored
106
external/portaudio/include/pa_dither.h
vendored
@ -1,106 +0,0 @@
|
|||||||
#ifndef PA_DITHER_H
|
|
||||||
#define PA_DITHER_H
|
|
||||||
/*
|
|
||||||
* $Id: pa_dither.h 1418 2009-10-12 21:00:53Z philburk $
|
|
||||||
* Portable Audio I/O Library triangular dither generator
|
|
||||||
*
|
|
||||||
* Based on the Open Source API proposed by Ross Bencina
|
|
||||||
* Copyright (c) 1999-2002 Phil Burk, Ross Bencina
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
|
|
||||||
@brief Functions for generating dither noise
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pa_types.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
/* Note that the linear congruential algorithm requires 32 bit integers
|
|
||||||
* because it uses arithmetic overflow. So use PaUint32 instead of
|
|
||||||
* unsigned long so it will work on 64 bit systems.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @brief State needed to generate a dither signal */
|
|
||||||
typedef struct PaUtilTriangularDitherGenerator{
|
|
||||||
PaUint32 previous;
|
|
||||||
PaUint32 randSeed1;
|
|
||||||
PaUint32 randSeed2;
|
|
||||||
} PaUtilTriangularDitherGenerator;
|
|
||||||
|
|
||||||
|
|
||||||
/** @brief Initialize dither state */
|
|
||||||
void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *ditherState );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
@brief Calculate 2 LSB dither signal with a triangular distribution.
|
|
||||||
Ranged for adding to a 1 bit right-shifted 32 bit integer
|
|
||||||
prior to >>15. eg:
|
|
||||||
<pre>
|
|
||||||
signed long in = *
|
|
||||||
signed long dither = PaUtil_Generate16BitTriangularDither( ditherState );
|
|
||||||
signed short out = (signed short)(((in>>1) + dither) >> 15);
|
|
||||||
</pre>
|
|
||||||
@return
|
|
||||||
A signed 32-bit integer with a range of +32767 to -32768
|
|
||||||
*/
|
|
||||||
PaInt32 PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *ditherState );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
@brief Calculate 2 LSB dither signal with a triangular distribution.
|
|
||||||
Ranged for adding to a pre-scaled float.
|
|
||||||
<pre>
|
|
||||||
float in = *
|
|
||||||
float dither = PaUtil_GenerateFloatTriangularDither( ditherState );
|
|
||||||
// use smaller scaler to prevent overflow when we add the dither
|
|
||||||
signed short out = (signed short)(in*(32766.0f) + dither );
|
|
||||||
</pre>
|
|
||||||
@return
|
|
||||||
A float with a range of -2.0 to +1.99999.
|
|
||||||
*/
|
|
||||||
float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *ditherState );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* PA_DITHER_H */
|
|
145
external/portaudio/include/pa_endianness.h
vendored
145
external/portaudio/include/pa_endianness.h
vendored
@ -1,145 +0,0 @@
|
|||||||
#ifndef PA_ENDIANNESS_H
|
|
||||||
#define PA_ENDIANNESS_H
|
|
||||||
/*
|
|
||||||
* $Id: pa_endianness.h 1324 2008-01-27 02:03:30Z bjornroche $
|
|
||||||
* Portable Audio I/O Library current platform endianness macros
|
|
||||||
*
|
|
||||||
* Based on the Open Source API proposed by Ross Bencina
|
|
||||||
* Copyright (c) 1999-2002 Phil Burk, Ross Bencina
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
|
|
||||||
@brief Configure endianness symbols for the target processor.
|
|
||||||
|
|
||||||
Arrange for either the PA_LITTLE_ENDIAN or PA_BIG_ENDIAN preprocessor symbols
|
|
||||||
to be defined. The one that is defined reflects the endianness of the target
|
|
||||||
platform and may be used to implement conditional compilation of byte-order
|
|
||||||
dependent code.
|
|
||||||
|
|
||||||
If either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN is defined already, then no attempt
|
|
||||||
is made to override that setting. This may be useful if you have a better way
|
|
||||||
of determining the platform's endianness. The autoconf mechanism uses this for
|
|
||||||
example.
|
|
||||||
|
|
||||||
A PA_VALIDATE_ENDIANNESS macro is provided to compare the compile time
|
|
||||||
and runtime endiannes and raise an assertion if they don't match.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
/* If this is an apple, we need to do detect endianness this way */
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
/* we need to do some endian detection that is sensitive to harware arch */
|
|
||||||
#if defined(__LITTLE_ENDIAN__)
|
|
||||||
#if !defined( PA_LITTLE_ENDIAN )
|
|
||||||
#define PA_LITTLE_ENDIAN
|
|
||||||
#endif
|
|
||||||
#if defined( PA_BIG_ENDIAN )
|
|
||||||
#undef PA_BIG_ENDIAN
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#if !defined( PA_BIG_ENDIAN )
|
|
||||||
#define PA_BIG_ENDIAN
|
|
||||||
#endif
|
|
||||||
#if defined( PA_LITTLE_ENDIAN )
|
|
||||||
#undef PA_LITTLE_ENDIAN
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
/* this is not an apple, so first check the existing defines, and, failing that,
|
|
||||||
detect well-known architechtures. */
|
|
||||||
|
|
||||||
#if defined(PA_LITTLE_ENDIAN) || defined(PA_BIG_ENDIAN)
|
|
||||||
/* endianness define has been set externally, such as by autoconf */
|
|
||||||
|
|
||||||
#if defined(PA_LITTLE_ENDIAN) && defined(PA_BIG_ENDIAN)
|
|
||||||
#error both PA_LITTLE_ENDIAN and PA_BIG_ENDIAN have been defined externally to pa_endianness.h - only one endianness at a time please
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
/* endianness define has not been set externally */
|
|
||||||
|
|
||||||
/* set PA_LITTLE_ENDIAN or PA_BIG_ENDIAN by testing well known platform specific defines */
|
|
||||||
|
|
||||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(LITTLE_ENDIAN) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__)
|
|
||||||
#define PA_LITTLE_ENDIAN /* win32, assume intel byte order */
|
|
||||||
#else
|
|
||||||
#define PA_BIG_ENDIAN
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PA_LITTLE_ENDIAN) && !defined(PA_BIG_ENDIAN)
|
|
||||||
/*
|
|
||||||
If the following error is raised, you either need to modify the code above
|
|
||||||
to automatically determine the endianness from other symbols defined on your
|
|
||||||
platform, or define either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN externally.
|
|
||||||
*/
|
|
||||||
#error pa_endianness.h was unable to automatically determine the endianness of the target platform
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* PA_VALIDATE_ENDIANNESS compares the compile time and runtime endianness,
|
|
||||||
and raises an assertion if they don't match. <assert.h> must be included in
|
|
||||||
the context in which this macro is used.
|
|
||||||
*/
|
|
||||||
#if defined(NDEBUG)
|
|
||||||
#define PA_VALIDATE_ENDIANNESS
|
|
||||||
#else
|
|
||||||
#if defined(PA_LITTLE_ENDIAN)
|
|
||||||
#define PA_VALIDATE_ENDIANNESS \
|
|
||||||
{ \
|
|
||||||
const long nativeOne = 1; \
|
|
||||||
assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 1 ); \
|
|
||||||
}
|
|
||||||
#elif defined(PA_BIG_ENDIAN)
|
|
||||||
#define PA_VALIDATE_ENDIANNESS \
|
|
||||||
{ \
|
|
||||||
const long nativeOne = 1; \
|
|
||||||
assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 0 ); \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* PA_ENDIANNESS_H */
|
|
362
external/portaudio/include/pa_hostapi.h
vendored
362
external/portaudio/include/pa_hostapi.h
vendored
@ -1,362 +0,0 @@
|
|||||||
#ifndef PA_HOSTAPI_H
|
|
||||||
#define PA_HOSTAPI_H
|
|
||||||
/*
|
|
||||||
* $Id: pa_hostapi.h 1880 2012-12-04 18:39:48Z rbencina $
|
|
||||||
* Portable Audio I/O Library
|
|
||||||
* host api representation
|
|
||||||
*
|
|
||||||
* Based on the Open Source API proposed by Ross Bencina
|
|
||||||
* Copyright (c) 1999-2008 Ross Bencina, Phil Burk
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
|
|
||||||
@brief Interfaces and representation structures used by pa_front.c
|
|
||||||
to manage and communicate with host API implementations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "portaudio.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
The PA_NO_* host API macros are now deprecated in favor of PA_USE_* macros.
|
|
||||||
PA_USE_* indicates whether a particular host API will be initialized by PortAudio.
|
|
||||||
An undefined or 0 value indicates that the host API will not be used. A value of 1
|
|
||||||
indicates that the host API will be used. PA_USE_* macros should be left undefined
|
|
||||||
or defined to either 0 or 1.
|
|
||||||
|
|
||||||
The code below ensures that PA_USE_* macros are always defined and have value
|
|
||||||
0 or 1. Undefined symbols are defaulted to 0. Symbols that are neither 0 nor 1
|
|
||||||
are defaulted to 1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PA_USE_SKELETON
|
|
||||||
#define PA_USE_SKELETON 0
|
|
||||||
#elif (PA_USE_SKELETON != 0) && (PA_USE_SKELETON != 1)
|
|
||||||
#undef PA_USE_SKELETON
|
|
||||||
#define PA_USE_SKELETON 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PA_NO_ASIO) || defined(PA_NO_DS) || defined(PA_NO_WMME) || defined(PA_NO_WASAPI) || defined(PA_NO_WDMKS)
|
|
||||||
#error "Portaudio: PA_NO_<APINAME> is no longer supported, please remove definition and use PA_USE_<APINAME> instead"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_USE_ASIO
|
|
||||||
#define PA_USE_ASIO 0
|
|
||||||
#elif (PA_USE_ASIO != 0) && (PA_USE_ASIO != 1)
|
|
||||||
#undef PA_USE_ASIO
|
|
||||||
#define PA_USE_ASIO 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_USE_DS
|
|
||||||
#define PA_USE_DS 0
|
|
||||||
#elif (PA_USE_DS != 0) && (PA_USE_DS != 1)
|
|
||||||
#undef PA_USE_DS
|
|
||||||
#define PA_USE_DS 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_USE_WMME
|
|
||||||
#define PA_USE_WMME 0
|
|
||||||
#elif (PA_USE_WMME != 0) && (PA_USE_WMME != 1)
|
|
||||||
#undef PA_USE_WMME
|
|
||||||
#define PA_USE_WMME 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_USE_WASAPI
|
|
||||||
#define PA_USE_WASAPI 0
|
|
||||||
#elif (PA_USE_WASAPI != 0) && (PA_USE_WASAPI != 1)
|
|
||||||
#undef PA_USE_WASAPI
|
|
||||||
#define PA_USE_WASAPI 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_USE_WDMKS
|
|
||||||
#define PA_USE_WDMKS 0
|
|
||||||
#elif (PA_USE_WDMKS != 0) && (PA_USE_WDMKS != 1)
|
|
||||||
#undef PA_USE_WDMKS
|
|
||||||
#define PA_USE_WDMKS 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Set default values for Unix based APIs. */
|
|
||||||
#if defined(PA_NO_OSS) || defined(PA_NO_ALSA) || defined(PA_NO_JACK) || defined(PA_NO_COREAUDIO) || defined(PA_NO_SGI) || defined(PA_NO_ASIHPI)
|
|
||||||
#error "Portaudio: PA_NO_<APINAME> is no longer supported, please remove definition and use PA_USE_<APINAME> instead"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_USE_OSS
|
|
||||||
#define PA_USE_OSS 0
|
|
||||||
#elif (PA_USE_OSS != 0) && (PA_USE_OSS != 1)
|
|
||||||
#undef PA_USE_OSS
|
|
||||||
#define PA_USE_OSS 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_USE_ALSA
|
|
||||||
#define PA_USE_ALSA 0
|
|
||||||
#elif (PA_USE_ALSA != 0) && (PA_USE_ALSA != 1)
|
|
||||||
#undef PA_USE_ALSA
|
|
||||||
#define PA_USE_ALSA 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_USE_JACK
|
|
||||||
#define PA_USE_JACK 0
|
|
||||||
#elif (PA_USE_JACK != 0) && (PA_USE_JACK != 1)
|
|
||||||
#undef PA_USE_JACK
|
|
||||||
#define PA_USE_JACK 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_USE_SGI
|
|
||||||
#define PA_USE_SGI 0
|
|
||||||
#elif (PA_USE_SGI != 0) && (PA_USE_SGI != 1)
|
|
||||||
#undef PA_USE_SGI
|
|
||||||
#define PA_USE_SGI 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_USE_COREAUDIO
|
|
||||||
#define PA_USE_COREAUDIO 0
|
|
||||||
#elif (PA_USE_COREAUDIO != 0) && (PA_USE_COREAUDIO != 1)
|
|
||||||
#undef PA_USE_COREAUDIO
|
|
||||||
#define PA_USE_COREAUDIO 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_USE_ASIHPI
|
|
||||||
#define PA_USE_ASIHPI 0
|
|
||||||
#elif (PA_USE_ASIHPI != 0) && (PA_USE_ASIHPI != 1)
|
|
||||||
#undef PA_USE_ASIHPI
|
|
||||||
#define PA_USE_ASIHPI 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
/** **FOR THE USE OF pa_front.c ONLY**
|
|
||||||
Do NOT use fields in this structure, they my change at any time.
|
|
||||||
Use functions defined in pa_util.h if you think you need functionality
|
|
||||||
which can be derived from here.
|
|
||||||
*/
|
|
||||||
typedef struct PaUtilPrivatePaFrontHostApiInfo {
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long baseDeviceIndex;
|
|
||||||
}PaUtilPrivatePaFrontHostApiInfo;
|
|
||||||
|
|
||||||
|
|
||||||
/** The common header for all data structures whose pointers are passed through
|
|
||||||
the hostApiSpecificStreamInfo field of the PaStreamParameters structure.
|
|
||||||
Note that in order to keep the public PortAudio interface clean, this structure
|
|
||||||
is not used explicitly when declaring hostApiSpecificStreamInfo data structures.
|
|
||||||
However, some code in pa_front depends on the first 3 members being equivalent
|
|
||||||
with this structure.
|
|
||||||
@see PaStreamParameters
|
|
||||||
*/
|
|
||||||
typedef struct PaUtilHostApiSpecificStreamInfoHeader
|
|
||||||
{
|
|
||||||
unsigned long size; /**< size of whole structure including this header */
|
|
||||||
PaHostApiTypeId hostApiType; /**< host API for which this data is intended */
|
|
||||||
unsigned long version; /**< structure version */
|
|
||||||
} PaUtilHostApiSpecificStreamInfoHeader;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** A structure representing the interface to a host API. Contains both
|
|
||||||
concrete data and pointers to functions which implement the interface.
|
|
||||||
*/
|
|
||||||
typedef struct PaUtilHostApiRepresentation {
|
|
||||||
PaUtilPrivatePaFrontHostApiInfo privatePaFrontInfo;
|
|
||||||
|
|
||||||
/** The host api implementation should populate the info field. In the
|
|
||||||
case of info.defaultInputDevice and info.defaultOutputDevice the
|
|
||||||
values stored should be 0 based indices within the host api's own
|
|
||||||
device index range (0 to deviceCount). These values will be converted
|
|
||||||
to global device indices by pa_front after PaUtilHostApiInitializer()
|
|
||||||
returns.
|
|
||||||
*/
|
|
||||||
PaHostApiInfo info;
|
|
||||||
|
|
||||||
PaDeviceInfo** deviceInfos;
|
|
||||||
|
|
||||||
/**
|
|
||||||
(*Terminate)() is guaranteed to be called with a valid <hostApi>
|
|
||||||
parameter, which was previously returned from the same implementation's
|
|
||||||
initializer.
|
|
||||||
*/
|
|
||||||
void (*Terminate)( struct PaUtilHostApiRepresentation *hostApi );
|
|
||||||
|
|
||||||
/**
|
|
||||||
The inputParameters and outputParameters pointers should not be saved
|
|
||||||
as they will not remain valid after OpenStream is called.
|
|
||||||
|
|
||||||
|
|
||||||
The following guarantees are made about parameters to (*OpenStream)():
|
|
||||||
|
|
||||||
[NOTE: the following list up to *END PA FRONT VALIDATIONS* should be
|
|
||||||
kept in sync with the one for ValidateOpenStreamParameters and
|
|
||||||
Pa_OpenStream in pa_front.c]
|
|
||||||
|
|
||||||
PaHostApiRepresentation *hostApi
|
|
||||||
- is valid for this implementation
|
|
||||||
|
|
||||||
PaStream** stream
|
|
||||||
- is non-null
|
|
||||||
|
|
||||||
- at least one of inputParameters & outputParmeters is valid (not NULL)
|
|
||||||
|
|
||||||
- if inputParameters & outputParmeters are both valid, that
|
|
||||||
inputParameters->device & outputParmeters->device both use the same host api
|
|
||||||
|
|
||||||
PaDeviceIndex inputParameters->device
|
|
||||||
- is within range (0 to Pa_CountDevices-1) Or:
|
|
||||||
- is paUseHostApiSpecificDeviceSpecification and
|
|
||||||
inputParameters->hostApiSpecificStreamInfo is non-NULL and refers
|
|
||||||
to a valid host api
|
|
||||||
|
|
||||||
int inputParameters->numChannels
|
|
||||||
- if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, numInputChannels is > 0
|
|
||||||
- upper bound is NOT validated against device capabilities
|
|
||||||
|
|
||||||
PaSampleFormat inputParameters->sampleFormat
|
|
||||||
- is one of the sample formats defined in portaudio.h
|
|
||||||
|
|
||||||
void *inputParameters->hostApiSpecificStreamInfo
|
|
||||||
- if supplied its hostApi field matches the input device's host Api
|
|
||||||
|
|
||||||
PaDeviceIndex outputParmeters->device
|
|
||||||
- is within range (0 to Pa_CountDevices-1)
|
|
||||||
|
|
||||||
int outputParmeters->numChannels
|
|
||||||
- if inputDevice is valid, numInputChannels is > 0
|
|
||||||
- upper bound is NOT validated against device capabilities
|
|
||||||
|
|
||||||
PaSampleFormat outputParmeters->sampleFormat
|
|
||||||
- is one of the sample formats defined in portaudio.h
|
|
||||||
|
|
||||||
void *outputParmeters->hostApiSpecificStreamInfo
|
|
||||||
- if supplied its hostApi field matches the output device's host Api
|
|
||||||
|
|
||||||
double sampleRate
|
|
||||||
- is not an 'absurd' rate (less than 1000. or greater than 384000.)
|
|
||||||
- sampleRate is NOT validated against device capabilities
|
|
||||||
|
|
||||||
PaStreamFlags streamFlags
|
|
||||||
- unused platform neutral flags are zero
|
|
||||||
- paNeverDropInput is only used for full-duplex callback streams
|
|
||||||
with variable buffer size (paFramesPerBufferUnspecified)
|
|
||||||
|
|
||||||
[*END PA FRONT VALIDATIONS*]
|
|
||||||
|
|
||||||
|
|
||||||
The following validations MUST be performed by (*OpenStream)():
|
|
||||||
|
|
||||||
- check that input device can support numInputChannels
|
|
||||||
|
|
||||||
- check that input device can support inputSampleFormat, or that
|
|
||||||
we have the capability to convert from outputSampleFormat to
|
|
||||||
a native format
|
|
||||||
|
|
||||||
- if inputStreamInfo is supplied, validate its contents,
|
|
||||||
or return an error if no inputStreamInfo is expected
|
|
||||||
|
|
||||||
- check that output device can support numOutputChannels
|
|
||||||
|
|
||||||
- check that output device can support outputSampleFormat, or that
|
|
||||||
we have the capability to convert from outputSampleFormat to
|
|
||||||
a native format
|
|
||||||
|
|
||||||
- if outputStreamInfo is supplied, validate its contents,
|
|
||||||
or return an error if no outputStreamInfo is expected
|
|
||||||
|
|
||||||
- if a full duplex stream is requested, check that the combination
|
|
||||||
of input and output parameters is supported
|
|
||||||
|
|
||||||
- check that the device supports sampleRate
|
|
||||||
|
|
||||||
- alter sampleRate to a close allowable rate if necessary
|
|
||||||
|
|
||||||
- validate inputLatency and outputLatency
|
|
||||||
|
|
||||||
- validate any platform specific flags, if flags are supplied they
|
|
||||||
must be valid.
|
|
||||||
*/
|
|
||||||
PaError (*OpenStream)( struct PaUtilHostApiRepresentation *hostApi,
|
|
||||||
PaStream** stream,
|
|
||||||
const PaStreamParameters *inputParameters,
|
|
||||||
const PaStreamParameters *outputParameters,
|
|
||||||
double sampleRate,
|
|
||||||
unsigned long framesPerCallback,
|
|
||||||
PaStreamFlags streamFlags,
|
|
||||||
PaStreamCallback *streamCallback,
|
|
||||||
void *userData );
|
|
||||||
|
|
||||||
|
|
||||||
PaError (*IsFormatSupported)( struct PaUtilHostApiRepresentation *hostApi,
|
|
||||||
const PaStreamParameters *inputParameters,
|
|
||||||
const PaStreamParameters *outputParameters,
|
|
||||||
double sampleRate );
|
|
||||||
} PaUtilHostApiRepresentation;
|
|
||||||
|
|
||||||
|
|
||||||
/** Prototype for the initialization function which must be implemented by every
|
|
||||||
host API.
|
|
||||||
|
|
||||||
This function should only return an error other than paNoError if it encounters
|
|
||||||
an unexpected and fatal error (memory allocation error for example). In general,
|
|
||||||
there may be conditions under which it returns a NULL interface pointer and also
|
|
||||||
returns paNoError. For example, if the ASIO implementation detects that ASIO is
|
|
||||||
not installed, it should return a NULL interface, and paNoError.
|
|
||||||
|
|
||||||
@see paHostApiInitializers
|
|
||||||
*/
|
|
||||||
typedef PaError PaUtilHostApiInitializer( PaUtilHostApiRepresentation**, PaHostApiIndex );
|
|
||||||
|
|
||||||
|
|
||||||
/** paHostApiInitializers is a NULL-terminated array of host API initialization
|
|
||||||
functions. These functions are called by pa_front.c to initialize the host APIs
|
|
||||||
when the client calls Pa_Initialize().
|
|
||||||
|
|
||||||
The initialization functions are invoked in order.
|
|
||||||
|
|
||||||
The first successfully initialized host API that has a default input *or* output
|
|
||||||
device is used as the default PortAudio host API. This is based on the logic that
|
|
||||||
there is only one default host API, and it must contain the default input and output
|
|
||||||
devices (if defined).
|
|
||||||
|
|
||||||
There is a platform specific file that defines paHostApiInitializers for that
|
|
||||||
platform, pa_win/pa_win_hostapis.c contains the Win32 definitions for example.
|
|
||||||
*/
|
|
||||||
extern PaUtilHostApiInitializer *paHostApiInitializers[];
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* PA_HOSTAPI_H */
|
|
77
external/portaudio/include/pa_jack.h
vendored
77
external/portaudio/include/pa_jack.h
vendored
@ -1,77 +0,0 @@
|
|||||||
#ifndef PA_JACK_H
|
|
||||||
#define PA_JACK_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* $Id:
|
|
||||||
* PortAudio Portable Real-Time Audio Library
|
|
||||||
* JACK-specific extensions
|
|
||||||
*
|
|
||||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
* @ingroup public_header
|
|
||||||
* @brief JACK-specific PortAudio API extension header file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "portaudio.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Set the JACK client name.
|
|
||||||
*
|
|
||||||
* During Pa_Initialize, When PA JACK connects as a client of the JACK server, it requests a certain
|
|
||||||
* name, which is for instance prepended to port names. By default this name is "PortAudio". The
|
|
||||||
* JACK server may append a suffix to the client name, in order to avoid clashes among clients that
|
|
||||||
* try to connect with the same name (e.g., different PA JACK clients).
|
|
||||||
*
|
|
||||||
* This function must be called before Pa_Initialize, otherwise it won't have any effect. Note that
|
|
||||||
* the string is not copied, but instead referenced directly, so it must not be freed for as long as
|
|
||||||
* PA might need it.
|
|
||||||
* @sa PaJack_GetClientName
|
|
||||||
*/
|
|
||||||
PaError PaJack_SetClientName( const char* name );
|
|
||||||
|
|
||||||
/** Get the JACK client name used by PA JACK.
|
|
||||||
*
|
|
||||||
* The caller is responsible for freeing the returned pointer.
|
|
||||||
*/
|
|
||||||
PaError PaJack_GetClientName(const char** clientName);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
107
external/portaudio/include/pa_linux_alsa.h
vendored
107
external/portaudio/include/pa_linux_alsa.h
vendored
@ -1,107 +0,0 @@
|
|||||||
#ifndef PA_LINUX_ALSA_H
|
|
||||||
#define PA_LINUX_ALSA_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* $Id: pa_linux_alsa.h 1597 2011-02-11 00:15:51Z dmitrykos $
|
|
||||||
* PortAudio Portable Real-Time Audio Library
|
|
||||||
* ALSA-specific extensions
|
|
||||||
*
|
|
||||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
* @ingroup public_header
|
|
||||||
* @brief ALSA-specific PortAudio API extension header file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "portaudio.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct PaAlsaStreamInfo
|
|
||||||
{
|
|
||||||
unsigned long size;
|
|
||||||
PaHostApiTypeId hostApiType;
|
|
||||||
unsigned long version;
|
|
||||||
|
|
||||||
const char *deviceString;
|
|
||||||
}
|
|
||||||
PaAlsaStreamInfo;
|
|
||||||
|
|
||||||
/** Initialize host API specific structure, call this before setting relevant attributes. */
|
|
||||||
void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info );
|
|
||||||
|
|
||||||
/** Instruct whether to enable real-time priority when starting the audio thread.
|
|
||||||
*
|
|
||||||
* If this is turned on by the stream is started, the audio callback thread will be created
|
|
||||||
* with the FIFO scheduling policy, which is suitable for realtime operation.
|
|
||||||
**/
|
|
||||||
void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable );
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void PaAlsa_EnableWatchdog( PaStream *s, int enable );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Get the ALSA-lib card index of this stream's input device. */
|
|
||||||
PaError PaAlsa_GetStreamInputCard( PaStream *s, int *card );
|
|
||||||
|
|
||||||
/** Get the ALSA-lib card index of this stream's output device. */
|
|
||||||
PaError PaAlsa_GetStreamOutputCard( PaStream *s, int *card );
|
|
||||||
|
|
||||||
/** Set the number of periods (buffer fragments) to configure devices with.
|
|
||||||
*
|
|
||||||
* By default the number of periods is 4, this is the lowest number of periods that works well on
|
|
||||||
* the author's soundcard.
|
|
||||||
* @param numPeriods The number of periods.
|
|
||||||
*/
|
|
||||||
PaError PaAlsa_SetNumPeriods( int numPeriods );
|
|
||||||
|
|
||||||
/** Set the maximum number of times to retry opening busy device (sleeping for a
|
|
||||||
* short interval inbetween).
|
|
||||||
*/
|
|
||||||
PaError PaAlsa_SetRetriesBusy( int retries );
|
|
||||||
|
|
||||||
/** Set the path and name of ALSA library file if PortAudio is configured to load it dynamically (see
|
|
||||||
* PA_ALSA_DYNAMIC). This setting will overwrite the default name set by PA_ALSA_PATHNAME define.
|
|
||||||
* @param pathName Full path with filename. Only filename can be used, but dlopen() will lookup default
|
|
||||||
* searchable directories (/usr/lib;/usr/local/lib) then.
|
|
||||||
*/
|
|
||||||
void PaAlsa_SetLibraryPathName( const char *pathName );
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
191
external/portaudio/include/pa_mac_core.h
vendored
191
external/portaudio/include/pa_mac_core.h
vendored
@ -1,191 +0,0 @@
|
|||||||
#ifndef PA_MAC_CORE_H
|
|
||||||
#define PA_MAC_CORE_H
|
|
||||||
/*
|
|
||||||
* PortAudio Portable Real-Time Audio Library
|
|
||||||
* Macintosh Core Audio specific extensions
|
|
||||||
* portaudio.h should be included before this file.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2005-2006 Bjorn Roche
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
* @ingroup public_header
|
|
||||||
* @brief CoreAudio-specific PortAudio API extension header file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "portaudio.h"
|
|
||||||
|
|
||||||
#include <AudioUnit/AudioUnit.h>
|
|
||||||
#include <AudioToolbox/AudioToolbox.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A pointer to a paMacCoreStreamInfo may be passed as
|
|
||||||
* the hostApiSpecificStreamInfo in the PaStreamParameters struct
|
|
||||||
* when opening a stream or querying the format. Use NULL, for the
|
|
||||||
* defaults. Note that for duplex streams, flags for input and output
|
|
||||||
* should be the same or behaviour is undefined.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned long size; /**size of whole structure including this header */
|
|
||||||
PaHostApiTypeId hostApiType; /**host API for which this data is intended */
|
|
||||||
unsigned long version; /**structure version */
|
|
||||||
unsigned long flags; /** flags to modify behaviour */
|
|
||||||
SInt32 const * channelMap; /** Channel map for HAL channel mapping , if not needed, use NULL;*/
|
|
||||||
unsigned long channelMapSize; /** Channel map size for HAL channel mapping , if not needed, use 0;*/
|
|
||||||
} PaMacCoreStreamInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/** Use this function to initialize a paMacCoreStreamInfo struct
|
|
||||||
* using the requested flags. Note that channel mapping is turned
|
|
||||||
* off after a call to this function.
|
|
||||||
* @param data The datastructure to initialize
|
|
||||||
* @param flags The flags to initialize the datastructure with.
|
|
||||||
*/
|
|
||||||
void PaMacCore_SetupStreamInfo( PaMacCoreStreamInfo *data, unsigned long flags );
|
|
||||||
|
|
||||||
/** call this after pa_SetupMacCoreStreamInfo to use channel mapping as described in notes.txt.
|
|
||||||
* @param data The stream info structure to assign a channel mapping to
|
|
||||||
* @param channelMap The channel map array, as described in notes.txt. This array pointer will be used directly (ie the underlying data will not be copied), so the caller should not free the array until after the stream has been opened.
|
|
||||||
* @param channelMapSize The size of the channel map array.
|
|
||||||
*/
|
|
||||||
void PaMacCore_SetupChannelMap( PaMacCoreStreamInfo *data, const SInt32 * const channelMap, unsigned long channelMapSize );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the AudioDeviceID of the input device assigned to an open stream
|
|
||||||
*
|
|
||||||
* @param s The stream to query.
|
|
||||||
*
|
|
||||||
* @return A valid AudioDeviceID, or NULL if an error occurred.
|
|
||||||
*/
|
|
||||||
AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the AudioDeviceID of the output device assigned to an open stream
|
|
||||||
*
|
|
||||||
* @param s The stream to query.
|
|
||||||
*
|
|
||||||
* @return A valid AudioDeviceID, or NULL if an error occurred.
|
|
||||||
*/
|
|
||||||
AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a statically allocated string with the device's name
|
|
||||||
* for the given channel. NULL will be returned on failure.
|
|
||||||
*
|
|
||||||
* This function's implemenation is not complete!
|
|
||||||
*
|
|
||||||
* @param device The PortAudio device index.
|
|
||||||
* @param channel The channel number who's name is requested.
|
|
||||||
* @return a statically allocated string with the name of the device.
|
|
||||||
* Because this string is statically allocated, it must be
|
|
||||||
* coppied if it is to be saved and used by the user after
|
|
||||||
* another call to this function.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input );
|
|
||||||
|
|
||||||
|
|
||||||
/** Retrieve the range of legal native buffer sizes for the specificed device, in sample frames.
|
|
||||||
|
|
||||||
@param device The global index of the PortAudio device about which the query is being made.
|
|
||||||
@param minBufferSizeFrames A pointer to the location which will receive the minimum buffer size value.
|
|
||||||
@param maxBufferSizeFrames A pointer to the location which will receive the maximum buffer size value.
|
|
||||||
|
|
||||||
@see kAudioDevicePropertyBufferFrameSizeRange in the CoreAudio SDK.
|
|
||||||
*/
|
|
||||||
PaError PaMacCore_GetBufferSizeRange( PaDeviceIndex device,
|
|
||||||
long *minBufferSizeFrames, long *maxBufferSizeFrames );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flags
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The following flags alter the behaviour of PA on the mac platform.
|
|
||||||
* they can be ORed together. These should work both for opening and
|
|
||||||
* checking a device.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Allows PortAudio to change things like the device's frame size,
|
|
||||||
* which allows for much lower latency, but might disrupt the device
|
|
||||||
* if other programs are using it, even when you are just Querying
|
|
||||||
* the device. */
|
|
||||||
#define paMacCoreChangeDeviceParameters (0x01)
|
|
||||||
|
|
||||||
/** In combination with the above flag,
|
|
||||||
* causes the stream opening to fail, unless the exact sample rates
|
|
||||||
* are supported by the device. */
|
|
||||||
#define paMacCoreFailIfConversionRequired (0x02)
|
|
||||||
|
|
||||||
/** These flags set the SR conversion quality, if required. The wierd ordering
|
|
||||||
* allows Maximum Quality to be the default.*/
|
|
||||||
#define paMacCoreConversionQualityMin (0x0100)
|
|
||||||
#define paMacCoreConversionQualityMedium (0x0200)
|
|
||||||
#define paMacCoreConversionQualityLow (0x0300)
|
|
||||||
#define paMacCoreConversionQualityHigh (0x0400)
|
|
||||||
#define paMacCoreConversionQualityMax (0x0000)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Here are some "preset" combinations of flags (above) to get to some
|
|
||||||
* common configurations. THIS IS OVERKILL, but if more flags are added
|
|
||||||
* it won't be.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**This is the default setting: do as much sample rate conversion as possible
|
|
||||||
* and as little mucking with the device as possible. */
|
|
||||||
#define paMacCorePlayNice (0x00)
|
|
||||||
/**This setting is tuned for pro audio apps. It allows SR conversion on input
|
|
||||||
and output, but it tries to set the appropriate SR on the device.*/
|
|
||||||
#define paMacCorePro (0x01)
|
|
||||||
/**This is a setting to minimize CPU usage and still play nice.*/
|
|
||||||
#define paMacCoreMinimizeCPUButPlayNice (0x0100)
|
|
||||||
/**This is a setting to minimize CPU usage, even if that means interrupting the device. */
|
|
||||||
#define paMacCoreMinimizeCPU (0x0101)
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /** __cplusplus */
|
|
||||||
|
|
||||||
#endif /** PA_MAC_CORE_H */
|
|
128
external/portaudio/include/pa_memorybarrier.h
vendored
128
external/portaudio/include/pa_memorybarrier.h
vendored
@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id: pa_memorybarrier.h 1240 2007-07-17 13:05:07Z bjornroche $
|
|
||||||
* Portable Audio I/O Library
|
|
||||||
* Memory barrier utilities
|
|
||||||
*
|
|
||||||
* Author: Bjorn Roche, XO Audio, LLC
|
|
||||||
*
|
|
||||||
* This program uses the PortAudio Portable Audio Library.
|
|
||||||
* For more information see: http://www.portaudio.com
|
|
||||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
@file pa_memorybarrier.h
|
|
||||||
@ingroup common_src
|
|
||||||
*/
|
|
||||||
|
|
||||||
/****************
|
|
||||||
* Some memory barrier primitives based on the system.
|
|
||||||
* right now only OS X, FreeBSD, and Linux are supported. In addition to providing
|
|
||||||
* memory barriers, these functions should ensure that data cached in registers
|
|
||||||
* is written out to cache where it can be snooped by other CPUs. (ie, the volatile
|
|
||||||
* keyword should not be required)
|
|
||||||
*
|
|
||||||
* the primitives that must be defined are:
|
|
||||||
*
|
|
||||||
* PaUtil_FullMemoryBarrier()
|
|
||||||
* PaUtil_ReadMemoryBarrier()
|
|
||||||
* PaUtil_WriteMemoryBarrier()
|
|
||||||
*
|
|
||||||
****************/
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
# include <libkern/OSAtomic.h>
|
|
||||||
/* Here are the memory barrier functions. Mac OS X only provides
|
|
||||||
full memory barriers, so the three types of barriers are the same,
|
|
||||||
however, these barriers are superior to compiler-based ones. */
|
|
||||||
# define PaUtil_FullMemoryBarrier() OSMemoryBarrier()
|
|
||||||
# define PaUtil_ReadMemoryBarrier() OSMemoryBarrier()
|
|
||||||
# define PaUtil_WriteMemoryBarrier() OSMemoryBarrier()
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
/* GCC >= 4.1 has built-in intrinsics. We'll use those */
|
|
||||||
# if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
|
|
||||||
# define PaUtil_FullMemoryBarrier() __sync_synchronize()
|
|
||||||
# define PaUtil_ReadMemoryBarrier() __sync_synchronize()
|
|
||||||
# define PaUtil_WriteMemoryBarrier() __sync_synchronize()
|
|
||||||
/* as a fallback, GCC understands volatile asm and "memory" to mean it
|
|
||||||
* should not reorder memory read/writes */
|
|
||||||
/* Note that it is not clear that any compiler actually defines __PPC__,
|
|
||||||
* it can probably removed safely. */
|
|
||||||
# elif defined( __ppc__ ) || defined( __powerpc__) || defined( __PPC__ )
|
|
||||||
# define PaUtil_FullMemoryBarrier() asm volatile("sync":::"memory")
|
|
||||||
# define PaUtil_ReadMemoryBarrier() asm volatile("sync":::"memory")
|
|
||||||
# define PaUtil_WriteMemoryBarrier() asm volatile("sync":::"memory")
|
|
||||||
# elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || \
|
|
||||||
defined( __i686__ ) || defined( __x86_64__ )
|
|
||||||
# define PaUtil_FullMemoryBarrier() asm volatile("mfence":::"memory")
|
|
||||||
# define PaUtil_ReadMemoryBarrier() asm volatile("lfence":::"memory")
|
|
||||||
# define PaUtil_WriteMemoryBarrier() asm volatile("sfence":::"memory")
|
|
||||||
# else
|
|
||||||
# ifdef ALLOW_SMP_DANGERS
|
|
||||||
# warning Memory barriers not defined on this system or system unknown
|
|
||||||
# warning For SMP safety, you should fix this.
|
|
||||||
# define PaUtil_FullMemoryBarrier()
|
|
||||||
# define PaUtil_ReadMemoryBarrier()
|
|
||||||
# define PaUtil_WriteMemoryBarrier()
|
|
||||||
# else
|
|
||||||
# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#elif (_MSC_VER >= 1400) && !defined(_WIN32_WCE)
|
|
||||||
# include <intrin.h>
|
|
||||||
# pragma intrinsic(_ReadWriteBarrier)
|
|
||||||
# pragma intrinsic(_ReadBarrier)
|
|
||||||
# pragma intrinsic(_WriteBarrier)
|
|
||||||
/* note that MSVC intrinsics _ReadWriteBarrier(), _ReadBarrier(), _WriteBarrier() are just compiler barriers *not* memory barriers */
|
|
||||||
# define PaUtil_FullMemoryBarrier() _ReadWriteBarrier()
|
|
||||||
# define PaUtil_ReadMemoryBarrier() _ReadBarrier()
|
|
||||||
# define PaUtil_WriteMemoryBarrier() _WriteBarrier()
|
|
||||||
#elif defined(_WIN32_WCE)
|
|
||||||
# define PaUtil_FullMemoryBarrier()
|
|
||||||
# define PaUtil_ReadMemoryBarrier()
|
|
||||||
# define PaUtil_WriteMemoryBarrier()
|
|
||||||
#elif defined(_MSC_VER) || defined(__BORLANDC__)
|
|
||||||
# define PaUtil_FullMemoryBarrier() _asm { lock add [esp], 0 }
|
|
||||||
# define PaUtil_ReadMemoryBarrier() _asm { lock add [esp], 0 }
|
|
||||||
# define PaUtil_WriteMemoryBarrier() _asm { lock add [esp], 0 }
|
|
||||||
#else
|
|
||||||
# ifdef ALLOW_SMP_DANGERS
|
|
||||||
# warning Memory barriers not defined on this system or system unknown
|
|
||||||
# warning For SMP safety, you should fix this.
|
|
||||||
# define PaUtil_FullMemoryBarrier()
|
|
||||||
# define PaUtil_ReadMemoryBarrier()
|
|
||||||
# define PaUtil_WriteMemoryBarrier()
|
|
||||||
# else
|
|
||||||
# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
|
|
||||||
# endif
|
|
||||||
#endif
|
|
754
external/portaudio/include/pa_process.h
vendored
754
external/portaudio/include/pa_process.h
vendored
@ -1,754 +0,0 @@
|
|||||||
#ifndef PA_PROCESS_H
|
|
||||||
#define PA_PROCESS_H
|
|
||||||
/*
|
|
||||||
* $Id: pa_process.h 1668 2011-05-02 17:07:11Z rossb $
|
|
||||||
* Portable Audio I/O Library callback buffer processing adapters
|
|
||||||
*
|
|
||||||
* Based on the Open Source API proposed by Ross Bencina
|
|
||||||
* Copyright (c) 1999-2002 Phil Burk, Ross Bencina
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
|
|
||||||
@brief Buffer Processor prototypes. A Buffer Processor performs buffer length
|
|
||||||
adaption, coordinates sample format conversion, and interleaves/deinterleaves
|
|
||||||
channels.
|
|
||||||
|
|
||||||
<h3>Overview</h3>
|
|
||||||
|
|
||||||
The "Buffer Processor" (PaUtilBufferProcessor) manages conversion of audio
|
|
||||||
data from host buffers to user buffers and back again. Where required, the
|
|
||||||
buffer processor takes care of converting between host and user sample formats,
|
|
||||||
interleaving and deinterleaving multichannel buffers, and adapting between host
|
|
||||||
and user buffers with different lengths. The buffer processor may be used with
|
|
||||||
full and half duplex streams, for both callback streams and blocking read/write
|
|
||||||
streams.
|
|
||||||
|
|
||||||
One of the important capabilities provided by the buffer processor is
|
|
||||||
the ability to adapt between user and host buffer sizes of different lengths
|
|
||||||
with minimum latency. Although this task is relatively easy to perform when
|
|
||||||
the host buffer size is an integer multiple of the user buffer size, the
|
|
||||||
problem is more complicated when this is not the case - especially for
|
|
||||||
full-duplex callback streams. Where necessary the adaption is implemented by
|
|
||||||
internally buffering some input and/or output data. The buffer adation
|
|
||||||
algorithm used by the buffer processor was originally implemented by
|
|
||||||
Stephan Letz for the ASIO version of PortAudio, and is described in his
|
|
||||||
Callback_adaption_.pdf which is included in the distribution.
|
|
||||||
|
|
||||||
The buffer processor performs sample conversion using the functions provided
|
|
||||||
by pa_converters.c.
|
|
||||||
|
|
||||||
The following sections provide an overview of how to use the buffer processor.
|
|
||||||
Interested readers are advised to consult the host API implementations for
|
|
||||||
examples of buffer processor usage.
|
|
||||||
|
|
||||||
|
|
||||||
<h4>Initialization, resetting and termination</h4>
|
|
||||||
|
|
||||||
When a stream is opened, the buffer processor should be initialized using
|
|
||||||
PaUtil_InitializeBufferProcessor. This function initializes internal state
|
|
||||||
and allocates temporary buffers as neccesary according to the supplied
|
|
||||||
configuration parameters. Some of the parameters correspond to those requested
|
|
||||||
by the user in their call to Pa_OpenStream(), others reflect the requirements
|
|
||||||
of the host API implementation - they indicate host buffer sizes, formats,
|
|
||||||
and the type of buffering which the Host API uses. The buffer processor should
|
|
||||||
be initialized for callback streams and blocking read/write streams.
|
|
||||||
|
|
||||||
Call PaUtil_ResetBufferProcessor to clear any sample data which is present
|
|
||||||
in the buffer processor before starting to use it (for example when
|
|
||||||
Pa_StartStream is called).
|
|
||||||
|
|
||||||
When the buffer processor is no longer used call
|
|
||||||
PaUtil_TerminateBufferProcessor.
|
|
||||||
|
|
||||||
|
|
||||||
<h4>Using the buffer processor for a callback stream</h4>
|
|
||||||
|
|
||||||
The buffer processor's role in a callback stream is to take host input buffers
|
|
||||||
process them with the stream callback, and fill host output buffers. For a
|
|
||||||
full duplex stream, the buffer processor handles input and output simultaneously
|
|
||||||
due to the requirements of the minimum-latency buffer adation algorithm.
|
|
||||||
|
|
||||||
When a host buffer becomes available, the implementation should call
|
|
||||||
the buffer processor to process the buffer. The buffer processor calls the
|
|
||||||
stream callback to consume and/or produce audio data as necessary. The buffer
|
|
||||||
processor will convert sample formats, interleave/deinterleave channels,
|
|
||||||
and slice or chunk the data to the appropriate buffer lengths according to
|
|
||||||
the requirements of the stream callback and the host API.
|
|
||||||
|
|
||||||
To process a host buffer (or a pair of host buffers for a full-duplex stream)
|
|
||||||
use the following calling sequence:
|
|
||||||
|
|
||||||
-# Call PaUtil_BeginBufferProcessing
|
|
||||||
-# For a stream which takes input:
|
|
||||||
- Call PaUtil_SetInputFrameCount with the number of frames in the host input
|
|
||||||
buffer.
|
|
||||||
- Call one of the following functions one or more times to tell the
|
|
||||||
buffer processor about the host input buffer(s): PaUtil_SetInputChannel,
|
|
||||||
PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel.
|
|
||||||
Which function you call will depend on whether the host buffer(s) are
|
|
||||||
interleaved or not.
|
|
||||||
- If the available host data is split accross two buffers (for example a
|
|
||||||
data range at the end of a circular buffer and another range at the
|
|
||||||
beginning of the circular buffer), also call
|
|
||||||
PaUtil_Set2ndInputFrameCount, PaUtil_Set2ndInputChannel,
|
|
||||||
PaUtil_Set2ndInterleavedInputChannels,
|
|
||||||
PaUtil_Set2ndNonInterleavedInputChannel as necessary to tell the buffer
|
|
||||||
processor about the second buffer.
|
|
||||||
-# For a stream which generates output:
|
|
||||||
- Call PaUtil_SetOutputFrameCount with the number of frames in the host
|
|
||||||
output buffer.
|
|
||||||
- Call one of the following functions one or more times to tell the
|
|
||||||
buffer processor about the host output buffer(s): PaUtil_SetOutputChannel,
|
|
||||||
PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel.
|
|
||||||
Which function you call will depend on whether the host buffer(s) are
|
|
||||||
interleaved or not.
|
|
||||||
- If the available host output buffer space is split accross two buffers
|
|
||||||
(for example a data range at the end of a circular buffer and another
|
|
||||||
range at the beginning of the circular buffer), call
|
|
||||||
PaUtil_Set2ndOutputFrameCount, PaUtil_Set2ndOutputChannel,
|
|
||||||
PaUtil_Set2ndInterleavedOutputChannels,
|
|
||||||
PaUtil_Set2ndNonInterleavedOutputChannel as necessary to tell the buffer
|
|
||||||
processor about the second buffer.
|
|
||||||
-# Call PaUtil_EndBufferProcessing, this function performs the actual data
|
|
||||||
conversion and processing.
|
|
||||||
|
|
||||||
|
|
||||||
<h4>Using the buffer processor for a blocking read/write stream</h4>
|
|
||||||
|
|
||||||
Blocking read/write streams use the buffer processor to convert and copy user
|
|
||||||
output data to a host buffer, and to convert and copy host input data to
|
|
||||||
the user's buffer. The buffer processor does not perform any buffer adaption.
|
|
||||||
When using the buffer processor in a blocking read/write stream the input and
|
|
||||||
output conversion are performed separately by the PaUtil_CopyInput and
|
|
||||||
PaUtil_CopyOutput functions.
|
|
||||||
|
|
||||||
To copy data from a host input buffer to the buffer(s) which the user supplies
|
|
||||||
to Pa_ReadStream, use the following calling sequence.
|
|
||||||
|
|
||||||
- Repeat the following three steps until the user buffer(s) have been filled
|
|
||||||
with samples from the host input buffers:
|
|
||||||
-# Call PaUtil_SetInputFrameCount with the number of frames in the host
|
|
||||||
input buffer.
|
|
||||||
-# Call one of the following functions one or more times to tell the
|
|
||||||
buffer processor about the host input buffer(s): PaUtil_SetInputChannel,
|
|
||||||
PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel.
|
|
||||||
Which function you call will depend on whether the host buffer(s) are
|
|
||||||
interleaved or not.
|
|
||||||
-# Call PaUtil_CopyInput with the user buffer pointer (or a copy of the
|
|
||||||
array of buffer pointers for a non-interleaved stream) passed to
|
|
||||||
Pa_ReadStream, along with the number of frames in the user buffer(s).
|
|
||||||
Be careful to pass a <i>copy</i> of the user buffer pointers to
|
|
||||||
PaUtil_CopyInput because PaUtil_CopyInput advances the pointers to
|
|
||||||
the start of the next region to copy.
|
|
||||||
- PaUtil_CopyInput will not copy more data than is available in the
|
|
||||||
host buffer(s), so the above steps need to be repeated until the user
|
|
||||||
buffer(s) are full.
|
|
||||||
|
|
||||||
|
|
||||||
To copy data to the host output buffer from the user buffers(s) supplied
|
|
||||||
to Pa_WriteStream use the following calling sequence.
|
|
||||||
|
|
||||||
- Repeat the following three steps until all frames from the user buffer(s)
|
|
||||||
have been copied to the host API:
|
|
||||||
-# Call PaUtil_SetOutputFrameCount with the number of frames in the host
|
|
||||||
output buffer.
|
|
||||||
-# Call one of the following functions one or more times to tell the
|
|
||||||
buffer processor about the host output buffer(s): PaUtil_SetOutputChannel,
|
|
||||||
PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel.
|
|
||||||
Which function you call will depend on whether the host buffer(s) are
|
|
||||||
interleaved or not.
|
|
||||||
-# Call PaUtil_CopyOutput with the user buffer pointer (or a copy of the
|
|
||||||
array of buffer pointers for a non-interleaved stream) passed to
|
|
||||||
Pa_WriteStream, along with the number of frames in the user buffer(s).
|
|
||||||
Be careful to pass a <i>copy</i> of the user buffer pointers to
|
|
||||||
PaUtil_CopyOutput because PaUtil_CopyOutput advances the pointers to
|
|
||||||
the start of the next region to copy.
|
|
||||||
- PaUtil_CopyOutput will not copy more data than fits in the host buffer(s),
|
|
||||||
so the above steps need to be repeated until all user data is copied.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "portaudio.h"
|
|
||||||
#include "pa_converters.h"
|
|
||||||
#include "pa_dither.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
/** @brief Mode flag passed to PaUtil_InitializeBufferProcessor indicating the type
|
|
||||||
of buffering that the host API uses.
|
|
||||||
|
|
||||||
The mode used depends on whether the host API or the implementation manages
|
|
||||||
the buffers, and how these buffers are used (scatter gather, circular buffer).
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
/** The host buffer size is a fixed known size. */
|
|
||||||
paUtilFixedHostBufferSize,
|
|
||||||
|
|
||||||
/** The host buffer size may vary, but has a known maximum size. */
|
|
||||||
paUtilBoundedHostBufferSize,
|
|
||||||
|
|
||||||
/** Nothing is known about the host buffer size. */
|
|
||||||
paUtilUnknownHostBufferSize,
|
|
||||||
|
|
||||||
/** The host buffer size varies, and the client does not require the buffer
|
|
||||||
processor to consume all of the input and fill all of the output buffer. This
|
|
||||||
is useful when the implementation has access to the host API's circular buffer
|
|
||||||
and only needs to consume/fill some of it, not necessarily all of it, with each
|
|
||||||
call to the buffer processor. This is the only mode where
|
|
||||||
PaUtil_EndBufferProcessing() may not consume the whole buffer.
|
|
||||||
*/
|
|
||||||
paUtilVariableHostBufferSizePartialUsageAllowed
|
|
||||||
}PaUtilHostBufferSizeMode;
|
|
||||||
|
|
||||||
|
|
||||||
/** @brief An auxilliary data structure used internally by the buffer processor
|
|
||||||
to represent host input and output buffers. */
|
|
||||||
typedef struct PaUtilChannelDescriptor{
|
|
||||||
void *data;
|
|
||||||
unsigned int stride; /**< stride in samples, not bytes */
|
|
||||||
}PaUtilChannelDescriptor;
|
|
||||||
|
|
||||||
|
|
||||||
/** @brief The main buffer processor data structure.
|
|
||||||
|
|
||||||
Allocate one of these, initialize it with PaUtil_InitializeBufferProcessor
|
|
||||||
and terminate it with PaUtil_TerminateBufferProcessor.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
unsigned long framesPerUserBuffer;
|
|
||||||
unsigned long framesPerHostBuffer;
|
|
||||||
|
|
||||||
PaUtilHostBufferSizeMode hostBufferSizeMode;
|
|
||||||
int useNonAdaptingProcess;
|
|
||||||
int userOutputSampleFormatIsEqualToHost;
|
|
||||||
int userInputSampleFormatIsEqualToHost;
|
|
||||||
unsigned long framesPerTempBuffer;
|
|
||||||
|
|
||||||
unsigned int inputChannelCount;
|
|
||||||
unsigned int bytesPerHostInputSample;
|
|
||||||
unsigned int bytesPerUserInputSample;
|
|
||||||
int userInputIsInterleaved;
|
|
||||||
PaUtilConverter *inputConverter;
|
|
||||||
PaUtilZeroer *inputZeroer;
|
|
||||||
|
|
||||||
unsigned int outputChannelCount;
|
|
||||||
unsigned int bytesPerHostOutputSample;
|
|
||||||
unsigned int bytesPerUserOutputSample;
|
|
||||||
int userOutputIsInterleaved;
|
|
||||||
PaUtilConverter *outputConverter;
|
|
||||||
PaUtilZeroer *outputZeroer;
|
|
||||||
|
|
||||||
unsigned long initialFramesInTempInputBuffer;
|
|
||||||
unsigned long initialFramesInTempOutputBuffer;
|
|
||||||
|
|
||||||
void *tempInputBuffer; /**< used for slips, block adaption, and conversion. */
|
|
||||||
void **tempInputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user input */
|
|
||||||
unsigned long framesInTempInputBuffer; /**< frames remaining in input buffer from previous adaption iteration */
|
|
||||||
|
|
||||||
void *tempOutputBuffer; /**< used for slips, block adaption, and conversion. */
|
|
||||||
void **tempOutputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user output */
|
|
||||||
unsigned long framesInTempOutputBuffer; /**< frames remaining in input buffer from previous adaption iteration */
|
|
||||||
|
|
||||||
PaStreamCallbackTimeInfo *timeInfo;
|
|
||||||
|
|
||||||
PaStreamCallbackFlags callbackStatusFlags;
|
|
||||||
|
|
||||||
int hostInputIsInterleaved;
|
|
||||||
unsigned long hostInputFrameCount[2];
|
|
||||||
PaUtilChannelDescriptor *hostInputChannels[2]; /**< pointers to arrays of channel descriptors.
|
|
||||||
pointers are NULL for half-duplex output processing.
|
|
||||||
hostInputChannels[i].data is NULL when the caller
|
|
||||||
calls PaUtil_SetNoInput()
|
|
||||||
*/
|
|
||||||
int hostOutputIsInterleaved;
|
|
||||||
unsigned long hostOutputFrameCount[2];
|
|
||||||
PaUtilChannelDescriptor *hostOutputChannels[2]; /**< pointers to arrays of channel descriptors.
|
|
||||||
pointers are NULL for half-duplex input processing.
|
|
||||||
hostOutputChannels[i].data is NULL when the caller
|
|
||||||
calls PaUtil_SetNoOutput()
|
|
||||||
*/
|
|
||||||
|
|
||||||
PaUtilTriangularDitherGenerator ditherGenerator;
|
|
||||||
|
|
||||||
double samplePeriod;
|
|
||||||
|
|
||||||
PaStreamCallback *streamCallback;
|
|
||||||
void *userData;
|
|
||||||
} PaUtilBufferProcessor;
|
|
||||||
|
|
||||||
|
|
||||||
/** @name Initialization, termination, resetting and info */
|
|
||||||
/*@{*/
|
|
||||||
|
|
||||||
/** Initialize a buffer processor's representation stored in a
|
|
||||||
PaUtilBufferProcessor structure. Be sure to call
|
|
||||||
PaUtil_TerminateBufferProcessor after finishing with a buffer processor.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor structure to initialize.
|
|
||||||
|
|
||||||
@param inputChannelCount The number of input channels as passed to
|
|
||||||
Pa_OpenStream or 0 for an output-only stream.
|
|
||||||
|
|
||||||
@param userInputSampleFormat Format of user input samples, as passed to
|
|
||||||
Pa_OpenStream. This parameter is ignored for ouput-only streams.
|
|
||||||
|
|
||||||
@param hostInputSampleFormat Format of host input samples. This parameter is
|
|
||||||
ignored for output-only streams. See note about host buffer interleave below.
|
|
||||||
|
|
||||||
@param outputChannelCount The number of output channels as passed to
|
|
||||||
Pa_OpenStream or 0 for an input-only stream.
|
|
||||||
|
|
||||||
@param userOutputSampleFormat Format of user output samples, as passed to
|
|
||||||
Pa_OpenStream. This parameter is ignored for input-only streams.
|
|
||||||
|
|
||||||
@param hostOutputSampleFormat Format of host output samples. This parameter is
|
|
||||||
ignored for input-only streams. See note about host buffer interleave below.
|
|
||||||
|
|
||||||
@param sampleRate Sample rate of the stream. The more accurate this is the
|
|
||||||
better - it is used for updating time stamps when adapting buffers.
|
|
||||||
|
|
||||||
@param streamFlags Stream flags as passed to Pa_OpenStream, this parameter is
|
|
||||||
used for selecting special sample conversion options such as clipping and
|
|
||||||
dithering.
|
|
||||||
|
|
||||||
@param framesPerUserBuffer Number of frames per user buffer, as requested
|
|
||||||
by the framesPerBuffer parameter to Pa_OpenStream. This parameter may be
|
|
||||||
zero to indicate that the user will accept any (and varying) buffer sizes.
|
|
||||||
|
|
||||||
@param framesPerHostBuffer Specifies the number of frames per host buffer
|
|
||||||
for the fixed buffer size mode, and the maximum number of frames
|
|
||||||
per host buffer for the bounded host buffer size mode. It is ignored for
|
|
||||||
the other modes.
|
|
||||||
|
|
||||||
@param hostBufferSizeMode A mode flag indicating the size variability of
|
|
||||||
host buffers that will be passed to the buffer processor. See
|
|
||||||
PaUtilHostBufferSizeMode for further details.
|
|
||||||
|
|
||||||
@param streamCallback The user stream callback passed to Pa_OpenStream.
|
|
||||||
|
|
||||||
@param userData The user data field passed to Pa_OpenStream.
|
|
||||||
|
|
||||||
@note The interleave flag is ignored for host buffer formats. Host
|
|
||||||
interleave is determined by the use of different SetInput and SetOutput
|
|
||||||
functions.
|
|
||||||
|
|
||||||
@return An error code indicating whether the initialization was successful.
|
|
||||||
If the error code is not PaNoError, the buffer processor was not initialized
|
|
||||||
and should not be used.
|
|
||||||
|
|
||||||
@see Pa_OpenStream, PaUtilHostBufferSizeMode, PaUtil_TerminateBufferProcessor
|
|
||||||
*/
|
|
||||||
PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
int inputChannelCount, PaSampleFormat userInputSampleFormat,
|
|
||||||
PaSampleFormat hostInputSampleFormat,
|
|
||||||
int outputChannelCount, PaSampleFormat userOutputSampleFormat,
|
|
||||||
PaSampleFormat hostOutputSampleFormat,
|
|
||||||
double sampleRate,
|
|
||||||
PaStreamFlags streamFlags,
|
|
||||||
unsigned long framesPerUserBuffer, /* 0 indicates don't care */
|
|
||||||
unsigned long framesPerHostBuffer,
|
|
||||||
PaUtilHostBufferSizeMode hostBufferSizeMode,
|
|
||||||
PaStreamCallback *streamCallback, void *userData );
|
|
||||||
|
|
||||||
|
|
||||||
/** Terminate a buffer processor's representation. Deallocates any temporary
|
|
||||||
buffers allocated by PaUtil_InitializeBufferProcessor.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor structure to terminate.
|
|
||||||
|
|
||||||
@see PaUtil_InitializeBufferProcessor.
|
|
||||||
*/
|
|
||||||
void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bufferProcessor );
|
|
||||||
|
|
||||||
|
|
||||||
/** Clear any internally buffered data. If you call
|
|
||||||
PaUtil_InitializeBufferProcessor in your OpenStream routine, make sure you
|
|
||||||
call PaUtil_ResetBufferProcessor in your StartStream call.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor to reset.
|
|
||||||
*/
|
|
||||||
void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bufferProcessor );
|
|
||||||
|
|
||||||
|
|
||||||
/** Retrieve the input latency of a buffer processor, in frames.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor examine.
|
|
||||||
|
|
||||||
@return The input latency introduced by the buffer processor, in frames.
|
|
||||||
|
|
||||||
@see PaUtil_GetBufferProcessorOutputLatencyFrames
|
|
||||||
*/
|
|
||||||
unsigned long PaUtil_GetBufferProcessorInputLatencyFrames( PaUtilBufferProcessor* bufferProcessor );
|
|
||||||
|
|
||||||
/** Retrieve the output latency of a buffer processor, in frames.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor examine.
|
|
||||||
|
|
||||||
@return The output latency introduced by the buffer processor, in frames.
|
|
||||||
|
|
||||||
@see PaUtil_GetBufferProcessorInputLatencyFrames
|
|
||||||
*/
|
|
||||||
unsigned long PaUtil_GetBufferProcessorOutputLatencyFrames( PaUtilBufferProcessor* bufferProcessor );
|
|
||||||
|
|
||||||
/*@}*/
|
|
||||||
|
|
||||||
|
|
||||||
/** @name Host buffer pointer configuration
|
|
||||||
|
|
||||||
Functions to set host input and output buffers, used by both callback streams
|
|
||||||
and blocking read/write streams.
|
|
||||||
*/
|
|
||||||
/*@{*/
|
|
||||||
|
|
||||||
|
|
||||||
/** Set the number of frames in the input host buffer(s) specified by the
|
|
||||||
PaUtil_Set*InputChannel functions.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
|
|
||||||
@param frameCount The number of host input frames. A 0 frameCount indicates to
|
|
||||||
use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor.
|
|
||||||
|
|
||||||
@see PaUtil_SetNoInput, PaUtil_SetInputChannel,
|
|
||||||
PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel
|
|
||||||
*/
|
|
||||||
void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned long frameCount );
|
|
||||||
|
|
||||||
|
|
||||||
/** Indicate that no input is avalable. This function should be used when
|
|
||||||
priming the output of a full-duplex stream opened with the
|
|
||||||
paPrimeOutputBuffersUsingStreamCallback flag. Note that it is not necessary
|
|
||||||
to call this or any othe PaUtil_Set*Input* functions for ouput-only streams.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
*/
|
|
||||||
void PaUtil_SetNoInput( PaUtilBufferProcessor* bufferProcessor );
|
|
||||||
|
|
||||||
|
|
||||||
/** Provide the buffer processor with a pointer to a host input channel.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
@param channel The channel number.
|
|
||||||
@param data The buffer.
|
|
||||||
@param stride The stride from one sample to the next, in samples. For
|
|
||||||
interleaved host buffers, the stride will usually be the same as the number of
|
|
||||||
channels in the buffer.
|
|
||||||
*/
|
|
||||||
void PaUtil_SetInputChannel( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int channel, void *data, unsigned int stride );
|
|
||||||
|
|
||||||
|
|
||||||
/** Provide the buffer processor with a pointer to an number of interleaved
|
|
||||||
host input channels.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
@param firstChannel The first channel number.
|
|
||||||
@param data The buffer.
|
|
||||||
@param channelCount The number of interleaved channels in the buffer. If
|
|
||||||
channelCount is zero, the number of channels specified to
|
|
||||||
PaUtil_InitializeBufferProcessor will be used.
|
|
||||||
*/
|
|
||||||
void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int firstChannel, void *data, unsigned int channelCount );
|
|
||||||
|
|
||||||
|
|
||||||
/** Provide the buffer processor with a pointer to one non-interleaved host
|
|
||||||
output channel.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
@param channel The channel number.
|
|
||||||
@param data The buffer.
|
|
||||||
*/
|
|
||||||
void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int channel, void *data );
|
|
||||||
|
|
||||||
|
|
||||||
/** Use for the second buffer half when the input buffer is split in two halves.
|
|
||||||
@see PaUtil_SetInputFrameCount
|
|
||||||
*/
|
|
||||||
void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned long frameCount );
|
|
||||||
|
|
||||||
/** Use for the second buffer half when the input buffer is split in two halves.
|
|
||||||
@see PaUtil_SetInputChannel
|
|
||||||
*/
|
|
||||||
void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int channel, void *data, unsigned int stride );
|
|
||||||
|
|
||||||
/** Use for the second buffer half when the input buffer is split in two halves.
|
|
||||||
@see PaUtil_SetInterleavedInputChannels
|
|
||||||
*/
|
|
||||||
void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int firstChannel, void *data, unsigned int channelCount );
|
|
||||||
|
|
||||||
/** Use for the second buffer half when the input buffer is split in two halves.
|
|
||||||
@see PaUtil_SetNonInterleavedInputChannel
|
|
||||||
*/
|
|
||||||
void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int channel, void *data );
|
|
||||||
|
|
||||||
|
|
||||||
/** Set the number of frames in the output host buffer(s) specified by the
|
|
||||||
PaUtil_Set*OutputChannel functions.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
|
|
||||||
@param frameCount The number of host output frames. A 0 frameCount indicates to
|
|
||||||
use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor.
|
|
||||||
|
|
||||||
@see PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels,
|
|
||||||
PaUtil_SetNonInterleavedOutputChannel
|
|
||||||
*/
|
|
||||||
void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned long frameCount );
|
|
||||||
|
|
||||||
|
|
||||||
/** Indicate that the output will be discarded. This function should be used
|
|
||||||
when implementing the paNeverDropInput mode for full duplex streams.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
*/
|
|
||||||
void PaUtil_SetNoOutput( PaUtilBufferProcessor* bufferProcessor );
|
|
||||||
|
|
||||||
|
|
||||||
/** Provide the buffer processor with a pointer to a host output channel.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
@param channel The channel number.
|
|
||||||
@param data The buffer.
|
|
||||||
@param stride The stride from one sample to the next, in samples. For
|
|
||||||
interleaved host buffers, the stride will usually be the same as the number of
|
|
||||||
channels in the buffer.
|
|
||||||
*/
|
|
||||||
void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int channel, void *data, unsigned int stride );
|
|
||||||
|
|
||||||
|
|
||||||
/** Provide the buffer processor with a pointer to a number of interleaved
|
|
||||||
host output channels.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
@param firstChannel The first channel number.
|
|
||||||
@param data The buffer.
|
|
||||||
@param channelCount The number of interleaved channels in the buffer. If
|
|
||||||
channelCount is zero, the number of channels specified to
|
|
||||||
PaUtil_InitializeBufferProcessor will be used.
|
|
||||||
*/
|
|
||||||
void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int firstChannel, void *data, unsigned int channelCount );
|
|
||||||
|
|
||||||
|
|
||||||
/** Provide the buffer processor with a pointer to one non-interleaved host
|
|
||||||
output channel.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
@param channel The channel number.
|
|
||||||
@param data The buffer.
|
|
||||||
*/
|
|
||||||
void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int channel, void *data );
|
|
||||||
|
|
||||||
|
|
||||||
/** Use for the second buffer half when the output buffer is split in two halves.
|
|
||||||
@see PaUtil_SetOutputFrameCount
|
|
||||||
*/
|
|
||||||
void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned long frameCount );
|
|
||||||
|
|
||||||
/** Use for the second buffer half when the output buffer is split in two halves.
|
|
||||||
@see PaUtil_SetOutputChannel
|
|
||||||
*/
|
|
||||||
void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int channel, void *data, unsigned int stride );
|
|
||||||
|
|
||||||
/** Use for the second buffer half when the output buffer is split in two halves.
|
|
||||||
@see PaUtil_SetInterleavedOutputChannels
|
|
||||||
*/
|
|
||||||
void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int firstChannel, void *data, unsigned int channelCount );
|
|
||||||
|
|
||||||
/** Use for the second buffer half when the output buffer is split in two halves.
|
|
||||||
@see PaUtil_SetNonInterleavedOutputChannel
|
|
||||||
*/
|
|
||||||
void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned int channel, void *data );
|
|
||||||
|
|
||||||
/*@}*/
|
|
||||||
|
|
||||||
|
|
||||||
/** @name Buffer processing functions for callback streams
|
|
||||||
*/
|
|
||||||
/*@{*/
|
|
||||||
|
|
||||||
/** Commence processing a host buffer (or a pair of host buffers in the
|
|
||||||
full-duplex case) for a callback stream.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
|
|
||||||
@param timeInfo Timing information for the first sample of the host
|
|
||||||
buffer(s). This information may be adjusted when buffer adaption is being
|
|
||||||
performed.
|
|
||||||
|
|
||||||
@param callbackStatusFlags Flags indicating whether underruns and overruns
|
|
||||||
have occurred since the last time the buffer processor was called.
|
|
||||||
*/
|
|
||||||
void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags );
|
|
||||||
|
|
||||||
|
|
||||||
/** Finish processing a host buffer (or a pair of host buffers in the
|
|
||||||
full-duplex case) for a callback stream.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
|
|
||||||
@param callbackResult On input, indicates a previous callback result, and on
|
|
||||||
exit, the result of the user stream callback, if it is called.
|
|
||||||
On entry callbackResult should contain one of { paContinue, paComplete, or
|
|
||||||
paAbort}. If paComplete is passed, the stream callback will not be called
|
|
||||||
but any audio that was generated by previous stream callbacks will be copied
|
|
||||||
to the output buffer(s). You can check whether the buffer processor's internal
|
|
||||||
buffer is empty by calling PaUtil_IsBufferProcessorOutputEmpty.
|
|
||||||
|
|
||||||
If the stream callback is called its result is stored in *callbackResult. If
|
|
||||||
the stream callback returns paComplete or paAbort, all output buffers will be
|
|
||||||
full of valid data - some of which may be zeros to acount for data that
|
|
||||||
wasn't generated by the terminating callback.
|
|
||||||
|
|
||||||
@return The number of frames processed. This usually corresponds to the
|
|
||||||
number of frames specified by the PaUtil_Set*FrameCount functions, exept in
|
|
||||||
the paUtilVariableHostBufferSizePartialUsageAllowed buffer size mode when a
|
|
||||||
smaller value may be returned.
|
|
||||||
*/
|
|
||||||
unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
int *callbackResult );
|
|
||||||
|
|
||||||
|
|
||||||
/** Determine whether any callback generated output remains in the bufffer
|
|
||||||
processor's internal buffers. This method may be used to determine when to
|
|
||||||
continue calling PaUtil_EndBufferProcessing() after the callback has returned
|
|
||||||
a callbackResult of paComplete.
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
|
|
||||||
@return Returns non-zero when callback generated output remains in the internal
|
|
||||||
buffer and zero (0) when there internal buffer contains no callback generated
|
|
||||||
data.
|
|
||||||
*/
|
|
||||||
int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bufferProcessor );
|
|
||||||
|
|
||||||
/*@}*/
|
|
||||||
|
|
||||||
|
|
||||||
/** @name Buffer processing functions for blocking read/write streams
|
|
||||||
*/
|
|
||||||
/*@{*/
|
|
||||||
|
|
||||||
/** Copy samples from host input channels set up by the PaUtil_Set*InputChannels
|
|
||||||
functions to a user supplied buffer. This function is intended for use with
|
|
||||||
blocking read/write streams. Copies the minimum of the number of
|
|
||||||
user frames (specified by the frameCount parameter) and the number of available
|
|
||||||
host frames (specified in a previous call to SetInputFrameCount()).
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
|
|
||||||
@param buffer A pointer to the user buffer pointer, or a pointer to a pointer
|
|
||||||
to an array of user buffer pointers for a non-interleaved stream. It is
|
|
||||||
important that this parameter points to a copy of the user buffer pointers,
|
|
||||||
not to the actual user buffer pointers, because this function updates the
|
|
||||||
pointers before returning.
|
|
||||||
|
|
||||||
@param frameCount The number of frames of data in the buffer(s) pointed to by
|
|
||||||
the buffer parameter.
|
|
||||||
|
|
||||||
@return The number of frames copied. The buffer pointer(s) pointed to by the
|
|
||||||
buffer parameter are advanced to point to the frame(s) following the last one
|
|
||||||
filled.
|
|
||||||
*/
|
|
||||||
unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
void **buffer, unsigned long frameCount );
|
|
||||||
|
|
||||||
|
|
||||||
/* Copy samples from a user supplied buffer to host output channels set up by
|
|
||||||
the PaUtil_Set*OutputChannels functions. This function is intended for use with
|
|
||||||
blocking read/write streams. Copies the minimum of the number of
|
|
||||||
user frames (specified by the frameCount parameter) and the number of
|
|
||||||
host frames (specified in a previous call to SetOutputFrameCount()).
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
|
|
||||||
@param buffer A pointer to the user buffer pointer, or a pointer to a pointer
|
|
||||||
to an array of user buffer pointers for a non-interleaved stream. It is
|
|
||||||
important that this parameter points to a copy of the user buffer pointers,
|
|
||||||
not to the actual user buffer pointers, because this function updates the
|
|
||||||
pointers before returning.
|
|
||||||
|
|
||||||
@param frameCount The number of frames of data in the buffer(s) pointed to by
|
|
||||||
the buffer parameter.
|
|
||||||
|
|
||||||
@return The number of frames copied. The buffer pointer(s) pointed to by the
|
|
||||||
buffer parameter are advanced to point to the frame(s) following the last one
|
|
||||||
copied.
|
|
||||||
*/
|
|
||||||
unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
const void ** buffer, unsigned long frameCount );
|
|
||||||
|
|
||||||
|
|
||||||
/* Zero samples in host output channels set up by the PaUtil_Set*OutputChannels
|
|
||||||
functions. This function is useful for flushing streams.
|
|
||||||
Zeros the minimum of frameCount and the number of host frames specified in a
|
|
||||||
previous call to SetOutputFrameCount().
|
|
||||||
|
|
||||||
@param bufferProcessor The buffer processor.
|
|
||||||
|
|
||||||
@param frameCount The maximum number of frames to zero.
|
|
||||||
|
|
||||||
@return The number of frames zeroed.
|
|
||||||
*/
|
|
||||||
unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bufferProcessor,
|
|
||||||
unsigned long frameCount );
|
|
||||||
|
|
||||||
|
|
||||||
/*@}*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* PA_PROCESS_H */
|
|
236
external/portaudio/include/pa_ringbuffer.h
vendored
236
external/portaudio/include/pa_ringbuffer.h
vendored
@ -1,236 +0,0 @@
|
|||||||
#ifndef PA_RINGBUFFER_H
|
|
||||||
#define PA_RINGBUFFER_H
|
|
||||||
/*
|
|
||||||
* $Id: pa_ringbuffer.h 1873 2012-10-07 19:00:11Z philburk $
|
|
||||||
* Portable Audio I/O Library
|
|
||||||
* Ring Buffer utility.
|
|
||||||
*
|
|
||||||
* Author: Phil Burk, http://www.softsynth.com
|
|
||||||
* modified for SMP safety on OS X by Bjorn Roche.
|
|
||||||
* also allowed for const where possible.
|
|
||||||
* modified for multiple-byte-sized data elements by Sven Fischer
|
|
||||||
*
|
|
||||||
* Note that this is safe only for a single-thread reader
|
|
||||||
* and a single-thread writer.
|
|
||||||
*
|
|
||||||
* This program is distributed with the PortAudio Portable Audio Library.
|
|
||||||
* For more information see: http://www.portaudio.com
|
|
||||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
@brief Single-reader single-writer lock-free ring buffer
|
|
||||||
|
|
||||||
PaUtilRingBuffer is a ring buffer used to transport samples between
|
|
||||||
different execution contexts (threads, OS callbacks, interrupt handlers)
|
|
||||||
without requiring the use of any locks. This only works when there is
|
|
||||||
a single reader and a single writer (ie. one thread or callback writes
|
|
||||||
to the ring buffer, another thread or callback reads from it).
|
|
||||||
|
|
||||||
The PaUtilRingBuffer structure manages a ring buffer containing N
|
|
||||||
elements, where N must be a power of two. An element may be any size
|
|
||||||
(specified in bytes).
|
|
||||||
|
|
||||||
The memory area used to store the buffer elements must be allocated by
|
|
||||||
the client prior to calling PaUtil_InitializeRingBuffer() and must outlive
|
|
||||||
the use of the ring buffer.
|
|
||||||
|
|
||||||
@note The ring buffer functions are not normally exposed in the PortAudio libraries.
|
|
||||||
If you want to call them then you will need to add pa_ringbuffer.c to your application source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#include <sys/types.h>
|
|
||||||
typedef int32_t ring_buffer_size_t;
|
|
||||||
#elif defined( __GNUC__ )
|
|
||||||
typedef long ring_buffer_size_t;
|
|
||||||
#elif (_MSC_VER >= 1400)
|
|
||||||
typedef long ring_buffer_size_t;
|
|
||||||
#elif defined(_MSC_VER) || defined(__BORLANDC__)
|
|
||||||
typedef long ring_buffer_size_t;
|
|
||||||
#else
|
|
||||||
typedef long ring_buffer_size_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
typedef struct PaUtilRingBuffer
|
|
||||||
{
|
|
||||||
ring_buffer_size_t bufferSize; /**< Number of elements in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */
|
|
||||||
volatile ring_buffer_size_t writeIndex; /**< Index of next writable element. Set by PaUtil_AdvanceRingBufferWriteIndex. */
|
|
||||||
volatile ring_buffer_size_t readIndex; /**< Index of next readable element. Set by PaUtil_AdvanceRingBufferReadIndex. */
|
|
||||||
ring_buffer_size_t bigMask; /**< Used for wrapping indices with extra bit to distinguish full/empty. */
|
|
||||||
ring_buffer_size_t smallMask; /**< Used for fitting indices to buffer. */
|
|
||||||
ring_buffer_size_t elementSizeBytes; /**< Number of bytes per element. */
|
|
||||||
char *buffer; /**< Pointer to the buffer containing the actual data. */
|
|
||||||
}PaUtilRingBuffer;
|
|
||||||
|
|
||||||
/** Initialize Ring Buffer to empty state ready to have elements written to it.
|
|
||||||
|
|
||||||
@param rbuf The ring buffer.
|
|
||||||
|
|
||||||
@param elementSizeBytes The size of a single data element in bytes.
|
|
||||||
|
|
||||||
@param elementCount The number of elements in the buffer (must be a power of 2).
|
|
||||||
|
|
||||||
@param dataPtr A pointer to a previously allocated area where the data
|
|
||||||
will be maintained. It must be elementCount*elementSizeBytes long.
|
|
||||||
|
|
||||||
@return -1 if elementCount is not a power of 2, otherwise 0.
|
|
||||||
*/
|
|
||||||
ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr );
|
|
||||||
|
|
||||||
/** Reset buffer to empty. Should only be called when buffer is NOT being read or written.
|
|
||||||
|
|
||||||
@param rbuf The ring buffer.
|
|
||||||
*/
|
|
||||||
void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf );
|
|
||||||
|
|
||||||
/** Retrieve the number of elements available in the ring buffer for writing.
|
|
||||||
|
|
||||||
@param rbuf The ring buffer.
|
|
||||||
|
|
||||||
@return The number of elements available for writing.
|
|
||||||
*/
|
|
||||||
ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( const PaUtilRingBuffer *rbuf );
|
|
||||||
|
|
||||||
/** Retrieve the number of elements available in the ring buffer for reading.
|
|
||||||
|
|
||||||
@param rbuf The ring buffer.
|
|
||||||
|
|
||||||
@return The number of elements available for reading.
|
|
||||||
*/
|
|
||||||
ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( const PaUtilRingBuffer *rbuf );
|
|
||||||
|
|
||||||
/** Write data to the ring buffer.
|
|
||||||
|
|
||||||
@param rbuf The ring buffer.
|
|
||||||
|
|
||||||
@param data The address of new data to write to the buffer.
|
|
||||||
|
|
||||||
@param elementCount The number of elements to be written.
|
|
||||||
|
|
||||||
@return The number of elements written.
|
|
||||||
*/
|
|
||||||
ring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount );
|
|
||||||
|
|
||||||
/** Read data from the ring buffer.
|
|
||||||
|
|
||||||
@param rbuf The ring buffer.
|
|
||||||
|
|
||||||
@param data The address where the data should be stored.
|
|
||||||
|
|
||||||
@param elementCount The number of elements to be read.
|
|
||||||
|
|
||||||
@return The number of elements read.
|
|
||||||
*/
|
|
||||||
ring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount );
|
|
||||||
|
|
||||||
/** Get address of region(s) to which we can write data.
|
|
||||||
|
|
||||||
@param rbuf The ring buffer.
|
|
||||||
|
|
||||||
@param elementCount The number of elements desired.
|
|
||||||
|
|
||||||
@param dataPtr1 The address where the first (or only) region pointer will be
|
|
||||||
stored.
|
|
||||||
|
|
||||||
@param sizePtr1 The address where the first (or only) region length will be
|
|
||||||
stored.
|
|
||||||
|
|
||||||
@param dataPtr2 The address where the second region pointer will be stored if
|
|
||||||
the first region is too small to satisfy elementCount.
|
|
||||||
|
|
||||||
@param sizePtr2 The address where the second region length will be stored if
|
|
||||||
the first region is too small to satisfy elementCount.
|
|
||||||
|
|
||||||
@return The room available to be written or elementCount, whichever is smaller.
|
|
||||||
*/
|
|
||||||
ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
|
|
||||||
void **dataPtr1, ring_buffer_size_t *sizePtr1,
|
|
||||||
void **dataPtr2, ring_buffer_size_t *sizePtr2 );
|
|
||||||
|
|
||||||
/** Advance the write index to the next location to be written.
|
|
||||||
|
|
||||||
@param rbuf The ring buffer.
|
|
||||||
|
|
||||||
@param elementCount The number of elements to advance.
|
|
||||||
|
|
||||||
@return The new position.
|
|
||||||
*/
|
|
||||||
ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount );
|
|
||||||
|
|
||||||
/** Get address of region(s) from which we can read data.
|
|
||||||
|
|
||||||
@param rbuf The ring buffer.
|
|
||||||
|
|
||||||
@param elementCount The number of elements desired.
|
|
||||||
|
|
||||||
@param dataPtr1 The address where the first (or only) region pointer will be
|
|
||||||
stored.
|
|
||||||
|
|
||||||
@param sizePtr1 The address where the first (or only) region length will be
|
|
||||||
stored.
|
|
||||||
|
|
||||||
@param dataPtr2 The address where the second region pointer will be stored if
|
|
||||||
the first region is too small to satisfy elementCount.
|
|
||||||
|
|
||||||
@param sizePtr2 The address where the second region length will be stored if
|
|
||||||
the first region is too small to satisfy elementCount.
|
|
||||||
|
|
||||||
@return The number of elements available for reading.
|
|
||||||
*/
|
|
||||||
ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
|
|
||||||
void **dataPtr1, ring_buffer_size_t *sizePtr1,
|
|
||||||
void **dataPtr2, ring_buffer_size_t *sizePtr2 );
|
|
||||||
|
|
||||||
/** Advance the read index to the next location to be read.
|
|
||||||
|
|
||||||
@param rbuf The ring buffer.
|
|
||||||
|
|
||||||
@param elementCount The number of elements to advance.
|
|
||||||
|
|
||||||
@return The new position.
|
|
||||||
*/
|
|
||||||
ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount );
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* PA_RINGBUFFER_H */
|
|
205
external/portaudio/include/pa_stream.h
vendored
205
external/portaudio/include/pa_stream.h
vendored
@ -1,205 +0,0 @@
|
|||||||
#ifndef PA_STREAM_H
|
|
||||||
#define PA_STREAM_H
|
|
||||||
/*
|
|
||||||
* $Id: pa_stream.h 1339 2008-02-15 07:50:33Z rossb $
|
|
||||||
* Portable Audio I/O Library
|
|
||||||
* stream interface
|
|
||||||
*
|
|
||||||
* Based on the Open Source API proposed by Ross Bencina
|
|
||||||
* Copyright (c) 1999-2008 Ross Bencina, Phil Burk
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
|
|
||||||
@brief Stream interfaces, representation structures and helper functions
|
|
||||||
used to interface between pa_front.c host API implementations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "portaudio.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
#define PA_STREAM_MAGIC (0x18273645)
|
|
||||||
|
|
||||||
|
|
||||||
/** A structure representing an (abstract) interface to a host API. Contains
|
|
||||||
pointers to functions which implement the interface.
|
|
||||||
|
|
||||||
All PaStreamInterface functions are guaranteed to be called with a non-null,
|
|
||||||
valid stream parameter.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
PaError (*Close)( PaStream* stream );
|
|
||||||
PaError (*Start)( PaStream *stream );
|
|
||||||
PaError (*Stop)( PaStream *stream );
|
|
||||||
PaError (*Abort)( PaStream *stream );
|
|
||||||
PaError (*IsStopped)( PaStream *stream );
|
|
||||||
PaError (*IsActive)( PaStream *stream );
|
|
||||||
PaTime (*GetTime)( PaStream *stream );
|
|
||||||
double (*GetCpuLoad)( PaStream* stream );
|
|
||||||
PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames );
|
|
||||||
PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames );
|
|
||||||
signed long (*GetReadAvailable)( PaStream* stream );
|
|
||||||
signed long (*GetWriteAvailable)( PaStream* stream );
|
|
||||||
} PaUtilStreamInterface;
|
|
||||||
|
|
||||||
|
|
||||||
/** Initialize the fields of a PaUtilStreamInterface structure.
|
|
||||||
*/
|
|
||||||
void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface,
|
|
||||||
PaError (*Close)( PaStream* ),
|
|
||||||
PaError (*Start)( PaStream* ),
|
|
||||||
PaError (*Stop)( PaStream* ),
|
|
||||||
PaError (*Abort)( PaStream* ),
|
|
||||||
PaError (*IsStopped)( PaStream* ),
|
|
||||||
PaError (*IsActive)( PaStream* ),
|
|
||||||
PaTime (*GetTime)( PaStream* ),
|
|
||||||
double (*GetCpuLoad)( PaStream* ),
|
|
||||||
PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ),
|
|
||||||
PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ),
|
|
||||||
signed long (*GetReadAvailable)( PaStream* stream ),
|
|
||||||
signed long (*GetWriteAvailable)( PaStream* stream ) );
|
|
||||||
|
|
||||||
|
|
||||||
/** Dummy Read function for use in interfaces to a callback based streams.
|
|
||||||
Pass to the Read parameter of PaUtil_InitializeStreamInterface.
|
|
||||||
@return An error code indicating that the function has no effect
|
|
||||||
because the stream is a callback stream.
|
|
||||||
*/
|
|
||||||
PaError PaUtil_DummyRead( PaStream* stream,
|
|
||||||
void *buffer,
|
|
||||||
unsigned long frames );
|
|
||||||
|
|
||||||
|
|
||||||
/** Dummy Write function for use in an interfaces to callback based streams.
|
|
||||||
Pass to the Write parameter of PaUtil_InitializeStreamInterface.
|
|
||||||
@return An error code indicating that the function has no effect
|
|
||||||
because the stream is a callback stream.
|
|
||||||
*/
|
|
||||||
PaError PaUtil_DummyWrite( PaStream* stream,
|
|
||||||
const void *buffer,
|
|
||||||
unsigned long frames );
|
|
||||||
|
|
||||||
|
|
||||||
/** Dummy GetReadAvailable function for use in interfaces to callback based
|
|
||||||
streams. Pass to the GetReadAvailable parameter of PaUtil_InitializeStreamInterface.
|
|
||||||
@return An error code indicating that the function has no effect
|
|
||||||
because the stream is a callback stream.
|
|
||||||
*/
|
|
||||||
signed long PaUtil_DummyGetReadAvailable( PaStream* stream );
|
|
||||||
|
|
||||||
|
|
||||||
/** Dummy GetWriteAvailable function for use in interfaces to callback based
|
|
||||||
streams. Pass to the GetWriteAvailable parameter of PaUtil_InitializeStreamInterface.
|
|
||||||
@return An error code indicating that the function has no effect
|
|
||||||
because the stream is a callback stream.
|
|
||||||
*/
|
|
||||||
signed long PaUtil_DummyGetWriteAvailable( PaStream* stream );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Dummy GetCpuLoad function for use in an interface to a read/write stream.
|
|
||||||
Pass to the GetCpuLoad parameter of PaUtil_InitializeStreamInterface.
|
|
||||||
@return Returns 0.
|
|
||||||
*/
|
|
||||||
double PaUtil_DummyGetCpuLoad( PaStream* stream );
|
|
||||||
|
|
||||||
|
|
||||||
/** Non host specific data for a stream. This data is used by pa_front to
|
|
||||||
forward to the appropriate functions in the streamInterface structure.
|
|
||||||
*/
|
|
||||||
typedef struct PaUtilStreamRepresentation {
|
|
||||||
unsigned long magic; /**< set to PA_STREAM_MAGIC */
|
|
||||||
struct PaUtilStreamRepresentation *nextOpenStream; /**< field used by multi-api code */
|
|
||||||
PaUtilStreamInterface *streamInterface;
|
|
||||||
PaStreamCallback *streamCallback;
|
|
||||||
PaStreamFinishedCallback *streamFinishedCallback;
|
|
||||||
void *userData;
|
|
||||||
PaStreamInfo streamInfo;
|
|
||||||
} PaUtilStreamRepresentation;
|
|
||||||
|
|
||||||
|
|
||||||
/** Initialize a PaUtilStreamRepresentation structure.
|
|
||||||
|
|
||||||
@see PaUtil_InitializeStreamRepresentation
|
|
||||||
*/
|
|
||||||
void PaUtil_InitializeStreamRepresentation(
|
|
||||||
PaUtilStreamRepresentation *streamRepresentation,
|
|
||||||
PaUtilStreamInterface *streamInterface,
|
|
||||||
PaStreamCallback *streamCallback,
|
|
||||||
void *userData );
|
|
||||||
|
|
||||||
|
|
||||||
/** Clean up a PaUtilStreamRepresentation structure previously initialized
|
|
||||||
by a call to PaUtil_InitializeStreamRepresentation.
|
|
||||||
|
|
||||||
@see PaUtil_InitializeStreamRepresentation
|
|
||||||
*/
|
|
||||||
void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation );
|
|
||||||
|
|
||||||
|
|
||||||
/** Check that the stream pointer is valid.
|
|
||||||
|
|
||||||
@return Returns paNoError if the stream pointer appears to be OK, otherwise
|
|
||||||
returns an error indicating the cause of failure.
|
|
||||||
*/
|
|
||||||
PaError PaUtil_ValidateStreamPointer( PaStream *stream );
|
|
||||||
|
|
||||||
|
|
||||||
/** Cast an opaque stream pointer into a pointer to a PaUtilStreamRepresentation.
|
|
||||||
|
|
||||||
@see PaUtilStreamRepresentation
|
|
||||||
*/
|
|
||||||
#define PA_STREAM_REP( stream )\
|
|
||||||
((PaUtilStreamRepresentation*) (stream) )
|
|
||||||
|
|
||||||
|
|
||||||
/** Cast an opaque stream pointer into a pointer to a PaUtilStreamInterface.
|
|
||||||
|
|
||||||
@see PaUtilStreamRepresentation, PaUtilStreamInterface
|
|
||||||
*/
|
|
||||||
#define PA_STREAM_INTERFACE( stream )\
|
|
||||||
PA_STREAM_REP( (stream) )->streamInterface
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* PA_STREAM_H */
|
|
117
external/portaudio/include/pa_trace.h
vendored
117
external/portaudio/include/pa_trace.h
vendored
@ -1,117 +0,0 @@
|
|||||||
#ifndef PA_TRACE_H
|
|
||||||
#define PA_TRACE_H
|
|
||||||
/*
|
|
||||||
* $Id: pa_trace.h 1812 2012-02-14 09:32:57Z robiwan $
|
|
||||||
* Portable Audio I/O Library Trace Facility
|
|
||||||
* Store trace information in real-time for later printing.
|
|
||||||
*
|
|
||||||
* Based on the Open Source API proposed by Ross Bencina
|
|
||||||
* Copyright (c) 1999-2000 Phil Burk
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
|
|
||||||
@brief Real-time safe event trace logging facility for debugging.
|
|
||||||
|
|
||||||
Allows data to be logged to a fixed size trace buffer in a real-time
|
|
||||||
execution context (such as at interrupt time). Each log entry consists
|
|
||||||
of a message comprising a string pointer and an int. The trace buffer
|
|
||||||
may be dumped to stdout later.
|
|
||||||
|
|
||||||
This facility is only active if PA_TRACE_REALTIME_EVENTS is set to 1,
|
|
||||||
otherwise the trace functions expand to no-ops.
|
|
||||||
|
|
||||||
@fn PaUtil_ResetTraceMessages
|
|
||||||
@brief Clear the trace buffer.
|
|
||||||
|
|
||||||
@fn PaUtil_AddTraceMessage
|
|
||||||
@brief Add a message to the trace buffer. A message consists of string and an int.
|
|
||||||
@param msg The string pointer must remain valid until PaUtil_DumpTraceMessages
|
|
||||||
is called. As a result, usually only string literals should be passed as
|
|
||||||
the msg parameter.
|
|
||||||
|
|
||||||
@fn PaUtil_DumpTraceMessages
|
|
||||||
@brief Print all messages in the trace buffer to stdout and clear the trace buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PA_TRACE_REALTIME_EVENTS
|
|
||||||
#define PA_TRACE_REALTIME_EVENTS (0) /**< Set to 1 to enable logging using the trace functions defined below */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PA_MAX_TRACE_RECORDS
|
|
||||||
#define PA_MAX_TRACE_RECORDS (2048) /**< Maximum number of records stored in trace buffer */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
#if PA_TRACE_REALTIME_EVENTS
|
|
||||||
|
|
||||||
void PaUtil_ResetTraceMessages();
|
|
||||||
void PaUtil_AddTraceMessage( const char *msg, int data );
|
|
||||||
void PaUtil_DumpTraceMessages();
|
|
||||||
|
|
||||||
/* Alternative interface */
|
|
||||||
|
|
||||||
typedef void* LogHandle;
|
|
||||||
|
|
||||||
int PaUtil_InitializeHighSpeedLog(LogHandle* phLog, unsigned maxSizeInBytes);
|
|
||||||
void PaUtil_ResetHighSpeedLogTimeRef(LogHandle hLog);
|
|
||||||
int PaUtil_AddHighSpeedLogMessage(LogHandle hLog, const char* fmt, ...);
|
|
||||||
void PaUtil_DumpHighSpeedLog(LogHandle hLog, const char* fileName);
|
|
||||||
void PaUtil_DiscardHighSpeedLog(LogHandle hLog);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define PaUtil_ResetTraceMessages() /* noop */
|
|
||||||
#define PaUtil_AddTraceMessage(msg,data) /* noop */
|
|
||||||
#define PaUtil_DumpTraceMessages() /* noop */
|
|
||||||
|
|
||||||
#define PaUtil_InitializeHighSpeedLog(phLog, maxSizeInBytes) (0)
|
|
||||||
#define PaUtil_ResetHighSpeedLogTimeRef(hLog)
|
|
||||||
#define PaUtil_AddHighSpeedLogMessage(...) (0)
|
|
||||||
#define PaUtil_DumpHighSpeedLog(hLog, fileName)
|
|
||||||
#define PaUtil_DiscardHighSpeedLog(hLog)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif /* PA_TRACE_H */
|
|
159
external/portaudio/include/pa_util.h
vendored
159
external/portaudio/include/pa_util.h
vendored
@ -1,159 +0,0 @@
|
|||||||
#ifndef PA_UTIL_H
|
|
||||||
#define PA_UTIL_H
|
|
||||||
/*
|
|
||||||
* $Id: pa_util.h 1584 2011-02-02 18:58:17Z rossb $
|
|
||||||
* Portable Audio I/O Library implementation utilities header
|
|
||||||
* common implementation utilities and interfaces
|
|
||||||
*
|
|
||||||
* Based on the Open Source API proposed by Ross Bencina
|
|
||||||
* Copyright (c) 1999-2008 Ross Bencina, Phil Burk
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files
|
|
||||||
* (the "Software"), to deal in the Software without restriction,
|
|
||||||
* including without limitation the rights to use, copy, modify, merge,
|
|
||||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
* and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
||||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
|
||||||
*
|
|
||||||
* Any person wishing to distribute modifications to the Software is
|
|
||||||
* requested to send the modifications to the original developer so that
|
|
||||||
* they can be incorporated into the canonical version. It is also
|
|
||||||
* requested that these non-binding requests be included along with the
|
|
||||||
* license above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
@ingroup common_src
|
|
||||||
|
|
||||||
@brief Prototypes for utility functions used by PortAudio implementations.
|
|
||||||
|
|
||||||
Some functions declared here are defined in pa_front.c while others
|
|
||||||
are implemented separately for each platform.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "portaudio.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
struct PaUtilHostApiRepresentation;
|
|
||||||
|
|
||||||
|
|
||||||
/** Retrieve a specific host API representation. This function can be used
|
|
||||||
by implementations to retrieve a pointer to their representation in
|
|
||||||
host api specific extension functions which aren't passed a rep pointer
|
|
||||||
by pa_front.c.
|
|
||||||
|
|
||||||
@param hostApi A pointer to a host API represenation pointer. Apon success
|
|
||||||
this will receive the requested representation pointer.
|
|
||||||
|
|
||||||
@param type A valid host API type identifier.
|
|
||||||
|
|
||||||
@returns An error code. If the result is PaNoError then a pointer to the
|
|
||||||
requested host API representation will be stored in *hostApi. If the host API
|
|
||||||
specified by type is not found, this function returns paHostApiNotFound.
|
|
||||||
*/
|
|
||||||
PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi,
|
|
||||||
PaHostApiTypeId type );
|
|
||||||
|
|
||||||
|
|
||||||
/** Convert a PortAudio device index into a host API specific device index.
|
|
||||||
@param hostApiDevice Pointer to a device index, on success this will recieve the
|
|
||||||
converted device index value.
|
|
||||||
@param device The PortAudio device index to convert.
|
|
||||||
@param hostApi The host api which the index should be converted for.
|
|
||||||
|
|
||||||
@returns On success returns PaNoError and places the converted index in the
|
|
||||||
hostApiDevice parameter.
|
|
||||||
*/
|
|
||||||
PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
|
|
||||||
PaDeviceIndex *hostApiDevice, PaDeviceIndex device,
|
|
||||||
struct PaUtilHostApiRepresentation *hostApi );
|
|
||||||
|
|
||||||
|
|
||||||
/** Set the host error information returned by Pa_GetLastHostErrorInfo. This
|
|
||||||
function and the paUnanticipatedHostError error code should be used as a
|
|
||||||
last resort. Implementors should use existing PA error codes where possible,
|
|
||||||
or nominate new ones. Note that at it is always better to use
|
|
||||||
PaUtil_SetLastHostErrorInfo() and paUnanticipatedHostError than to return an
|
|
||||||
ambiguous or inaccurate PaError code.
|
|
||||||
|
|
||||||
@param hostApiType The host API which encountered the error (ie of the caller)
|
|
||||||
|
|
||||||
@param errorCode The error code returned by the native API function.
|
|
||||||
|
|
||||||
@param errorText A string describing the error. PaUtil_SetLastHostErrorInfo
|
|
||||||
makes a copy of the string, so it is not necessary for the pointer to remain
|
|
||||||
valid after the call to PaUtil_SetLastHostErrorInfo() returns.
|
|
||||||
|
|
||||||
*/
|
|
||||||
void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
|
|
||||||
const char *errorText );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* the following functions are implemented in a platform platform specific
|
|
||||||
.c file
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Allocate size bytes, guaranteed to be aligned to a FIXME byte boundary */
|
|
||||||
void *PaUtil_AllocateMemory( long size );
|
|
||||||
|
|
||||||
|
|
||||||
/** Realease block if non-NULL. block may be NULL */
|
|
||||||
void PaUtil_FreeMemory( void *block );
|
|
||||||
|
|
||||||
|
|
||||||
/** Return the number of currently allocated blocks. This function can be
|
|
||||||
used for detecting memory leaks.
|
|
||||||
|
|
||||||
@note Allocations will only be tracked if PA_TRACK_MEMORY is #defined. If
|
|
||||||
it isn't, this function will always return 0.
|
|
||||||
*/
|
|
||||||
int PaUtil_CountCurrentlyAllocatedBlocks( void );
|
|
||||||
|
|
||||||
|
|
||||||
/** Initialize the clock used by PaUtil_GetTime(). Call this before calling
|
|
||||||
PaUtil_GetTime.
|
|
||||||
|
|
||||||
@see PaUtil_GetTime
|
|
||||||
*/
|
|
||||||
void PaUtil_InitializeClock( void );
|
|
||||||
|
|
||||||
|
|
||||||
/** Return the system time in seconds. Used to implement CPU load functions
|
|
||||||
|
|
||||||
@see PaUtil_InitializeClock
|
|
||||||
*/
|
|
||||||
double PaUtil_GetTime( void );
|
|
||||||
|
|
||||||
|
|
||||||
/* void Pa_Sleep( long msec ); must also be implemented in per-platform .c file */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif /* PA_UTIL_H */
|
|
BIN
external/portaudio/libs/32/portaudio_x86.dll
vendored
Normal file
BIN
external/portaudio/libs/32/portaudio_x86.dll
vendored
Normal file
Binary file not shown.
BIN
external/portaudio/libs/32/portaudio_x86.lib
vendored
Normal file
BIN
external/portaudio/libs/32/portaudio_x86.lib
vendored
Normal file
Binary file not shown.
BIN
external/portaudio/libs/64/libportaudio_static_x86.a
vendored
Normal file
BIN
external/portaudio/libs/64/libportaudio_static_x86.a
vendored
Normal file
Binary file not shown.
BIN
external/portaudio/libs/64/libportaudio_x86.dll
vendored
Normal file
BIN
external/portaudio/libs/64/libportaudio_x86.dll
vendored
Normal file
Binary file not shown.
BIN
external/portaudio/libs/64/libportaudio_x86.dll.a
vendored
Normal file
BIN
external/portaudio/libs/64/libportaudio_x86.dll.a
vendored
Normal file
Binary file not shown.
BIN
external/portaudio/libs/libportaudio.dll
vendored
BIN
external/portaudio/libs/libportaudio.dll
vendored
Binary file not shown.
BIN
external/portaudio/libs/libportaudio.dll.a
vendored
BIN
external/portaudio/libs/libportaudio.dll.a
vendored
Binary file not shown.
BIN
external/portaudio/libs/libportaudio_static.a
vendored
BIN
external/portaudio/libs/libportaudio_static.a
vendored
Binary file not shown.
5
external/rtl-sdr-release/rtl-sdr.h
vendored
5
external/rtl-sdr-release/rtl-sdr.h
vendored
@ -351,9 +351,10 @@ RTLSDR_API int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, v
|
|||||||
* \param cb callback function to return received samples
|
* \param cb callback function to return received samples
|
||||||
* \param ctx user specific context to pass via the callback function
|
* \param ctx user specific context to pass via the callback function
|
||||||
* \param buf_num optional buffer count, buf_num * buf_len = overall buffer size
|
* \param buf_num optional buffer count, buf_num * buf_len = overall buffer size
|
||||||
* set to 0 for default buffer count (32)
|
* set to 0 for default buffer count (15)
|
||||||
* \param buf_len optional buffer length, must be multiple of 512,
|
* \param buf_len optional buffer length, must be multiple of 512,
|
||||||
* set to 0 for default buffer length (16 * 32 * 512)
|
* should be a multiple of 16384 (URB size), set to 0
|
||||||
|
* for default buffer length (16 * 32 * 512)
|
||||||
* \return 0 on success
|
* \return 0 on success
|
||||||
*/
|
*/
|
||||||
RTLSDR_API int rtlsdr_read_async(rtlsdr_dev_t *dev,
|
RTLSDR_API int rtlsdr_read_async(rtlsdr_dev_t *dev,
|
||||||
|
BIN
external/rtl-sdr-release/x64/convenience_static.lib
vendored
BIN
external/rtl-sdr-release/x64/convenience_static.lib
vendored
Binary file not shown.
BIN
external/rtl-sdr-release/x64/libconvenience_static.a
vendored
Normal file
BIN
external/rtl-sdr-release/x64/libconvenience_static.a
vendored
Normal file
Binary file not shown.
BIN
external/rtl-sdr-release/x64/liblibgetopt_static.a
vendored
Normal file
BIN
external/rtl-sdr-release/x64/liblibgetopt_static.a
vendored
Normal file
Binary file not shown.
BIN
external/rtl-sdr-release/x64/librtlsdr.dll
vendored
Normal file
BIN
external/rtl-sdr-release/x64/librtlsdr.dll
vendored
Normal file
Binary file not shown.
BIN
external/rtl-sdr-release/x64/librtlsdr.dll.a
vendored
Normal file
BIN
external/rtl-sdr-release/x64/librtlsdr.dll.a
vendored
Normal file
Binary file not shown.
BIN
external/rtl-sdr-release/x64/librtlsdr_static.a
vendored
Normal file
BIN
external/rtl-sdr-release/x64/librtlsdr_static.a
vendored
Normal file
Binary file not shown.
BIN
external/rtl-sdr-release/x64/libusb-1.0.dll
vendored
BIN
external/rtl-sdr-release/x64/libusb-1.0.dll
vendored
Binary file not shown.
BIN
external/rtl-sdr-release/x64/rtlsdr.dll
vendored
BIN
external/rtl-sdr-release/x64/rtlsdr.dll
vendored
Binary file not shown.
BIN
external/rtl-sdr-release/x64/rtlsdr.lib
vendored
BIN
external/rtl-sdr-release/x64/rtlsdr.lib
vendored
Binary file not shown.
BIN
external/rtl-sdr-release/x64/rtlsdr_static.lib
vendored
BIN
external/rtl-sdr-release/x64/rtlsdr_static.lib
vendored
Binary file not shown.
134
src/AppFrame.cpp
134
src/AppFrame.cpp
@ -12,10 +12,12 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "SDRThread.h"
|
#include "SDRThread.h"
|
||||||
#include "DemodulatorThread.h"
|
#include "DemodulatorMgr.h"
|
||||||
#include "AudioThread.h"
|
#include "AudioThread.h"
|
||||||
#include "CubicSDR.h"
|
#include "CubicSDR.h"
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
wxBEGIN_EVENT_TABLE(AppFrame, wxFrame)
|
wxBEGIN_EVENT_TABLE(AppFrame, wxFrame)
|
||||||
//EVT_MENU(wxID_NEW, AppFrame::OnNewWindow)
|
//EVT_MENU(wxID_NEW, AppFrame::OnNewWindow)
|
||||||
EVT_MENU(wxID_CLOSE, AppFrame::OnClose)
|
EVT_MENU(wxID_CLOSE, AppFrame::OnClose)
|
||||||
@ -56,32 +58,26 @@ AppFrame::AppFrame() :
|
|||||||
Centre();
|
Centre();
|
||||||
Show();
|
Show();
|
||||||
|
|
||||||
threadQueueSDR = new SDRThreadQueue(this);
|
audioInputQueue = new AudioThreadInputQueue;
|
||||||
t_SDR = new SDRThread(threadQueueSDR);
|
audioThread = new AudioThread(audioInputQueue);
|
||||||
if (t_SDR->Run() != wxTHREAD_NO_ERROR) {
|
|
||||||
wxLogError
|
|
||||||
("Can't create the SDR thread!");
|
|
||||||
delete t_SDR;
|
|
||||||
t_SDR = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
threadQueueDemod = new DemodulatorThreadQueue(this);
|
threadAudio = new std::thread(&AudioThread::threadMain, audioThread);
|
||||||
t_Demod = new DemodulatorThread(threadQueueDemod);
|
|
||||||
if (t_Demod->Run() != wxTHREAD_NO_ERROR) {
|
|
||||||
wxLogError
|
|
||||||
("Can't create the Demodulator thread!");
|
|
||||||
delete t_Demod;
|
|
||||||
t_Demod = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
threadQueueAudio = new AudioThreadQueue(this);
|
demodulatorTest = demodMgr.newThread();
|
||||||
t_Audio = new AudioThread(threadQueueAudio);
|
demodulatorTest->params.audioInputQueue = audioInputQueue;
|
||||||
if (t_Audio->Run() != wxTHREAD_NO_ERROR) {
|
demodulatorTest->init();
|
||||||
wxLogError
|
|
||||||
("Can't create the Audio thread!");
|
audioVisualQueue = new DemodulatorThreadOutputQueue();
|
||||||
delete t_Audio;
|
demodulatorTest->setVisualOutputQueue(audioVisualQueue);
|
||||||
t_Audio = NULL;
|
|
||||||
}
|
threadCmdQueueSDR = new SDRThreadCommandQueue;
|
||||||
|
sdrThread = new SDRThread(threadCmdQueueSDR);
|
||||||
|
sdrThread->bindDemodulator(demodulatorTest);
|
||||||
|
|
||||||
|
iqVisualQueue = new SDRThreadIQDataQueue;
|
||||||
|
sdrThread->setIQVisualQueue(iqVisualQueue);
|
||||||
|
|
||||||
|
threadSDR = new std::thread(&SDRThread::threadMain, sdrThread);
|
||||||
|
|
||||||
// static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
|
// static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
|
||||||
// wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not");
|
// wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not");
|
||||||
@ -89,21 +85,11 @@ AppFrame::AppFrame() :
|
|||||||
}
|
}
|
||||||
|
|
||||||
AppFrame::~AppFrame() {
|
AppFrame::~AppFrame() {
|
||||||
{
|
|
||||||
wxCriticalSectionLocker enter(m_pThreadCS);
|
|
||||||
if (t_SDR) {
|
|
||||||
wxMessageOutputDebug().Printf("CubicSDR: deleting thread");
|
|
||||||
if (t_SDR->Delete() != wxTHREAD_NO_ERROR) {
|
|
||||||
wxLogError
|
|
||||||
("Can't delete the thread!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete t_SDR;
|
// delete t_SDR;
|
||||||
delete threadQueueAudio;
|
delete audioInputQueue;
|
||||||
delete threadQueueDemod;
|
delete audioThread;
|
||||||
delete threadQueueSDR;
|
delete threadCmdQueueSDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) {
|
void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) {
|
||||||
@ -118,70 +104,62 @@ void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
|
|||||||
|
|
||||||
void AppFrame::OnThread(wxCommandEvent& event) {
|
void AppFrame::OnThread(wxCommandEvent& event) {
|
||||||
SDRThreadIQData *iqData;
|
SDRThreadIQData *iqData;
|
||||||
DemodulatorThreadAudioData *demodAudioData;
|
|
||||||
|
|
||||||
std::vector<signed char> *new_uc_buffer;
|
std::vector<signed char> *new_uc_buffer;
|
||||||
std::vector<float> *new_float_buffer;
|
std::vector<float> *new_float_buffer;
|
||||||
|
std::string asdf("beep");
|
||||||
switch (event.GetId()) {
|
|
||||||
|
|
||||||
// SDR IQ -> Demodulator
|
// SDR IQ -> Demodulator
|
||||||
case SDRThreadTask::SDR_THREAD_DATA:
|
|
||||||
iqData = (SDRThreadIQData *) event.GetClientData();
|
|
||||||
new_uc_buffer = &(iqData->data);
|
|
||||||
if (new_uc_buffer->size()) {
|
|
||||||
DemodulatorThreadTask task = DemodulatorThreadTask(DemodulatorThreadTask::DEMOD_THREAD_DATA);
|
|
||||||
task.data = new DemodulatorThreadIQData(iqData->bandwidth, iqData->frequency, iqData->data);
|
|
||||||
threadQueueDemod->addTask(task, DemodulatorThreadQueue::DEMOD_PRIORITY_HIGHEST);
|
|
||||||
|
|
||||||
spectrumCanvas->setData(new_uc_buffer);
|
event.Skip();
|
||||||
waterfallCanvas->setData(new_uc_buffer);
|
}
|
||||||
|
|
||||||
|
void AppFrame::OnIdle(wxIdleEvent& event) {
|
||||||
|
bool work_done = false;
|
||||||
|
|
||||||
|
if (!iqVisualQueue->empty()) {
|
||||||
|
SDRThreadIQData iqData;
|
||||||
|
iqVisualQueue->pop(iqData);
|
||||||
|
|
||||||
|
if (iqData.data.size()) {
|
||||||
|
spectrumCanvas->setData(&iqData.data);
|
||||||
|
waterfallCanvas->setData(&iqData.data);
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Incoming IQ data empty?" << std::endl;
|
std::cout << "Incoming IQ data empty?" << std::endl;
|
||||||
}
|
}
|
||||||
delete iqData;
|
work_done = true;
|
||||||
|
|
||||||
break; // thread wants to exit: disable controls and destroy main window
|
|
||||||
|
|
||||||
// Demodulator -> Audio
|
|
||||||
case DemodulatorThreadTask::DEMOD_THREAD_AUDIO_DATA:
|
|
||||||
demodAudioData = (DemodulatorThreadAudioData *) event.GetClientData();
|
|
||||||
new_float_buffer = &(demodAudioData->data);
|
|
||||||
if (new_float_buffer->size()) {
|
|
||||||
AudioThreadTask task = AudioThreadTask(AudioThreadTask::AUDIO_THREAD_DATA);
|
|
||||||
task.data = new AudioThreadData(demodAudioData->frequency, demodAudioData->sampleRate, demodAudioData->data);
|
|
||||||
threadQueueAudio->addTask(task, AudioThreadQueue::AUDIO_PRIORITY_HIGHEST);
|
|
||||||
|
|
||||||
if (scopeCanvas->waveform_points.size() != new_float_buffer->size() * 2) {
|
|
||||||
scopeCanvas->waveform_points.resize(new_float_buffer->size() * 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0, iMax = new_float_buffer->size(); i < iMax; i++) {
|
if (!audioVisualQueue->empty()) {
|
||||||
scopeCanvas->waveform_points[i * 2 + 1] = (*new_float_buffer)[i] * 0.5f;
|
AudioThreadInput demodAudioData;
|
||||||
|
audioVisualQueue->pop(demodAudioData);
|
||||||
|
if (demodAudioData.data.size()) {
|
||||||
|
|
||||||
|
if (scopeCanvas->waveform_points.size() != demodAudioData.data.size() * 2) {
|
||||||
|
scopeCanvas->waveform_points.resize(demodAudioData.data.size() * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iMax = demodAudioData.data.size(); i < iMax; i++) {
|
||||||
|
scopeCanvas->waveform_points[i * 2 + 1] = demodAudioData.data[i] * 0.5f;
|
||||||
scopeCanvas->waveform_points[i * 2] = ((double) i / (double) iMax);
|
scopeCanvas->waveform_points[i * 2] = ((double) i / (double) iMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Incoming Demodulator data empty?" << std::endl;
|
std::cout << "Incoming Demodulator data empty?" << std::endl;
|
||||||
}
|
}
|
||||||
delete demodAudioData;
|
work_done = true;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
if (!work_done) {
|
||||||
default:
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppFrame::OnIdle(wxIdleEvent& event) {
|
|
||||||
|
|
||||||
event.Skip();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppFrame::setFrequency(unsigned int freq) {
|
void AppFrame::setFrequency(unsigned int freq) {
|
||||||
frequency = freq;
|
frequency = freq;
|
||||||
SDRThreadTask task = SDRThreadTask(SDRThreadTask::SDR_THREAD_TUNING);
|
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_TUNE);
|
||||||
task.setUInt(freq);
|
command.int_value = freq;
|
||||||
threadQueueSDR->addTask(task, SDRThreadQueue::SDR_PRIORITY_HIGHEST);
|
threadCmdQueueSDR->push(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AppFrame::getFrequency() {
|
int AppFrame::getFrequency() {
|
||||||
|
@ -4,21 +4,21 @@
|
|||||||
#include "PrimaryGLContext.h"
|
#include "PrimaryGLContext.h"
|
||||||
#include "SDRThread.h"
|
#include "SDRThread.h"
|
||||||
#include "AudioThread.h"
|
#include "AudioThread.h"
|
||||||
#include "DemodulatorThread.h"
|
#include "DemodulatorMgr.h"
|
||||||
|
|
||||||
#include "ScopeCanvas.h"
|
#include "ScopeCanvas.h"
|
||||||
#include "SpectrumCanvas.h"
|
#include "SpectrumCanvas.h"
|
||||||
#include "WaterfallCanvas.h"
|
#include "WaterfallCanvas.h"
|
||||||
|
#include "ThreadQueue.h"
|
||||||
|
|
||||||
// Define a new frame type
|
// Define a new frame type
|
||||||
class AppFrame: public wxFrame {
|
class AppFrame: public wxFrame {
|
||||||
public:
|
public:
|
||||||
AppFrame();
|
AppFrame();
|
||||||
~AppFrame();
|
~AppFrame();
|
||||||
void OnThread (wxCommandEvent& event);
|
void OnThread(wxCommandEvent& event);
|
||||||
void OnEventInput(wxThreadEvent& event);
|
void OnEventInput(wxThreadEvent& event);
|
||||||
|
|
||||||
|
|
||||||
void setFrequency(unsigned int freq);
|
void setFrequency(unsigned int freq);
|
||||||
int getFrequency();
|
int getFrequency();
|
||||||
|
|
||||||
@ -31,16 +31,24 @@ private:
|
|||||||
SpectrumCanvas *spectrumCanvas;
|
SpectrumCanvas *spectrumCanvas;
|
||||||
WaterfallCanvas *waterfallCanvas;
|
WaterfallCanvas *waterfallCanvas;
|
||||||
|
|
||||||
SDRThread *t_SDR;
|
DemodulatorMgr demodMgr;
|
||||||
SDRThreadQueue* threadQueueSDR;
|
|
||||||
AudioThread *t_Audio;
|
|
||||||
AudioThreadQueue* threadQueueAudio;
|
|
||||||
DemodulatorThread *t_Demod;
|
|
||||||
DemodulatorThreadQueue* threadQueueDemod;
|
|
||||||
|
|
||||||
wxCriticalSection m_pThreadCS;
|
wxCriticalSection m_pThreadCS;
|
||||||
unsigned int frequency;
|
unsigned int frequency;
|
||||||
|
|
||||||
|
DemodulatorInstance *demodulatorTest;
|
||||||
|
|
||||||
|
AudioThreadInputQueue *audioInputQueue;
|
||||||
|
AudioThread *audioThread;
|
||||||
|
|
||||||
|
SDRThread *sdrThread;
|
||||||
|
SDRThreadCommandQueue* threadCmdQueueSDR;
|
||||||
|
SDRThreadIQDataQueue* iqVisualQueue;
|
||||||
|
DemodulatorThreadOutputQueue* audioVisualQueue;
|
||||||
|
|
||||||
|
std::thread *threadAudio;
|
||||||
|
std::thread *threadSDR;
|
||||||
|
|
||||||
// event table
|
// event table
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
};
|
};
|
||||||
|
@ -1,126 +0,0 @@
|
|||||||
#include "AudioThread.h"
|
|
||||||
#include "CubicSDRDefs.h"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
//wxDEFINE_EVENT(wxEVT_COMMAND_AudioThread_INPUT, wxThreadEvent);
|
|
||||||
|
|
||||||
AudioThread::AudioThread(AudioThreadQueue* pQueue, int id) :
|
|
||||||
wxThread(wxTHREAD_DETACHED), m_pQueue(pQueue), m_ID(id), audio_queue_ptr(0), stream(NULL) {
|
|
||||||
|
|
||||||
}
|
|
||||||
AudioThread::~AudioThread() {
|
|
||||||
PaError err;
|
|
||||||
err = Pa_StopStream(stream);
|
|
||||||
err = Pa_CloseStream(stream);
|
|
||||||
Pa_Terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo,
|
|
||||||
PaStreamCallbackFlags statusFlags, void *userData) {
|
|
||||||
|
|
||||||
AudioThread *src = (AudioThread *) userData;
|
|
||||||
|
|
||||||
float *out = (float*) outputBuffer;
|
|
||||||
|
|
||||||
if (!src->audio_queue.size()) {
|
|
||||||
for (int i = 0; i < framesPerBuffer * 2; i++) {
|
|
||||||
out[i] = 0;
|
|
||||||
}
|
|
||||||
return paContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<float> nextBuffer = src->audio_queue.front();
|
|
||||||
|
|
||||||
for (int i = 0; i < framesPerBuffer * 2; i++) {
|
|
||||||
out[i] = nextBuffer[src->audio_queue_ptr];
|
|
||||||
|
|
||||||
src->audio_queue_ptr++;
|
|
||||||
|
|
||||||
if (src->audio_queue_ptr == nextBuffer.size()) {
|
|
||||||
src->audio_queue.pop();
|
|
||||||
src->audio_queue_ptr = 0;
|
|
||||||
if (!src->audio_queue.size()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
nextBuffer = src->audio_queue.front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return paContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxThread::ExitCode AudioThread::Entry() {
|
|
||||||
|
|
||||||
PaError err;
|
|
||||||
err = Pa_Initialize();
|
|
||||||
if (err != paNoError) {
|
|
||||||
std::cout << "Error starting :(\n";
|
|
||||||
return (wxThread::ExitCode) 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int preferred_device = -1;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
wchar_t dev_str[255];
|
|
||||||
memset(dev_str, 0, sizeof(wchar_t) * 255);
|
|
||||||
std::wstring env_name(L"PA_RECOMMENDED_OUTPUT_DEVICE");
|
|
||||||
GetEnvironmentVariable(env_name.c_str(), dev_str, 255);
|
|
||||||
std::wstring env_result(dev_str);
|
|
||||||
|
|
||||||
int env_dev = _wtoi(env_result.c_str());
|
|
||||||
|
|
||||||
if (env_dev || env_result.length()) {
|
|
||||||
std::cout << "Using preferred PortAudio device PA_RECOMMENDED_OUTPUT_DEVICE=" << env_result.c_str() << std::endl;
|
|
||||||
preferred_device = env_dev;
|
|
||||||
} else {
|
|
||||||
std::cout << "Environment variable PA_RECOMMENDED_OUTPUT_DEVICE not set, using PortAudio defaults." << std::endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
outputParameters.device = (preferred_device != -1) ? preferred_device : Pa_GetDefaultOutputDevice();
|
|
||||||
if (outputParameters.device == paNoDevice) {
|
|
||||||
std::cout << "Error: No default output device.\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
outputParameters.channelCount = 2; /* Stereo output, most likely supported. */
|
|
||||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output. */
|
|
||||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
|
|
||||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
|
||||||
|
|
||||||
stream = NULL;
|
|
||||||
|
|
||||||
err = Pa_OpenStream(&stream, NULL, &outputParameters, AUDIO_FREQUENCY, 1024, paClipOff, &patestCallback, this);
|
|
||||||
|
|
||||||
err = Pa_StartStream(stream);
|
|
||||||
if (err != paNoError) {
|
|
||||||
std::cout << "Error starting stream: " << Pa_GetErrorText(err) << std::endl;
|
|
||||||
std::cout << "\tPortAudio error: " << Pa_GetErrorText(err) << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!TestDestroy()) {
|
|
||||||
|
|
||||||
if (m_pQueue->stackSize()) {
|
|
||||||
|
|
||||||
while (m_pQueue->stackSize()) {
|
|
||||||
AudioThreadTask task = m_pQueue->pop(); // pop a task from the queue. this will block the worker thread if queue is empty
|
|
||||||
switch (task.m_cmd) {
|
|
||||||
case AudioThreadTask::AUDIO_THREAD_DATA:
|
|
||||||
if (!TestDestroy()) {
|
|
||||||
audio_queue.push(task.data->data);
|
|
||||||
}
|
|
||||||
delete task.data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this->Yield();
|
|
||||||
this->Sleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cout << std::endl << "Audio Thread Done." << std::endl << std::endl;
|
|
||||||
|
|
||||||
return (wxThread::ExitCode) 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <queue>
|
|
||||||
#include <vector>
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "wx/thread.h"
|
|
||||||
|
|
||||||
#include "AudioThreadQueue.h"
|
|
||||||
#include "portaudio.h"
|
|
||||||
#ifdef WIN32
|
|
||||||
#include "pa_stream.h"
|
|
||||||
#include "pa_debugprint.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo,
|
|
||||||
PaStreamCallbackFlags statusFlags, void *userData);
|
|
||||||
|
|
||||||
// declare a new type of event, to be used by our AudioThread class:
|
|
||||||
//wxDECLARE_EVENT(wxEVT_COMMAND_AudioThread_COMPLETED, wxThreadEvent);
|
|
||||||
//wxDECLARE_EVENT(wxEVT_COMMAND_AudioThread_UPDATE, wxThreadEvent);
|
|
||||||
//wxDECLARE_EVENT(wxEVT_COMMAND_AudioThread_INPUT, wxThreadEvent);
|
|
||||||
|
|
||||||
enum {
|
|
||||||
EVENT_AUDIO_INPUT = wxID_HIGHEST + 3
|
|
||||||
};
|
|
||||||
|
|
||||||
class AudioThread: public wxThread {
|
|
||||||
public:
|
|
||||||
std::queue<std::vector<float> > audio_queue;
|
|
||||||
unsigned int audio_queue_ptr;
|
|
||||||
|
|
||||||
AudioThread(AudioThreadQueue* pQueue, int id = 0);
|
|
||||||
~AudioThread();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ExitCode Entry();
|
|
||||||
AudioThreadQueue* m_pQueue;
|
|
||||||
int m_ID;
|
|
||||||
|
|
||||||
PaStreamParameters outputParameters;
|
|
||||||
PaStream *stream;
|
|
||||||
};
|
|
@ -1,43 +0,0 @@
|
|||||||
#include "AudioThreadQueue.h"
|
|
||||||
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AudioThreadQueue::AudioThreadQueue(wxEvtHandler* pParent) :
|
|
||||||
m_pParent(pParent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioThreadQueue::addTask(const AudioThreadTask& task, const AUDIO_PRIORITY& priority) {
|
|
||||||
wxMutexLocker lock(m_MutexQueue);
|
|
||||||
m_Tasks.insert(std::make_pair(priority, task));
|
|
||||||
m_QueueCount.Post();
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioThreadTask AudioThreadQueue::pop() {
|
|
||||||
AudioThreadTask element;
|
|
||||||
m_QueueCount.Wait();
|
|
||||||
m_MutexQueue.Lock();
|
|
||||||
element = (m_Tasks.begin())->second;
|
|
||||||
m_Tasks.erase(m_Tasks.begin());
|
|
||||||
m_MutexQueue.Unlock();
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioThreadQueue::report(const AudioThreadTask::AUDIO_THREAD_COMMAND& cmd, const wxString& sArg, int iArg) {
|
|
||||||
wxCommandEvent evt(wxEVT_THREAD, cmd);
|
|
||||||
evt.SetString(sArg);
|
|
||||||
evt.SetInt(iArg);
|
|
||||||
m_pParent->AddPendingEvent(evt);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t AudioThreadQueue::stackSize() {
|
|
||||||
wxMutexLocker lock(m_MutexQueue);
|
|
||||||
return m_Tasks.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
wxEvtHandler* AudioThreadQueue::getHandler() {
|
|
||||||
return m_pParent;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include "AudioThreadTask.h"
|
|
||||||
|
|
||||||
#include "wx/event.h"
|
|
||||||
|
|
||||||
class AudioThreadQueue {
|
|
||||||
public:
|
|
||||||
enum AUDIO_PRIORITY {
|
|
||||||
AUDIO_PRIORITY_HIGHEST, AUDIO_PRIORITY_HIGHER, AUDIO_PRIORITY_NORMAL, AUDIO_PRIORITY_BELOW_NORMAL, AUDIO_PRIORITY_LOW, AUDIO_PRIORITY_IDLE
|
|
||||||
};
|
|
||||||
AudioThreadQueue(wxEvtHandler* pParent);
|
|
||||||
|
|
||||||
void addTask(const AudioThreadTask& task, const AUDIO_PRIORITY& priority = AUDIO_PRIORITY_NORMAL);
|
|
||||||
void report(const AudioThreadTask::AUDIO_THREAD_COMMAND& cmd, const wxString& sArg = wxEmptyString, int iArg = 0);
|
|
||||||
|
|
||||||
AudioThreadTask pop();
|
|
||||||
size_t stackSize();
|
|
||||||
|
|
||||||
wxEvtHandler* getHandler();
|
|
||||||
|
|
||||||
private:
|
|
||||||
wxEvtHandler* m_pParent;
|
|
||||||
std::multimap<AUDIO_PRIORITY, AudioThreadTask> m_Tasks;
|
|
||||||
wxMutex m_MutexQueue;
|
|
||||||
wxSemaphore m_QueueCount;
|
|
||||||
};
|
|
@ -1,2 +0,0 @@
|
|||||||
#include "AudioThreadTask.h"
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "wx/defs.h"
|
|
||||||
#include "wx/string.h"
|
|
||||||
#include "wx/object.h"
|
|
||||||
|
|
||||||
class AudioThreadData: public wxObject {
|
|
||||||
public:
|
|
||||||
unsigned int frequency;
|
|
||||||
unsigned int sampleRate;
|
|
||||||
unsigned short channels;
|
|
||||||
|
|
||||||
std::vector<float> data;
|
|
||||||
|
|
||||||
AudioThreadData(unsigned int frequency, unsigned int sampleRate, std::vector<float> data) :
|
|
||||||
data(data), sampleRate(sampleRate), frequency(frequency) {
|
|
||||||
channels = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
~AudioThreadData() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class AudioThreadTask {
|
|
||||||
public:
|
|
||||||
enum AUDIO_THREAD_COMMAND {
|
|
||||||
AUDIO_THREAD_EXIT = wxID_EXIT,
|
|
||||||
AUDIO_THREAD_NULL = wxID_HIGHEST + 200,
|
|
||||||
AUDIO_THREAD_STARTED,
|
|
||||||
AUDIO_THREAD_PROCESS,
|
|
||||||
AUDIO_THREAD_ERROR,
|
|
||||||
AUDIO_THREAD_DATA
|
|
||||||
};
|
|
||||||
|
|
||||||
AudioThreadTask() :
|
|
||||||
m_cmd(AUDIO_THREAD_NULL), data(NULL) {
|
|
||||||
}
|
|
||||||
AudioThreadTask(AUDIO_THREAD_COMMAND cmd) :
|
|
||||||
m_cmd(cmd), data(NULL) {
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioThreadData *data;
|
|
||||||
|
|
||||||
AUDIO_THREAD_COMMAND m_cmd;
|
|
||||||
};
|
|
@ -1,154 +0,0 @@
|
|||||||
#include "DemodulatorThread.h"
|
|
||||||
#include "CubicSDRDefs.h"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
DemodulatorThread::DemodulatorThread(DemodulatorThreadQueue* pQueue, int id) :
|
|
||||||
wxThread(wxTHREAD_DETACHED), m_pQueue(pQueue), m_ID(id) {
|
|
||||||
|
|
||||||
bandwidth = 200000;
|
|
||||||
resample_ratio = (float) (bandwidth) / (float) SRATE;
|
|
||||||
wbfm_frequency = 100000;
|
|
||||||
wbfm_resample_ratio = (float) (wbfm_frequency) / (float) bandwidth;
|
|
||||||
audio_frequency = AUDIO_FREQUENCY;
|
|
||||||
audio_resample_ratio = (float) (audio_frequency) / (float) wbfm_frequency;
|
|
||||||
|
|
||||||
float fc = 0.5f * ((float) bandwidth / (float) SRATE) * 0.75; // filter cutoff frequency
|
|
||||||
float ft = 0.05f; // filter transition
|
|
||||||
float As = 60.0f; // stop-band attenuation [dB]
|
|
||||||
float mu = 0.0f; // fractional timing offset
|
|
||||||
|
|
||||||
// estimate required filter length and generate filter
|
|
||||||
unsigned int h_len = estimate_req_filter_len(ft, As);
|
|
||||||
float h[h_len];
|
|
||||||
liquid_firdes_kaiser(h_len, fc, As, mu, h);
|
|
||||||
|
|
||||||
fir_filter = firfilt_crcf_create(h, h_len);
|
|
||||||
|
|
||||||
h_len = estimate_req_filter_len(ft, As);
|
|
||||||
liquid_firdes_kaiser(h_len, 32000.0 / (float) wbfm_frequency, As, mu, h);
|
|
||||||
|
|
||||||
fir_audio_filter = firfilt_crcf_create(h, h_len);
|
|
||||||
|
|
||||||
// create multi-stage arbitrary resampler object
|
|
||||||
resampler = msresamp_crcf_create(resample_ratio, As);
|
|
||||||
msresamp_crcf_print(resampler);
|
|
||||||
|
|
||||||
wbfm_resampler = msresamp_crcf_create(wbfm_resample_ratio, As);
|
|
||||||
msresamp_crcf_print(wbfm_resampler);
|
|
||||||
|
|
||||||
audio_resampler = msresamp_crcf_create(audio_resample_ratio, As);
|
|
||||||
msresamp_crcf_print(audio_resampler);
|
|
||||||
|
|
||||||
float kf = 0.75; // modulation factor
|
|
||||||
|
|
||||||
fdem = freqdem_create(kf);
|
|
||||||
freqdem_print(fdem);
|
|
||||||
}
|
|
||||||
|
|
||||||
DemodulatorThread::~DemodulatorThread() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
wxThread::ExitCode DemodulatorThread::Entry() {
|
|
||||||
|
|
||||||
while (!TestDestroy()) {
|
|
||||||
|
|
||||||
if (m_pQueue->stackSize()) {
|
|
||||||
|
|
||||||
while (m_pQueue->stackSize()) {
|
|
||||||
DemodulatorThreadTask task = m_pQueue->pop(); // pop a task from the queue. this will block the worker thread if queue is empty
|
|
||||||
switch (task.m_cmd) {
|
|
||||||
case DemodulatorThreadTask::DEMOD_THREAD_DATA:
|
|
||||||
std::vector<signed char> *data = &task.data->data;
|
|
||||||
if (data->size()) {
|
|
||||||
liquid_float_complex filtered_input[BUF_SIZE / 2];
|
|
||||||
|
|
||||||
for (int i = 0; i < BUF_SIZE / 2; i++) {
|
|
||||||
|
|
||||||
liquid_float_complex x;
|
|
||||||
liquid_float_complex y;
|
|
||||||
|
|
||||||
x.real = (float) (*data)[i * 2] / 127.0f;
|
|
||||||
x.imag = (float) (*data)[i * 2 + 1] / 127.0f;
|
|
||||||
|
|
||||||
firfilt_crcf_push(fir_filter, x); // push input sample
|
|
||||||
firfilt_crcf_execute(fir_filter, &y); // compute output
|
|
||||||
|
|
||||||
filtered_input[i] = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
int out_size = ceil((float) (BUF_SIZE / 2) * resample_ratio);
|
|
||||||
|
|
||||||
liquid_float_complex resampled_output[out_size];
|
|
||||||
|
|
||||||
unsigned int num_written; // number of values written to buffer
|
|
||||||
msresamp_crcf_execute(resampler, filtered_input, (BUF_SIZE / 2), resampled_output, &num_written);
|
|
||||||
|
|
||||||
float waveform_ceil = 0, waveform_floor = 0;
|
|
||||||
|
|
||||||
float pcm = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < num_written; i++) {
|
|
||||||
freqdem_demodulate(fdem, resampled_output[i], &pcm);
|
|
||||||
|
|
||||||
resampled_output[i].real = (float) pcm;
|
|
||||||
resampled_output[i].imag = 0;
|
|
||||||
|
|
||||||
if (waveform_ceil < resampled_output[i].real) {
|
|
||||||
waveform_ceil = resampled_output[i].real;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waveform_floor > resampled_output[i].real) {
|
|
||||||
waveform_floor = resampled_output[i].real;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int wbfm_out_size = ceil((float) (num_written) * wbfm_resample_ratio);
|
|
||||||
liquid_float_complex resampled_wbfm_output[wbfm_out_size];
|
|
||||||
|
|
||||||
unsigned int num_wbfm_written;
|
|
||||||
msresamp_crcf_execute(wbfm_resampler, resampled_output, num_written, resampled_wbfm_output, &num_wbfm_written);
|
|
||||||
|
|
||||||
for (int i = 0; i < num_wbfm_written; i++) {
|
|
||||||
firfilt_crcf_push(fir_audio_filter, resampled_wbfm_output[i]);
|
|
||||||
firfilt_crcf_execute(fir_audio_filter, &resampled_wbfm_output[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int audio_out_size = ceil((float) (num_wbfm_written) * audio_resample_ratio);
|
|
||||||
liquid_float_complex resampled_audio_output[audio_out_size];
|
|
||||||
|
|
||||||
unsigned int num_audio_written;
|
|
||||||
msresamp_crcf_execute(audio_resampler, resampled_wbfm_output, num_wbfm_written, resampled_audio_output, &num_audio_written);
|
|
||||||
|
|
||||||
std::vector<float> newBuffer;
|
|
||||||
newBuffer.resize(num_audio_written * 2);
|
|
||||||
for (int i = 0; i < num_audio_written; i++) {
|
|
||||||
liquid_float_complex y = resampled_audio_output[i];
|
|
||||||
|
|
||||||
newBuffer[i * 2] = y.real;
|
|
||||||
newBuffer[i * 2 + 1] = y.real;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!TestDestroy()) {
|
|
||||||
DemodulatorThreadAudioData *audioOut = new DemodulatorThreadAudioData(task.data->frequency,audio_frequency,newBuffer);
|
|
||||||
|
|
||||||
m_pQueue->sendAudioData(DemodulatorThreadTask::DEMOD_THREAD_AUDIO_DATA,audioOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete task.data;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this->Yield();
|
|
||||||
this->Sleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cout << std::endl << "Demodulator Thread Done." << std::endl << std::endl;
|
|
||||||
|
|
||||||
return (wxThread::ExitCode) 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <queue>
|
|
||||||
#include <vector>
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "wx/thread.h"
|
|
||||||
|
|
||||||
#include "DemodulatorThreadQueue.h"
|
|
||||||
#include "liquid/liquid.h"
|
|
||||||
|
|
||||||
|
|
||||||
enum {
|
|
||||||
EVENT_DEMOD_INPUT = wxID_HIGHEST + 2
|
|
||||||
};
|
|
||||||
|
|
||||||
class DemodulatorThread: public wxThread {
|
|
||||||
public:
|
|
||||||
DemodulatorThread(DemodulatorThreadQueue* pQueue, int id = 0);
|
|
||||||
~DemodulatorThread();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ExitCode Entry();
|
|
||||||
DemodulatorThreadQueue* m_pQueue;
|
|
||||||
int m_ID;
|
|
||||||
|
|
||||||
firfilt_crcf fir_filter;
|
|
||||||
firfilt_crcf fir_audio_filter;
|
|
||||||
|
|
||||||
unsigned int bandwidth;
|
|
||||||
msresamp_crcf resampler;
|
|
||||||
float resample_ratio;
|
|
||||||
|
|
||||||
unsigned int wbfm_frequency;
|
|
||||||
msresamp_crcf wbfm_resampler;
|
|
||||||
float wbfm_resample_ratio;
|
|
||||||
|
|
||||||
unsigned int audio_frequency;
|
|
||||||
msresamp_crcf audio_resampler;
|
|
||||||
float audio_resample_ratio;
|
|
||||||
|
|
||||||
freqdem fdem;
|
|
||||||
};
|
|
@ -1,44 +0,0 @@
|
|||||||
#include "DemodulatorThreadQueue.h"
|
|
||||||
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DemodulatorThreadQueue::DemodulatorThreadQueue(wxEvtHandler* pParent) :
|
|
||||||
m_pParent(pParent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void DemodulatorThreadQueue::addTask(const DemodulatorThreadTask& task, const DEMOD_PRIORITY& priority) {
|
|
||||||
wxMutexLocker lock(m_MutexQueue);
|
|
||||||
m_Tasks.insert(std::make_pair(priority, task));
|
|
||||||
m_QueueCount.Post();
|
|
||||||
}
|
|
||||||
|
|
||||||
DemodulatorThreadTask DemodulatorThreadQueue::pop() {
|
|
||||||
DemodulatorThreadTask element;
|
|
||||||
m_QueueCount.Wait();
|
|
||||||
m_MutexQueue.Lock();
|
|
||||||
element = (m_Tasks.begin())->second;
|
|
||||||
m_Tasks.erase(m_Tasks.begin());
|
|
||||||
m_MutexQueue.Unlock();
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DemodulatorThreadQueue::sendAudioData(const DemodulatorThreadTask::DEMOD_THREAD_COMMAND& cmd, DemodulatorThreadAudioData *data) {
|
|
||||||
wxCommandEvent evt(wxEVT_THREAD, cmd);
|
|
||||||
|
|
||||||
evt.SetClientData(data);
|
|
||||||
|
|
||||||
m_pParent->AddPendingEvent(evt);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t DemodulatorThreadQueue::stackSize() {
|
|
||||||
wxMutexLocker lock(m_MutexQueue);
|
|
||||||
return m_Tasks.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
wxEvtHandler* DemodulatorThreadQueue::getHandler() {
|
|
||||||
return m_pParent;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include "DemodulatorThreadTask.h"
|
|
||||||
|
|
||||||
#include "wx/event.h"
|
|
||||||
|
|
||||||
class DemodulatorThreadQueue {
|
|
||||||
public:
|
|
||||||
enum DEMOD_PRIORITY {
|
|
||||||
DEMOD_PRIORITY_HIGHEST, DEMOD_PRIORITY_HIGHER, DEMOD_PRIORITY_NORMAL, DEMOD_PRIORITY_BELOW_NORMAL, DEMOD_PRIORITY_LOW, DEMOD_PRIORITY_IDLE
|
|
||||||
};
|
|
||||||
DemodulatorThreadQueue(wxEvtHandler* pParent);
|
|
||||||
|
|
||||||
void addTask(const DemodulatorThreadTask& task, const DEMOD_PRIORITY& priority = DEMOD_PRIORITY_NORMAL);
|
|
||||||
void sendAudioData(const DemodulatorThreadTask::DEMOD_THREAD_COMMAND& cmd, DemodulatorThreadAudioData *data);
|
|
||||||
|
|
||||||
DemodulatorThreadTask pop();
|
|
||||||
size_t stackSize();
|
|
||||||
|
|
||||||
wxEvtHandler* getHandler();
|
|
||||||
|
|
||||||
private:
|
|
||||||
wxEvtHandler* m_pParent;
|
|
||||||
std::multimap<DEMOD_PRIORITY, DemodulatorThreadTask> m_Tasks;
|
|
||||||
wxMutex m_MutexQueue;
|
|
||||||
wxSemaphore m_QueueCount;
|
|
||||||
};
|
|
@ -1,2 +0,0 @@
|
|||||||
#include "DemodulatorThreadTask.h"
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include "wx/defs.h"
|
|
||||||
#include "wx/string.h"
|
|
||||||
#include "wx/object.h"
|
|
||||||
|
|
||||||
class DemodulatorThreadIQData: public wxObject {
|
|
||||||
public:
|
|
||||||
unsigned int frequency;
|
|
||||||
unsigned int bandwidth;
|
|
||||||
std::vector<signed char> data;
|
|
||||||
|
|
||||||
DemodulatorThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector<signed char> data) :
|
|
||||||
data(data), frequency(frequency), bandwidth(bandwidth) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
~DemodulatorThreadIQData() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DemodulatorThreadAudioData: public wxObject {
|
|
||||||
public:
|
|
||||||
unsigned int frequency;
|
|
||||||
unsigned int sampleRate;
|
|
||||||
unsigned char channels;
|
|
||||||
|
|
||||||
std::vector<float> data;
|
|
||||||
|
|
||||||
DemodulatorThreadAudioData(unsigned int frequency, unsigned int sampleRate, std::vector<float> data) :
|
|
||||||
data(data), sampleRate(sampleRate), frequency(frequency), channels(1) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
~DemodulatorThreadAudioData() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DemodulatorThreadTask {
|
|
||||||
public:
|
|
||||||
enum DEMOD_THREAD_COMMAND {
|
|
||||||
DEMOD_THREAD_EXIT = wxID_EXIT,
|
|
||||||
DEMOD_THREAD_NULL = wxID_HIGHEST + 100,
|
|
||||||
DEMOD_THREAD_STARTED,
|
|
||||||
DEMOD_THREAD_PROCESS,
|
|
||||||
DEMOD_THREAD_ERROR,
|
|
||||||
DEMOD_THREAD_DATA,
|
|
||||||
DEMOD_THREAD_AUDIO_DATA
|
|
||||||
};
|
|
||||||
|
|
||||||
DemodulatorThreadTask() :
|
|
||||||
m_cmd(DEMOD_THREAD_NULL), data(NULL) {
|
|
||||||
}
|
|
||||||
DemodulatorThreadTask(DEMOD_THREAD_COMMAND cmd) :
|
|
||||||
m_cmd(cmd), data(NULL) {
|
|
||||||
}
|
|
||||||
|
|
||||||
DEMOD_THREAD_COMMAND m_cmd;
|
|
||||||
|
|
||||||
DemodulatorThreadIQData *data;
|
|
||||||
};
|
|
@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
#include "rtl-sdr.h"
|
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "wx/thread.h"
|
|
||||||
|
|
||||||
#include "SDRThreadQueue.h"
|
|
||||||
|
|
||||||
class SDRThread: public wxThread {
|
|
||||||
public:
|
|
||||||
rtlsdr_dev_t *dev;
|
|
||||||
|
|
||||||
SDRThread(SDRThreadQueue* pQueue, int id = 0);
|
|
||||||
~SDRThread();
|
|
||||||
|
|
||||||
int enumerate_rtl();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ExitCode Entry();
|
|
||||||
uint32_t sample_rate;
|
|
||||||
SDRThreadQueue* m_pQueue;
|
|
||||||
int m_ID;
|
|
||||||
};
|
|
@ -1,44 +0,0 @@
|
|||||||
#include "SDRThreadQueue.h"
|
|
||||||
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SDRThreadQueue::SDRThreadQueue(wxEvtHandler* pParent) :
|
|
||||||
m_pParent(pParent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDRThreadQueue::addTask(const SDRThreadTask& task, const SDR_PRIORITY& priority) {
|
|
||||||
wxMutexLocker lock(m_MutexQueue);
|
|
||||||
m_Tasks.insert(std::make_pair(priority, task));
|
|
||||||
m_QueueCount.Post();
|
|
||||||
}
|
|
||||||
|
|
||||||
SDRThreadTask SDRThreadQueue::pop() {
|
|
||||||
SDRThreadTask element;
|
|
||||||
m_QueueCount.Wait();
|
|
||||||
m_MutexQueue.Lock();
|
|
||||||
element = (m_Tasks.begin())->second;
|
|
||||||
m_Tasks.erase(m_Tasks.begin());
|
|
||||||
m_MutexQueue.Unlock();
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDRThreadQueue::sendIQData(const SDRThreadTask::SDR_COMMAND& cmd, SDRThreadIQData *data) {
|
|
||||||
wxCommandEvent evt(wxEVT_THREAD, cmd);
|
|
||||||
|
|
||||||
evt.SetClientData(data);
|
|
||||||
|
|
||||||
m_pParent->AddPendingEvent(evt);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t SDRThreadQueue::stackSize() {
|
|
||||||
wxMutexLocker lock(m_MutexQueue);
|
|
||||||
return m_Tasks.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
wxEvtHandler* SDRThreadQueue::getHandler() {
|
|
||||||
return m_pParent;
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include "SDRThreadTask.h"
|
|
||||||
|
|
||||||
#include "wx/event.h"
|
|
||||||
|
|
||||||
class SDRThreadQueue {
|
|
||||||
public:
|
|
||||||
enum SDR_PRIORITY {
|
|
||||||
SDR_PRIORITY_HIGHEST, SDR_PRIORITY_HIGHER, SDR_PRIORITY_NORMAL, SDR_PRIORITY_BELOW_NORMAL, SDR_PRIORITY_LOW, SDR_PRIORITY_IDLE
|
|
||||||
};
|
|
||||||
SDRThreadQueue(wxEvtHandler* pParent);
|
|
||||||
|
|
||||||
void addTask(const SDRThreadTask& task, const SDR_PRIORITY& priority = SDR_PRIORITY_NORMAL);
|
|
||||||
void sendIQData(const SDRThreadTask::SDR_COMMAND& cmd, SDRThreadIQData *data);
|
|
||||||
|
|
||||||
SDRThreadTask pop();
|
|
||||||
size_t stackSize();
|
|
||||||
|
|
||||||
wxEvtHandler* getHandler();
|
|
||||||
|
|
||||||
private:
|
|
||||||
wxEvtHandler* m_pParent;
|
|
||||||
std::multimap<SDR_PRIORITY, SDRThreadTask> m_Tasks;
|
|
||||||
wxMutex m_MutexQueue;
|
|
||||||
wxSemaphore m_QueueCount;
|
|
||||||
};
|
|
@ -1,9 +0,0 @@
|
|||||||
#include "SDRThreadTask.h"
|
|
||||||
|
|
||||||
void SDRThreadTask::setUInt(unsigned int i) {
|
|
||||||
arg_int = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int SDRThreadTask::getUInt() {
|
|
||||||
return arg_int;
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include "wx/defs.h"
|
|
||||||
#include "wx/string.h"
|
|
||||||
#include "wx/object.h"
|
|
||||||
|
|
||||||
class SDRThreadIQData: public wxObject {
|
|
||||||
public:
|
|
||||||
unsigned int frequency;
|
|
||||||
unsigned int bandwidth;
|
|
||||||
std::vector<signed char> data;
|
|
||||||
|
|
||||||
SDRThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector<signed char> data) :
|
|
||||||
data(data), frequency(frequency), bandwidth(bandwidth) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
~SDRThreadIQData() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SDRThreadTask {
|
|
||||||
public:
|
|
||||||
enum SDR_COMMAND {
|
|
||||||
SDR_THREAD_EXIT = wxID_EXIT,
|
|
||||||
SDR_THREAD_NULL = wxID_HIGHEST + 1,
|
|
||||||
SDR_THREAD_STARTED,
|
|
||||||
SDR_THREAD_PROCESS,
|
|
||||||
SDR_THREAD_ERROR,
|
|
||||||
SDR_THREAD_TUNING,
|
|
||||||
SDR_THREAD_DATA
|
|
||||||
};
|
|
||||||
|
|
||||||
SDRThreadTask() :
|
|
||||||
m_cmd(SDR_THREAD_NULL), arg_int(0) {
|
|
||||||
}
|
|
||||||
SDRThreadTask(SDR_COMMAND cmd) :
|
|
||||||
arg_int(0), m_cmd(cmd) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void setUInt(unsigned int i);
|
|
||||||
unsigned int getUInt();
|
|
||||||
|
|
||||||
SDR_COMMAND m_cmd;
|
|
||||||
unsigned int arg_int;
|
|
||||||
};
|
|
176
src/Timer.h
176
src/Timer.h
@ -1,176 +0,0 @@
|
|||||||
|
|
||||||
#ifndef TIMER_H
|
|
||||||
#define TIMER_H
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
#include <sys/time.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Timer Class, high resolution timer
|
|
||||||
/**
|
|
||||||
* Class provides high resolution timing and useful time control functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Timer
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
unsigned long time_elapsed;
|
|
||||||
unsigned long system_milliseconds;
|
|
||||||
unsigned long start_time;
|
|
||||||
unsigned long end_time;
|
|
||||||
unsigned long last_update;
|
|
||||||
unsigned long num_updates;
|
|
||||||
unsigned long paused_time;
|
|
||||||
unsigned long offset;
|
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
struct timeval time_val;
|
|
||||||
struct timezone time_zone;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
bool paused_state;
|
|
||||||
bool lock_state;
|
|
||||||
float lock_rate;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
Timer();
|
|
||||||
|
|
||||||
/// Start the timer
|
|
||||||
/**
|
|
||||||
* Resets the timer to 0 and begins timing
|
|
||||||
*/
|
|
||||||
void start(void);
|
|
||||||
|
|
||||||
/// Stop the timer
|
|
||||||
/**
|
|
||||||
* Stops the timer and records the end time
|
|
||||||
*/
|
|
||||||
void stop(void);
|
|
||||||
|
|
||||||
|
|
||||||
/// Locks the timer to a specified framerate (for recording / benchmarking purposes typically)
|
|
||||||
/**
|
|
||||||
* Locks the timer to a specified framerate (for recording / benchmarking purposes typically)
|
|
||||||
*/
|
|
||||||
void lockFramerate(float f_rate);
|
|
||||||
|
|
||||||
|
|
||||||
/// Unlock any framerate lock that's been applied
|
|
||||||
/**
|
|
||||||
* Unlock any framerate lock that's been applied
|
|
||||||
*/
|
|
||||||
void unlock();
|
|
||||||
|
|
||||||
|
|
||||||
/// Check locked state
|
|
||||||
/**
|
|
||||||
* Check locked state
|
|
||||||
*/
|
|
||||||
bool locked();
|
|
||||||
|
|
||||||
|
|
||||||
/// Reset the timer counter
|
|
||||||
/**
|
|
||||||
* Resetting the timer will reset the current time to 0
|
|
||||||
*/
|
|
||||||
void reset(void);
|
|
||||||
|
|
||||||
|
|
||||||
/// Timer update
|
|
||||||
/**
|
|
||||||
* Calling the update command will bring the timer value up to date, this is meant
|
|
||||||
* to be called at the begining of the frame to establish the time index which is being drawn.
|
|
||||||
*/
|
|
||||||
void update(void);
|
|
||||||
|
|
||||||
|
|
||||||
/// Get the total time elapsed since the timer start, not counting paused time
|
|
||||||
/**
|
|
||||||
* Returns the total time elapsed in since the timer start() to the last update() but
|
|
||||||
* does not count the time elapsed while the timer is paused().
|
|
||||||
* \return Total time elapsed since the timer start() to the last update() excluding time paused() in milliseconds
|
|
||||||
*/
|
|
||||||
unsigned long getMilliseconds(void);
|
|
||||||
/// Alias of getMilliseconds() which returns time in seconds
|
|
||||||
/**
|
|
||||||
* \return Total time elapsed since the timer start() to the last update() excluding time paused() in seconds
|
|
||||||
*/
|
|
||||||
double getSeconds(void);
|
|
||||||
|
|
||||||
|
|
||||||
/// Get the total time elapsed since the timer start
|
|
||||||
/**
|
|
||||||
* Returns the total time elapsed in since the timer start() to the last update()
|
|
||||||
* this includes any time accumulated during updates while paused()
|
|
||||||
* \return Total time elapsed since the timer start() to the last update() including time paused() in milliseconds
|
|
||||||
*/
|
|
||||||
unsigned long totalMilliseconds(void);
|
|
||||||
/// Alias of totalMilliseconds() which returns time in seconds
|
|
||||||
/**
|
|
||||||
* \return Total time elapsed since the timer start() to the last update() including time paused() in seconds
|
|
||||||
*/
|
|
||||||
double totalSeconds(void);
|
|
||||||
|
|
||||||
|
|
||||||
/// Set the amount of time elapsed
|
|
||||||
/**
|
|
||||||
* Force the timer duration to a specific value, useful for rolling forward or back in a system
|
|
||||||
* based upon the timer.
|
|
||||||
* \param milliseconds_in Time to set timer to in milliseconds
|
|
||||||
*/
|
|
||||||
void setMilliseconds(unsigned long milliseconds_in);
|
|
||||||
/// alias of setMilliseconds() which accepts time in seconds
|
|
||||||
/**
|
|
||||||
* \param seconds_in Time to set timer to in seconds
|
|
||||||
*/
|
|
||||||
void setSeconds(double seconds_in);
|
|
||||||
|
|
||||||
|
|
||||||
/// Get the amount of times the update() command has been called
|
|
||||||
/**
|
|
||||||
* By using the number of times the update() command has been called you can easily determine
|
|
||||||
* an average frame rate. Also useful for merely determining how many frames have been drawn.
|
|
||||||
* \return Number of times update() has been called
|
|
||||||
*/
|
|
||||||
unsigned long getNumUpdates(void);
|
|
||||||
|
|
||||||
|
|
||||||
/// Get the timer duration during the last update
|
|
||||||
/**
|
|
||||||
* Useful for determining the amount of time which elapsed during the last update
|
|
||||||
* can be used to accurately control values with a per-second rate or determine the current frame rate.
|
|
||||||
* \return Duration of time between the last two calls to update() in milliseconds
|
|
||||||
*/
|
|
||||||
unsigned long lastUpdateMilliseconds(void);
|
|
||||||
/// Alias of lastUpdateMilliseconds() which returns time in seconds
|
|
||||||
/**
|
|
||||||
* \return Duration of time between the last two calls to update() in seconds
|
|
||||||
*/
|
|
||||||
double lastUpdateSeconds(void);
|
|
||||||
|
|
||||||
|
|
||||||
/// Set the timer pause state
|
|
||||||
/**
|
|
||||||
* Pause the timer, allowing for continued update() calls without an increment in timing but
|
|
||||||
* maintaining the update and total time count, useful for pausing a scene but allowing frame
|
|
||||||
* timing to resume.
|
|
||||||
* \param pause_in Value to set the current pause state to
|
|
||||||
*/
|
|
||||||
void paused(bool pause_in);
|
|
||||||
|
|
||||||
/// Check if the timer is currently in a paused state
|
|
||||||
/**
|
|
||||||
* \return Current pause state, true if paused, false otherwise
|
|
||||||
*/
|
|
||||||
bool paused();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
156
src/audio/AudioThread.cpp
Normal file
156
src/audio/AudioThread.cpp
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#include "AudioThread.h"
|
||||||
|
#include "CubicSDRDefs.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
AudioThread::AudioThread(AudioThreadInputQueue *inputQueue) :
|
||||||
|
inputQueue(inputQueue), stream(NULL) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioThread::~AudioThread() {
|
||||||
|
PaError err;
|
||||||
|
err = Pa_StopStream(stream);
|
||||||
|
err = Pa_CloseStream(stream);
|
||||||
|
Pa_Terminate();
|
||||||
|
|
||||||
|
std::cout << std::endl << "Audio Thread Done." << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioThread::threadMain() {
|
||||||
|
PaError err;
|
||||||
|
err = Pa_Initialize();
|
||||||
|
if (err != paNoError) {
|
||||||
|
std::cout << "Error starting portaudio :(\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int preferred_device = -1;
|
||||||
|
|
||||||
|
outputParameters.device =
|
||||||
|
(preferred_device != -1) ?
|
||||||
|
preferred_device : Pa_GetDefaultOutputDevice();
|
||||||
|
if (outputParameters.device == paNoDevice) {
|
||||||
|
std::cout << "Error: No default output device.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
outputParameters.channelCount = 2;
|
||||||
|
outputParameters.sampleFormat = paFloat32;
|
||||||
|
outputParameters.suggestedLatency = Pa_GetDeviceInfo(
|
||||||
|
outputParameters.device)->defaultHighOutputLatency;
|
||||||
|
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||||
|
|
||||||
|
stream = NULL;
|
||||||
|
|
||||||
|
// err = Pa_OpenStream(&stream, NULL, &outputParameters, AUDIO_FREQUENCY,
|
||||||
|
// paFramesPerBufferUnspecified,
|
||||||
|
// paPrimeOutputBuffersUsingStreamCallback | paClipOff, &audioCallback,
|
||||||
|
// this);
|
||||||
|
|
||||||
|
err = Pa_OpenStream(&stream, NULL, &outputParameters, AUDIO_FREQUENCY,
|
||||||
|
paFramesPerBufferUnspecified, paClipOff, NULL, NULL);
|
||||||
|
|
||||||
|
err = Pa_StartStream(stream);
|
||||||
|
if (err != paNoError) {
|
||||||
|
std::cout << "Error starting stream: " << Pa_GetErrorText(err)
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << "\tPortAudio error: " << Pa_GetErrorText(err) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
AudioThreadInput inp;
|
||||||
|
inputQueue->pop(inp);
|
||||||
|
Pa_WriteStream(stream, &inp.data[0], inp.data.size()/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <cctype>
|
||||||
|
#include <locale>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
// trim from start
|
||||||
|
static inline std::wstring &wltrim(std::wstring &s) {
|
||||||
|
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// trim from end
|
||||||
|
static inline std::wstring &wrtrim(std::wstring &s) {
|
||||||
|
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// trim from both ends
|
||||||
|
static inline std::wstring &wtrim(std::wstring &s) {
|
||||||
|
return wltrim(wrtrim(s));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//wxDEFINE_EVENT(wxEVT_COMMAND_AudioThread_INPUT, wxThreadEvent);
|
||||||
|
|
||||||
|
AudioThread::AudioThread(AudioThreadQueue* pQueue, int id) :
|
||||||
|
wxThread(wxTHREAD_DETACHED), m_pQueue(pQueue), m_ID(id), audio_queue_ptr(0), stream(NULL) {
|
||||||
|
|
||||||
|
}
|
||||||
|
AudioThread::~AudioThread() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
wxThread::ExitCode AudioThread::Entry() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#ifdef WIN32
|
||||||
|
// wchar_t dev_str[255];
|
||||||
|
// memset(dev_str, 0, sizeof(wchar_t) * 255);
|
||||||
|
// std::wstring env_name(L"PA_RECOMMENDED_OUTPUT_DEVICE");
|
||||||
|
// GetEnvironmentVariable(wtrim(env_name).c_str(), dev_str, 255);
|
||||||
|
// std::wistringstream env_result(dev_str);
|
||||||
|
//
|
||||||
|
// if (!env_result.eof()) {
|
||||||
|
// int env_dev = -1;
|
||||||
|
// env_result >> env_dev;
|
||||||
|
//
|
||||||
|
// if (env_result.eof()) { // read everything, was all a number
|
||||||
|
// if (env_dev >= 0) {
|
||||||
|
// std::cout << "Using preferred PortAudio device PA_RECOMMENDED_OUTPUT_DEVICE=" << env_dev << std::endl;
|
||||||
|
// preferred_device = env_dev;
|
||||||
|
// } else {
|
||||||
|
// std::cout << "Environment variable PA_RECOMMENDED_OUTPUT_DEVICE not set, using PortAudio defaults." << std::endl;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// std::cout << "Environment variable PA_RECOMMENDED_OUTPUT_DEVICE didn't evaluate to a number, using PortAudio defaults." << std::endl;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
while (!TestDestroy()) {
|
||||||
|
|
||||||
|
if (m_pQueue->stackSize()) {
|
||||||
|
|
||||||
|
while (m_pQueue->stackSize()) {
|
||||||
|
AudioThreadTask task = m_pQueue->pop(); // pop a task from the queue. this will block the worker thread if queue is empty
|
||||||
|
switch (task.m_cmd) {
|
||||||
|
case AudioThreadTask::AUDIO_THREAD_DATA:
|
||||||
|
if (!TestDestroy()) {
|
||||||
|
audio_queue.push(task.data->data);
|
||||||
|
}
|
||||||
|
delete task.data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this->Yield();
|
||||||
|
this->Sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << std::endl << "Audio Thread Done." << std::endl << std::endl;
|
||||||
|
|
||||||
|
return (wxThread::ExitCode) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
41
src/audio/AudioThread.h
Normal file
41
src/audio/AudioThread.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include "wx/wx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/thread.h"
|
||||||
|
|
||||||
|
#include "AudioThread.h"
|
||||||
|
#include "ThreadQueue.h"
|
||||||
|
#include "portaudio.h"
|
||||||
|
|
||||||
|
class AudioThreadInput {
|
||||||
|
public:
|
||||||
|
int frequency;
|
||||||
|
int sampleRate;
|
||||||
|
|
||||||
|
std::vector<float> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef ThreadQueue<AudioThreadInput> AudioThreadInputQueue;
|
||||||
|
|
||||||
|
class AudioThread {
|
||||||
|
public:
|
||||||
|
AudioThread(AudioThreadInputQueue *inputQueue);
|
||||||
|
|
||||||
|
~AudioThread();
|
||||||
|
|
||||||
|
void threadMain();
|
||||||
|
|
||||||
|
private:
|
||||||
|
AudioThreadInputQueue *inputQueue;
|
||||||
|
PaStreamParameters outputParameters;
|
||||||
|
PaStream *stream;
|
||||||
|
};
|
||||||
|
|
40
src/demod/DemodulatorMgr.cpp
Normal file
40
src/demod/DemodulatorMgr.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include <DemodulatorMgr.h>
|
||||||
|
|
||||||
|
DemodulatorInstance::DemodulatorInstance() :
|
||||||
|
t_Demod(NULL), threadQueueDemod(NULL), demodulatorThread(NULL) {
|
||||||
|
}
|
||||||
|
void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) {
|
||||||
|
demodulatorThread->setVisualOutputQueue(tQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DemodulatorInstance::init() {
|
||||||
|
if (threadQueueDemod) {
|
||||||
|
delete threadQueueDemod;
|
||||||
|
}
|
||||||
|
if (demodulatorThread) {
|
||||||
|
delete demodulatorThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
threadQueueDemod = new DemodulatorThreadInputQueue;
|
||||||
|
demodulatorThread = new DemodulatorThread(threadQueueDemod, ¶ms);
|
||||||
|
|
||||||
|
t_Demod = new std::thread(&DemodulatorThread::threadMain, demodulatorThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
DemodulatorMgr::DemodulatorMgr() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DemodulatorMgr::~DemodulatorMgr() {
|
||||||
|
while (demods.size()) {
|
||||||
|
DemodulatorInstance *d = demods.back();
|
||||||
|
demods.pop_back();
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DemodulatorInstance *DemodulatorMgr::newThread() {
|
||||||
|
DemodulatorInstance *newDemod = new DemodulatorInstance;
|
||||||
|
demods.push_back(newDemod);
|
||||||
|
return newDemod;
|
||||||
|
}
|
30
src/demod/DemodulatorMgr.h
Normal file
30
src/demod/DemodulatorMgr.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "DemodulatorThread.h"
|
||||||
|
|
||||||
|
class DemodulatorInstance {
|
||||||
|
public:
|
||||||
|
DemodulatorThread *demodulatorThread;
|
||||||
|
std::thread *t_Demod;
|
||||||
|
|
||||||
|
DemodulatorThreadInputQueue* threadQueueDemod;
|
||||||
|
DemodulatorThreadParameters params;
|
||||||
|
|
||||||
|
DemodulatorInstance();
|
||||||
|
void setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue);
|
||||||
|
void init();
|
||||||
|
};
|
||||||
|
|
||||||
|
class DemodulatorMgr {
|
||||||
|
public:
|
||||||
|
DemodulatorMgr();
|
||||||
|
~DemodulatorMgr();
|
||||||
|
|
||||||
|
DemodulatorInstance *newThread();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<DemodulatorInstance *> demods;
|
||||||
|
};
|
145
src/demod/DemodulatorThread.cpp
Normal file
145
src/demod/DemodulatorThread.cpp
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
#include "DemodulatorThread.h"
|
||||||
|
#include "CubicSDRDefs.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
DemodulatorThread::DemodulatorThread(DemodulatorThreadInputQueue* pQueue, DemodulatorThreadParameters *params_in) :
|
||||||
|
inputQueue(pQueue), visOutQueue(NULL) {
|
||||||
|
|
||||||
|
DemodulatorThreadParameters defaultParams;
|
||||||
|
if (!params_in) {
|
||||||
|
params = defaultParams;
|
||||||
|
} else {
|
||||||
|
params = *params_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
resample_ratio = (float) (params.inputResampleRate) / (float) params.inputRate;
|
||||||
|
second_resampler_ratio = (float) (params.demodResampleRate) / (float) params.inputResampleRate;
|
||||||
|
audio_resample_ratio = (float) (params.audioSampleRate) / (float) params.demodResampleRate;
|
||||||
|
|
||||||
|
float fc = 0.5f * ((float) params.inputResampleRate / (float) params.inputRate) * 0.75; // filter cutoff frequency
|
||||||
|
float ft = 0.05f; // filter transition
|
||||||
|
float As = 60.0f; // stop-band attenuation [dB]
|
||||||
|
float mu = 0.0f; // fractional timing offset
|
||||||
|
|
||||||
|
// estimate required filter length and generate filter
|
||||||
|
unsigned int h_len = estimate_req_filter_len(ft, As);
|
||||||
|
float h[h_len];
|
||||||
|
liquid_firdes_kaiser(h_len, fc, As, mu, h);
|
||||||
|
|
||||||
|
fir_filter = firfilt_crcf_create(h, h_len);
|
||||||
|
|
||||||
|
h_len = estimate_req_filter_len(ft, As);
|
||||||
|
liquid_firdes_kaiser(h_len, (float) params.filterFrequency / (float) params.demodResampleRate, As, mu, h);
|
||||||
|
|
||||||
|
fir_audio_filter = firfilt_crcf_create(h, h_len);
|
||||||
|
|
||||||
|
// create multi-stage arbitrary resampler object
|
||||||
|
resampler = msresamp_crcf_create(resample_ratio, As);
|
||||||
|
msresamp_crcf_print(resampler);
|
||||||
|
|
||||||
|
second_resampler = msresamp_crcf_create(second_resampler_ratio, As);
|
||||||
|
msresamp_crcf_print(second_resampler);
|
||||||
|
|
||||||
|
audio_resampler = msresamp_crcf_create(audio_resample_ratio, As);
|
||||||
|
msresamp_crcf_print(audio_resampler);
|
||||||
|
|
||||||
|
float kf = 0.75; // modulation factor
|
||||||
|
|
||||||
|
fdem = freqdem_create(kf);
|
||||||
|
freqdem_print(fdem);
|
||||||
|
}
|
||||||
|
|
||||||
|
DemodulatorThread::~DemodulatorThread() {
|
||||||
|
std::cout << std::endl << "Demodulator Thread Done." << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DemodulatorThread::threadMain() {
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
DemodulatorThreadIQData inp;
|
||||||
|
inputQueue->pop(inp);
|
||||||
|
|
||||||
|
std::vector<signed char> *data = &inp.data;
|
||||||
|
if (data->size()) {
|
||||||
|
liquid_float_complex filtered_input[BUF_SIZE / 2];
|
||||||
|
|
||||||
|
for (int i = 0; i < BUF_SIZE / 2; i++) {
|
||||||
|
|
||||||
|
liquid_float_complex x;
|
||||||
|
liquid_float_complex y;
|
||||||
|
|
||||||
|
x.real = (float) (*data)[i * 2] / 127.0f;
|
||||||
|
x.imag = (float) (*data)[i * 2 + 1] / 127.0f;
|
||||||
|
|
||||||
|
firfilt_crcf_push(fir_filter, x); // push input sample
|
||||||
|
firfilt_crcf_execute(fir_filter, &y); // compute output
|
||||||
|
|
||||||
|
filtered_input[i] = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int out_size = ceil((float) (BUF_SIZE / 2) * resample_ratio);
|
||||||
|
|
||||||
|
liquid_float_complex resampled_output[out_size];
|
||||||
|
|
||||||
|
unsigned int num_written; // number of values written to buffer
|
||||||
|
msresamp_crcf_execute(resampler, filtered_input, (BUF_SIZE / 2), resampled_output, &num_written);
|
||||||
|
|
||||||
|
float waveform_ceil = 0, waveform_floor = 0;
|
||||||
|
|
||||||
|
float pcm = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < num_written; i++) {
|
||||||
|
freqdem_demodulate(fdem, resampled_output[i], &pcm);
|
||||||
|
|
||||||
|
resampled_output[i].real = (float) pcm;
|
||||||
|
resampled_output[i].imag = 0;
|
||||||
|
|
||||||
|
if (waveform_ceil < resampled_output[i].real) {
|
||||||
|
waveform_ceil = resampled_output[i].real;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waveform_floor > resampled_output[i].real) {
|
||||||
|
waveform_floor = resampled_output[i].real;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int wbfm_out_size = ceil((float) (num_written) * second_resampler_ratio);
|
||||||
|
liquid_float_complex resampled_wbfm_output[wbfm_out_size];
|
||||||
|
|
||||||
|
unsigned int num_wbfm_written;
|
||||||
|
msresamp_crcf_execute(second_resampler, resampled_output, num_written, resampled_wbfm_output, &num_wbfm_written);
|
||||||
|
|
||||||
|
for (int i = 0; i < num_wbfm_written; i++) {
|
||||||
|
firfilt_crcf_push(fir_audio_filter, resampled_wbfm_output[i]);
|
||||||
|
firfilt_crcf_execute(fir_audio_filter, &resampled_wbfm_output[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int audio_out_size = ceil((float) (num_wbfm_written) * audio_resample_ratio);
|
||||||
|
liquid_float_complex resampled_audio_output[audio_out_size];
|
||||||
|
|
||||||
|
unsigned int num_audio_written;
|
||||||
|
msresamp_crcf_execute(audio_resampler, resampled_wbfm_output, num_wbfm_written, resampled_audio_output, &num_audio_written);
|
||||||
|
|
||||||
|
std::vector<float> newBuffer;
|
||||||
|
newBuffer.resize(num_audio_written * 2);
|
||||||
|
for (int i = 0; i < num_audio_written; i++) {
|
||||||
|
liquid_float_complex y = resampled_audio_output[i];
|
||||||
|
|
||||||
|
newBuffer[i * 2] = y.real;
|
||||||
|
newBuffer[i * 2 + 1] = y.real;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioThreadInput ati;
|
||||||
|
ati.data = newBuffer;
|
||||||
|
|
||||||
|
if (params.audioInputQueue != NULL) {
|
||||||
|
params.audioInputQueue->push(ati);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visOutQueue != NULL) {
|
||||||
|
visOutQueue->push(ati);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
122
src/demod/DemodulatorThread.h
Normal file
122
src/demod/DemodulatorThread.h
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
#include <vector>
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include "wx/wx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/thread.h"
|
||||||
|
|
||||||
|
#include "liquid/liquid.h"
|
||||||
|
#include "AudioThread.h"
|
||||||
|
#include "ThreadQueue.h"
|
||||||
|
#include "CubicSDRDefs.h"
|
||||||
|
|
||||||
|
enum DemodulatorType {
|
||||||
|
DEMOD_TYPE_NULL, DEMOD_TYPE_AM, DEMOD_TYPE_FM, DEMOD_TYPE_LSB, DEMOD_TYPE_USB, DEMOD_TYPE_WFM
|
||||||
|
};
|
||||||
|
|
||||||
|
class DemodulatorThreadIQData {
|
||||||
|
public:
|
||||||
|
unsigned int frequency;
|
||||||
|
unsigned int bandwidth;
|
||||||
|
std::vector<signed char> data;
|
||||||
|
|
||||||
|
DemodulatorThreadIQData() :
|
||||||
|
frequency(0), bandwidth(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DemodulatorThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector<signed char> data) :
|
||||||
|
data(data), frequency(frequency), bandwidth(bandwidth) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~DemodulatorThreadIQData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DemodulatorThreadAudioData {
|
||||||
|
public:
|
||||||
|
unsigned int frequency;
|
||||||
|
unsigned int sampleRate;
|
||||||
|
unsigned char channels;
|
||||||
|
|
||||||
|
std::vector<float> data;
|
||||||
|
|
||||||
|
DemodulatorThreadAudioData() :
|
||||||
|
sampleRate(0), frequency(0), channels(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DemodulatorThreadAudioData(unsigned int frequency, unsigned int sampleRate, std::vector<float> data) :
|
||||||
|
data(data), sampleRate(sampleRate), frequency(frequency), channels(1) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~DemodulatorThreadAudioData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DemodulatorThreadParameters {
|
||||||
|
public:
|
||||||
|
unsigned int inputRate;
|
||||||
|
unsigned int inputResampleRate; // set equal to disable second stage re-sampling?
|
||||||
|
unsigned int demodResampleRate;
|
||||||
|
unsigned int filterFrequency;
|
||||||
|
unsigned int audioSampleRate;
|
||||||
|
AudioThreadInputQueue *audioInputQueue;
|
||||||
|
|
||||||
|
DemodulatorType demodType;
|
||||||
|
|
||||||
|
DemodulatorThreadParameters() :
|
||||||
|
audioInputQueue(NULL), inputRate(SRATE), inputResampleRate(200000), demodResampleRate(100000), audioSampleRate(48000), filterFrequency(
|
||||||
|
32000), demodType(DEMOD_TYPE_WFM) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~DemodulatorThreadParameters() {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef ThreadQueue<DemodulatorThreadIQData> DemodulatorThreadInputQueue;
|
||||||
|
typedef ThreadQueue<AudioThreadInput> DemodulatorThreadOutputQueue;
|
||||||
|
|
||||||
|
class DemodulatorThread {
|
||||||
|
public:
|
||||||
|
|
||||||
|
DemodulatorThread(DemodulatorThreadInputQueue* pQueue, DemodulatorThreadParameters *params);
|
||||||
|
~DemodulatorThread();
|
||||||
|
|
||||||
|
void threadMain();
|
||||||
|
|
||||||
|
void setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) {
|
||||||
|
visOutQueue = tQueue;
|
||||||
|
visOutQueue->set_max_num_items(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DemodulatorThreadInputQueue* inputQueue;
|
||||||
|
DemodulatorThreadOutputQueue* visOutQueue;
|
||||||
|
|
||||||
|
firfilt_crcf fir_filter;
|
||||||
|
firfilt_crcf fir_audio_filter;
|
||||||
|
|
||||||
|
msresamp_crcf resampler;
|
||||||
|
float resample_ratio;
|
||||||
|
|
||||||
|
msresamp_crcf second_resampler;
|
||||||
|
float second_resampler_ratio;
|
||||||
|
|
||||||
|
msresamp_crcf audio_resampler;
|
||||||
|
float audio_resample_ratio;
|
||||||
|
|
||||||
|
DemodulatorThreadParameters params;
|
||||||
|
freqdem fdem;
|
||||||
|
};
|
0
src/demod/DemodulatorThreadQueue.cpp
Normal file
0
src/demod/DemodulatorThreadQueue.cpp
Normal file
0
src/demod/DemodulatorThreadQueue.h
Normal file
0
src/demod/DemodulatorThreadQueue.h
Normal file
0
src/demod/DemodulatorThreadTask.cpp
Normal file
0
src/demod/DemodulatorThreadTask.cpp
Normal file
0
src/demod/DemodulatorThreadTask.h
Normal file
0
src/demod/DemodulatorThreadTask.h
Normal file
@ -3,15 +3,15 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "CubicSDR.h"
|
#include "CubicSDR.h"
|
||||||
|
|
||||||
//wxDEFINE_EVENT(wxEVT_COMMAND_SDRThread_INPUT, wxThreadEvent);
|
SDRThread::SDRThread(SDRThreadCommandQueue* pQueue) :
|
||||||
|
m_pQueue(pQueue), iqDataOutQueue(NULL), iqVisualQueue(NULL) {
|
||||||
SDRThread::SDRThread(SDRThreadQueue* pQueue, int id) :
|
|
||||||
wxThread(wxTHREAD_DETACHED), m_pQueue(pQueue), m_ID(id) {
|
|
||||||
dev = NULL;
|
dev = NULL;
|
||||||
sample_rate = SRATE;
|
sample_rate = SRATE;
|
||||||
}
|
}
|
||||||
SDRThread::~SDRThread() {
|
|
||||||
|
|
||||||
|
SDRThread::~SDRThread() {
|
||||||
|
std::cout << std::endl << "SDR Thread Done." << std::endl << std::endl;
|
||||||
|
rtlsdr_close(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDRThread::enumerate_rtl() {
|
int SDRThread::enumerate_rtl() {
|
||||||
@ -89,19 +89,19 @@ int SDRThread::enumerate_rtl() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxThread::ExitCode SDRThread::Entry() {
|
void SDRThread::threadMain() {
|
||||||
|
|
||||||
int dev_count = rtlsdr_get_device_count();
|
int dev_count = rtlsdr_get_device_count();
|
||||||
int first_available = enumerate_rtl();
|
int first_available = enumerate_rtl();
|
||||||
|
|
||||||
if (first_available == -1) {
|
if (first_available == -1) {
|
||||||
std::cout << "No devices found.. SDR Thread exiting.." << std::endl;
|
std::cout << "No devices found.. SDR Thread exiting.." << std::endl;
|
||||||
return (wxThread::ExitCode) 0;
|
return;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Using first available RTL-SDR device #" << first_available << std::endl;
|
std::cout << "Using first available RTL-SDR device #" << first_available << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
signed char *buf = (signed char *) malloc(BUF_SIZE);
|
signed char buf[BUF_SIZE];
|
||||||
|
|
||||||
unsigned int frequency = DEFAULT_FREQ;
|
unsigned int frequency = DEFAULT_FREQ;
|
||||||
unsigned int bandwidth = SRATE;
|
unsigned int bandwidth = SRATE;
|
||||||
@ -121,19 +121,20 @@ wxThread::ExitCode SDRThread::Entry() {
|
|||||||
double seconds = 0.0;
|
double seconds = 0.0;
|
||||||
|
|
||||||
std::cout << "Sampling..";
|
std::cout << "Sampling..";
|
||||||
while (!TestDestroy()) {
|
while (1) {
|
||||||
|
if (!m_pQueue->empty()) {
|
||||||
if (m_pQueue->stackSize()) {
|
|
||||||
bool freq_changed = false;
|
bool freq_changed = false;
|
||||||
float new_freq;
|
float new_freq;
|
||||||
|
|
||||||
while (m_pQueue->stackSize()) {
|
while (!m_pQueue->empty()) {
|
||||||
SDRThreadTask task = m_pQueue->pop(); // pop a task from the queue. this will block the worker thread if queue is empty
|
SDRThreadCommand command;
|
||||||
switch (task.m_cmd) {
|
m_pQueue->pop(command);
|
||||||
case SDRThreadTask::SDR_THREAD_TUNING:
|
|
||||||
std::cout << "Set frequency: " << task.getUInt() << std::endl;
|
switch (command.cmd) {
|
||||||
|
case SDRThreadCommand::SDR_THREAD_CMD_TUNE:
|
||||||
|
std::cout << "Set frequency: " << command.int_value << std::endl;
|
||||||
freq_changed = true;
|
freq_changed = true;
|
||||||
new_freq = task.getUInt();
|
new_freq = command.int_value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,7 +147,6 @@ wxThread::ExitCode SDRThread::Entry() {
|
|||||||
|
|
||||||
rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read);
|
rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read);
|
||||||
|
|
||||||
if (!TestDestroy()) {
|
|
||||||
std::vector<signed char> new_buffer;
|
std::vector<signed char> new_buffer;
|
||||||
|
|
||||||
for (int i = 0; i < n_read; i++) {
|
for (int i = 0; i < n_read; i++) {
|
||||||
@ -156,21 +156,33 @@ wxThread::ExitCode SDRThread::Entry() {
|
|||||||
double time_slice = (double) n_read / (double) sample_rate;
|
double time_slice = (double) n_read / (double) sample_rate;
|
||||||
seconds += time_slice;
|
seconds += time_slice;
|
||||||
|
|
||||||
// std::cout << "Time Slice: " << time_slice << std::endl;
|
SDRThreadIQData dataOut;
|
||||||
if (!TestDestroy()) {
|
dataOut.frequency = frequency;
|
||||||
SDRThreadIQData *iqData = new SDRThreadIQData(bandwidth,frequency,new_buffer);
|
dataOut.bandwidth = bandwidth;
|
||||||
m_pQueue->sendIQData(SDRThreadTask::SDR_THREAD_DATA, iqData);
|
dataOut.data = new_buffer;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this->Yield();
|
|
||||||
this->Sleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cout << std::endl << "Done." << std::endl << std::endl;
|
|
||||||
|
|
||||||
rtlsdr_close(dev);
|
if (iqDataOutQueue != NULL) {
|
||||||
free(buf);
|
iqDataOutQueue->push(dataOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iqVisualQueue != NULL) {
|
||||||
|
iqVisualQueue->push(dataOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (demodulators.size()) {
|
||||||
|
DemodulatorThreadIQData demodDataOut;
|
||||||
|
demodDataOut.frequency = frequency;
|
||||||
|
demodDataOut.bandwidth = bandwidth;
|
||||||
|
demodDataOut.data = new_buffer;
|
||||||
|
|
||||||
|
for (int i = 0, iMax = demodulators.size(); i < iMax; i++) {
|
||||||
|
DemodulatorInstance *demod = demodulators[i];
|
||||||
|
DemodulatorThreadInputQueue *demodQueue = demod->threadQueueDemod;
|
||||||
|
demodQueue->push(demodDataOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return (wxThread::ExitCode) 0;
|
|
||||||
}
|
}
|
||||||
|
|
88
src/sdr/SDRThread.h
Normal file
88
src/sdr/SDRThread.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
#include "rtl-sdr.h"
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include "wx/wx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/thread.h"
|
||||||
|
|
||||||
|
#include "ThreadQueue.h"
|
||||||
|
#include "DemodulatorMgr.h"
|
||||||
|
|
||||||
|
class SDRThreadCommand {
|
||||||
|
public:
|
||||||
|
enum SDRThreadCommandEnum {
|
||||||
|
SDR_THREAD_CMD_NULL,
|
||||||
|
SDR_THREAD_CMD_TUNE
|
||||||
|
};
|
||||||
|
|
||||||
|
SDRThreadCommand() : cmd(cmd), int_value(SDR_THREAD_CMD_NULL){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SDRThreadCommand(SDRThreadCommandEnum cmd) : cmd(cmd), int_value(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SDRThreadCommandEnum cmd;
|
||||||
|
int int_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SDRThreadIQData {
|
||||||
|
public:
|
||||||
|
unsigned int frequency;
|
||||||
|
unsigned int bandwidth;
|
||||||
|
std::vector<signed char> data;
|
||||||
|
|
||||||
|
SDRThreadIQData(): frequency(0), bandwidth(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SDRThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector<signed char> data) :
|
||||||
|
data(data), frequency(frequency), bandwidth(bandwidth) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~SDRThreadIQData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef ThreadQueue<SDRThreadCommand> SDRThreadCommandQueue;
|
||||||
|
typedef ThreadQueue<SDRThreadIQData> SDRThreadIQDataQueue;
|
||||||
|
|
||||||
|
class SDRThread {
|
||||||
|
public:
|
||||||
|
rtlsdr_dev_t *dev;
|
||||||
|
|
||||||
|
SDRThread(SDRThreadCommandQueue* pQueue);
|
||||||
|
~SDRThread();
|
||||||
|
|
||||||
|
int enumerate_rtl();
|
||||||
|
|
||||||
|
void bindDemodulator(DemodulatorInstance *demod) {
|
||||||
|
demodulators.push_back(demod);
|
||||||
|
}
|
||||||
|
|
||||||
|
void threadMain();
|
||||||
|
|
||||||
|
void setIQDataOutQueue(SDRThreadIQDataQueue* iqDataQueue) {
|
||||||
|
iqDataOutQueue = iqDataQueue;
|
||||||
|
}
|
||||||
|
void setIQVisualQueue(SDRThreadIQDataQueue *iqVisQueue) {
|
||||||
|
iqVisualQueue = iqVisQueue;
|
||||||
|
iqVisualQueue->set_max_num_items(1);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
|
||||||
|
uint32_t sample_rate;
|
||||||
|
SDRThreadCommandQueue* m_pQueue;
|
||||||
|
SDRThreadIQDataQueue* iqDataOutQueue;
|
||||||
|
SDRThreadIQDataQueue* iqVisualQueue;
|
||||||
|
|
||||||
|
std::vector<DemodulatorInstance *> demodulators;
|
||||||
|
};
|
1
src/util/ThreadQueue.cpp
Normal file
1
src/util/ThreadQueue.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include <ThreadQueue.h>
|
266
src/util/ThreadQueue.h
Normal file
266
src/util/ThreadQueue.h
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* Credit to Alfredo Pons / https://plus.google.com/109903449837592676231
|
||||||
|
* Code from http://gnodebian.blogspot.com.es/2013/07/a-thread-safe-asynchronous-queue-in-c11.html
|
||||||
|
*
|
||||||
|
* Changes:
|
||||||
|
* Charles J. Nov-19-2014
|
||||||
|
* - Renamed SafeQueue -> ThreadQueue
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
|
/** A thread-safe asynchronous queue */
|
||||||
|
template<class T, class Container = std::list<T>>
|
||||||
|
class ThreadQueue {
|
||||||
|
|
||||||
|
typedef typename Container::value_type value_type;
|
||||||
|
typedef typename Container::size_type size_type;
|
||||||
|
typedef Container container_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/*! Create safe queue. */
|
||||||
|
ThreadQueue() = default;
|
||||||
|
ThreadQueue(ThreadQueue&& sq) {
|
||||||
|
m_queue = std::move(sq.m_queue);
|
||||||
|
}
|
||||||
|
ThreadQueue(const ThreadQueue& sq) {
|
||||||
|
std::lock_guard < std::mutex > lock(sq.m_mutex);
|
||||||
|
m_queue = sq.m_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Destroy safe queue. */
|
||||||
|
~ThreadQueue() {
|
||||||
|
std::lock_guard < std::mutex > lock(m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maximum number of items in the queue. Defaults is 0: No limit
|
||||||
|
* \param[in] item An item.
|
||||||
|
*/
|
||||||
|
void set_max_num_items(unsigned int max_num_items) {
|
||||||
|
m_max_num_items = max_num_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes the item into the queue.
|
||||||
|
* \param[in] item An item.
|
||||||
|
* \return true if an item was pushed into the queue
|
||||||
|
*/
|
||||||
|
bool push(const value_type& item) {
|
||||||
|
std::lock_guard < std::mutex > lock(m_mutex);
|
||||||
|
|
||||||
|
if (m_max_num_items > 0 && m_queue.size() > m_max_num_items)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_queue.push(item);
|
||||||
|
m_condition.notify_one();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes the item into the queue.
|
||||||
|
* \param[in] item An item.
|
||||||
|
* \return true if an item was pushed into the queue
|
||||||
|
*/
|
||||||
|
bool push(const value_type&& item) {
|
||||||
|
std::lock_guard < std::mutex > lock(m_mutex);
|
||||||
|
|
||||||
|
if (m_max_num_items > 0 && m_queue.size() > m_max_num_items)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_queue.push(item);
|
||||||
|
m_condition.notify_one();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pops item from the queue. If queue is empty, this function blocks until item becomes available.
|
||||||
|
* \param[out] item The item.
|
||||||
|
*/
|
||||||
|
void pop(value_type& item) {
|
||||||
|
std::unique_lock < std::mutex > lock(m_mutex);
|
||||||
|
m_condition.wait(lock, [this]() // Lambda funct
|
||||||
|
{
|
||||||
|
return !m_queue.empty();
|
||||||
|
});
|
||||||
|
item = m_queue.front();
|
||||||
|
m_queue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pops item from the queue using the contained type's move assignment operator, if it has one..
|
||||||
|
* This method is identical to the pop() method if that type has no move assignment operator.
|
||||||
|
* If queue is empty, this function blocks until item becomes available.
|
||||||
|
* \param[out] item The item.
|
||||||
|
*/
|
||||||
|
void move_pop(value_type& item) {
|
||||||
|
std::unique_lock < std::mutex > lock(m_mutex);
|
||||||
|
m_condition.wait(lock, [this]() // Lambda funct
|
||||||
|
{
|
||||||
|
return !m_queue.empty();
|
||||||
|
});
|
||||||
|
item = std::move(m_queue.front());
|
||||||
|
m_queue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to pop item from the queue.
|
||||||
|
* \param[out] item The item.
|
||||||
|
* \return False is returned if no item is available.
|
||||||
|
*/
|
||||||
|
bool try_pop(value_type& item) {
|
||||||
|
std::unique_lock < std::mutex > lock(m_mutex);
|
||||||
|
|
||||||
|
if (m_queue.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
item = m_queue.front();
|
||||||
|
m_queue.pop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to pop item from the queue using the contained type's move assignment operator, if it has one..
|
||||||
|
* This method is identical to the try_pop() method if that type has no move assignment operator.
|
||||||
|
* \param[out] item The item.
|
||||||
|
* \return False is returned if no item is available.
|
||||||
|
*/
|
||||||
|
bool try_move_pop(value_type& item) {
|
||||||
|
std::unique_lock < std::mutex > lock(m_mutex);
|
||||||
|
|
||||||
|
if (m_queue.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
item = std::move(m_queue.front());
|
||||||
|
m_queue.pop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pops item from the queue. If the queue is empty, blocks for timeout microseconds, or until item becomes available.
|
||||||
|
* \param[out] t An item.
|
||||||
|
* \param[in] timeout The number of microseconds to wait.
|
||||||
|
* \return true if get an item from the queue, false if no item is received before the timeout.
|
||||||
|
*/
|
||||||
|
bool timeout_pop(value_type& item, std::uint64_t timeout) {
|
||||||
|
std::unique_lock < std::mutex > lock(m_mutex);
|
||||||
|
|
||||||
|
if (m_queue.empty()) {
|
||||||
|
if (timeout == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_condition.wait_for(lock, std::chrono::microseconds(timeout)) == std::cv_status::timeout)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = m_queue.front();
|
||||||
|
m_queue.pop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pops item from the queue using the contained type's move assignment operator, if it has one..
|
||||||
|
* If the queue is empty, blocks for timeout microseconds, or until item becomes available.
|
||||||
|
* This method is identical to the try_pop() method if that type has no move assignment operator.
|
||||||
|
* \param[out] t An item.
|
||||||
|
* \param[in] timeout The number of microseconds to wait.
|
||||||
|
* \return true if get an item from the queue, false if no item is received before the timeout.
|
||||||
|
*/
|
||||||
|
bool timeout_move_pop(value_type& item, std::uint64_t timeout) {
|
||||||
|
std::unique_lock < std::mutex > lock(m_mutex);
|
||||||
|
|
||||||
|
if (m_queue.empty()) {
|
||||||
|
if (timeout == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_condition.wait_for(lock, std::chrono::microseconds(timeout)) == std::cv_status::timeout)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = std::move(m_queue.front());
|
||||||
|
m_queue.pop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of items in the queue.
|
||||||
|
* \return Number of items in the queue.
|
||||||
|
*/
|
||||||
|
size_type size() const {
|
||||||
|
std::lock_guard < std::mutex > lock(m_mutex);
|
||||||
|
return m_queue.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the queue is empty.
|
||||||
|
* \return true if queue is empty.
|
||||||
|
*/
|
||||||
|
bool empty() const {
|
||||||
|
std::lock_guard < std::mutex > lock(m_mutex);
|
||||||
|
return m_queue.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swaps the contents.
|
||||||
|
* \param[out] sq The ThreadQueue to swap with 'this'.
|
||||||
|
*/
|
||||||
|
void swap(ThreadQueue& sq) {
|
||||||
|
if (this != &sq) {
|
||||||
|
std::lock_guard < std::mutex > lock1(m_mutex);
|
||||||
|
std::lock_guard < std::mutex > lock2(sq.m_mutex);
|
||||||
|
m_queue.swap(sq.m_queue);
|
||||||
|
|
||||||
|
if (!m_queue.empty())
|
||||||
|
m_condition.notify_all();
|
||||||
|
|
||||||
|
if (!sq.m_queue.empty())
|
||||||
|
sq.m_condition.notify_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! The copy assignment operator */
|
||||||
|
ThreadQueue& operator=(const ThreadQueue& sq) {
|
||||||
|
if (this != &sq) {
|
||||||
|
std::lock_guard < std::mutex > lock1(m_mutex);
|
||||||
|
std::lock_guard < std::mutex > lock2(sq.m_mutex);
|
||||||
|
std::queue<T, Container> temp { sq.m_queue };
|
||||||
|
m_queue.swap(temp);
|
||||||
|
|
||||||
|
if (!m_queue.empty())
|
||||||
|
m_condition.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! The move assignment operator */
|
||||||
|
ThreadQueue& operator=(ThreadQueue && sq) {
|
||||||
|
std::lock_guard < std::mutex > lock(m_mutex);
|
||||||
|
m_queue = std::move(sq.m_queue);
|
||||||
|
|
||||||
|
if (!m_queue.empty())
|
||||||
|
m_condition.notify_all();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::queue<T, Container> m_queue;
|
||||||
|
mutable std::mutex m_mutex;
|
||||||
|
std::condition_variable m_condition;
|
||||||
|
unsigned int m_max_num_items = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! Swaps the contents of two ThreadQueue objects. */
|
||||||
|
template<class T, class Container>
|
||||||
|
void swap(ThreadQueue<T, Container>& q1, ThreadQueue<T, Container>& q2) {
|
||||||
|
q1.swap(q2);
|
||||||
|
}
|
161
src/util/Timer.h
Normal file
161
src/util/Timer.h
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#ifndef TIMER_H
|
||||||
|
#define TIMER_H
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Timer Class, high resolution timer
|
||||||
|
/**
|
||||||
|
* Class provides high resolution timing and useful time control functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Timer {
|
||||||
|
private:
|
||||||
|
|
||||||
|
unsigned long time_elapsed;
|
||||||
|
unsigned long system_milliseconds;
|
||||||
|
unsigned long start_time;
|
||||||
|
unsigned long end_time;
|
||||||
|
unsigned long last_update;
|
||||||
|
unsigned long num_updates;
|
||||||
|
unsigned long paused_time;
|
||||||
|
unsigned long offset;
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
struct timeval time_val;
|
||||||
|
struct timezone time_zone;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool paused_state;
|
||||||
|
bool lock_state;
|
||||||
|
float lock_rate;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
Timer();
|
||||||
|
|
||||||
|
/// Start the timer
|
||||||
|
/**
|
||||||
|
* Resets the timer to 0 and begins timing
|
||||||
|
*/
|
||||||
|
void start(void);
|
||||||
|
|
||||||
|
/// Stop the timer
|
||||||
|
/**
|
||||||
|
* Stops the timer and records the end time
|
||||||
|
*/
|
||||||
|
void stop(void);
|
||||||
|
|
||||||
|
/// Locks the timer to a specified framerate (for recording / benchmarking purposes typically)
|
||||||
|
/**
|
||||||
|
* Locks the timer to a specified framerate (for recording / benchmarking purposes typically)
|
||||||
|
*/
|
||||||
|
void lockFramerate(float f_rate);
|
||||||
|
|
||||||
|
/// Unlock any framerate lock that's been applied
|
||||||
|
/**
|
||||||
|
* Unlock any framerate lock that's been applied
|
||||||
|
*/
|
||||||
|
void unlock();
|
||||||
|
|
||||||
|
/// Check locked state
|
||||||
|
/**
|
||||||
|
* Check locked state
|
||||||
|
*/
|
||||||
|
bool locked();
|
||||||
|
|
||||||
|
/// Reset the timer counter
|
||||||
|
/**
|
||||||
|
* Resetting the timer will reset the current time to 0
|
||||||
|
*/
|
||||||
|
void reset(void);
|
||||||
|
|
||||||
|
/// Timer update
|
||||||
|
/**
|
||||||
|
* Calling the update command will bring the timer value up to date, this is meant
|
||||||
|
* to be called at the begining of the frame to establish the time index which is being drawn.
|
||||||
|
*/
|
||||||
|
void update(void);
|
||||||
|
|
||||||
|
/// Get the total time elapsed since the timer start, not counting paused time
|
||||||
|
/**
|
||||||
|
* Returns the total time elapsed in since the timer start() to the last update() but
|
||||||
|
* does not count the time elapsed while the timer is paused().
|
||||||
|
* \return Total time elapsed since the timer start() to the last update() excluding time paused() in milliseconds
|
||||||
|
*/
|
||||||
|
unsigned long getMilliseconds(void);
|
||||||
|
/// Alias of getMilliseconds() which returns time in seconds
|
||||||
|
/**
|
||||||
|
* \return Total time elapsed since the timer start() to the last update() excluding time paused() in seconds
|
||||||
|
*/
|
||||||
|
double getSeconds(void);
|
||||||
|
|
||||||
|
/// Get the total time elapsed since the timer start
|
||||||
|
/**
|
||||||
|
* Returns the total time elapsed in since the timer start() to the last update()
|
||||||
|
* this includes any time accumulated during updates while paused()
|
||||||
|
* \return Total time elapsed since the timer start() to the last update() including time paused() in milliseconds
|
||||||
|
*/
|
||||||
|
unsigned long totalMilliseconds(void);
|
||||||
|
/// Alias of totalMilliseconds() which returns time in seconds
|
||||||
|
/**
|
||||||
|
* \return Total time elapsed since the timer start() to the last update() including time paused() in seconds
|
||||||
|
*/
|
||||||
|
double totalSeconds(void);
|
||||||
|
|
||||||
|
/// Set the amount of time elapsed
|
||||||
|
/**
|
||||||
|
* Force the timer duration to a specific value, useful for rolling forward or back in a system
|
||||||
|
* based upon the timer.
|
||||||
|
* \param milliseconds_in Time to set timer to in milliseconds
|
||||||
|
*/
|
||||||
|
void setMilliseconds(unsigned long milliseconds_in);
|
||||||
|
/// alias of setMilliseconds() which accepts time in seconds
|
||||||
|
/**
|
||||||
|
* \param seconds_in Time to set timer to in seconds
|
||||||
|
*/
|
||||||
|
void setSeconds(double seconds_in);
|
||||||
|
|
||||||
|
/// Get the amount of times the update() command has been called
|
||||||
|
/**
|
||||||
|
* By using the number of times the update() command has been called you can easily determine
|
||||||
|
* an average frame rate. Also useful for merely determining how many frames have been drawn.
|
||||||
|
* \return Number of times update() has been called
|
||||||
|
*/
|
||||||
|
unsigned long getNumUpdates(void);
|
||||||
|
|
||||||
|
/// Get the timer duration during the last update
|
||||||
|
/**
|
||||||
|
* Useful for determining the amount of time which elapsed during the last update
|
||||||
|
* can be used to accurately control values with a per-second rate or determine the current frame rate.
|
||||||
|
* \return Duration of time between the last two calls to update() in milliseconds
|
||||||
|
*/
|
||||||
|
unsigned long lastUpdateMilliseconds(void);
|
||||||
|
/// Alias of lastUpdateMilliseconds() which returns time in seconds
|
||||||
|
/**
|
||||||
|
* \return Duration of time between the last two calls to update() in seconds
|
||||||
|
*/
|
||||||
|
double lastUpdateSeconds(void);
|
||||||
|
|
||||||
|
/// Set the timer pause state
|
||||||
|
/**
|
||||||
|
* Pause the timer, allowing for continued update() calls without an increment in timing but
|
||||||
|
* maintaining the update and total time count, useful for pausing a scene but allowing frame
|
||||||
|
* timing to resume.
|
||||||
|
* \param pause_in Value to set the current pause state to
|
||||||
|
*/
|
||||||
|
void paused(bool pause_in);
|
||||||
|
|
||||||
|
/// Check if the timer is currently in a paused state
|
||||||
|
/**
|
||||||
|
* \return Current pause state, true if paused, false otherwise
|
||||||
|
*/
|
||||||
|
bool paused();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -76,10 +76,10 @@ void ScopeCanvas::OnKeyDown(wxKeyEvent& event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ScopeCanvas::OnIdle(wxIdleEvent &event) {
|
void ScopeCanvas::OnIdle(wxIdleEvent &event) {
|
||||||
timer.update();
|
// timer.update();
|
||||||
frameTimer += timer.lastUpdateSeconds();
|
// frameTimer += timer.lastUpdateSeconds();
|
||||||
if (frameTimer > 1.0/30.0) {
|
// if (frameTimer > 1.0/30.0) {
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
frameTimer = 0;
|
// frameTimer = 0;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@ -153,10 +153,10 @@ void SpectrumCanvas::setData(std::vector<signed char> *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SpectrumCanvas::OnIdle(wxIdleEvent &event) {
|
void SpectrumCanvas::OnIdle(wxIdleEvent &event) {
|
||||||
timer.update();
|
// timer.update();
|
||||||
frameTimer += timer.lastUpdateSeconds();
|
// frameTimer += timer.lastUpdateSeconds();
|
||||||
if (frameTimer > 1.0/30.0) {
|
// if (frameTimer > 1.0/30.0) {
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
frameTimer = 0;
|
// frameTimer = 0;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@ -151,10 +151,10 @@ void WaterfallCanvas::setData(std::vector<signed char> *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WaterfallCanvas::OnIdle(wxIdleEvent &event) {
|
void WaterfallCanvas::OnIdle(wxIdleEvent &event) {
|
||||||
timer.update();
|
// timer.update();
|
||||||
frameTimer += timer.lastUpdateSeconds();
|
// frameTimer += timer.lastUpdateSeconds();
|
||||||
if (frameTimer > 1.0/30.0) {
|
// if (frameTimer > 1.0/30.0) {
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
frameTimer = 0;
|
// frameTimer = 0;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user