Output of a sine wave now works. Pfff
This commit is contained in:
parent
7095f9d5e7
commit
6a006e27f9
25
.gitignore
vendored
25
.gitignore
vendored
@ -1,35 +1,20 @@
|
|||||||
*.a
|
*.a
|
||||||
*.cxx
|
|
||||||
*.pyc
|
*.pyc
|
||||||
|
*.so
|
||||||
dist
|
dist
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
lasp/*.cpp
|
|
||||||
Makefile
|
Makefile
|
||||||
build
|
build
|
||||||
*.html
|
|
||||||
__pycache__
|
__pycache__
|
||||||
cython_debug
|
cython_debug
|
||||||
lasp/config.pxi
|
|
||||||
lasp/wrappers.c
|
|
||||||
lasp/resources_rc.py
|
|
||||||
*.so
|
|
||||||
test/test_bf
|
|
||||||
test/test_fft
|
|
||||||
test/test_math
|
|
||||||
test/test_workers
|
|
||||||
test/test_uldaq
|
|
||||||
doc
|
doc
|
||||||
LASP.egg-info
|
|
||||||
lasp_octave_fir.*
|
|
||||||
lasp/ui_*
|
|
||||||
resources_rc.py
|
|
||||||
.ropeproject
|
.ropeproject
|
||||||
.spyproject
|
.spyproject
|
||||||
test/test_uldaq
|
|
||||||
lasp/device/lasp_daq.cxx
|
|
||||||
lasp/c/lasp_config.h
|
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
.cache
|
.cache
|
||||||
lasp_config.h
|
_skbuild
|
||||||
|
src/lasp.egg-info
|
||||||
|
test/.ipynb_checkpoints
|
||||||
|
src/lasp/lasp_config.h
|
||||||
|
11
.gitmodules
vendored
11
.gitmodules
vendored
@ -1,12 +1,15 @@
|
|||||||
[submodule "STL-Threadsafe"]
|
[submodule "STL-Threadsafe"]
|
||||||
path = STL-Threadsafe
|
path = third_party/STL-Threadsafe
|
||||||
url = https://github.com/miachm/STL-Threadsafe
|
url = https://github.com/miachm/STL-Threadsafe
|
||||||
[submodule "gsl-lite"]
|
[submodule "gsl-lite"]
|
||||||
path = gsl-lite
|
path = third_party/gsl-lite
|
||||||
url = https://github.com/gsl-lite/gsl-lite
|
url = https://github.com/gsl-lite/gsl-lite
|
||||||
[submodule "DebugTrace-cpp"]
|
[submodule "DebugTrace-cpp"]
|
||||||
path = DebugTrace-cpp
|
path = third_party/DebugTrace-cpp
|
||||||
url = https://github.com/MasatoKokubo/DebugTrace-cpp
|
url = https://github.com/MasatoKokubo/DebugTrace-cpp
|
||||||
[submodule "armadillo-code"]
|
[submodule "armadillo-code"]
|
||||||
path = armadillo-code
|
path = third_party/armadillo-code
|
||||||
url = https://gitlab.com/conradsnicta/armadillo-code
|
url = https://gitlab.com/conradsnicta/armadillo-code
|
||||||
|
[submodule "third_party/tomlplusplus"]
|
||||||
|
path = third_party/tomlplusplus
|
||||||
|
url = https://github.com/marzer/tomlplusplus
|
||||||
|
132
CMakeLists.txt
132
CMakeLists.txt
@ -1,157 +1,65 @@
|
|||||||
cmake_minimum_required (VERSION 3.16)
|
cmake_minimum_required (VERSION 3.16)
|
||||||
|
|
||||||
|
project(LASP LANGUAGES CXX)
|
||||||
|
|
||||||
# To allow linking to static libs from other directories
|
# To allow linking to static libs from other directories
|
||||||
cmake_policy(SET CMP0079 NEW)
|
cmake_policy(SET CMP0079 NEW)
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/lasp/cmake")
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
|
||||||
include("BuildType")
|
include("BuildType")
|
||||||
|
include("QueryPythonForPybind11")
|
||||||
|
|
||||||
|
|
||||||
|
# Generate stubs for the Python module
|
||||||
|
option(WITH_PY_STUBS
|
||||||
|
"Generate Python stub files (.pyi) for the Python module." On)
|
||||||
|
|
||||||
|
# Find the pybind11 package
|
||||||
|
find_pybind11_python_first()
|
||||||
|
|
||||||
# This is used for code completion in vim
|
# This is used for code completion in vim
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
project(LASP LANGUAGES C CXX)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED)
|
set(CMAKE_CXX_STANDARD_REQUIRED)
|
||||||
set(CMAKE_C_STANDARD 11)
|
|
||||||
|
|
||||||
option(LASP_DOUBLE_PRECISION "Compile as double precision floating point" ON)
|
option(LASP_DOUBLE_PRECISION "Compile as double precision floating point" ON)
|
||||||
option(LASP_HAS_RTAUDIO "Compile with RtAudio Daq backend" ON)
|
option(LASP_HAS_RTAUDIO "Compile with RtAudio Daq backend" ON)
|
||||||
option(LASP_HAS_ULDAQ "Compile with UlDaq backend" ON)
|
option(LASP_HAS_ULDAQ "Compile with UlDaq backend" ON)
|
||||||
|
|
||||||
set(LASP_TRACERNAME "defaulttracer" CACHE STRING "Name of tracer variable containing level")
|
|
||||||
set(LASP_FFT_BACKEND "FFTW" CACHE STRING "FFT Library backend")
|
set(LASP_FFT_BACKEND "FFTW" CACHE STRING "FFT Library backend")
|
||||||
set_property(CACHE LASP_FFT_BACKEND PROPERTY STRINGS "FFTW" "FFTPack" "None")
|
set_property(CACHE LASP_FFT_BACKEND PROPERTY STRINGS "FFTW" "FFTPack" "None")
|
||||||
|
|
||||||
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
|
set(PY_FULL_VERSION ${PROJECT_VERSION}${PY_VERSION_SUFFIX})
|
||||||
include_directories(${Python3_INCLUDE_DIRS})
|
|
||||||
find_package(pybind11 CONFIG REQUIRED)
|
|
||||||
|
|
||||||
# Required for PYBIND11
|
# Required for PYBIND11
|
||||||
set(POSITION_INDEPENDENT_CODE True)
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL Debug)
|
if(CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||||
|
add_definitions(-DDEBUG=1)
|
||||||
set(LASP_DEBUG True)
|
set(LASP_DEBUG True)
|
||||||
else()
|
else()
|
||||||
set(LASP_DEBUG False)
|
set(LASP_DEBUG False)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(LASP_PARALLEL)
|
|
||||||
add_definitions(-D_REENTRANT)
|
|
||||||
set(LASP_THREADING_LIBRARIES pthread)
|
|
||||||
else()
|
|
||||||
set(LASP_THREADING_LIBRARIES "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# link openblas
|
# link openblas
|
||||||
set(BLA_VENDOR OpenBLAS)
|
set(BLA_VENDOR OpenBLAS)
|
||||||
find_package(BLAS REQUIRED)
|
find_package(BLAS REQUIRED)
|
||||||
|
|
||||||
# Armadillo
|
|
||||||
include_directories(SYSTEM armadillo-code/include)
|
|
||||||
|
|
||||||
|
|
||||||
# Reasonable maximum to the nfft size, at 48kHz this is 700s of data...
|
# Reasonable maximum to the nfft size, at 48kHz this is 700s of data...
|
||||||
add_definitions(-DLASP_MAX_NFFT=33554432) # 2**25
|
add_definitions(-DLASP_MAX_NFFT=33554432) # 2**25
|
||||||
|
|
||||||
# ####################################### End of user-adjustable variables section
|
# ####################################### End of user-adjustable variables section
|
||||||
|
|
||||||
if(LASP_FFT_BACKEND STREQUAL "FFTW")
|
include(OSSpecific)
|
||||||
find_library(FFTW_LIBRARY NAMES fftw3 fftw)
|
|
||||||
set(FFT_LIBRARIES "${FFTW_LIBRARY}")
|
|
||||||
elseif(LASP_FFT_BACKEND STREQUAL "FFTPack")
|
|
||||||
include_directories(fftpack)
|
|
||||||
set(FFT_LIBRARIES fftpack)
|
|
||||||
add_subdirectory(fftpack)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# General make flags
|
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-type-limits \
|
|
||||||
-Werror=implicit-function-declaration -Wno-unused-parameter \
|
|
||||||
-Werror=return-type -Wfatal-errors")
|
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|
||||||
set(win32 true)
|
|
||||||
set(home $ENV{USERPROFILE})
|
|
||||||
# set(miniconda_dir ${home}\\Miniconda3)
|
|
||||||
|
|
||||||
message("Building for Windows")
|
|
||||||
include_directories(
|
|
||||||
..\\rtaudio
|
|
||||||
C:\\mingw\\mingw64\\include\\OpenBLAS
|
|
||||||
link_directories(${home}\\miniconda3\\Library\\include)
|
|
||||||
)
|
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH} $miniconda_dir\\Lib\\cmake")
|
|
||||||
# include(
|
|
||||||
add_definitions(-DMS_WIN64)
|
|
||||||
link_directories(C:\\mingw\\mingw64\\lib)
|
|
||||||
link_directories(C:\\mingw\\mingw64\\bin)
|
|
||||||
link_directories(..\\rtaudio)
|
|
||||||
link_directories(${home}\\Miniconda3)
|
|
||||||
add_definitions(-DHAS_RTAUDIO_WIN_WASAPI_API)
|
|
||||||
else() # Linux compile
|
|
||||||
set(win32 false)
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=incompatible-pointer-types")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wfatal-errors")
|
|
||||||
include_directories(/usr/local/include/rtaudio)
|
|
||||||
include_directories(/usr/include/rtaudio)
|
|
||||||
link_directories(/usr/local/lib)
|
|
||||||
# This should become optional later on, and be added to the windows list as
|
|
||||||
# well.
|
|
||||||
|
|
||||||
endif()
|
|
||||||
# The last argument here takes care of calling SIGABRT when an integer overflow
|
|
||||||
# occures.
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-type-limits")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-type-limits")
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS_RELEASE "-O2 -mfpmath=sse -march=x86-64 -mtune=native \
|
set(CMAKE_C_FLAGS_RELEASE "-O3 -mfpmath=sse -march=x86-64 -mtune=native \
|
||||||
-fdata-sections -ffunction-sections -fomit-frame-pointer -finline-functions")
|
-fdata-sections -ffunction-sections -fomit-frame-pointer -finline-functions")
|
||||||
|
|
||||||
# ############################# End compilation flags
|
# ############################# End compilation flags
|
||||||
|
|
||||||
|
add_subdirectory(third_party)
|
||||||
# Add FFTpack dir if used as FFT backend
|
add_subdirectory(src/lasp)
|
||||||
if(LASP_FFTPACK_BACKEND)
|
|
||||||
add_subdirectory(fftpack)
|
|
||||||
include_directories(
|
|
||||||
fftpack
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include_directories(STL-Threadsafe/include)
|
|
||||||
include_directories(gsl-lite/include)
|
|
||||||
include_directories(DebugTrace-cpp/include)
|
|
||||||
|
|
||||||
add_subdirectory(lasp)
|
|
||||||
add_subdirectory(gsl-lite)
|
|
||||||
add_subdirectory(test)
|
|
||||||
|
|
||||||
# set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in")
|
|
||||||
set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
|
|
||||||
|
|
||||||
set(DEPS "${CMAKE_CURRENT_SOURCE_DIR}/*.py"
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/lasp/*.py"
|
|
||||||
# "wrappers"
|
|
||||||
# "lasp_device_lib")
|
|
||||||
)
|
|
||||||
|
|
||||||
# set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp")
|
|
||||||
|
|
||||||
# # configure_file(${SETUP_PY_IN} ${SETUP_PY})
|
|
||||||
# add_custom_command(OUTPUT ${OUTPUT}
|
|
||||||
# COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build
|
|
||||||
# COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT}
|
|
||||||
# DEPENDS ${DEPS})
|
|
||||||
|
|
||||||
# add_custom_target(target ALL DEPENDS ${OUTPUT})
|
|
||||||
|
|
||||||
# if(DEFINED INSTALL_DEBUG)
|
|
||||||
# set(EXTRA_SETUP_ARG --user -e)
|
|
||||||
# else()
|
|
||||||
# set(EXTRA_SETUP_ARG "")
|
|
||||||
# endif()
|
|
||||||
|
|
||||||
|
|
||||||
# install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip install ${EXTRA_SETUP_ARG} .)")
|
|
||||||
|
358
Doxyfile
358
Doxyfile
@ -1,4 +1,4 @@
|
|||||||
# Doxyfile 1.8.14
|
# Doxyfile 1.9.3
|
||||||
|
|
||||||
# This file describes the settings to be used by the documentation system
|
# This file describes the settings to be used by the documentation system
|
||||||
# doxygen (www.doxygen.org) for a project.
|
# doxygen (www.doxygen.org) for a project.
|
||||||
@ -17,10 +17,10 @@
|
|||||||
# Project related configuration options
|
# Project related configuration options
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# This tag specifies the encoding used for all characters in the config file
|
# This tag specifies the encoding used for all characters in the configuration
|
||||||
# that follow. The default is UTF-8 which is also the encoding used for all text
|
# file that follow. The default is UTF-8 which is also the encoding used for all
|
||||||
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
|
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
|
||||||
# built into libc) for the transcoding. See
|
# iconv built into libc) for the transcoding. See
|
||||||
# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
|
# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
|
||||||
# The default value is: UTF-8.
|
# The default value is: UTF-8.
|
||||||
|
|
||||||
@ -38,20 +38,20 @@ PROJECT_NAME = LASP
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER =
|
PROJECT_NUMBER =
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
# quick idea about the purpose of the project. Keep the description short.
|
# quick idea about the purpose of the project. Keep the description short.
|
||||||
|
|
||||||
PROJECT_BRIEF =
|
PROJECT_BRIEF =
|
||||||
|
|
||||||
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
|
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
|
||||||
# in the documentation. The maximum height of the logo should not exceed 55
|
# in the documentation. The maximum height of the logo should not exceed 55
|
||||||
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
|
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
|
||||||
# the logo to the output directory.
|
# the logo to the output directory.
|
||||||
|
|
||||||
PROJECT_LOGO =
|
PROJECT_LOGO =
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||||
# into which the generated documentation will be written. If a relative path is
|
# into which the generated documentation will be written. If a relative path is
|
||||||
@ -93,6 +93,14 @@ ALLOW_UNICODE_NAMES = NO
|
|||||||
|
|
||||||
OUTPUT_LANGUAGE = English
|
OUTPUT_LANGUAGE = English
|
||||||
|
|
||||||
|
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
|
||||||
|
# documentation generated by doxygen is written. Doxygen will use this
|
||||||
|
# information to generate all generated output in the proper direction.
|
||||||
|
# Possible values are: None, LTR, RTL and Context.
|
||||||
|
# The default value is: None.
|
||||||
|
|
||||||
|
OUTPUT_TEXT_DIRECTION = None
|
||||||
|
|
||||||
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
|
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
|
||||||
# descriptions after the members that are listed in the file and class
|
# descriptions after the members that are listed in the file and class
|
||||||
# documentation (similar to Javadoc). Set to NO to disable this.
|
# documentation (similar to Javadoc). Set to NO to disable this.
|
||||||
@ -162,7 +170,7 @@ FULL_PATH_NAMES = YES
|
|||||||
# will be relative from the directory where doxygen is started.
|
# will be relative from the directory where doxygen is started.
|
||||||
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
|
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
|
||||||
|
|
||||||
STRIP_FROM_PATH =
|
STRIP_FROM_PATH =
|
||||||
|
|
||||||
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
|
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
|
||||||
# path mentioned in the documentation of a class, which tells the reader which
|
# path mentioned in the documentation of a class, which tells the reader which
|
||||||
@ -171,7 +179,7 @@ STRIP_FROM_PATH =
|
|||||||
# specify the list of include paths that are normally passed to the compiler
|
# specify the list of include paths that are normally passed to the compiler
|
||||||
# using the -I flag.
|
# using the -I flag.
|
||||||
|
|
||||||
STRIP_FROM_INC_PATH =
|
STRIP_FROM_INC_PATH =
|
||||||
|
|
||||||
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
|
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
|
||||||
# less readable) file names. This can be useful is your file systems doesn't
|
# less readable) file names. This can be useful is your file systems doesn't
|
||||||
@ -189,6 +197,16 @@ SHORT_NAMES = NO
|
|||||||
|
|
||||||
JAVADOC_AUTOBRIEF = NO
|
JAVADOC_AUTOBRIEF = NO
|
||||||
|
|
||||||
|
# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
|
||||||
|
# such as
|
||||||
|
# /***************
|
||||||
|
# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
|
||||||
|
# Javadoc-style will behave just like regular comments and it will not be
|
||||||
|
# interpreted by doxygen.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
JAVADOC_BANNER = NO
|
||||||
|
|
||||||
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
|
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
|
||||||
# line (until the first dot) of a Qt-style comment as the brief description. If
|
# line (until the first dot) of a Qt-style comment as the brief description. If
|
||||||
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
|
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
|
||||||
@ -238,14 +256,18 @@ TAB_SIZE = 4
|
|||||||
# "Side Effects:". You can put \n's in the value part of an alias to insert
|
# "Side Effects:". You can put \n's in the value part of an alias to insert
|
||||||
# newlines (in the resulting output). You can put ^^ in the value part of an
|
# newlines (in the resulting output). You can put ^^ in the value part of an
|
||||||
# alias to insert a newline as if a physical newline was in the original file.
|
# alias to insert a newline as if a physical newline was in the original file.
|
||||||
|
# When you need a literal { or } or , in the value part of an alias you have to
|
||||||
|
# escape them by means of a backslash (\), this can lead to conflicts with the
|
||||||
|
# commands \{ and \} for these it is advised to use the version @{ and @} or use
|
||||||
|
# a double escape (\\{ and \\})
|
||||||
|
|
||||||
ALIASES =
|
ALIASES =
|
||||||
|
|
||||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||||
# will allow you to use the command class in the itcl::class meaning.
|
# will allow you to use the command class in the itcl::class meaning.
|
||||||
|
|
||||||
TCL_SUBST =
|
TCL_SUBST =
|
||||||
|
|
||||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||||
# only. Doxygen will then generate output that is more tailored for C. For
|
# only. Doxygen will then generate output that is more tailored for C. For
|
||||||
@ -253,7 +275,7 @@ TCL_SUBST =
|
|||||||
# members will be omitted, etc.
|
# members will be omitted, etc.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||||
|
|
||||||
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
|
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
|
||||||
# Python sources only. Doxygen will then generate output that is more tailored
|
# Python sources only. Doxygen will then generate output that is more tailored
|
||||||
@ -275,28 +297,37 @@ OPTIMIZE_FOR_FORTRAN = NO
|
|||||||
|
|
||||||
OPTIMIZE_OUTPUT_VHDL = NO
|
OPTIMIZE_OUTPUT_VHDL = NO
|
||||||
|
|
||||||
|
# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
|
||||||
|
# sources only. Doxygen will then generate output that is more tailored for that
|
||||||
|
# language. For instance, namespaces will be presented as modules, types will be
|
||||||
|
# separated into more groups, etc.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
OPTIMIZE_OUTPUT_SLICE = NO
|
||||||
|
|
||||||
# Doxygen selects the parser to use depending on the extension of the files it
|
# Doxygen selects the parser to use depending on the extension of the files it
|
||||||
# parses. With this tag you can assign which parser to use for a given
|
# parses. With this tag you can assign which parser to use for a given
|
||||||
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
||||||
# using this tag. The format is ext=language, where ext is a file extension, and
|
# using this tag. The format is ext=language, where ext is a file extension, and
|
||||||
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
|
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
|
||||||
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
|
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
|
||||||
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
|
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
|
||||||
# Fortran. In the later case the parser tries to guess whether the code is fixed
|
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
|
||||||
# or free formatted code, this is the default for Fortran type files), VHDL. For
|
# tries to guess whether the code is fixed or free formatted code, this is the
|
||||||
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
|
# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
|
||||||
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
|
# .inc files as Fortran files (default is PHP), and .f files as C (default is
|
||||||
|
# Fortran), use: inc=Fortran f=C.
|
||||||
#
|
#
|
||||||
# Note: For files without extension you can use no_extension as a placeholder.
|
# Note: For files without extension you can use no_extension as a placeholder.
|
||||||
#
|
#
|
||||||
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
|
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
|
||||||
# the files are not read by doxygen.
|
# the files are not read by doxygen.
|
||||||
|
|
||||||
EXTENSION_MAPPING =
|
EXTENSION_MAPPING =
|
||||||
|
|
||||||
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
|
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
|
||||||
# according to the Markdown format, which allows for more readable
|
# according to the Markdown format, which allows for more readable
|
||||||
# documentation. See http://daringfireball.net/projects/markdown/ for details.
|
# documentation. See https://daringfireball.net/projects/markdown/ for details.
|
||||||
# The output of markdown processing is further processed by doxygen, so you can
|
# The output of markdown processing is further processed by doxygen, so you can
|
||||||
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
|
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
|
||||||
# case of backward compatibilities issues.
|
# case of backward compatibilities issues.
|
||||||
@ -308,7 +339,7 @@ MARKDOWN_SUPPORT = YES
|
|||||||
# to that level are automatically included in the table of contents, even if
|
# to that level are automatically included in the table of contents, even if
|
||||||
# they do not have an id attribute.
|
# they do not have an id attribute.
|
||||||
# Note: This feature currently applies only to Markdown headings.
|
# Note: This feature currently applies only to Markdown headings.
|
||||||
# Minimum value: 0, maximum value: 99, default value: 0.
|
# Minimum value: 0, maximum value: 99, default value: 5.
|
||||||
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
|
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
|
||||||
|
|
||||||
TOC_INCLUDE_HEADINGS = 0
|
TOC_INCLUDE_HEADINGS = 0
|
||||||
@ -444,6 +475,12 @@ EXTRACT_ALL = YES
|
|||||||
|
|
||||||
EXTRACT_PRIVATE = NO
|
EXTRACT_PRIVATE = NO
|
||||||
|
|
||||||
|
# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
|
||||||
|
# methods of a class will be included in the documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
EXTRACT_PRIV_VIRTUAL = NO
|
||||||
|
|
||||||
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
|
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
|
||||||
# scope will be included in the documentation.
|
# scope will be included in the documentation.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
@ -498,8 +535,8 @@ HIDE_UNDOC_MEMBERS = NO
|
|||||||
HIDE_UNDOC_CLASSES = NO
|
HIDE_UNDOC_CLASSES = NO
|
||||||
|
|
||||||
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
|
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
|
||||||
# (class|struct|union) declarations. If set to NO, these declarations will be
|
# declarations. If set to NO, these declarations will be included in the
|
||||||
# included in the documentation.
|
# documentation.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
HIDE_FRIEND_COMPOUNDS = NO
|
HIDE_FRIEND_COMPOUNDS = NO
|
||||||
@ -522,7 +559,7 @@ INTERNAL_DOCS = NO
|
|||||||
# names in lower-case letters. If set to YES, upper-case letters are also
|
# names in lower-case letters. If set to YES, upper-case letters are also
|
||||||
# allowed. This is useful if you have classes or files whose names only differ
|
# allowed. This is useful if you have classes or files whose names only differ
|
||||||
# in case and if your file system supports case sensitive file names. Windows
|
# in case and if your file system supports case sensitive file names. Windows
|
||||||
# and Mac users are advised to set this option to NO.
|
# (including Cygwin) ands Mac users are advised to set this option to NO.
|
||||||
# The default value is: system dependent.
|
# The default value is: system dependent.
|
||||||
|
|
||||||
CASE_SENSE_NAMES = NO
|
CASE_SENSE_NAMES = NO
|
||||||
@ -532,7 +569,7 @@ CASE_SENSE_NAMES = NO
|
|||||||
# scope will be hidden.
|
# scope will be hidden.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
HIDE_SCOPE_NAMES = YES
|
HIDE_SCOPE_NAMES = NO
|
||||||
|
|
||||||
# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
|
# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
|
||||||
# append additional text to a page's title, such as Class Reference. If set to
|
# append additional text to a page's title, such as Class Reference. If set to
|
||||||
@ -649,7 +686,7 @@ GENERATE_DEPRECATEDLIST= YES
|
|||||||
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
|
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
|
||||||
# ... \endcond blocks.
|
# ... \endcond blocks.
|
||||||
|
|
||||||
ENABLED_SECTIONS =
|
ENABLED_SECTIONS =
|
||||||
|
|
||||||
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
|
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
|
||||||
# initial value of a variable or macro / define can have for it to appear in the
|
# initial value of a variable or macro / define can have for it to appear in the
|
||||||
@ -691,7 +728,7 @@ SHOW_NAMESPACES = YES
|
|||||||
# by doxygen. Whatever the program writes to standard output is used as the file
|
# by doxygen. Whatever the program writes to standard output is used as the file
|
||||||
# version. For an example see the documentation.
|
# version. For an example see the documentation.
|
||||||
|
|
||||||
FILE_VERSION_FILTER =
|
FILE_VERSION_FILTER =
|
||||||
|
|
||||||
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
|
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
|
||||||
# by doxygen. The layout file controls the global structure of the generated
|
# by doxygen. The layout file controls the global structure of the generated
|
||||||
@ -704,7 +741,7 @@ FILE_VERSION_FILTER =
|
|||||||
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
|
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
|
||||||
# tag is left empty.
|
# tag is left empty.
|
||||||
|
|
||||||
LAYOUT_FILE =
|
LAYOUT_FILE =
|
||||||
|
|
||||||
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
|
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
|
||||||
# the reference definitions. This must be a list of .bib files. The .bib
|
# the reference definitions. This must be a list of .bib files. The .bib
|
||||||
@ -714,7 +751,7 @@ LAYOUT_FILE =
|
|||||||
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
|
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
|
||||||
# search path. See also \cite for info how to create references.
|
# search path. See also \cite for info how to create references.
|
||||||
|
|
||||||
CITE_BIB_FILES =
|
CITE_BIB_FILES =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to warning and progress messages
|
# Configuration options related to warning and progress messages
|
||||||
@ -754,7 +791,8 @@ WARN_IF_DOC_ERROR = YES
|
|||||||
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
|
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
|
||||||
# are documented, but have no documentation for their parameters or return
|
# are documented, but have no documentation for their parameters or return
|
||||||
# value. If set to NO, doxygen will only warn about wrong or incomplete
|
# value. If set to NO, doxygen will only warn about wrong or incomplete
|
||||||
# parameter documentation, but not about the absence of documentation.
|
# parameter documentation, but not about the absence of documentation. If
|
||||||
|
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
WARN_NO_PARAMDOC = NO
|
WARN_NO_PARAMDOC = NO
|
||||||
@ -779,7 +817,7 @@ WARN_FORMAT = "$file:$line: $text"
|
|||||||
# messages should be written. If left blank the output is written to standard
|
# messages should be written. If left blank the output is written to standard
|
||||||
# error (stderr).
|
# error (stderr).
|
||||||
|
|
||||||
WARN_LOGFILE =
|
WARN_LOGFILE =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the input files
|
# Configuration options related to the input files
|
||||||
@ -791,7 +829,7 @@ WARN_LOGFILE =
|
|||||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = lasp
|
INPUT = src
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
@ -813,8 +851,10 @@ INPUT_ENCODING = UTF-8
|
|||||||
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
|
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
|
||||||
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
|
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
|
||||||
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
|
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
|
||||||
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
|
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
|
||||||
# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
|
# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen
|
||||||
|
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd,
|
||||||
|
# *.vhdl, *.ucf, *.qsf and *.ice.
|
||||||
|
|
||||||
FILE_PATTERNS = *.c \
|
FILE_PATTERNS = *.c \
|
||||||
*.cc \
|
*.cc \
|
||||||
@ -874,7 +914,7 @@ RECURSIVE = YES
|
|||||||
# Note that relative paths are relative to the directory from which doxygen is
|
# Note that relative paths are relative to the directory from which doxygen is
|
||||||
# run.
|
# run.
|
||||||
|
|
||||||
EXCLUDE =
|
EXCLUDE =
|
||||||
|
|
||||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||||
# directories that are symbolic links (a Unix file system feature) are excluded
|
# directories that are symbolic links (a Unix file system feature) are excluded
|
||||||
@ -890,7 +930,7 @@ EXCLUDE_SYMLINKS = NO
|
|||||||
# Note that the wildcards are matched against the file with absolute path, so to
|
# Note that the wildcards are matched against the file with absolute path, so to
|
||||||
# exclude all test directories for example use the pattern */test/*
|
# exclude all test directories for example use the pattern */test/*
|
||||||
|
|
||||||
EXCLUDE_PATTERNS =
|
EXCLUDE_PATTERNS =
|
||||||
|
|
||||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||||
@ -901,13 +941,13 @@ EXCLUDE_PATTERNS =
|
|||||||
# Note that the wildcards are matched against the file with absolute path, so to
|
# Note that the wildcards are matched against the file with absolute path, so to
|
||||||
# exclude all test directories use the pattern */test/*
|
# exclude all test directories use the pattern */test/*
|
||||||
|
|
||||||
EXCLUDE_SYMBOLS =
|
EXCLUDE_SYMBOLS =
|
||||||
|
|
||||||
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
|
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
|
||||||
# that contain example code fragments that are included (see the \include
|
# that contain example code fragments that are included (see the \include
|
||||||
# command).
|
# command).
|
||||||
|
|
||||||
EXAMPLE_PATH =
|
EXAMPLE_PATH =
|
||||||
|
|
||||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
||||||
@ -927,7 +967,7 @@ EXAMPLE_RECURSIVE = NO
|
|||||||
# that contain images that are to be included in the documentation (see the
|
# that contain images that are to be included in the documentation (see the
|
||||||
# \image command).
|
# \image command).
|
||||||
|
|
||||||
IMAGE_PATH =
|
IMAGE_PATH =
|
||||||
|
|
||||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||||
@ -948,7 +988,7 @@ IMAGE_PATH =
|
|||||||
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||||
# properly processed by doxygen.
|
# properly processed by doxygen.
|
||||||
|
|
||||||
INPUT_FILTER =
|
INPUT_FILTER =
|
||||||
|
|
||||||
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
|
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
|
||||||
# basis. Doxygen will compare the file name with each pattern and apply the
|
# basis. Doxygen will compare the file name with each pattern and apply the
|
||||||
@ -961,7 +1001,7 @@ INPUT_FILTER =
|
|||||||
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||||
# properly processed by doxygen.
|
# properly processed by doxygen.
|
||||||
|
|
||||||
FILTER_PATTERNS =
|
FILTER_PATTERNS =
|
||||||
|
|
||||||
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
|
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
|
||||||
# INPUT_FILTER) will also be used to filter the input files that are used for
|
# INPUT_FILTER) will also be used to filter the input files that are used for
|
||||||
@ -976,14 +1016,14 @@ FILTER_SOURCE_FILES = NO
|
|||||||
# *.ext= (so without naming a filter).
|
# *.ext= (so without naming a filter).
|
||||||
# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
|
# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
|
||||||
|
|
||||||
FILTER_SOURCE_PATTERNS =
|
FILTER_SOURCE_PATTERNS =
|
||||||
|
|
||||||
# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
|
# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
|
||||||
# is part of the input, its contents will be placed on the main page
|
# is part of the input, its contents will be placed on the main page
|
||||||
# (index.html). This can be useful if you have a project on for instance GitHub
|
# (index.html). This can be useful if you have a project on for instance GitHub
|
||||||
# and want to reuse the introduction page also for the doxygen output.
|
# and want to reuse the introduction page also for the doxygen output.
|
||||||
|
|
||||||
USE_MDFILE_AS_MAINPAGE =
|
USE_MDFILE_AS_MAINPAGE =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to source browsing
|
# Configuration options related to source browsing
|
||||||
@ -1012,7 +1052,7 @@ INLINE_SOURCES = NO
|
|||||||
STRIP_CODE_COMMENTS = YES
|
STRIP_CODE_COMMENTS = YES
|
||||||
|
|
||||||
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
|
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
|
||||||
# function all documented functions referencing it will be listed.
|
# entity all documented functions referencing it will be listed.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
REFERENCED_BY_RELATION = NO
|
REFERENCED_BY_RELATION = NO
|
||||||
@ -1049,7 +1089,7 @@ SOURCE_TOOLTIPS = YES
|
|||||||
#
|
#
|
||||||
# To use it do the following:
|
# To use it do the following:
|
||||||
# - Install the latest version of global
|
# - Install the latest version of global
|
||||||
# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
|
# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
|
||||||
# - Make sure the INPUT points to the root of the source tree
|
# - Make sure the INPUT points to the root of the source tree
|
||||||
# - Run doxygen as normal
|
# - Run doxygen as normal
|
||||||
#
|
#
|
||||||
@ -1071,6 +1111,35 @@ USE_HTAGS = NO
|
|||||||
|
|
||||||
VERBATIM_HEADERS = YES
|
VERBATIM_HEADERS = YES
|
||||||
|
|
||||||
|
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
|
||||||
|
# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
|
||||||
|
# cost of reduced performance. This can be particularly helpful with template
|
||||||
|
# rich C++ code for which doxygen's built-in parser lacks the necessary type
|
||||||
|
# information.
|
||||||
|
# Note: The availability of this option depends on whether or not doxygen was
|
||||||
|
# generated with the -Duse_libclang=ON option for CMake.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
CLANG_ASSISTED_PARSING = NO
|
||||||
|
|
||||||
|
# If clang assisted parsing is enabled you can provide the compiler with command
|
||||||
|
# line options that you would normally use when invoking the compiler. Note that
|
||||||
|
# the include paths will already be set by doxygen for the files and directories
|
||||||
|
# specified with INPUT and INCLUDE_PATH.
|
||||||
|
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
|
||||||
|
|
||||||
|
CLANG_OPTIONS =
|
||||||
|
|
||||||
|
# If clang assisted parsing is enabled you can provide the clang parser with the
|
||||||
|
# path to the compilation database (see:
|
||||||
|
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files
|
||||||
|
# were built. This is equivalent to specifying the "-p" option to a clang tool,
|
||||||
|
# such as clang-check. These options will then be passed to the parser.
|
||||||
|
# Note: The availability of this option depends on whether or not doxygen was
|
||||||
|
# generated with the -Duse_libclang=ON option for CMake.
|
||||||
|
|
||||||
|
CLANG_DATABASE_PATH =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the alphabetical class index
|
# Configuration options related to the alphabetical class index
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@ -1095,7 +1164,7 @@ COLS_IN_ALPHA_INDEX = 5
|
|||||||
# while generating the index headers.
|
# while generating the index headers.
|
||||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||||
|
|
||||||
IGNORE_PREFIX =
|
IGNORE_PREFIX =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the HTML output
|
# Configuration options related to the HTML output
|
||||||
@ -1139,7 +1208,7 @@ HTML_FILE_EXTENSION = .html
|
|||||||
# of the possible markers and block names see the documentation.
|
# of the possible markers and block names see the documentation.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_HEADER =
|
HTML_HEADER =
|
||||||
|
|
||||||
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
|
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
|
||||||
# generated HTML page. If the tag is left blank doxygen will generate a standard
|
# generated HTML page. If the tag is left blank doxygen will generate a standard
|
||||||
@ -1149,7 +1218,7 @@ HTML_HEADER =
|
|||||||
# that doxygen normally uses.
|
# that doxygen normally uses.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_FOOTER =
|
HTML_FOOTER =
|
||||||
|
|
||||||
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
|
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
|
||||||
# sheet that is used by each HTML page. It can be used to fine-tune the look of
|
# sheet that is used by each HTML page. It can be used to fine-tune the look of
|
||||||
@ -1161,7 +1230,7 @@ HTML_FOOTER =
|
|||||||
# obsolete.
|
# obsolete.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_STYLESHEET =
|
HTML_STYLESHEET =
|
||||||
|
|
||||||
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
|
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
|
||||||
# cascading style sheets that are included after the standard style sheets
|
# cascading style sheets that are included after the standard style sheets
|
||||||
@ -1174,7 +1243,7 @@ HTML_STYLESHEET =
|
|||||||
# list). For an example see the documentation.
|
# list). For an example see the documentation.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_EXTRA_STYLESHEET =
|
HTML_EXTRA_STYLESHEET =
|
||||||
|
|
||||||
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||||
# other source files which should be copied to the HTML output directory. Note
|
# other source files which should be copied to the HTML output directory. Note
|
||||||
@ -1184,7 +1253,7 @@ HTML_EXTRA_STYLESHEET =
|
|||||||
# files will be copied as-is; there are no commands or markers available.
|
# files will be copied as-is; there are no commands or markers available.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_EXTRA_FILES =
|
HTML_EXTRA_FILES =
|
||||||
|
|
||||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
||||||
# will adjust the colors in the style sheet and background images according to
|
# will adjust the colors in the style sheet and background images according to
|
||||||
@ -1227,9 +1296,9 @@ HTML_TIMESTAMP = NO
|
|||||||
|
|
||||||
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
|
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
|
||||||
# documentation will contain a main index with vertical navigation menus that
|
# documentation will contain a main index with vertical navigation menus that
|
||||||
# are dynamically created via Javascript. If disabled, the navigation index will
|
# are dynamically created via JavaScript. If disabled, the navigation index will
|
||||||
# consists of multiple levels of tabs that are statically embedded in every HTML
|
# consists of multiple levels of tabs that are statically embedded in every HTML
|
||||||
# page. Disable this option to support browsers that do not have Javascript,
|
# page. Disable this option to support browsers that do not have JavaScript,
|
||||||
# like the Qt help browser.
|
# like the Qt help browser.
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
@ -1259,13 +1328,13 @@ HTML_INDEX_NUM_ENTRIES = 100
|
|||||||
|
|
||||||
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
|
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
|
||||||
# generated that can be used as input for Apple's Xcode 3 integrated development
|
# generated that can be used as input for Apple's Xcode 3 integrated development
|
||||||
# environment (see: https://developer.apple.com/tools/xcode/), introduced with
|
# environment (see: https://developer.apple.com/xcode/), introduced with OSX
|
||||||
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
|
# 10.5 (Leopard). To create a documentation set, doxygen will generate a
|
||||||
# Makefile in the HTML output directory. Running make will produce the docset in
|
# Makefile in the HTML output directory. Running make will produce the docset in
|
||||||
# that directory and running make install will install the docset in
|
# that directory and running make install will install the docset in
|
||||||
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
|
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
|
||||||
# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html
|
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
|
||||||
# for more information.
|
# genXcode/_index.html for more information.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
@ -1304,7 +1373,7 @@ DOCSET_PUBLISHER_NAME = Publisher
|
|||||||
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
|
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
|
||||||
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
|
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
|
||||||
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
|
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
|
||||||
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
|
# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
|
||||||
# Windows.
|
# Windows.
|
||||||
#
|
#
|
||||||
# The HTML Help Workshop contains a compiler that can convert all HTML output
|
# The HTML Help Workshop contains a compiler that can convert all HTML output
|
||||||
@ -1324,7 +1393,7 @@ GENERATE_HTMLHELP = NO
|
|||||||
# written to the html output directory.
|
# written to the html output directory.
|
||||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
CHM_FILE =
|
CHM_FILE =
|
||||||
|
|
||||||
# The HHC_LOCATION tag can be used to specify the location (absolute path
|
# The HHC_LOCATION tag can be used to specify the location (absolute path
|
||||||
# including file name) of the HTML help compiler (hhc.exe). If non-empty,
|
# including file name) of the HTML help compiler (hhc.exe). If non-empty,
|
||||||
@ -1332,7 +1401,7 @@ CHM_FILE =
|
|||||||
# The file has to be specified with full path.
|
# The file has to be specified with full path.
|
||||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
HHC_LOCATION =
|
HHC_LOCATION =
|
||||||
|
|
||||||
# The GENERATE_CHI flag controls if a separate .chi index file is generated
|
# The GENERATE_CHI flag controls if a separate .chi index file is generated
|
||||||
# (YES) or that it should be included in the master .chm file (NO).
|
# (YES) or that it should be included in the master .chm file (NO).
|
||||||
@ -1345,7 +1414,7 @@ GENERATE_CHI = NO
|
|||||||
# and project file content.
|
# and project file content.
|
||||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
CHM_INDEX_ENCODING =
|
CHM_INDEX_ENCODING =
|
||||||
|
|
||||||
# The BINARY_TOC flag controls whether a binary table of contents is generated
|
# The BINARY_TOC flag controls whether a binary table of contents is generated
|
||||||
# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
|
# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
|
||||||
@ -1376,11 +1445,11 @@ GENERATE_QHP = NO
|
|||||||
# the HTML output folder.
|
# the HTML output folder.
|
||||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
QCH_FILE =
|
QCH_FILE =
|
||||||
|
|
||||||
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
|
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
|
||||||
# Project output. For more information please see Qt Help Project / Namespace
|
# Project output. For more information please see Qt Help Project / Namespace
|
||||||
# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace).
|
# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
|
||||||
# The default value is: org.doxygen.Project.
|
# The default value is: org.doxygen.Project.
|
||||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
@ -1388,7 +1457,8 @@ QHP_NAMESPACE = org.doxygen.Project
|
|||||||
|
|
||||||
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
|
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
|
||||||
# Help Project output. For more information please see Qt Help Project / Virtual
|
# Help Project output. For more information please see Qt Help Project / Virtual
|
||||||
# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders).
|
# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
|
||||||
|
# folders).
|
||||||
# The default value is: doc.
|
# The default value is: doc.
|
||||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
@ -1396,31 +1466,33 @@ QHP_VIRTUAL_FOLDER = doc
|
|||||||
|
|
||||||
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
|
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
|
||||||
# filter to add. For more information please see Qt Help Project / Custom
|
# filter to add. For more information please see Qt Help Project / Custom
|
||||||
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
|
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
|
||||||
|
# filters).
|
||||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
QHP_CUST_FILTER_NAME =
|
QHP_CUST_FILTER_NAME =
|
||||||
|
|
||||||
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
|
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
|
||||||
# custom filter to add. For more information please see Qt Help Project / Custom
|
# custom filter to add. For more information please see Qt Help Project / Custom
|
||||||
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
|
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
|
||||||
|
# filters).
|
||||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
QHP_CUST_FILTER_ATTRS =
|
QHP_CUST_FILTER_ATTRS =
|
||||||
|
|
||||||
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
|
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
|
||||||
# project's filter section matches. Qt Help Project / Filter Attributes (see:
|
# project's filter section matches. Qt Help Project / Filter Attributes (see:
|
||||||
# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes).
|
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
|
||||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
QHP_SECT_FILTER_ATTRS =
|
QHP_SECT_FILTER_ATTRS =
|
||||||
|
|
||||||
# The QHG_LOCATION tag can be used to specify the location of Qt's
|
# The QHG_LOCATION tag can be used to specify the location of Qt's
|
||||||
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
|
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
|
||||||
# generated .qhp file.
|
# generated .qhp file.
|
||||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
QHG_LOCATION =
|
QHG_LOCATION =
|
||||||
|
|
||||||
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
|
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
|
||||||
# generated, together with the HTML files, they form an Eclipse help plugin. To
|
# generated, together with the HTML files, they form an Eclipse help plugin. To
|
||||||
@ -1514,8 +1586,14 @@ FORMULA_FONTSIZE = 10
|
|||||||
|
|
||||||
FORMULA_TRANSPARENT = YES
|
FORMULA_TRANSPARENT = YES
|
||||||
|
|
||||||
|
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
|
||||||
|
# to create new LaTeX commands to be used in formulas as building blocks. See
|
||||||
|
# the section "Including formulas" for details.
|
||||||
|
|
||||||
|
FORMULA_MACROFILE =
|
||||||
|
|
||||||
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
|
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
|
||||||
# https://www.mathjax.org) which uses client side Javascript for the rendering
|
# https://www.mathjax.org) which uses client side JavaScript for the rendering
|
||||||
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
|
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
|
||||||
# installed or if you want to formulas look prettier in the HTML output. When
|
# installed or if you want to formulas look prettier in the HTML output. When
|
||||||
# enabled you may also need to install MathJax separately and configure the path
|
# enabled you may also need to install MathJax separately and configure the path
|
||||||
@ -1543,7 +1621,7 @@ MATHJAX_FORMAT = HTML-CSS
|
|||||||
# Content Delivery Network so you can quickly see the result without installing
|
# Content Delivery Network so you can quickly see the result without installing
|
||||||
# MathJax. However, it is strongly recommended to install a local copy of
|
# MathJax. However, it is strongly recommended to install a local copy of
|
||||||
# MathJax from https://www.mathjax.org before deployment.
|
# MathJax from https://www.mathjax.org before deployment.
|
||||||
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/.
|
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
|
||||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/
|
MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/
|
||||||
@ -1553,7 +1631,7 @@ MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/
|
|||||||
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
|
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
|
||||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
MATHJAX_EXTENSIONS =
|
MATHJAX_EXTENSIONS =
|
||||||
|
|
||||||
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
|
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
|
||||||
# of code that will be used on startup of the MathJax code. See the MathJax site
|
# of code that will be used on startup of the MathJax code. See the MathJax site
|
||||||
@ -1561,7 +1639,7 @@ MATHJAX_EXTENSIONS =
|
|||||||
# example see the documentation.
|
# example see the documentation.
|
||||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
MATHJAX_CODEFILE =
|
MATHJAX_CODEFILE =
|
||||||
|
|
||||||
# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
|
# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
|
||||||
# the HTML output. The underlying search engine uses javascript and DHTML and
|
# the HTML output. The underlying search engine uses javascript and DHTML and
|
||||||
@ -1585,7 +1663,7 @@ MATHJAX_CODEFILE =
|
|||||||
SEARCHENGINE = YES
|
SEARCHENGINE = YES
|
||||||
|
|
||||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||||
# implemented using a web server instead of a web client using Javascript. There
|
# implemented using a web server instead of a web client using JavaScript. There
|
||||||
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
|
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
|
||||||
# setting. When disabled, doxygen will generate a PHP script for searching and
|
# setting. When disabled, doxygen will generate a PHP script for searching and
|
||||||
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
|
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
|
||||||
@ -1621,7 +1699,7 @@ EXTERNAL_SEARCH = NO
|
|||||||
# Searching" for details.
|
# Searching" for details.
|
||||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
SEARCHENGINE_URL =
|
SEARCHENGINE_URL =
|
||||||
|
|
||||||
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
|
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
|
||||||
# search data is written to a file for indexing by an external tool. With the
|
# search data is written to a file for indexing by an external tool. With the
|
||||||
@ -1637,7 +1715,7 @@ SEARCHDATA_FILE = searchdata.xml
|
|||||||
# projects and redirect the results back to the right project.
|
# projects and redirect the results back to the right project.
|
||||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
EXTERNAL_SEARCH_ID =
|
EXTERNAL_SEARCH_ID =
|
||||||
|
|
||||||
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
|
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
|
||||||
# projects other than the one defined by this configuration file, but that are
|
# projects other than the one defined by this configuration file, but that are
|
||||||
@ -1647,7 +1725,7 @@ EXTERNAL_SEARCH_ID =
|
|||||||
# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
|
# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
|
||||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
EXTRA_SEARCH_MAPPINGS =
|
EXTRA_SEARCH_MAPPINGS =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the LaTeX output
|
# Configuration options related to the LaTeX output
|
||||||
@ -1669,21 +1747,35 @@ LATEX_OUTPUT = latex
|
|||||||
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
||||||
# invoked.
|
# invoked.
|
||||||
#
|
#
|
||||||
# Note that when enabling USE_PDFLATEX this option is only used for generating
|
# Note that when not enabling USE_PDFLATEX the default is latex when enabling
|
||||||
# bitmaps for formulas in the HTML output, but not in the Makefile that is
|
# USE_PDFLATEX the default is pdflatex and when in the later case latex is
|
||||||
# written to the output directory.
|
# chosen this is overwritten by pdflatex. For specific output languages the
|
||||||
# The default file is: latex.
|
# default can have been set differently, this depends on the implementation of
|
||||||
|
# the output language.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_CMD_NAME = latex
|
LATEX_CMD_NAME = latex
|
||||||
|
|
||||||
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
|
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
|
||||||
# index for LaTeX.
|
# index for LaTeX.
|
||||||
|
# Note: This tag is used in the Makefile / make.bat.
|
||||||
|
# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
|
||||||
|
# (.tex).
|
||||||
# The default file is: makeindex.
|
# The default file is: makeindex.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
MAKEINDEX_CMD_NAME = makeindex
|
MAKEINDEX_CMD_NAME = makeindex
|
||||||
|
|
||||||
|
# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
|
||||||
|
# generate index for LaTeX. In case there is no backslash (\) as first character
|
||||||
|
# it will be automatically added in the LaTeX code.
|
||||||
|
# Note: This tag is used in the generated output file (.tex).
|
||||||
|
# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
|
||||||
|
# The default value is: makeindex.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_MAKEINDEX_CMD = makeindex
|
||||||
|
|
||||||
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
|
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
|
||||||
# documents. This may be useful for small projects and may help to save some
|
# documents. This may be useful for small projects and may help to save some
|
||||||
# trees in general.
|
# trees in general.
|
||||||
@ -1711,7 +1803,7 @@ PAPER_TYPE = a4
|
|||||||
# If left blank no extra packages will be included.
|
# If left blank no extra packages will be included.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
EXTRA_PACKAGES =
|
EXTRA_PACKAGES =
|
||||||
|
|
||||||
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
|
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
|
||||||
# generated LaTeX document. The header should contain everything until the first
|
# generated LaTeX document. The header should contain everything until the first
|
||||||
@ -1727,7 +1819,7 @@ EXTRA_PACKAGES =
|
|||||||
# to HTML_HEADER.
|
# to HTML_HEADER.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_HEADER =
|
LATEX_HEADER =
|
||||||
|
|
||||||
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
|
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
|
||||||
# generated LaTeX document. The footer should contain everything after the last
|
# generated LaTeX document. The footer should contain everything after the last
|
||||||
@ -1738,7 +1830,7 @@ LATEX_HEADER =
|
|||||||
# Note: Only use a user-defined footer if you know what you are doing!
|
# Note: Only use a user-defined footer if you know what you are doing!
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_FOOTER =
|
LATEX_FOOTER =
|
||||||
|
|
||||||
# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
|
# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
|
||||||
# LaTeX style sheets that are included after the standard style sheets created
|
# LaTeX style sheets that are included after the standard style sheets created
|
||||||
@ -1749,7 +1841,7 @@ LATEX_FOOTER =
|
|||||||
# list).
|
# list).
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_EXTRA_STYLESHEET =
|
LATEX_EXTRA_STYLESHEET =
|
||||||
|
|
||||||
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
|
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||||
# other source files which should be copied to the LATEX_OUTPUT output
|
# other source files which should be copied to the LATEX_OUTPUT output
|
||||||
@ -1757,7 +1849,7 @@ LATEX_EXTRA_STYLESHEET =
|
|||||||
# markers available.
|
# markers available.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
LATEX_EXTRA_FILES =
|
LATEX_EXTRA_FILES =
|
||||||
|
|
||||||
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
|
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
|
||||||
# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
|
# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
|
||||||
@ -1818,6 +1910,14 @@ LATEX_BIB_STYLE = plain
|
|||||||
|
|
||||||
LATEX_TIMESTAMP = NO
|
LATEX_TIMESTAMP = NO
|
||||||
|
|
||||||
|
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
|
# path from which the emoji images will be read. If a relative path is entered,
|
||||||
|
# it will be relative to the LATEX_OUTPUT directory. If left blank the
|
||||||
|
# LATEX_OUTPUT directory will be used.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_EMOJI_DIRECTORY =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the RTF output
|
# Configuration options related to the RTF output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@ -1857,22 +1957,22 @@ COMPACT_RTF = NO
|
|||||||
|
|
||||||
RTF_HYPERLINKS = NO
|
RTF_HYPERLINKS = NO
|
||||||
|
|
||||||
# Load stylesheet definitions from file. Syntax is similar to doxygen's config
|
# Load stylesheet definitions from file. Syntax is similar to doxygen's
|
||||||
# file, i.e. a series of assignments. You only have to provide replacements,
|
# configuration file, i.e. a series of assignments. You only have to provide
|
||||||
# missing definitions are set to their default value.
|
# replacements, missing definitions are set to their default value.
|
||||||
#
|
#
|
||||||
# See also section "Doxygen usage" for information on how to generate the
|
# See also section "Doxygen usage" for information on how to generate the
|
||||||
# default style sheet that doxygen normally uses.
|
# default style sheet that doxygen normally uses.
|
||||||
# This tag requires that the tag GENERATE_RTF is set to YES.
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
RTF_STYLESHEET_FILE =
|
RTF_STYLESHEET_FILE =
|
||||||
|
|
||||||
# Set optional variables used in the generation of an RTF document. Syntax is
|
# Set optional variables used in the generation of an RTF document. Syntax is
|
||||||
# similar to doxygen's config file. A template extensions file can be generated
|
# similar to doxygen's configuration file. A template extensions file can be
|
||||||
# using doxygen -e rtf extensionFile.
|
# generated using doxygen -e rtf extensionFile.
|
||||||
# This tag requires that the tag GENERATE_RTF is set to YES.
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
RTF_EXTENSIONS_FILE =
|
RTF_EXTENSIONS_FILE =
|
||||||
|
|
||||||
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
|
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
|
||||||
# with syntax highlighting in the RTF output.
|
# with syntax highlighting in the RTF output.
|
||||||
@ -1917,7 +2017,7 @@ MAN_EXTENSION = .3
|
|||||||
# MAN_EXTENSION with the initial . removed.
|
# MAN_EXTENSION with the initial . removed.
|
||||||
# This tag requires that the tag GENERATE_MAN is set to YES.
|
# This tag requires that the tag GENERATE_MAN is set to YES.
|
||||||
|
|
||||||
MAN_SUBDIR =
|
MAN_SUBDIR =
|
||||||
|
|
||||||
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
|
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
|
||||||
# will generate one additional man file for each entity documented in the real
|
# will generate one additional man file for each entity documented in the real
|
||||||
@ -1955,6 +2055,13 @@ XML_OUTPUT = xml
|
|||||||
|
|
||||||
XML_PROGRAMLISTING = YES
|
XML_PROGRAMLISTING = YES
|
||||||
|
|
||||||
|
# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
|
||||||
|
# namespace members in file scope as well, matching the HTML output.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||||
|
|
||||||
|
XML_NS_MEMB_FILE_SCOPE = NO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the DOCBOOK output
|
# Configuration options related to the DOCBOOK output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@ -2030,7 +2137,7 @@ PERLMOD_PRETTY = YES
|
|||||||
# overwrite each other's variables.
|
# overwrite each other's variables.
|
||||||
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
|
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
|
||||||
|
|
||||||
PERLMOD_MAKEVAR_PREFIX =
|
PERLMOD_MAKEVAR_PREFIX =
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the preprocessor
|
# Configuration options related to the preprocessor
|
||||||
@ -2071,7 +2178,7 @@ SEARCH_INCLUDES = YES
|
|||||||
# preprocessor.
|
# preprocessor.
|
||||||
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
|
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
|
||||||
|
|
||||||
INCLUDE_PATH =
|
INCLUDE_PATH =
|
||||||
|
|
||||||
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
|
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
|
||||||
# patterns (like *.h and *.hpp) to filter out the header-files in the
|
# patterns (like *.h and *.hpp) to filter out the header-files in the
|
||||||
@ -2079,7 +2186,7 @@ INCLUDE_PATH =
|
|||||||
# used.
|
# used.
|
||||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
INCLUDE_FILE_PATTERNS =
|
INCLUDE_FILE_PATTERNS =
|
||||||
|
|
||||||
# The PREDEFINED tag can be used to specify one or more macro names that are
|
# The PREDEFINED tag can be used to specify one or more macro names that are
|
||||||
# defined before the preprocessor is started (similar to the -D option of e.g.
|
# defined before the preprocessor is started (similar to the -D option of e.g.
|
||||||
@ -2089,7 +2196,7 @@ INCLUDE_FILE_PATTERNS =
|
|||||||
# recursively expanded use the := operator instead of the = operator.
|
# recursively expanded use the := operator instead of the = operator.
|
||||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
PREDEFINED =
|
PREDEFINED =
|
||||||
|
|
||||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||||
# tag can be used to specify a list of macro names that should be expanded. The
|
# tag can be used to specify a list of macro names that should be expanded. The
|
||||||
@ -2098,7 +2205,7 @@ PREDEFINED =
|
|||||||
# definition found in the source code.
|
# definition found in the source code.
|
||||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
EXPAND_AS_DEFINED =
|
EXPAND_AS_DEFINED =
|
||||||
|
|
||||||
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
|
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
|
||||||
# remove all references to function-like macros that are alone on a line, have
|
# remove all references to function-like macros that are alone on a line, have
|
||||||
@ -2127,13 +2234,13 @@ SKIP_FUNCTION_MACROS = YES
|
|||||||
# the path). If a tag file is not located in the directory in which doxygen is
|
# the path). If a tag file is not located in the directory in which doxygen is
|
||||||
# run, you must also specify the path to the tagfile here.
|
# run, you must also specify the path to the tagfile here.
|
||||||
|
|
||||||
TAGFILES =
|
TAGFILES =
|
||||||
|
|
||||||
# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
|
# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
|
||||||
# tag file that is based on the input files it reads. See section "Linking to
|
# tag file that is based on the input files it reads. See section "Linking to
|
||||||
# external documentation" for more information about the usage of tag files.
|
# external documentation" for more information about the usage of tag files.
|
||||||
|
|
||||||
GENERATE_TAGFILE =
|
GENERATE_TAGFILE =
|
||||||
|
|
||||||
# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
|
# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
|
||||||
# the class index. If set to NO, only the inherited external classes will be
|
# the class index. If set to NO, only the inherited external classes will be
|
||||||
@ -2156,12 +2263,6 @@ EXTERNAL_GROUPS = YES
|
|||||||
|
|
||||||
EXTERNAL_PAGES = YES
|
EXTERNAL_PAGES = YES
|
||||||
|
|
||||||
# The PERL_PATH should be the absolute path and name of the perl script
|
|
||||||
# interpreter (i.e. the result of 'which perl').
|
|
||||||
# The default file (with absolute path) is: /usr/bin/perl.
|
|
||||||
|
|
||||||
PERL_PATH = /usr/bin/perl
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the dot tool
|
# Configuration options related to the dot tool
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@ -2175,21 +2276,12 @@ PERL_PATH = /usr/bin/perl
|
|||||||
|
|
||||||
CLASS_DIAGRAMS = YES
|
CLASS_DIAGRAMS = YES
|
||||||
|
|
||||||
# You can define message sequence charts within doxygen comments using the \msc
|
|
||||||
# command. Doxygen will then run the mscgen tool (see:
|
|
||||||
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
|
|
||||||
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
|
|
||||||
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
|
||||||
# default search path.
|
|
||||||
|
|
||||||
MSCGEN_PATH =
|
|
||||||
|
|
||||||
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
||||||
# then run dia to produce the diagram and insert it in the documentation. The
|
# then run dia to produce the diagram and insert it in the documentation. The
|
||||||
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
||||||
# If left empty dia is assumed to be found in the default search path.
|
# If left empty dia is assumed to be found in the default search path.
|
||||||
|
|
||||||
DIA_PATH =
|
DIA_PATH =
|
||||||
|
|
||||||
# If set to YES the inheritance and collaboration graphs will hide inheritance
|
# If set to YES the inheritance and collaboration graphs will hide inheritance
|
||||||
# and usage relations if the target is undocumented or is not a class.
|
# and usage relations if the target is undocumented or is not a class.
|
||||||
@ -2202,9 +2294,9 @@ HIDE_UNDOC_RELATIONS = YES
|
|||||||
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
|
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
|
||||||
# Bell Labs. The other options in this section have no effect if this option is
|
# Bell Labs. The other options in this section have no effect if this option is
|
||||||
# set to NO
|
# set to NO
|
||||||
# The default value is: NO.
|
# The default value is: YES.
|
||||||
|
|
||||||
HAVE_DOT = NO
|
HAVE_DOT = YES
|
||||||
|
|
||||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
||||||
# to run in parallel. When set to 0 doxygen will base this on the number of
|
# to run in parallel. When set to 0 doxygen will base this on the number of
|
||||||
@ -2238,7 +2330,7 @@ DOT_FONTSIZE = 10
|
|||||||
# the path where dot can find it using this tag.
|
# the path where dot can find it using this tag.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_FONTPATH =
|
DOT_FONTPATH =
|
||||||
|
|
||||||
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
|
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
|
||||||
# each documented class showing the direct and indirect inheritance relations.
|
# each documented class showing the direct and indirect inheritance relations.
|
||||||
@ -2358,7 +2450,9 @@ DIRECTORY_GRAPH = YES
|
|||||||
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
|
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
|
||||||
# to make the SVG files visible in IE 9+ (other browsers do not have this
|
# to make the SVG files visible in IE 9+ (other browsers do not have this
|
||||||
# requirement).
|
# requirement).
|
||||||
# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
|
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
|
||||||
|
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
|
||||||
|
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
|
||||||
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
|
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
|
||||||
# png:gdiplus:gdiplus.
|
# png:gdiplus:gdiplus.
|
||||||
# The default value is: png.
|
# The default value is: png.
|
||||||
@ -2382,26 +2476,26 @@ INTERACTIVE_SVG = NO
|
|||||||
# found. If left blank, it is assumed the dot tool can be found in the path.
|
# found. If left blank, it is assumed the dot tool can be found in the path.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_PATH =
|
DOT_PATH =
|
||||||
|
|
||||||
# The DOTFILE_DIRS tag can be used to specify one or more directories that
|
# The DOTFILE_DIRS tag can be used to specify one or more directories that
|
||||||
# contain dot files that are included in the documentation (see the \dotfile
|
# contain dot files that are included in the documentation (see the \dotfile
|
||||||
# command).
|
# command).
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOTFILE_DIRS =
|
DOTFILE_DIRS =
|
||||||
|
|
||||||
# The MSCFILE_DIRS tag can be used to specify one or more directories that
|
# The MSCFILE_DIRS tag can be used to specify one or more directories that
|
||||||
# contain msc files that are included in the documentation (see the \mscfile
|
# contain msc files that are included in the documentation (see the \mscfile
|
||||||
# command).
|
# command).
|
||||||
|
|
||||||
MSCFILE_DIRS =
|
MSCFILE_DIRS =
|
||||||
|
|
||||||
# The DIAFILE_DIRS tag can be used to specify one or more directories that
|
# The DIAFILE_DIRS tag can be used to specify one or more directories that
|
||||||
# contain dia files that are included in the documentation (see the \diafile
|
# contain dia files that are included in the documentation (see the \diafile
|
||||||
# command).
|
# command).
|
||||||
|
|
||||||
DIAFILE_DIRS =
|
DIAFILE_DIRS =
|
||||||
|
|
||||||
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
|
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
|
||||||
# path where java can find the plantuml.jar file. If left blank, it is assumed
|
# path where java can find the plantuml.jar file. If left blank, it is assumed
|
||||||
@ -2409,17 +2503,17 @@ DIAFILE_DIRS =
|
|||||||
# generate a warning when it encounters a \startuml command in this case and
|
# generate a warning when it encounters a \startuml command in this case and
|
||||||
# will not generate output for the diagram.
|
# will not generate output for the diagram.
|
||||||
|
|
||||||
PLANTUML_JAR_PATH =
|
PLANTUML_JAR_PATH =
|
||||||
|
|
||||||
# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
|
# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
|
||||||
# configuration file for plantuml.
|
# configuration file for plantuml.
|
||||||
|
|
||||||
PLANTUML_CFG_FILE =
|
PLANTUML_CFG_FILE =
|
||||||
|
|
||||||
# When using plantuml, the specified paths are searched for files specified by
|
# When using plantuml, the specified paths are searched for files specified by
|
||||||
# the !include statement in a plantuml block.
|
# the !include statement in a plantuml block.
|
||||||
|
|
||||||
PLANTUML_INCLUDE_PATH =
|
PLANTUML_INCLUDE_PATH =
|
||||||
|
|
||||||
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
|
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
|
||||||
# that will be shown in the graph. If the number of nodes in a graph becomes
|
# that will be shown in the graph. If the number of nodes in a graph becomes
|
||||||
|
35
README.md
35
README.md
@ -31,31 +31,48 @@ Future features (wish-list)
|
|||||||
|
|
||||||
For now, the source code is well-documented but it requires some
|
For now, the source code is well-documented but it requires some
|
||||||
additional documentation (the math behind it). This will be published
|
additional documentation (the math behind it). This will be published
|
||||||
in a sister repository in a later stage.
|
in a sister repository (https://code.ascee.nl/ascee/lasp-doc).
|
||||||
|
|
||||||
If you have any question(s), please feel free to contact us: info@ascee.nl.
|
If you have any question(s), please feel free to contact us: info@ascee.nl.
|
||||||
|
|
||||||
|
|
||||||
# Building from source
|
# Building from source
|
||||||
|
|
||||||
## Dependencies
|
Two commands that install all requirements (for Ubuntu / Linux Mint)
|
||||||
|
|
||||||
Optional dependencies, which can be turned ON/OFF using CMake:
|
- `pip install scipy numpy build scikit-build appdirs`
|
||||||
|
- `sudo apt install libusb-dev
|
||||||
|
|
||||||
- Build tools, including [http://cmake.org](CMake).
|
## Runtime dependencies (Linux)
|
||||||
- FFTW (For really fast FFT's)
|
|
||||||
|
- FFTW (For really fast FFT's). If compiled with Ffftpack, this library is not
|
||||||
|
required.
|
||||||
- libUlDAQ, for the Measurement Computing DT9837A USB DAQ box
|
- libUlDAQ, for the Measurement Computing DT9837A USB DAQ box
|
||||||
- GNU Autotools, for compiling libUlDAQ
|
- GNU Autotools, for compiling libUlDAQ
|
||||||
- RtAudio, for Audio DAQ backends
|
- RtAudio, for Audio DAQ backends
|
||||||
- Cython, for wrapping the C-code to Python.
|
- libusb
|
||||||
|
- BLAS (OpenBLAS, other).
|
||||||
|
- RtAudio (optional)
|
||||||
|
- UlDaq (optional)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Build dependencies
|
||||||
|
|
||||||
|
Optional dependencies, which can be turned ON/OFF using CMake:
|
||||||
|
|
||||||
|
- Build tools: compiler [http://cmake.org](CMake), the Python packages:
|
||||||
|
- Scipy
|
||||||
|
- Numpy
|
||||||
|
- py-build-cmake
|
||||||
|
- appdirs
|
||||||
|
These can all be installed using:
|
||||||
|
|
||||||
- The following Python packages need also be available:
|
- The following Python packages need also be available:
|
||||||
- `Scipy` (which includes Numpy). Install with `sudo apt install
|
- `Scipy` (which includes Numpy). Install with `sudo apt install
|
||||||
python3-scipy`, or `pacman -S scipy`.
|
python3-scipy`, or `pacman -S scipy`.
|
||||||
- `appdirs`, which can be grabbed from [https://pypi.org](Pypi)
|
- `appdirs`, which can be grabbed from [https://pypi.org](Pypi)
|
||||||
|
|
||||||
## Installation of dependencies
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Compilation of LASP
|
## Compilation of LASP
|
||||||
|
29
cmake/OSSpecific.cmake
Normal file
29
cmake/OSSpecific.cmake
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
if(WIN32)
|
||||||
|
set(home $ENV{USERPROFILE})
|
||||||
|
|
||||||
|
# set(miniconda_dir ${home}\\Miniconda3)
|
||||||
|
message("Building for Windows")
|
||||||
|
include_directories(
|
||||||
|
..\\rtaudio
|
||||||
|
C:\\mingw\\mingw64\\include\\OpenBLAS
|
||||||
|
link_directories(${home}\\miniconda3\\Library\\include)
|
||||||
|
)
|
||||||
|
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH} $miniconda_dir\\Lib\\cmake")
|
||||||
|
# include(
|
||||||
|
add_definitions(-DMS_WIN64)
|
||||||
|
link_directories(C:\\mingw\\mingw64\\lib)
|
||||||
|
link_directories(C:\\mingw\\mingw64\\bin)
|
||||||
|
link_directories(..\\rtaudio)
|
||||||
|
link_directories(${home}\\Miniconda3)
|
||||||
|
add_definitions(-DHAS_RTAUDIO_WIN_WASAPI_API)
|
||||||
|
else() # Linux compile
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wfatal-errors")
|
||||||
|
include_directories(/usr/local/include/rtaudio)
|
||||||
|
include_directories(/usr/include/rtaudio)
|
||||||
|
link_directories(/usr/local/lib)
|
||||||
|
# This should become optional later on, and be added to the windows list as
|
||||||
|
# well.
|
||||||
|
|
||||||
|
endif()
|
||||||
|
# The last argument here takes care of calling SIGABRT when an integer overflow
|
||||||
|
# occures.
|
26
cmake/QueryPythonForPybind11.cmake
Normal file
26
cmake/QueryPythonForPybind11.cmake
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# First tries to find Python 3, then tries to import the pybind11 module to
|
||||||
|
# query the CMake config location, and finally imports pybind11 using
|
||||||
|
# find_package(pybind11 REQUIRED CONFIG).
|
||||||
|
function(find_pybind11_python_first)
|
||||||
|
|
||||||
|
# Query Python to see if it knows where the headers are
|
||||||
|
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
|
||||||
|
if (NOT pybind11_ROOT OR NOT EXISTS ${pybind11_ROOT})
|
||||||
|
execute_process(COMMAND ${Python3_EXECUTABLE}
|
||||||
|
-m pybind11 --cmakedir
|
||||||
|
OUTPUT_VARIABLE PY_BUILD_PYBIND11_CMAKE
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
RESULT_VARIABLE PY_BUILD_CMAKE_PYBIND11_RESULT)
|
||||||
|
# If it was successful
|
||||||
|
if (PY_BUILD_CMAKE_PYBIND11_RESULT EQUAL 0)
|
||||||
|
message(STATUS "Found pybind11: ${PY_BUILD_PYBIND11_CMAKE}")
|
||||||
|
set(pybind11_ROOT ${PY_BUILD_PYBIND11_CMAKE}
|
||||||
|
CACHE PATH "Path to the pybind11 CMake configuration." FORCE)
|
||||||
|
else()
|
||||||
|
unset(pybind11_ROOT CACHE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(pybind11 REQUIRED CONFIG)
|
||||||
|
|
||||||
|
endfunction()
|
@ -1,3 +0,0 @@
|
|||||||
add_subdirectory(c)
|
|
||||||
add_subdirectory(device)
|
|
||||||
add_subdirectory(dsp)
|
|
@ -1,2 +0,0 @@
|
|||||||
from .lasp_device import *
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
|||||||
#include "lasp_daqconfig.h"
|
|
||||||
#include "lasp_deviceinfo.h"
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#define MAX_DEV_COUNT_PER_API 20
|
|
||||||
|
|
||||||
using std::vector;
|
|
||||||
|
|
||||||
|
|
||||||
vector<DaqApi> DaqApi::getAvailableApis() {
|
|
||||||
|
|
||||||
vector<DaqApi> apis;
|
|
||||||
apis.resize(6);
|
|
||||||
#if LASP_HAS_ULDAQ == 1
|
|
||||||
apis.at(uldaqapi.apicode) = uldaqapi;
|
|
||||||
#endif
|
|
||||||
#if LASP_HAS_RTAUDIO == 1
|
|
||||||
apis.at(rtaudioAlsaApi.apicode) = rtaudioAlsaApi;
|
|
||||||
apis.at(rtaudioPulseaudioApi.apicode) = rtaudioPulseaudioApi;
|
|
||||||
apis.at(rtaudioWasapiApi.apicode) = rtaudioWasapiApi;
|
|
||||||
apis.at(rtaudioDsApi.apicode) = rtaudioDsApi;
|
|
||||||
apis.at(rtaudioAsioApi.apicode) = rtaudioAsioApi;
|
|
||||||
#endif
|
|
||||||
return apis;
|
|
||||||
}
|
|
||||||
|
|
||||||
DaqConfiguration::DaqConfiguration(const DeviceInfo &device) {
|
|
||||||
|
|
||||||
api = device.api;
|
|
||||||
device_name = device.device_name;
|
|
||||||
|
|
||||||
eninchannels.resize(device.ninchannels, false);
|
|
||||||
enoutchannels.resize(device.noutchannels, false);
|
|
||||||
|
|
||||||
inchannel_sensitivities.resize(device.ninchannels, 1.0);
|
|
||||||
inchannel_metadata.resize(device.ninchannels, "");
|
|
||||||
for (us i = 0; i < eninchannels.size(); i++) {
|
|
||||||
std::stringstream chname;
|
|
||||||
chname << "Unnamed input channel " << i;
|
|
||||||
inchannel_names.push_back(chname.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
outchannel_metadata.resize(device.noutchannels, "");
|
|
||||||
outchannel_sensitivities.resize(device.noutchannels, 1.0);
|
|
||||||
for (us i = 0; i < enoutchannels.size(); i++) {
|
|
||||||
std::stringstream chname;
|
|
||||||
chname << "Unnamed output channel " << i;
|
|
||||||
outchannel_names.push_back(chname.str());
|
|
||||||
}
|
|
||||||
sampleRateIndex = device.prefSampleRateIndex;
|
|
||||||
dataTypeIndex = device.prefDataTypeIndex;
|
|
||||||
framesPerBlockIndex = device.prefFramesPerBlockIndex;
|
|
||||||
|
|
||||||
monitorOutput = false;
|
|
||||||
|
|
||||||
inputIEPEEnabled.resize(device.ninchannels, false);
|
|
||||||
inputACCouplingMode.resize(device.ninchannels, false);
|
|
||||||
inputRangeIndices.resize(device.ninchannels, device.prefInputRangeIndex);
|
|
||||||
|
|
||||||
assert(match(device));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DaqConfiguration::match(const DeviceInfo &dev) const {
|
|
||||||
return (dev.device_name == device_name && dev.api == api);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DaqConfiguration::getHighestInChannel() const {
|
|
||||||
for (int i = eninchannels.size() - 1; i > -1; i--) {
|
|
||||||
if (eninchannels.at(i))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DaqConfiguration::getHighestOutChannel() const {
|
|
||||||
for (us i = enoutchannels.size() - 1; i >= 0; i--) {
|
|
||||||
if (enoutchannels.at(i))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int DaqConfiguration::getLowestInChannel() const {
|
|
||||||
for (us i = 0; i < eninchannels.size(); i++) {
|
|
||||||
if (eninchannels.at(i))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int DaqConfiguration::getLowestOutChannel() const {
|
|
||||||
for (us i = 0; i < enoutchannels.size(); i++) {
|
|
||||||
if (enoutchannels.at(i))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
|||||||
#include "lasp_deviceinfo.h"
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#define MAX_DEV_COUNT_PER_API 20
|
|
||||||
|
|
||||||
#if LASP_HAS_ULDAQ == 1
|
|
||||||
#include "lasp_uldaq.h"
|
|
||||||
#endif
|
|
||||||
#if LASP_HAS_RTAUDIO == 1
|
|
||||||
#include "lasp_rtaudiodaq.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
string DeviceInfo::serialize() const {
|
|
||||||
// Simple serializer for this object, used because we found a bit late
|
|
||||||
// that this object needs to be send over the wire. We do not want to make
|
|
||||||
// this implementation in Python, as these objects are created here, in
|
|
||||||
// the C++ code. The Python wrapper is just a readonly wrapper.
|
|
||||||
std::stringstream str;
|
|
||||||
|
|
||||||
str << api.apiname << "\t";
|
|
||||||
str << api.apicode << "\t";
|
|
||||||
str << api.api_specific_subcode << "\t";
|
|
||||||
str << device_name << "\t";
|
|
||||||
|
|
||||||
str << availableDataTypes.size() << "\t";
|
|
||||||
for (const auto &dtype : availableDataTypes) {
|
|
||||||
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
|
|
||||||
str << static_cast<int>(dtype) << "\t";
|
|
||||||
}
|
|
||||||
str << prefDataTypeIndex << "\t";
|
|
||||||
|
|
||||||
str << availableSampleRates.size() << "\t";
|
|
||||||
for (const double &fs : availableSampleRates) {
|
|
||||||
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
|
|
||||||
str << fs << "\t";
|
|
||||||
}
|
|
||||||
str << prefSampleRateIndex << "\t";
|
|
||||||
|
|
||||||
str << availableFramesPerBlock.size() << "\t";
|
|
||||||
for (const us &fb : availableFramesPerBlock) {
|
|
||||||
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
|
|
||||||
str << fb << "\t";
|
|
||||||
}
|
|
||||||
str << prefFramesPerBlockIndex << "\t";
|
|
||||||
|
|
||||||
str << availableInputRanges.size() << "\t";
|
|
||||||
for (const double &ir : availableInputRanges) {
|
|
||||||
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
|
|
||||||
str << ir << "\t";
|
|
||||||
}
|
|
||||||
str << prefInputRangeIndex << "\t";
|
|
||||||
|
|
||||||
str << ninchannels << "\t";
|
|
||||||
str << noutchannels << "\t";
|
|
||||||
str << int(hasInputIEPE) << "\t";
|
|
||||||
str << int(hasInputACCouplingSwitch) << "\t";
|
|
||||||
str << int(hasInputTrigger) << "\t";
|
|
||||||
|
|
||||||
return str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceInfo DeviceInfo::deserialize(const string &dstr) {
|
|
||||||
DeviceInfo devinfo;
|
|
||||||
|
|
||||||
std::stringstream str(dstr);
|
|
||||||
string tmp;
|
|
||||||
us N;
|
|
||||||
// Lambda functions for deserializing
|
|
||||||
auto nexts = [&]() {
|
|
||||||
getline(str, tmp, '\t');
|
|
||||||
return tmp;
|
|
||||||
};
|
|
||||||
auto nexti = [&]() {
|
|
||||||
getline(str, tmp, '\t');
|
|
||||||
return std::atoi(tmp.c_str());
|
|
||||||
};
|
|
||||||
auto nextf = [&]() {
|
|
||||||
getline(str, tmp, '\t');
|
|
||||||
return std::atof(tmp.c_str());
|
|
||||||
};
|
|
||||||
|
|
||||||
// Api
|
|
||||||
string apiname = nexts();
|
|
||||||
auto apicode = nexti();
|
|
||||||
auto api_specific_subcode = nexti();
|
|
||||||
DaqApi api(apiname, apicode, api_specific_subcode);
|
|
||||||
devinfo.api = api;
|
|
||||||
|
|
||||||
devinfo.device_name = nexts();
|
|
||||||
|
|
||||||
N = us(nexti());
|
|
||||||
for (us i = 0; i < N; i++) {
|
|
||||||
devinfo.availableDataTypes.push_back(
|
|
||||||
static_cast<DataTypeDescriptor::DataType>(nexti()));
|
|
||||||
}
|
|
||||||
|
|
||||||
devinfo.prefDataTypeIndex = nexti();
|
|
||||||
|
|
||||||
N = us(nexti());
|
|
||||||
for (us i = 0; i < N; i++) {
|
|
||||||
devinfo.availableSampleRates.push_back(nextf());
|
|
||||||
}
|
|
||||||
devinfo.prefSampleRateIndex = nexti();
|
|
||||||
|
|
||||||
N = us(nexti());
|
|
||||||
for (us i = 0; i < N; i++) {
|
|
||||||
devinfo.availableFramesPerBlock.push_back(nexti());
|
|
||||||
}
|
|
||||||
devinfo.prefFramesPerBlockIndex = nexti();
|
|
||||||
|
|
||||||
N = us(nexti());
|
|
||||||
for (us i = 0; i < N; i++) {
|
|
||||||
devinfo.availableInputRanges.push_back(nexti());
|
|
||||||
}
|
|
||||||
devinfo.prefInputRangeIndex = nexti();
|
|
||||||
|
|
||||||
devinfo.ninchannels = nexti();
|
|
||||||
devinfo.noutchannels = nexti();
|
|
||||||
devinfo.hasInputIEPE = bool(nexti());
|
|
||||||
devinfo.hasInputACCouplingSwitch = bool(nexti());
|
|
||||||
devinfo.hasInputTrigger = bool(nexti());
|
|
||||||
|
|
||||||
return devinfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<DeviceInfo> DeviceInfo::getDeviceInfo() {
|
|
||||||
std::vector<DeviceInfo> devs;
|
|
||||||
#if LASP_HAS_ULDAQ ==1
|
|
||||||
fillUlDaqDeviceInfo(devs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LASP_HAS_RTAUDIO == 1
|
|
||||||
fillRtAudioDeviceInfo(devs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return devs;
|
|
||||||
}
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
|||||||
#include <algorithm>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <pybind11/numpy.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include "lasp_daqconfig.h"
|
|
||||||
#include "lasp_deviceinfo.h"
|
|
||||||
|
|
||||||
using std::cerr;
|
|
||||||
namespace py = pybind11;
|
|
||||||
|
|
||||||
PYBIND11_MODULE(lasp_device, m) {
|
|
||||||
|
|
||||||
m.doc() = "Lasp device interface";
|
|
||||||
|
|
||||||
/// DataType
|
|
||||||
py::class_<DataTypeDescriptor> dtype_desc(m, "DataTypeDescriptor");
|
|
||||||
dtype_desc.def_readonly("name", &DataTypeDescriptor::name);
|
|
||||||
dtype_desc.def_readonly("sw", &DataTypeDescriptor::sw);
|
|
||||||
dtype_desc.def_readonly("is_floating", &DataTypeDescriptor::is_floating);
|
|
||||||
|
|
||||||
py::enum_<DataTypeDescriptor::DataType>(dtype_desc, "DataType")
|
|
||||||
.value("dtype_fl32", DataTypeDescriptor::DataType::dtype_fl32)
|
|
||||||
.value("dtype_fl64", DataTypeDescriptor::DataType::dtype_fl64)
|
|
||||||
.value("dtype_int8", DataTypeDescriptor::DataType::dtype_int8)
|
|
||||||
.value("dtype_int16", DataTypeDescriptor::DataType::dtype_int16)
|
|
||||||
.value("dtype_int32", DataTypeDescriptor::DataType::dtype_int32).export_values();
|
|
||||||
|
|
||||||
dtype_desc.def_readonly("dtype", &DataTypeDescriptor::dtype);
|
|
||||||
|
|
||||||
|
|
||||||
/// DaqApi
|
|
||||||
py::class_<DaqApi> daqapi(m, "DaqApi");
|
|
||||||
daqapi.def_readonly("apiname", &DaqApi::apiname);
|
|
||||||
daqapi.def_readonly("apicode", &DaqApi::apicode);
|
|
||||||
daqapi.def_readonly("api_specific_subcode", &DaqApi::api_specific_subcode);
|
|
||||||
daqapi.def("__str__", [](const DaqApi &d) { return std::string(d); });
|
|
||||||
|
|
||||||
/// DeviceInfo
|
|
||||||
py::class_<DeviceInfo> devinfo(m, "DeviceInfo");
|
|
||||||
devinfo.def_readonly("api", &DeviceInfo::api);
|
|
||||||
devinfo.def_readonly("device_name", &DeviceInfo::device_name);
|
|
||||||
|
|
||||||
devinfo.def_readonly("availableDataTypes", &DeviceInfo::availableDataTypes);
|
|
||||||
devinfo.def_readonly("prefDataTypeIndex", &DeviceInfo::prefDataTypeIndex);
|
|
||||||
|
|
||||||
devinfo.def_readonly("availableSampleRates",
|
|
||||||
&DeviceInfo::availableSampleRates);
|
|
||||||
devinfo.def_readonly("prefSampleRateIndex", &DeviceInfo::prefSampleRateIndex);
|
|
||||||
|
|
||||||
devinfo.def_readonly("availableFramesPerBlock",
|
|
||||||
&DeviceInfo::availableFramesPerBlock);
|
|
||||||
devinfo.def_readonly("prefFramesPerBlockIndex",
|
|
||||||
&DeviceInfo::prefFramesPerBlockIndex);
|
|
||||||
|
|
||||||
devinfo.def_readonly("availableInputRanges",
|
|
||||||
&DeviceInfo::availableInputRanges);
|
|
||||||
devinfo.def_readonly("prefInputRangeIndex", &DeviceInfo::prefInputRangeIndex);
|
|
||||||
|
|
||||||
devinfo.def_readonly("ninchannels", &DeviceInfo::ninchannels);
|
|
||||||
devinfo.def_readonly("noutchannels", &DeviceInfo::noutchannels);
|
|
||||||
devinfo.def_readonly("hasInputIEPE", &DeviceInfo::hasInputIEPE);
|
|
||||||
devinfo.def_readonly("hasInputACCouplingSwitch",
|
|
||||||
&DeviceInfo::hasInputACCouplingSwitch);
|
|
||||||
|
|
||||||
devinfo.def("serialize", &DeviceInfo::serialize);
|
|
||||||
|
|
||||||
devinfo.def_static("deserialize", &DeviceInfo::deserialize);
|
|
||||||
|
|
||||||
/// DaqConfiguration
|
|
||||||
py::class_<DaqConfiguration> daqconfig(m, "DaqConfiguration");
|
|
||||||
daqconfig.def(py::init<>());
|
|
||||||
daqconfig.def_readwrite("eninchannels", &DaqConfiguration::eninchannels);
|
|
||||||
daqconfig.def_readwrite("enoutchannels", &DaqConfiguration::enoutchannels);
|
|
||||||
|
|
||||||
daqconfig.def_readwrite("inchannel_sensitivities",
|
|
||||||
&DaqConfiguration::inchannel_sensitivities);
|
|
||||||
daqconfig.def_readwrite("inchannel_metadata",
|
|
||||||
&DaqConfiguration::inchannel_metadata);
|
|
||||||
daqconfig.def_readwrite("inchannel_names",
|
|
||||||
&DaqConfiguration::inchannel_names);
|
|
||||||
|
|
||||||
daqconfig.def_readwrite("outchannel_sensitivities",
|
|
||||||
&DaqConfiguration::outchannel_sensitivities);
|
|
||||||
daqconfig.def_readwrite("outchannel_names",
|
|
||||||
&DaqConfiguration::outchannel_names);
|
|
||||||
daqconfig.def_readwrite("inchannel_metadata",
|
|
||||||
&DaqConfiguration::inchannel_metadata);
|
|
||||||
|
|
||||||
daqconfig.def_readwrite("sampleRateIndex",
|
|
||||||
&DaqConfiguration::sampleRateIndex);
|
|
||||||
daqconfig.def_readwrite("dataTypeIndex",
|
|
||||||
&DaqConfiguration::dataTypeIndex);
|
|
||||||
|
|
||||||
daqconfig.def_readwrite("framesPerBlockIndex",
|
|
||||||
&DaqConfiguration::framesPerBlockIndex);
|
|
||||||
daqconfig.def_readwrite("monitorOutput",
|
|
||||||
&DaqConfiguration::monitorOutput);
|
|
||||||
|
|
||||||
daqconfig.def_readwrite("inputIEPEEnabled",
|
|
||||||
&DaqConfiguration::inputIEPEEnabled);
|
|
||||||
daqconfig.def_readwrite("inputACCouplingMode",
|
|
||||||
&DaqConfiguration::inputACCouplingMode);
|
|
||||||
|
|
||||||
daqconfig.def_readwrite("inputRangeIndices",
|
|
||||||
&DaqConfiguration::inputRangeIndices);
|
|
||||||
|
|
||||||
daqconfig.def("match", &DaqConfiguration::match);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
configure_file(lasp_config.h.in lasp_config.h)
|
|
||||||
|
|
||||||
set(lasp_dsp_files
|
|
||||||
lasp_filter.cpp
|
|
||||||
lasp_siggen.cpp
|
|
||||||
lasp_siggen_impl.cpp
|
|
||||||
lasp_window.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
SET_SOURCE_FILES_PROPERTIES(${lasp_dsp_files} PROPERTIES COMPILE_FLAGS
|
|
||||||
"-DARMA_DONT_USE_WRAPPER")
|
|
||||||
|
|
||||||
|
|
||||||
add_library(lasp_dsp_lib STATIC ${lasp_dsp_files})
|
|
||||||
|
|
||||||
pybind11_add_module(lasp_dsp lasp_dsp_pybind.cpp)
|
|
||||||
|
|
||||||
target_link_libraries(lasp_dsp PRIVATE lasp_dsp_lib ${BLAS_LIBRARIES})
|
|
||||||
|
|
||||||
target_include_directories(lasp_dsp_lib PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
from .lasp_dsp import *
|
|
27
pyproject.toml
Normal file
27
pyproject.toml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
[project] # Project metadata
|
||||||
|
name = "lasp"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.8"
|
||||||
|
license = { "file" = "LICENSE" }
|
||||||
|
authors = [{ "name" = "J.A. de Jong et al.", "email" = "info@ascee.nl" }]
|
||||||
|
keywords = ["DSP", "DAQ", "Signal processing"]
|
||||||
|
classifiers = [
|
||||||
|
"Topic :: Scientific/Engineering",
|
||||||
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Operating System :: POSIX :: Linux",
|
||||||
|
"Operating System :: Microsoft :: Windows",
|
||||||
|
]
|
||||||
|
# urls = { "Documentation" = "https://" }
|
||||||
|
dependencies = ["numpy", "scipy", "appdirs"]
|
||||||
|
dynamic = ["version", "description"]
|
||||||
|
|
||||||
|
[build-system] # How pip and other frontends should build this project
|
||||||
|
requires = [
|
||||||
|
"setuptools>=42",
|
||||||
|
"wheel",
|
||||||
|
"scikit-build",
|
||||||
|
"cmake",
|
||||||
|
]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
|
37
setup.py
Executable file → Normal file
37
setup.py
Executable file → Normal file
@ -1,28 +1,15 @@
|
|||||||
#!/usr/bin/env python3.8
|
from skbuild import setup
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
@author: J.A. de Jong - ASCEE
|
|
||||||
"""
|
|
||||||
from setuptools import setup, find_packages
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="LASP",
|
name="lasp",
|
||||||
version="1.0",
|
version="1.0",
|
||||||
packages=find_packages(),
|
description="LASP Library of Acoustic Signal Processing",
|
||||||
long_description=open("./README.md", 'r').read(),
|
author='J.A. de Jong (ASCEE / Redu-Sone)',
|
||||||
long_description_content_type="text/markdown",
|
author_email='info@ascee.nl',
|
||||||
# ext_modules=[CMakeExtension('lasp/wrappers.so'),
|
license="MIT",
|
||||||
# ],
|
packages=['lasp'],
|
||||||
#package_data={'lasp': ['wrappers.so']},
|
package_dir= {'': 'src'},
|
||||||
author='J.A. de Jong - ASCEE',
|
cmake_install_dir='src/lasp',
|
||||||
author_email="j.a.dejong@ascee.nl",
|
# cmake_install_target='src',
|
||||||
install_requires=['matplotlib>=1.0',
|
python_requires='>=3.8',
|
||||||
'scipy>=1.0', 'numpy>=1.0', 'h5py',
|
|
||||||
'dataclasses_json', 'cython',
|
|
||||||
],
|
|
||||||
license='MIT',
|
|
||||||
description="Library for Acoustic Signal Processing",
|
|
||||||
keywords="",
|
|
||||||
url="https://www.ascee.nl/lasp/", # project home page
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
28
src/lasp/CMakeLists.txt
Normal file
28
src/lasp/CMakeLists.txt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# cpp_src/CMakeLists.txt
|
||||||
|
|
||||||
|
# Armadillo
|
||||||
|
add_definitions(-DARMA_DONT_USE_WRAPPER)
|
||||||
|
|
||||||
|
configure_file(lasp_config.h.in lasp_config.h)
|
||||||
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
include_directories(SYSTEM ../../third_party/armadillo-code/include)
|
||||||
|
include_directories(../../third_party/DebugTrace-cpp/include)
|
||||||
|
include_directories(../../third_party/STL-Threadsafe/include)
|
||||||
|
include_directories(../../third_party/gsl-lite/include)
|
||||||
|
include_directories(../../third_party/tomlplusplus/include)
|
||||||
|
|
||||||
|
add_subdirectory(device)
|
||||||
|
add_subdirectory(dsp)
|
||||||
|
|
||||||
|
pybind11_add_module(lasp_cpp MODULE lasp_cpp.cpp
|
||||||
|
pybind11/lasp_deviceinfo.cpp
|
||||||
|
pybind11/lasp_daqconfiguration.cpp
|
||||||
|
pybind11//lasp_dsp_pybind.cpp
|
||||||
|
pybind11/lasp_streammgr.cpp
|
||||||
|
pybind11/lasp_daq.cpp
|
||||||
|
pybind11/lasp_deviceinfo.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(lasp_cpp PRIVATE lasp_device_lib lasp_dsp_lib)
|
||||||
|
|
||||||
|
install(TARGETS lasp_cpp DESTINATION .)
|
@ -1,3 +1,5 @@
|
|||||||
|
# cpp_src/src/device/CMakeLists.txt
|
||||||
|
|
||||||
add_library(lasp_device_lib OBJECT
|
add_library(lasp_device_lib OBJECT
|
||||||
lasp_daq.cpp
|
lasp_daq.cpp
|
||||||
lasp_daqconfig.cpp
|
lasp_daqconfig.cpp
|
||||||
@ -8,16 +10,23 @@ add_library(lasp_device_lib OBJECT
|
|||||||
lasp_uldaq.cpp
|
lasp_uldaq.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Callback requires certain arguments that are not used by code. This disables
|
||||||
|
# a compiler warning about it.
|
||||||
|
set_source_files_properties(lasp_rtaudiodaq.cpp PROPERTIES COMPILE_OPTIONS
|
||||||
|
"-Wno-unused")
|
||||||
|
|
||||||
target_include_directories(lasp_device_lib PUBLIC ../dsp)
|
target_include_directories(lasp_device_lib PUBLIC ../dsp)
|
||||||
target_include_directories(lasp_device_lib PUBLIC ../c)
|
target_include_directories(lasp_device_lib PUBLIC ../c)
|
||||||
|
target_include_directories(lasp_device_lib INTERFACE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
if(LASP_HAS_ULDAQ)
|
if(LASP_HAS_ULDAQ)
|
||||||
target_link_libraries(lasp_device_lib uldaq)
|
target_link_libraries(lasp_device_lib uldaq)
|
||||||
endif()
|
endif()
|
||||||
if(LASP_HAS_RTAUDIO)
|
if(LASP_HAS_RTAUDIO)
|
||||||
target_link_libraries(lasp_device_lib rtaudio)
|
target_link_libraries(lasp_device_lib rtaudio)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(lasp_device_lib lasp_dsp_lib)
|
target_link_libraries(lasp_device_lib lasp_dsp_lib)
|
||||||
|
target_link_libraries(lasp_device_lib PRIVATE )
|
||||||
pybind11_add_module(lasp_device lasp_devicepybind.cpp)
|
|
||||||
target_link_libraries(lasp_device PRIVATE lasp_device_lib)
|
|
||||||
|
|
@ -11,32 +11,15 @@ DEBUGTRACE_VARIABLES;
|
|||||||
#endif
|
#endif
|
||||||
using std::runtime_error;
|
using std::runtime_error;
|
||||||
|
|
||||||
|
Daq::~Daq() {}
|
||||||
|
|
||||||
std::unique_ptr<Daq> Daq::createDaq(const DeviceInfo &devinfo,
|
std::unique_ptr<Daq> Daq::createDaq(const DeviceInfo &devinfo,
|
||||||
const DaqConfiguration &config) {
|
const DaqConfiguration &config) {
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
|
|
||||||
if (!config.match(devinfo)) {
|
|
||||||
throw std::runtime_error("DaqConfiguration does not match device info");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some basic sanity checks
|
|
||||||
if ((devinfo.ninchannels != config.eninchannels.size())) {
|
|
||||||
/* cerr << "devinfo.ninchannels: " << devinfo.ninchannels << endl; */
|
|
||||||
/* cerr << "config.eninchannels.size(): " << config.eninchannels.size() <<
|
|
||||||
* endl; */
|
|
||||||
throw runtime_error("Invalid length of enabled input channels specified");
|
|
||||||
}
|
|
||||||
if ((devinfo.noutchannels != config.enoutchannels.size())) {
|
|
||||||
throw runtime_error("outvalid length of enabled output channels specified");
|
|
||||||
}
|
|
||||||
|
|
||||||
int apicode = devinfo.api.apicode;
|
int apicode = devinfo.api.apicode;
|
||||||
if (devinfo.api == DaqApi()) {
|
|
||||||
throw std::runtime_error(string("Unable to match API: ") +
|
|
||||||
devinfo.api.apiname);
|
|
||||||
}
|
|
||||||
#if LASP_HAS_ULDAQ == 1
|
#if LASP_HAS_ULDAQ == 1
|
||||||
else if (devinfo.api == uldaqapi) {
|
if (devinfo.api == uldaqapi) {
|
||||||
return createUlDaqDevice(devinfo, config);
|
return createUlDaqDevice(devinfo, config);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -53,14 +36,23 @@ std::unique_ptr<Daq> Daq::createDaq(const DeviceInfo &devinfo,
|
|||||||
|
|
||||||
Daq::Daq(const DeviceInfo &devinfo, const DaqConfiguration &config)
|
Daq::Daq(const DeviceInfo &devinfo, const DaqConfiguration &config)
|
||||||
: DaqConfiguration(config), DeviceInfo(devinfo) {
|
: DaqConfiguration(config), DeviceInfo(devinfo) {
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
|
|
||||||
if (monitorOutput && !(nenoutchannels() > 0)) {
|
if (!hasInternalOutputMonitor && monitorOutput) {
|
||||||
throw runtime_error(
|
throw std::runtime_error(
|
||||||
"Output monitoring only possible when at least one output channel is "
|
"Output monitor flag set, but device does not have output monitor");
|
||||||
"enabled. Please make sure to enable at least one output channel, or "
|
|
||||||
"disable monitoring output.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!config.match(devinfo)) {
|
||||||
|
throw std::runtime_error("DaqConfiguration does not match device info");
|
||||||
|
}
|
||||||
|
if(neninchannels(false) > ninchannels) {
|
||||||
|
throw std::runtime_error("Number of enabled input channels is higher than device capability");
|
||||||
|
}
|
||||||
|
if(nenoutchannels() > noutchannels) {
|
||||||
|
throw std::runtime_error("Number of enabled output channels is higher than device capability");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double Daq::samplerate() const {
|
double Daq::samplerate() const {
|
||||||
@ -70,25 +62,40 @@ double Daq::samplerate() const {
|
|||||||
DataTypeDescriptor::DataType Daq::dataType() const {
|
DataTypeDescriptor::DataType Daq::dataType() const {
|
||||||
return availableDataTypes.at(dataTypeIndex);
|
return availableDataTypes.at(dataTypeIndex);
|
||||||
}
|
}
|
||||||
DataTypeDescriptor Daq::dtypeDescr() const {
|
DataTypeDescriptor Daq::dtypeDescr() const { return dtype_map.at(dataType()); }
|
||||||
return dtype_map.at(dataType());
|
|
||||||
}
|
|
||||||
|
|
||||||
double Daq::inputRangeForChannel(us ch) const {
|
double Daq::inputRangeForChannel(us ch) const {
|
||||||
if (!(ch < ninchannels)) {
|
if (!(ch < ninchannels)) {
|
||||||
throw runtime_error("Invalid channel number");
|
throw runtime_error("Invalid channel number");
|
||||||
}
|
}
|
||||||
return availableInputRanges.at(inputRangeIndices.at(ch));
|
return availableInputRanges.at(inchannel_config[ch].rangeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
us Daq::neninchannels(bool include_monitorchannel) const {
|
us Daq::neninchannels(bool include_monitorchannel) const {
|
||||||
us inch = std::count(eninchannels.begin(), eninchannels.end(), true);
|
boolvec eninchannels = this->eninchannels(include_monitorchannel);
|
||||||
if (monitorOutput && include_monitorchannel) {
|
return std::count(eninchannels.cbegin(), eninchannels.cend(), true);
|
||||||
inch += nenoutchannels();
|
|
||||||
}
|
|
||||||
return inch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
us Daq::nenoutchannels() const {
|
us Daq::nenoutchannels() const {
|
||||||
return std::count(enoutchannels.begin(), enoutchannels.end(), true);
|
boolvec enchannels = this->enoutchannels();
|
||||||
|
return std::count(enchannels.cbegin(), enchannels.cend(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolvec Daq::eninchannels(bool include_monitor) const {
|
||||||
|
boolvec res;
|
||||||
|
if (hasInternalOutputMonitor && include_monitor) {
|
||||||
|
res.push_back(monitorOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &ch : inchannel_config) {
|
||||||
|
res.push_back(ch.enabled);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
boolvec Daq::enoutchannels() const {
|
||||||
|
boolvec res;
|
||||||
|
for (auto &ch : outchannel_config) {
|
||||||
|
res.push_back(ch.enabled);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
@ -7,24 +7,6 @@
|
|||||||
#include <gsl/gsl-lite.hpp>
|
#include <gsl/gsl-lite.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Information regarding a stream.
|
|
||||||
*/
|
|
||||||
class StreamStatus {
|
|
||||||
public:
|
|
||||||
bool isRunning = false;
|
|
||||||
bool error = false;
|
|
||||||
std::string error_msg{};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns true if everything is OK with a certain stream and the
|
|
||||||
* stream is running.
|
|
||||||
*
|
|
||||||
* @return as described above.
|
|
||||||
*/
|
|
||||||
bool runningOK() const { return isRunning && !error; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Callback of DAQ for input data. Callback should return
|
* @brief Callback of DAQ for input data. Callback should return
|
||||||
* false for a stop request.
|
* false for a stop request.
|
||||||
@ -46,6 +28,55 @@ protected:
|
|||||||
Daq(const Daq &) = delete;
|
Daq(const Daq &) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Information regarding a stream.
|
||||||
|
*/
|
||||||
|
class StreamStatus {
|
||||||
|
public:
|
||||||
|
enum class StreamError {
|
||||||
|
noError,
|
||||||
|
inputXRun,
|
||||||
|
outputXRun,
|
||||||
|
driverError,
|
||||||
|
systemError,
|
||||||
|
threadError,
|
||||||
|
logicError,
|
||||||
|
apiSpecificError
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Map between error types and messages
|
||||||
|
*/
|
||||||
|
inline static const std::map<StreamError, std::string> errorMessages{
|
||||||
|
{StreamError::noError, "No error"},
|
||||||
|
{StreamError::inputXRun, "Input buffer overrun"},
|
||||||
|
{StreamError::outputXRun, "Output buffer underrun"},
|
||||||
|
{StreamError::driverError, "Driver error"},
|
||||||
|
{StreamError::systemError, "System error"},
|
||||||
|
{StreamError::threadError, "Thread error"},
|
||||||
|
{StreamError::logicError, "Logic error (probably a bug)"},
|
||||||
|
};
|
||||||
|
bool isRunning = false;
|
||||||
|
/**
|
||||||
|
* @brief Check if stream has error
|
||||||
|
*
|
||||||
|
* @return true if there is an error.
|
||||||
|
*/
|
||||||
|
bool error() const { return errorType != StreamError::noError; };
|
||||||
|
|
||||||
|
StreamError errorType{StreamError::noError};
|
||||||
|
|
||||||
|
std::string errorMsg() const { return errorMessages.at(errorType); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true if everything is OK with a certain stream and the
|
||||||
|
* stream is running.
|
||||||
|
*
|
||||||
|
* @return as described above.
|
||||||
|
*/
|
||||||
|
bool runningOK() const { return isRunning && !error(); }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a Daq based on given device info and configuration
|
* @brief Create a Daq based on given device info and configuration
|
||||||
*
|
*
|
||||||
@ -65,8 +96,8 @@ public:
|
|||||||
* required, the return value of the function should be nullptr. If no input
|
* required, the return value of the function should be nullptr. If no input
|
||||||
* data is presented, the function is called with a nullptr as argument.
|
* data is presented, the function is called with a nullptr as argument.
|
||||||
*/
|
*/
|
||||||
virtual void start(std::optional<InDaqCallback> inCallback,
|
virtual void start(InDaqCallback inCallback,
|
||||||
std::optional<OutDaqCallback> outCallback) = 0;
|
OutDaqCallback outCallback) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Stop the Daq device. Throws an exception if the device is not
|
* @brief Stop the Daq device. Throws an exception if the device is not
|
||||||
@ -74,14 +105,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
|
|
||||||
/**
|
virtual ~Daq() = 0;
|
||||||
* @brief Returns whether the data stream is running Y/N
|
|
||||||
*
|
|
||||||
* @return true if running
|
|
||||||
*/
|
|
||||||
virtual bool isRunning() const = 0;
|
|
||||||
|
|
||||||
virtual ~Daq() = default;
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the number of enabled input channels
|
* @brief Returns the number of enabled input channels
|
||||||
*
|
*
|
||||||
@ -91,6 +116,7 @@ public:
|
|||||||
* @return number of enabled input channels
|
* @return number of enabled input channels
|
||||||
*/
|
*/
|
||||||
us neninchannels(bool include_monitorchannel = true) const;
|
us neninchannels(bool include_monitorchannel = true) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the number of enabled output channels
|
* @brief Returns the number of enabled output channels
|
||||||
*
|
*
|
||||||
@ -98,12 +124,30 @@ public:
|
|||||||
*/
|
*/
|
||||||
us nenoutchannels() const;
|
us nenoutchannels() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a vector of boolean values of the enabled input channels.
|
||||||
|
*
|
||||||
|
* @param include_monitor If set to true and a monitor channel is available,
|
||||||
|
* the first index in the array will correspond to the monitor channel, and
|
||||||
|
* whether it is enabled
|
||||||
|
*
|
||||||
|
* @return Boolean vector
|
||||||
|
*/
|
||||||
|
boolvec eninchannels(bool include_monitor = true) const;
|
||||||
|
/**
|
||||||
|
* @brief Create an array of booleans for each enabled output channel.
|
||||||
|
*
|
||||||
|
* @return Boolean vector
|
||||||
|
*/
|
||||||
|
boolvec enoutchannels() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns current sample rate
|
* @brief Returns current sample rate
|
||||||
*
|
*
|
||||||
* @return Sample rate in [Hz]
|
* @return Sample rate in [Hz]
|
||||||
*/
|
*/
|
||||||
double samplerate() const;
|
double samplerate() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the input range for each channel. Means the minimum from
|
* @brief Returns the input range for each channel. Means the minimum from
|
||||||
* the absolute value of the minumum and maximum value that is allowed to
|
* the absolute value of the minumum and maximum value that is allowed to
|
||||||
@ -114,6 +158,7 @@ public:
|
|||||||
* @return Maximum offset from 0 before clipping.
|
* @return Maximum offset from 0 before clipping.
|
||||||
*/
|
*/
|
||||||
double inputRangeForChannel(us ch) const;
|
double inputRangeForChannel(us ch) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns datatype (enum) corresponding to the datatype of the
|
* @brief Returns datatype (enum) corresponding to the datatype of the
|
||||||
* samples.
|
* samples.
|
||||||
@ -121,6 +166,7 @@ public:
|
|||||||
* @return That as stated aboce
|
* @return That as stated aboce
|
||||||
*/
|
*/
|
||||||
DataTypeDescriptor::DataType dataType() const;
|
DataTypeDescriptor::DataType dataType() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief More elaborate description of the datatypes.
|
* @brief More elaborate description of the datatypes.
|
||||||
*
|
*
|
||||||
@ -151,6 +197,6 @@ public:
|
|||||||
* @return true if duplex
|
* @return true if duplex
|
||||||
*/
|
*/
|
||||||
bool duplexMode() const {
|
bool duplexMode() const {
|
||||||
return (neninchannels(false) > 0 && nenoutchannels() > 0);
|
return (neninchannels() > 0 && nenoutchannels() > 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
137
src/lasp/device/lasp_daqconfig.cpp
Normal file
137
src/lasp/device/lasp_daqconfig.cpp
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#include "lasp_daqconfig.h"
|
||||||
|
#include "lasp_deviceinfo.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#define MAX_DEV_COUNT_PER_API 20
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
vector<DaqApi> DaqApi::getAvailableApis() {
|
||||||
|
|
||||||
|
vector<DaqApi> apis;
|
||||||
|
apis.resize(6);
|
||||||
|
#if LASP_HAS_ULDAQ == 1
|
||||||
|
apis.at(uldaqapi.apicode) = uldaqapi;
|
||||||
|
#endif
|
||||||
|
#if LASP_HAS_RTAUDIO == 1
|
||||||
|
apis.at(rtaudioAlsaApi.apicode) = rtaudioAlsaApi;
|
||||||
|
apis.at(rtaudioPulseaudioApi.apicode) = rtaudioPulseaudioApi;
|
||||||
|
apis.at(rtaudioWasapiApi.apicode) = rtaudioWasapiApi;
|
||||||
|
apis.at(rtaudioDsApi.apicode) = rtaudioDsApi;
|
||||||
|
apis.at(rtaudioAsioApi.apicode) = rtaudioAsioApi;
|
||||||
|
#endif
|
||||||
|
return apis;
|
||||||
|
}
|
||||||
|
|
||||||
|
DaqConfiguration::DaqConfiguration(const DeviceInfo &device) {
|
||||||
|
|
||||||
|
api = device.api;
|
||||||
|
device_name = device.device_name;
|
||||||
|
|
||||||
|
inchannel_config.resize(device.ninchannels);
|
||||||
|
outchannel_config.resize(device.noutchannels);
|
||||||
|
us i = 0;
|
||||||
|
for(auto& inch: inchannel_config) {
|
||||||
|
inch.name = "Unnamed input channel " + std::to_string(i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for(auto& outch: outchannel_config) {
|
||||||
|
outch.name = "Unnamed output channel " + std::to_string(i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleRateIndex = device.prefSampleRateIndex;
|
||||||
|
dataTypeIndex = device.prefDataTypeIndex;
|
||||||
|
framesPerBlockIndex = device.prefFramesPerBlockIndex;
|
||||||
|
|
||||||
|
monitorOutput = false;
|
||||||
|
|
||||||
|
assert(match(device));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DaqConfiguration::match(const DeviceInfo &dev) const {
|
||||||
|
return (dev.device_name == device_name && dev.api == api);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DaqConfiguration::getHighestInChannel() const {
|
||||||
|
for (int i = inchannel_config.size() - 1; i > -1; i--) {
|
||||||
|
if (inchannel_config.at(i).enabled)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DaqConfiguration::getHighestOutChannel() const {
|
||||||
|
for (us i = outchannel_config.size() - 1; i >= 0; i--) {
|
||||||
|
if (outchannel_config.at(i).enabled)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int DaqConfiguration::getLowestInChannel() const {
|
||||||
|
for (us i = 0; i < inchannel_config.size(); i++) {
|
||||||
|
if (inchannel_config.at(i).enabled)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int DaqConfiguration::getLowestOutChannel() const {
|
||||||
|
for (us i = 0; i < outchannel_config.size(); i++) {
|
||||||
|
if (outchannel_config.at(i).enabled)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "toml++/toml.h"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
toml::table daqChannelToTOML(const DaqChannel& ch) {
|
||||||
|
toml::table tbl;
|
||||||
|
tbl.emplace("enabled", ch.enabled);
|
||||||
|
tbl.emplace("name", ch.name);
|
||||||
|
tbl.emplace("sensitivity", ch.sensitivity);
|
||||||
|
tbl.emplace("IEPEEnabled", ch.IEPEEnabled);
|
||||||
|
tbl.emplace("ACCouplingMode", ch.ACCouplingMode);
|
||||||
|
tbl.emplace("rangeIndex", ch.rangeIndex);
|
||||||
|
tbl.emplace("qty", static_cast<int>(ch.qty));
|
||||||
|
tbl.emplace("digitalHighpassCutOn", ch.digitalHighPassCutOn);
|
||||||
|
|
||||||
|
return tbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
string DaqConfiguration::toTOML() const {
|
||||||
|
|
||||||
|
toml::table apitbl{{"name", api.apiname},
|
||||||
|
{"code", api.apicode},
|
||||||
|
{"subcode", api.api_specific_subcode}};
|
||||||
|
|
||||||
|
toml::table tbl{{"daqapi", apitbl}};
|
||||||
|
|
||||||
|
tbl.emplace("device_name", device_name);
|
||||||
|
tbl.emplace("sampleRateIndex", sampleRateIndex);
|
||||||
|
tbl.emplace("dataTypeIndex", dataTypeIndex);
|
||||||
|
tbl.emplace("framesPerBlockIndex", framesPerBlockIndex);
|
||||||
|
tbl.emplace("monitorOutput", monitorOutput);
|
||||||
|
|
||||||
|
toml::array inchannel_config_tbl;
|
||||||
|
for(const auto& ch: inchannel_config) {
|
||||||
|
inchannel_config_tbl.emplace_back(daqChannelToTOML(ch));
|
||||||
|
}
|
||||||
|
tbl.emplace("inchannel_config", inchannel_config_tbl);
|
||||||
|
|
||||||
|
toml::array outchannel_config_tbl;
|
||||||
|
for(const auto& ch: outchannel_config) {
|
||||||
|
outchannel_config_tbl.emplace_back(daqChannelToTOML(ch));
|
||||||
|
}
|
||||||
|
tbl.emplace("outchannel_config", outchannel_config_tbl);
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
|
||||||
|
str << tbl;
|
||||||
|
|
||||||
|
return str.str();
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include "lasp_config.h"
|
#include "lasp_config.h"
|
||||||
#include "lasp_types.h"
|
#include "lasp_types.h"
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::to_string;
|
using std::to_string;
|
||||||
@ -122,16 +122,85 @@ const DaqApi rtaudioAsioApi("RtAudio Windows ASIO", 5,
|
|||||||
RtAudio::Api::WINDOWS_ASIO);
|
RtAudio::Api::WINDOWS_ASIO);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class DeviceInfo;
|
class DeviceInfo;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stores channel configuration data for each channel.
|
||||||
|
*/
|
||||||
|
class DaqChannel {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Possible physical quantities that are recorded.
|
||||||
|
*/
|
||||||
|
enum class Qty {
|
||||||
|
Number,
|
||||||
|
AcousticPressure,
|
||||||
|
Voltage,
|
||||||
|
UserDefined
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Whether the channel is enabled.
|
||||||
|
*/
|
||||||
|
bool enabled = false;
|
||||||
|
|
||||||
|
string name = "";
|
||||||
|
/**
|
||||||
|
* @brief The conversion between recorded physical unit and stored /
|
||||||
|
* outputed number, i.e. Number/Volt or Number/Pa. Converting stored numbers
|
||||||
|
* to physical qty, *divide* by the sensitivity.
|
||||||
|
*/
|
||||||
|
double sensitivity = -1;
|
||||||
|
/**
|
||||||
|
* @brief For input-only: enable IEPE constant current power supply for
|
||||||
|
* this channel. Only for hardware that is capable of doing so.
|
||||||
|
*/
|
||||||
|
bool IEPEEnabled = false;
|
||||||
|
/**
|
||||||
|
* @brief Whether to enable HW AC-coupling for this channel.
|
||||||
|
*/
|
||||||
|
bool ACCouplingMode = false;
|
||||||
|
/**
|
||||||
|
* @brief Index in possible ranges for input / output
|
||||||
|
*/
|
||||||
|
int rangeIndex = 0;
|
||||||
|
/**
|
||||||
|
* @brief The physical quantity that is inputed / outputed
|
||||||
|
*/
|
||||||
|
Qty qty = Qty::Number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Whether to enable a digital high pass on the signal before
|
||||||
|
* passing the result in case of input, or outputing the result in case of
|
||||||
|
* output.
|
||||||
|
*/
|
||||||
|
double digitalHighPassCutOn = -1;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configuration of a DAQ device
|
* @brief Configuration of a DAQ device
|
||||||
*/
|
*/
|
||||||
class DaqConfiguration {
|
class DaqConfiguration {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief The API of the DAQ system this configuration applies to.
|
* @brief Export the class to TOML markup language.
|
||||||
|
*
|
||||||
|
* @return String with TOML exported data.
|
||||||
*/
|
*/
|
||||||
|
std::string toTOML() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load in a DAQConfiguration from TOML.
|
||||||
|
*
|
||||||
|
* @param toml String containing TOML data
|
||||||
|
*
|
||||||
|
* @return DaqConfiguration object
|
||||||
|
*/
|
||||||
|
static DaqConfiguration fromTOML(const std::string &toml);
|
||||||
|
|
||||||
DaqApi api;
|
DaqApi api;
|
||||||
/**
|
/**
|
||||||
* @brief The internal device name this DAQ configuration applies to.
|
* @brief The internal device name this DAQ configuration applies to.
|
||||||
@ -139,37 +208,30 @@ public:
|
|||||||
string device_name;
|
string device_name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enabled input channels
|
* @brief Channel configuration for input channels
|
||||||
*/
|
*/
|
||||||
boolvec eninchannels;
|
std::vector<DaqChannel> inchannel_config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enabled 'normal' output channels, i.e. no internal loopbacks.
|
* @brief Channel configuration for output channels
|
||||||
*/
|
*/
|
||||||
boolvec enoutchannels;
|
std::vector<DaqChannel> outchannel_config;
|
||||||
|
|
||||||
std::vector<double> inchannel_sensitivities;
|
|
||||||
std::vector<string> inchannel_names;
|
|
||||||
std::vector<string> inchannel_metadata;
|
|
||||||
|
|
||||||
std::vector<double> outchannel_sensitivities;
|
|
||||||
std::vector<string> outchannel_names;
|
|
||||||
std::vector<string> outchannel_metadata;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Index in list of sample rates that are available for the device.
|
* @brief Index in list of sample rates that are available for the device.
|
||||||
*/
|
*/
|
||||||
us sampleRateIndex = 0; //
|
int sampleRateIndex = 0; //
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Required datatype for output, should be present in the list
|
* @brief Required datatype for output, should be present in the list
|
||||||
*/
|
*/
|
||||||
us dataTypeIndex = 0;
|
int dataTypeIndex = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The index in the array of frames per block that can be used for the
|
* @brief The index in the array of frames per block that can be used for the
|
||||||
* device.
|
* device.
|
||||||
*/
|
*/
|
||||||
us framesPerBlockIndex = 0;
|
int framesPerBlockIndex = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief If set to true and if the device has this capability, the output
|
* @brief If set to true and if the device has this capability, the output
|
||||||
@ -177,22 +239,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool monitorOutput = false;
|
bool monitorOutput = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief If the device is capable, enable IEPE constant current power supply
|
|
||||||
* for given channel number.
|
|
||||||
*/
|
|
||||||
boolvec inputIEPEEnabled;
|
|
||||||
/**
|
|
||||||
* @brief If the device is capable, here we can define whether the channel
|
|
||||||
* should enable hardware AC-coupling.
|
|
||||||
*/
|
|
||||||
boolvec inputACCouplingMode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Stores the index of the used input range for each of the channels.
|
|
||||||
*/
|
|
||||||
usvec inputRangeIndices;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a default configuration, with all channels disabled on both
|
* @brief Create a default configuration, with all channels disabled on both
|
||||||
* input and output, and default channel names
|
* input and output, and default channel names
|
||||||
@ -200,7 +246,8 @@ public:
|
|||||||
* @param deviceinfo DeviceInfo structure
|
* @param deviceinfo DeviceInfo structure
|
||||||
*/
|
*/
|
||||||
DaqConfiguration(const DeviceInfo &DeviceInfo);
|
DaqConfiguration(const DeviceInfo &DeviceInfo);
|
||||||
DaqConfiguration();
|
|
||||||
|
DaqConfiguration() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check to see whether the DAQ configuration matches with the device.
|
* @brief Check to see whether the DAQ configuration matches with the device.
|
||||||
@ -246,5 +293,6 @@ public:
|
|||||||
* enabled.
|
* enabled.
|
||||||
*/
|
*/
|
||||||
int getLowestOutChannel() const;
|
int getLowestOutChannel() const;
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
@ -1,14 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "lasp_daqconfig.h"
|
||||||
|
#include "lasp_types.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <gsl/gsl-lite.hpp>
|
#include <gsl/gsl-lite.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
|
||||||
#include "lasp_daqconfig.h"
|
|
||||||
#include "lasp_types.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Data coming from / going to DAQ. **Non-interleaved format**, which
|
* @brief Data coming from / going to DAQ. **Non-interleaved format**, which
|
||||||
* means data in buffer is ordered by channel: _ptr[sample+channel*nframes]
|
* means data in buffer is ordered by channel: _ptr[frame+channel*nframes]
|
||||||
*/
|
*/
|
||||||
class DaqData {
|
class DaqData {
|
||||||
protected:
|
protected:
|
||||||
@ -28,7 +27,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
const us nframes;
|
const us nframes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The data type corresponding to a sample
|
||||||
|
*/
|
||||||
const DataTypeDescriptor::DataType dtype;
|
const DataTypeDescriptor::DataType dtype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The data type description corresponding to a sample
|
||||||
|
*/
|
||||||
const DataTypeDescriptor &dtype_descr;
|
const DataTypeDescriptor &dtype_descr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,16 +42,29 @@ public:
|
|||||||
*/
|
*/
|
||||||
const us sw;
|
const us sw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize an empty frame of data
|
||||||
|
*
|
||||||
|
* @param nchannels The number of channels
|
||||||
|
* @param nframes The number of frames
|
||||||
|
* @param dtype The data type
|
||||||
|
*/
|
||||||
DaqData(const us nchannels, const us nframes,
|
DaqData(const us nchannels, const us nframes,
|
||||||
const DataTypeDescriptor::DataType dtype);
|
const DataTypeDescriptor::DataType dtype);
|
||||||
virtual ~DaqData() = default;
|
virtual ~DaqData() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return reference to internal vector
|
* @brief Return pointer to the raw data corresponding to a certain sample.
|
||||||
*
|
*
|
||||||
* @return Reference to vector of data storage.
|
* @param frame The frame number
|
||||||
|
* @param channel The channel number
|
||||||
|
*
|
||||||
|
* @return Pointer to sample, not casted to final type
|
||||||
*/
|
*/
|
||||||
int8_t *raw_ptr() { return _data.data(); }
|
int8_t *raw_ptr(const us frame = 0, const us channel = 0) {
|
||||||
|
return &(_data.data()[sw * (frame + channel * nframes)]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the total number of bytes
|
* @brief Return the total number of bytes
|
||||||
*
|
*
|
||||||
@ -76,13 +95,29 @@ public:
|
|||||||
const DataTypeDescriptor::DataType dtype_descr)
|
const DataTypeDescriptor::DataType dtype_descr)
|
||||||
: DaqData(nchannels, nframes, dtype_descr) {}
|
: DaqData(nchannels, nframes, dtype_descr) {}
|
||||||
|
|
||||||
T &operator[](const us i) { return _data[this->sw * i]; }
|
T &operator[](const us i) { return _data[sw * i]; }
|
||||||
|
|
||||||
T &operator()(const us sample, const us channel) {
|
/**
|
||||||
return reinterpret_cast<T &>(_data[sw * (sample + channel * nframes)]);
|
* @brief Reference of sample, casted to the right type. Same as raw_ptr(),
|
||||||
|
* but then as reference, and corresponding to right type.
|
||||||
|
*
|
||||||
|
* @param frame Frame number
|
||||||
|
* @param channel Channel number
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
T &operator()(const us frame = 0, const us channel = 0) {
|
||||||
|
return reinterpret_cast<T &>(*raw_ptr(frame, channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyToRaw(const us channel, T *ptr) {
|
/**
|
||||||
DaqData::copyToRaw(channel, reinterpret_cast<uint8_t *>(ptr));
|
* @brief Copy out the data for a certain channel to a buffer
|
||||||
|
*
|
||||||
|
* @param channel The channel to copy
|
||||||
|
* @param buffer The buffer to copy to. *Make sure* it is allocated with at
|
||||||
|
* least `sw*nframes` bytes.
|
||||||
|
*/
|
||||||
|
void copyToRaw(const us channel, T *buffer) {
|
||||||
|
DaqData::copyToRaw(channel, reinterpret_cast<uint8_t *>(buffer));
|
||||||
}
|
}
|
||||||
};
|
};
|
27
src/lasp/device/lasp_deviceinfo.cpp
Normal file
27
src/lasp/device/lasp_deviceinfo.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "lasp_deviceinfo.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#define MAX_DEV_COUNT_PER_API 20
|
||||||
|
|
||||||
|
#if LASP_HAS_ULDAQ == 1
|
||||||
|
#include "lasp_uldaq.h"
|
||||||
|
#endif
|
||||||
|
#if LASP_HAS_RTAUDIO == 1
|
||||||
|
#include "lasp_rtaudiodaq.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<DeviceInfo> DeviceInfo::getDeviceInfo() {
|
||||||
|
std::vector<DeviceInfo> devs;
|
||||||
|
#if LASP_HAS_ULDAQ ==1
|
||||||
|
fillUlDaqDeviceInfo(devs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LASP_HAS_RTAUDIO == 1
|
||||||
|
fillRtAudioDeviceInfo(devs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return devs;
|
||||||
|
}
|
||||||
|
|
@ -93,6 +93,11 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Whether the device has an internal monitor of the output signal.
|
||||||
|
*/
|
||||||
|
bool hasInternalOutputMonitor = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief String representation of DeviceInfo
|
* @brief String representation of DeviceInfo
|
||||||
*
|
*
|
||||||
@ -110,20 +115,6 @@ public:
|
|||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief For backwards-compatibility: serialize device info to string
|
|
||||||
*
|
|
||||||
* @return Serialize-string
|
|
||||||
*/
|
|
||||||
string serialize() const;
|
|
||||||
/**
|
|
||||||
* @brief Create a device info structure from serialized string
|
|
||||||
*
|
|
||||||
* @param dstr String to deserialize from
|
|
||||||
*
|
|
||||||
* @return resulting DeviceInfo
|
|
||||||
*/
|
|
||||||
static DeviceInfo deserialize(const string& dstr);
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a list of DeviceInfo's that are at call time avalable
|
* @brief Create a list of DeviceInfo's that are at call time avalable
|
||||||
*
|
*
|
@ -1,11 +1,10 @@
|
|||||||
#include "lasp_rtaudiodaq.h"
|
#include "lasp_rtaudiodaq.h"
|
||||||
#if LASP_HAS_RTAUDIO == 1
|
#if LASP_HAS_RTAUDIO == 1
|
||||||
#include "lasp_daqconfig.h"
|
#include "debugtrace.hpp"
|
||||||
|
#include "lasp_daq.h"
|
||||||
#include <RtAudio.h>
|
#include <RtAudio.h>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdint>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
using std::atomic;
|
using std::atomic;
|
||||||
using std::cerr;
|
using std::cerr;
|
||||||
@ -13,6 +12,8 @@ using std::endl;
|
|||||||
using std::runtime_error;
|
using std::runtime_error;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
|
DEBUGTRACE_VARIABLES;
|
||||||
|
|
||||||
void fillRtAudioDeviceInfo(vector<DeviceInfo> &devinfolist) {
|
void fillRtAudioDeviceInfo(vector<DeviceInfo> &devinfolist) {
|
||||||
|
|
||||||
vector<RtAudio::Api> apis;
|
vector<RtAudio::Api> apis;
|
||||||
@ -103,10 +104,10 @@ void fillRtAudioDeviceInfo(vector<DeviceInfo> &devinfolist) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mycallback(void *outputBuffer, void *inputBuffer, unsigned int nFrames,
|
static int mycallback(void *outputBuffer, void *inputBuffer, unsigned int nFrames,
|
||||||
double streamTime, RtAudioStreamStatus status, void *userData);
|
double streamTime, RtAudioStreamStatus status, void *userData);
|
||||||
|
|
||||||
void myerrorcallback(RtAudioError::Type, const string &errorText);
|
static void myerrorcallback(RtAudioError::Type, const string &errorText);
|
||||||
|
|
||||||
class RtAudioDaq : public Daq {
|
class RtAudioDaq : public Daq {
|
||||||
|
|
||||||
@ -119,20 +120,25 @@ class RtAudioDaq : public Daq {
|
|||||||
InDaqCallback _incallback;
|
InDaqCallback _incallback;
|
||||||
OutDaqCallback _outcallback;
|
OutDaqCallback _outcallback;
|
||||||
|
|
||||||
|
std::atomic<StreamStatus> _streamStatus{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RtAudioDaq(const DeviceInfo &devinfo, const DaqConfiguration &config)
|
RtAudioDaq(const DeviceInfo &devinfo, const DaqConfiguration &config)
|
||||||
: Daq(devinfo, config),
|
: Daq(devinfo, config),
|
||||||
rtaudio(static_cast<RtAudio::Api>(devinfo.api.api_specific_subcode)),
|
rtaudio(static_cast<RtAudio::Api>(devinfo.api.api_specific_subcode)),
|
||||||
nFramesPerBlock(Daq::framesPerBlock()) {
|
nFramesPerBlock(Daq::framesPerBlock()) {
|
||||||
|
|
||||||
std::unique_ptr<RtAudio::StreamParameters> inParams, outParams;
|
DEBUGTRACE_ENTER;
|
||||||
|
|
||||||
// We make sure not to run RtAudio in duplex mode. This seems to be buggy
|
// We make sure not to run RtAudio in duplex mode. This seems to be buggy
|
||||||
// and untested. Better to use a hardware-type loopback into the system.
|
// and untested. Better to use a hardware-type loopback into the system.
|
||||||
if (neninchannels(false) > 0 && nenoutchannels() > 0) {
|
if (duplexMode()) {
|
||||||
throw runtime_error("RtAudio backend cannot run in duplex mode.");
|
throw runtime_error("RtAudio backend cannot run in duplex mode.");
|
||||||
}
|
}
|
||||||
assert(!monitorOutput);
|
assert(!monitorOutput);
|
||||||
|
|
||||||
|
std::unique_ptr<RtAudio::StreamParameters> inParams, outParams;
|
||||||
|
|
||||||
if (neninchannels() > 0) {
|
if (neninchannels() > 0) {
|
||||||
|
|
||||||
inParams = std::make_unique<RtAudio::StreamParameters>();
|
inParams = std::make_unique<RtAudio::StreamParameters>();
|
||||||
@ -193,57 +199,91 @@ public:
|
|||||||
unsigned int nFramesPerBlock_copy = nFramesPerBlock;
|
unsigned int nFramesPerBlock_copy = nFramesPerBlock;
|
||||||
|
|
||||||
// Final step: open the stream.
|
// Final step: open the stream.
|
||||||
rtaudio.openStream(&(*outParams), &(*inParams), format,
|
rtaudio.openStream(outParams.get(), inParams.get(), format,
|
||||||
static_cast<us>(samplerate()), &nFramesPerBlock_copy,
|
static_cast<us>(samplerate()), &nFramesPerBlock_copy,
|
||||||
&mycallback, (void *)this, &streamoptions,
|
mycallback, (void *)this, &streamoptions,
|
||||||
&myerrorcallback);
|
&myerrorcallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void start(std::optional<InDaqCallback> inCallback,
|
virtual void start(InDaqCallback inCallback,
|
||||||
std::optional<OutDaqCallback> outCallback) override {
|
OutDaqCallback outCallback) override {
|
||||||
|
|
||||||
|
DEBUGTRACE_ENTER;
|
||||||
|
|
||||||
assert(!monitorOutput);
|
assert(!monitorOutput);
|
||||||
|
|
||||||
if (isRunning()) {
|
if (StreamStatus().runningOK()) {
|
||||||
throw runtime_error("Stream already running");
|
throw runtime_error("Stream already running");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logical XOR
|
// Logical XOR
|
||||||
if (!inCallback != !outCallback) {
|
if (inCallback && outCallback) {
|
||||||
throw runtime_error("Either input or output stream possible for RtAudio. "
|
throw runtime_error("Either input or output stream possible for RtAudio. "
|
||||||
"Stream duplex mode not provided.");
|
"Stream duplex mode not provided.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inCallback) {
|
if (inCallback) {
|
||||||
_incallback = *inCallback;
|
_incallback = inCallback;
|
||||||
if (!neninchannels()) {
|
if (neninchannels()==0) {
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"Input callback given, but stream does not provide input data");
|
"Input callback given, but stream does not provide input data");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (outCallback) {
|
if (outCallback) {
|
||||||
_outcallback = *outCallback;
|
_outcallback = outCallback;
|
||||||
if (!nenoutchannels()) {
|
if (nenoutchannels()==0) {
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"Output callback given, but stream does not provide output data");
|
"Output callback given, but stream does not provide output data");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rtaudio.startStream();
|
rtaudio.startStream();
|
||||||
|
|
||||||
|
// If we are here, we are running without errors.
|
||||||
|
StreamStatus status;
|
||||||
|
status.isRunning = true;
|
||||||
|
_streamStatus = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRunning() const override { return (rtaudio.isStreamRunning()); }
|
StreamStatus getStreamStatus() const override { return _streamStatus; }
|
||||||
|
|
||||||
void stop() override {
|
void stop() override {
|
||||||
if (!isRunning()) {
|
DEBUGTRACE_ENTER;
|
||||||
/* cerr << "Stream is already stopped" << endl; */
|
if (getStreamStatus().runningOK()) {
|
||||||
} else {
|
|
||||||
rtaudio.stopStream();
|
rtaudio.stopStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int streamCallback(void *outputBuffer, void *inputBuffer,
|
int streamCallback(void *outputBuffer, void *inputBuffer,
|
||||||
unsigned int nFrames, double streamTime,
|
unsigned int nFrames, double streamTime,
|
||||||
|
|
||||||
RtAudioStreamStatus status) {
|
RtAudioStreamStatus status) {
|
||||||
|
|
||||||
|
/* DEBUGTRACE_ENTER; */
|
||||||
|
|
||||||
|
using se = StreamStatus::StreamError;
|
||||||
|
|
||||||
|
int rval = 0;
|
||||||
|
auto stopWithError = [&](se e) {
|
||||||
|
DEBUGTRACE_PRINT("stopWithError");
|
||||||
|
StreamStatus stat = _streamStatus;
|
||||||
|
stat.errorType = e;
|
||||||
|
stat.isRunning = false;
|
||||||
|
rval = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case RTAUDIO_INPUT_OVERFLOW:
|
||||||
|
stopWithError(se::inputXRun);
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case RTAUDIO_OUTPUT_UNDERFLOW:
|
||||||
|
stopWithError(se::outputXRun);
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const auto &dtype_descr = DataTypeDescriptor();
|
const auto &dtype_descr = DataTypeDescriptor();
|
||||||
const auto dtype = dataType();
|
const auto dtype = dataType();
|
||||||
us neninchannels = this->neninchannels();
|
us neninchannels = this->neninchannels();
|
||||||
@ -252,6 +292,7 @@ public:
|
|||||||
if (nFrames != nFramesPerBlock) {
|
if (nFrames != nFramesPerBlock) {
|
||||||
cerr << "RtAudio backend error: nFrames does not match block size!"
|
cerr << "RtAudio backend error: nFrames does not match block size!"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
stopWithError(se::logicError);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,15 +301,18 @@ public:
|
|||||||
ptrs.reserve(neninchannels);
|
ptrs.reserve(neninchannels);
|
||||||
/* DaqData(neninchannels_inc_mon, nFramesPerBlock, dtype); */
|
/* DaqData(neninchannels_inc_mon, nFramesPerBlock, dtype); */
|
||||||
for (int ch = getLowestInChannel(); ch <= getHighestInChannel(); ch++) {
|
for (int ch = getLowestInChannel(); ch <= getHighestInChannel(); ch++) {
|
||||||
if (eninchannels[ch]) {
|
if (inchannel_config.at(ch).enabled) {
|
||||||
ptrs.push_back(&static_cast<uint8_t *>(
|
ptrs.push_back(&static_cast<uint8_t *>(
|
||||||
inputBuffer)[sw * ninchannels * ch * nFramesPerBlock]);
|
inputBuffer)[sw * ninchannels * ch * nFramesPerBlock]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DaqData d{neninchannels, nFramesPerBlock, dtype};
|
DaqData d{neninchannels, nFramesPerBlock, dtype};
|
||||||
d.copyInFromRaw(ptrs);
|
d.copyInFromRaw(ptrs);
|
||||||
|
|
||||||
|
assert(_incallback);
|
||||||
bool ret = _incallback(d);
|
bool ret = _incallback(d);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
stopWithError(se::noError);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,14 +324,17 @@ public:
|
|||||||
|
|
||||||
/* outCallback */
|
/* outCallback */
|
||||||
for (int ch = 0; ch <= getHighestOutChannel(); ch++) {
|
for (int ch = 0; ch <= getHighestOutChannel(); ch++) {
|
||||||
if (enoutchannels[ch]) {
|
if (outchannel_config.at(ch).enabled) {
|
||||||
ptrs.push_back(&static_cast<uint8_t *>(
|
ptrs.push_back(&static_cast<uint8_t *>(
|
||||||
outputBuffer)[sw * nenoutchannels * ch * nFramesPerBlock]);
|
outputBuffer)[sw * nenoutchannels * ch * nFramesPerBlock]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DaqData d{nenoutchannels, nFramesPerBlock, dtype};
|
DaqData d{nenoutchannels, nFramesPerBlock, dtype};
|
||||||
|
|
||||||
|
assert(_outcallback);
|
||||||
bool ret = _outcallback(d);
|
bool ret = _outcallback(d);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
stopWithError(se::noError);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
us j = 0;
|
us j = 0;
|
||||||
@ -297,7 +344,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RtAudio documentation says: if a stream is open, it will be stopped and
|
// RtAudio documentation says: if a stream is open, it will be stopped and
|
||||||
@ -312,7 +359,7 @@ std::unique_ptr<Daq> createRtAudioDevice(const DeviceInfo &devinfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void myerrorcallback(RtAudioError::Type, const string &errorText) {
|
void myerrorcallback(RtAudioError::Type, const string &errorText) {
|
||||||
cerr << errorText << endl;
|
cerr << "RtAudio backend stream error: " << errorText << endl;
|
||||||
}
|
}
|
||||||
int mycallback(void *outputBuffer, void *inputBuffer, unsigned int nFrames,
|
int mycallback(void *outputBuffer, void *inputBuffer, unsigned int nFrames,
|
||||||
double streamTime, RtAudioStreamStatus status, void *userData) {
|
double streamTime, RtAudioStreamStatus status, void *userData) {
|
@ -1,17 +1,19 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <algorithm>
|
|
||||||
#include "lasp_streammgr.h"
|
#include "lasp_streammgr.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <functional>
|
||||||
|
#include "debugtrace.hpp"
|
||||||
|
|
||||||
InDataHandler::InDataHandler(StreamMgr &mgr) : _mgr(mgr) {
|
InDataHandler::InDataHandler(StreamMgr &mgr) : _mgr(mgr) {
|
||||||
mgr.addInDataHandler(*this);
|
mgr.addInDataHandler(*this);
|
||||||
}
|
}
|
||||||
InDataHandler::~InDataHandler() { _mgr.removeInDataHandler(*this); }
|
InDataHandler::~InDataHandler() { _mgr.removeInDataHandler(*this); }
|
||||||
|
|
||||||
|
|
||||||
StreamMgr &StreamMgr::getInstance() {
|
StreamMgr &StreamMgr::getInstance() {
|
||||||
static StreamMgr mgr;
|
static StreamMgr mgr;
|
||||||
return mgr;
|
return mgr;
|
||||||
}
|
}
|
||||||
|
StreamMgr::StreamMgr() {}
|
||||||
|
|
||||||
bool StreamMgr::inCallback(const DaqData &data) {
|
bool StreamMgr::inCallback(const DaqData &data) {
|
||||||
std::scoped_lock<std::mutex> lck(_inDataHandler_mtx);
|
std::scoped_lock<std::mutex> lck(_inDataHandler_mtx);
|
||||||
@ -37,11 +39,11 @@ bool StreamMgr::inCallback(const DaqData &data) {
|
|||||||
template <typename T> bool fillData(DaqData &data, const vd &signal) {
|
template <typename T> bool fillData(DaqData &data, const vd &signal) {
|
||||||
assert(data.nframes == signal.size());
|
assert(data.nframes == signal.size());
|
||||||
|
|
||||||
T* res = reinterpret_cast<T*>(data.raw_ptr());
|
T *res = reinterpret_cast<T *>(data.raw_ptr());
|
||||||
if (std::is_floating_point<T>()) {
|
if (std::is_floating_point<T>()) {
|
||||||
for (us ch = 0; ch < data.nchannels; ch++) {
|
for (us ch = 0; ch < data.nchannels; ch++) {
|
||||||
for (us frame = 0; frame < data.nframes; frame++) {
|
for (us frame = 0; frame < data.nframes; frame++) {
|
||||||
res[ch * data.nframes + frame ] = signal[frame];
|
res[ch * data.nframes + frame] = signal[frame];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -60,20 +62,23 @@ void StreamMgr::setSiggen(std::shared_ptr<Siggen> siggen) {
|
|||||||
|
|
||||||
std::scoped_lock<std::mutex> lck(_siggen_mtx);
|
std::scoped_lock<std::mutex> lck(_siggen_mtx);
|
||||||
_siggen = siggen;
|
_siggen = siggen;
|
||||||
|
|
||||||
// If not set to nullptr, and a stream is running, we update the signal
|
// If not set to nullptr, and a stream is running, we update the signal
|
||||||
// generator by resetting it.
|
// generator by resetting it.
|
||||||
if(isStreamRunning(StreamType::outputType) && siggen) {
|
if (isStreamRunningOK(StreamType::output) && siggen) {
|
||||||
const Daq* daq = getDaq(StreamType::outputType);
|
const Daq *daq = getDaq(StreamType::output);
|
||||||
assert(daq != nullptr);
|
assert(daq != nullptr);
|
||||||
// Reset the signal generator.
|
// Reset the signal generator.
|
||||||
_siggen->reset(daq->samplerate());
|
_siggen->reset(daq->samplerate());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StreamMgr::outCallback(DaqData& data) {
|
bool StreamMgr::outCallback(DaqData &data) {
|
||||||
|
|
||||||
|
/* DEBUGTRACE_ENTER; */
|
||||||
|
|
||||||
std::scoped_lock<std::mutex> lck(_siggen_mtx);
|
std::scoped_lock<std::mutex> lck(_siggen_mtx);
|
||||||
if(_siggen) {
|
if (_siggen) {
|
||||||
vd signal = _siggen->genSignal(data.nframes);
|
vd signal = _siggen->genSignal(data.nframes);
|
||||||
switch (data.dtype) {
|
switch (data.dtype) {
|
||||||
case (DataTypeDescriptor::DataType::dtype_fl32):
|
case (DataTypeDescriptor::DataType::dtype_fl32):
|
||||||
@ -94,51 +99,72 @@ bool StreamMgr::outCallback(DaqData& data) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Set all values to 0.
|
// Set all values to 0.
|
||||||
std::fill(data.raw_ptr(), data.raw_ptr()+data.size_bytes(), 0);
|
std::fill(data.raw_ptr(), data.raw_ptr() + data.size_bytes(), 0);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamMgr::~StreamMgr() { stopAllStreams(); }
|
StreamMgr::~StreamMgr() { stopAllStreams(); }
|
||||||
void StreamMgr::stopAllStreams() { _streams.clear(); }
|
void StreamMgr::stopAllStreams() {
|
||||||
|
_inputStream.reset();
|
||||||
|
_outputStream.reset();
|
||||||
|
}
|
||||||
|
|
||||||
void StreamMgr::startStream(const DeviceInfo &devinfo,
|
void StreamMgr::startStream(const DeviceInfo &devinfo,
|
||||||
const DaqConfiguration &config) {
|
const DaqConfiguration &config) {
|
||||||
|
|
||||||
bool isInput = std::count(config.eninchannels.begin(),
|
bool isInput = std::count_if(config.inchannel_config.cbegin(),
|
||||||
config.eninchannels.end(), true) > 0;
|
config.inchannel_config.cend(),
|
||||||
bool isOutput = std::count(config.enoutchannels.begin(),
|
[](auto &i) { return i.enabled; });
|
||||||
config.enoutchannels.end(), true) > 0;
|
isInput |= config.monitorOutput && devinfo.hasInternalOutputMonitor;
|
||||||
|
|
||||||
|
bool isOutput = std::count_if(config.outchannel_config.cbegin(),
|
||||||
|
config.outchannel_config.cend(),
|
||||||
|
[](auto &i) { return i.enabled; });
|
||||||
|
|
||||||
bool isDuplex = isInput && isOutput;
|
bool isDuplex = isInput && isOutput;
|
||||||
|
|
||||||
if (!isInput && !isOutput) {
|
if (!isInput && !isOutput) {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"Neither input, nor output channels enabled for stream");
|
"Neither input, nor output channels enabled for stream. Cannotr start.");
|
||||||
}
|
}
|
||||||
StreamType streamtype;
|
|
||||||
|
|
||||||
if (isDuplex) {
|
if ((isDuplex || isInput) && _inputStream) {
|
||||||
if (_streams.size()) {
|
throw std::runtime_error("Error: an input stream is already running. Please "
|
||||||
throw std::runtime_error("Error: a stream is already running. Please "
|
"first stop existing stream");
|
||||||
"first stop existing stream");
|
} else if (isOutput && _outputStream) {
|
||||||
}
|
throw std::runtime_error("Error: output stream is already running. Please "
|
||||||
streamtype = StreamType::duplex;
|
"first stop existing stream");
|
||||||
|
|
||||||
} else if (isInput) {
|
|
||||||
if (_streams[StreamType::input]) {
|
|
||||||
throw std::runtime_error("Error: input stream is already running. Please "
|
|
||||||
"first stop existing stream");
|
|
||||||
}
|
|
||||||
streamtype = StreamType::input;
|
|
||||||
} else if (isOutput) {
|
|
||||||
if (_streams[StreamType::output]) {
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Error: output stream is already running. Please "
|
|
||||||
"first stop existing stream");
|
|
||||||
}
|
|
||||||
streamtype = StreamType::input;
|
|
||||||
}
|
}
|
||||||
_streams[streamtype] = Daq::createDaq(devinfo, config);
|
|
||||||
|
InDaqCallback inCallback;
|
||||||
|
OutDaqCallback outCallback;
|
||||||
|
|
||||||
|
using namespace std::placeholders;
|
||||||
|
std::unique_ptr<Daq> daq = Daq::createDaq(devinfo, config);
|
||||||
|
|
||||||
|
if(isInput) {
|
||||||
|
inCallback = std::bind(&StreamMgr::inCallback, this, _1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isOutput) {
|
||||||
|
if(_siggen) {
|
||||||
|
_siggen->reset(daq->samplerate());
|
||||||
|
}
|
||||||
|
outCallback = std::bind(&StreamMgr::outCallback, this, _1);
|
||||||
|
}
|
||||||
|
DEBUGTRACE_PRINT(isInput);
|
||||||
|
DEBUGTRACE_PRINT(isOutput);
|
||||||
|
|
||||||
|
daq->start(inCallback, outCallback);
|
||||||
|
|
||||||
|
if(isInput) {
|
||||||
|
_inputStream = std::move(daq);
|
||||||
|
} else {
|
||||||
|
assert(isOutput);
|
||||||
|
_outputStream = std::move(daq);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamMgr::addInDataHandler(InDataHandler &handler) {
|
void StreamMgr::addInDataHandler(InDataHandler &handler) {
|
||||||
@ -149,3 +175,28 @@ void StreamMgr::removeInDataHandler(InDataHandler &handler) {
|
|||||||
std::scoped_lock<std::mutex> lck(_inDataHandler_mtx);
|
std::scoped_lock<std::mutex> lck(_inDataHandler_mtx);
|
||||||
_inDataHandlers.remove(&handler);
|
_inDataHandlers.remove(&handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Daq::StreamStatus StreamMgr::getStreamStatus(const StreamType type) const {
|
||||||
|
|
||||||
|
// Default constructor, says stream is not running, but also no errors
|
||||||
|
Daq::StreamStatus s;
|
||||||
|
|
||||||
|
const Daq *daq = getDaq(type);
|
||||||
|
if (daq) {
|
||||||
|
s = daq->getStreamStatus();
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Daq *StreamMgr::getDaq(StreamType type) const {
|
||||||
|
if (type == StreamType::input) {
|
||||||
|
return _inputStream.get();
|
||||||
|
} else {
|
||||||
|
// Output stream. If input runs in duplex mode, this is also the output
|
||||||
|
// stream. In that case, we return the outputstram
|
||||||
|
if (_inputStream && _inputStream->duplexMode()) {
|
||||||
|
return _inputStream.get();
|
||||||
|
}
|
||||||
|
return _outputStream.get();
|
||||||
|
}
|
||||||
|
}
|
@ -7,24 +7,6 @@
|
|||||||
|
|
||||||
class StreamMgr;
|
class StreamMgr;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Information regarding a stream.
|
|
||||||
*/
|
|
||||||
class StreamStatus {
|
|
||||||
public:
|
|
||||||
bool isRunning = false;
|
|
||||||
bool error = false;
|
|
||||||
std::string error_msg{};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns true if everything is OK with a certain stream and the
|
|
||||||
* stream is running.
|
|
||||||
*
|
|
||||||
* @return as described above.
|
|
||||||
*/
|
|
||||||
bool runningOK() const { return isRunning && !error; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class InDataHandler {
|
class InDataHandler {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -60,31 +42,19 @@ class StreamMgr {
|
|||||||
|
|
||||||
enum class StreamType : us {
|
enum class StreamType : us {
|
||||||
/**
|
/**
|
||||||
* @brief Input-only stream
|
* @brief Input stream
|
||||||
*/
|
*/
|
||||||
input = 1 << 0,
|
input = 1 << 0,
|
||||||
/**
|
/**
|
||||||
* @brief Output-only stream
|
* @brief Output stream
|
||||||
*/
|
*/
|
||||||
output = 1 << 1,
|
output = 1 << 1,
|
||||||
/**
|
|
||||||
* @brief Duplex stream (does both input and output)
|
|
||||||
*/
|
|
||||||
duplex = 1 << 2,
|
|
||||||
/**
|
|
||||||
* @brief Either input, or duplex
|
|
||||||
*/
|
|
||||||
inputType = 1 << 3,
|
|
||||||
/**
|
|
||||||
* @brief Either output, or duplex
|
|
||||||
*/
|
|
||||||
outputType = 1 << 4
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Storage for streams
|
* @brief Storage for streams.
|
||||||
*/
|
*/
|
||||||
std::map<StreamType, std::unique_ptr<Daq>> _streams;
|
std::unique_ptr<Daq> _inputStream, _outputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief All indata handlers are called when input data is available. Note
|
* @brief All indata handlers are called when input data is available. Note
|
||||||
@ -106,10 +76,12 @@ class StreamMgr {
|
|||||||
friend class InDataHandler;
|
friend class InDataHandler;
|
||||||
friend class Siggen;
|
friend class Siggen;
|
||||||
|
|
||||||
|
// Singleton, no public destructor
|
||||||
|
~StreamMgr();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StreamMgr(const StreamMgr &) = delete;
|
StreamMgr(const StreamMgr &) = delete;
|
||||||
StreamMgr &operator=(const StreamMgr &) = delete;
|
StreamMgr &operator=(const StreamMgr &) = delete;
|
||||||
~StreamMgr();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get access to stream manager instance
|
* @brief Get access to stream manager instance
|
||||||
@ -144,7 +116,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @return status object.
|
* @return status object.
|
||||||
*/
|
*/
|
||||||
StreamStatus getStreamStatus(const StreamType type) const;
|
Daq::StreamStatus getStreamStatus(const StreamType type) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get DAQ pointer for a given stream. Gives a nullptr if stream is
|
* @brief Get DAQ pointer for a given stream. Gives a nullptr if stream is
|
||||||
@ -169,19 +141,29 @@ public:
|
|||||||
*/
|
*/
|
||||||
void stopAllStreams();
|
void stopAllStreams();
|
||||||
|
|
||||||
private:
|
|
||||||
bool inCallback(const DaqData &data);
|
|
||||||
bool outCallback(DaqData &data);
|
|
||||||
|
|
||||||
void addInDataHandler(InDataHandler &handler);
|
|
||||||
void removeInDataHandler(InDataHandler &handler);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set active signal generator for output streams. Only one `Siggen'
|
* @brief Set active signal generator for output streams. Only one `Siggen'
|
||||||
* is active at the same time. Siggen controls its own data race protection
|
* is active at the same time. Siggen controls its own data race protection
|
||||||
* using a mutex.
|
* using a mutex.
|
||||||
*
|
*
|
||||||
* @param s Siggen pointer
|
* @param s New Siggen pointer
|
||||||
*/
|
*/
|
||||||
void setSiggen(std::shared_ptr<Siggen> s);
|
void setSiggen(std::shared_ptr<Siggen> s);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool inCallback(const DaqData &data);
|
||||||
|
bool outCallback(DaqData &data);
|
||||||
|
|
||||||
|
void removeInDataHandler(InDataHandler &handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add an input data handler. The handler's inCallback() function is
|
||||||
|
* called with data when available. This function should *NOT* be called by
|
||||||
|
* the user, instead, an InDataHandler can only be created with the StreamMgr
|
||||||
|
* as argument.
|
||||||
|
*
|
||||||
|
* @param handler The handler to add.
|
||||||
|
*/
|
||||||
|
void addInDataHandler(InDataHandler &handler);
|
||||||
|
|
||||||
};
|
};
|
@ -1,4 +1,5 @@
|
|||||||
#include "lasp_uldaq.h"
|
#include "lasp_uldaq.h"
|
||||||
|
#if LASP_HAS_ULDAQ == 1
|
||||||
#include "lasp_daqconfig.h"
|
#include "lasp_daqconfig.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
@ -55,11 +56,12 @@ class DT9837A : public Daq {
|
|||||||
|
|
||||||
std::thread _thread;
|
std::thread _thread;
|
||||||
atomic<bool> _stopThread{false};
|
atomic<bool> _stopThread{false};
|
||||||
|
atomic<StreamStatus> _streamStatus;
|
||||||
|
|
||||||
const us _nFramesPerBlock;
|
const us _nFramesPerBlock;
|
||||||
|
|
||||||
void threadFcn(std::optional<InDaqCallback> inCallback,
|
void threadFcn(InDaqCallback inCallback,
|
||||||
std::optional<OutDaqCallback> outcallback);
|
OutDaqCallback outcallback);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config);
|
DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config);
|
||||||
@ -78,12 +80,17 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRunning() const override final { return _thread.joinable(); }
|
bool isRunning() const { return _thread.joinable(); }
|
||||||
virtual void start(std::optional<InDaqCallback> inCallback,
|
virtual void start(InDaqCallback inCallback,
|
||||||
std::optional<OutDaqCallback> outCallback) override final;
|
OutDaqCallback outCallback) override final;
|
||||||
|
|
||||||
|
virtual StreamStatus getStreamStatus() const override {
|
||||||
|
return _streamStatus;
|
||||||
|
}
|
||||||
|
|
||||||
void stop() override final {
|
void stop() override final {
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
|
StreamStatus status = _streamStatus;
|
||||||
if (!isRunning()) {
|
if (!isRunning()) {
|
||||||
throw runtime_error("No data acquisition running");
|
throw runtime_error("No data acquisition running");
|
||||||
}
|
}
|
||||||
@ -93,13 +100,16 @@ public:
|
|||||||
_thread.join();
|
_thread.join();
|
||||||
}
|
}
|
||||||
_stopThread = false;
|
_stopThread = false;
|
||||||
|
status.isRunning = false;
|
||||||
|
_streamStatus = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class InBufHandler;
|
friend class InBufHandler;
|
||||||
friend class OutBufHandler;
|
friend class OutBufHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
void DT9837A::start(std::optional<InDaqCallback> inCallback,
|
void DT9837A::start(InDaqCallback inCallback,
|
||||||
std::optional<OutDaqCallback> outCallback) {
|
OutDaqCallback outCallback) {
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
throw runtime_error("DAQ is already running");
|
throw runtime_error("DAQ is already running");
|
||||||
@ -163,7 +173,7 @@ public:
|
|||||||
|
|
||||||
std::vector<DaqInChanDescriptor> indescs;
|
std::vector<DaqInChanDescriptor> indescs;
|
||||||
|
|
||||||
boolvec eninchannels = daq.eninchannels;
|
boolvec eninchannels = daq.eninchannels();
|
||||||
|
|
||||||
// Initialize input, if any
|
// Initialize input, if any
|
||||||
for (us chin = 0; chin < 4; chin++) {
|
for (us chin = 0; chin < 4; chin++) {
|
||||||
@ -360,37 +370,56 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void DT9837A::threadFcn(std::optional<InDaqCallback> inCallback,
|
void DT9837A::threadFcn(InDaqCallback inCallback,
|
||||||
std::optional<OutDaqCallback> outCallback) {
|
OutDaqCallback outCallback) {
|
||||||
|
|
||||||
DEBUGTRACE_ENTER;
|
DEBUGTRACE_ENTER;
|
||||||
std::unique_ptr<InBufHandler> ibh;
|
|
||||||
std::unique_ptr<OutBufHandler> obh;
|
|
||||||
|
|
||||||
if (neninchannels() > 0) {
|
cerr << "******************\n"
|
||||||
ibh = std::make_unique<InBufHandler>(*this, inCallback.value());
|
"Todo: the current way of handling timing in this DAQ thread is not "
|
||||||
}
|
"really robust, due "
|
||||||
if (nenoutchannels() > 0) {
|
"to input / output callbacks that can be too time-consuming. We have "
|
||||||
obh = std::make_unique<OutBufHandler>(*this, outCallback.value());
|
"to fix the "
|
||||||
}
|
"sleep_for to properly deal with longer callbacks."
|
||||||
|
"\n*****************"
|
||||||
|
<< endl;
|
||||||
|
try {
|
||||||
|
std::unique_ptr<InBufHandler> ibh;
|
||||||
|
std::unique_ptr<OutBufHandler> obh;
|
||||||
|
|
||||||
const double sleeptime =
|
if (neninchannels() > 0) {
|
||||||
static_cast<double>(_nFramesPerBlock) / (16 * samplerate());
|
assert(inCallback);
|
||||||
const us sleeptime_us = static_cast<us>(sleeptime * 1e6);
|
ibh = std::make_unique<InBufHandler>(*this, inCallback);
|
||||||
|
|
||||||
while (!_stopThread) {
|
|
||||||
if (ibh) {
|
|
||||||
if (!(*ibh)()) {
|
|
||||||
_stopThread = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (obh) {
|
if (nenoutchannels() > 0) {
|
||||||
if (!(*obh)()) {
|
assert(outCallback);
|
||||||
_stopThread = true;
|
obh = std::make_unique<OutBufHandler>(*this, outCallback);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
std::this_thread::sleep_for(std::chrono::microseconds(sleeptime_us));
|
|
||||||
|
const double sleeptime =
|
||||||
|
static_cast<double>(_nFramesPerBlock) / (16 * samplerate());
|
||||||
|
const us sleeptime_us = static_cast<us>(sleeptime * 1e6);
|
||||||
|
|
||||||
|
while (!_stopThread) {
|
||||||
|
if (ibh) {
|
||||||
|
if (!(*ibh)()) {
|
||||||
|
_stopThread = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (obh) {
|
||||||
|
if (!(*obh)()) {
|
||||||
|
_stopThread = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::microseconds(sleeptime_us));
|
||||||
|
}
|
||||||
|
} catch (std::runtime_error &e) {
|
||||||
}
|
}
|
||||||
|
StreamStatus status = _streamStatus;
|
||||||
|
;
|
||||||
|
status.isRunning = false;
|
||||||
|
_streamStatus = status;
|
||||||
|
_stopThread = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Daq> createUlDaqDevice(const DeviceInfo &devinfo,
|
std::unique_ptr<Daq> createUlDaqDevice(const DeviceInfo &devinfo,
|
||||||
@ -403,11 +432,11 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config)
|
|||||||
_nFramesPerBlock(availableFramesPerBlock.at(framesPerBlockIndex)) {
|
_nFramesPerBlock(availableFramesPerBlock.at(framesPerBlockIndex)) {
|
||||||
|
|
||||||
// Some sanity checks
|
// Some sanity checks
|
||||||
if (eninchannels.size() != 4) {
|
if (inchannel_config.size() != 4) {
|
||||||
throw runtime_error("Invalid length of enabled inChannels vector");
|
throw runtime_error("Invalid length of enabled inChannels vector");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enoutchannels.size() != 1) {
|
if (outchannel_config.size() != 1) {
|
||||||
throw runtime_error("Invalid length of enabled outChannels vector");
|
throw runtime_error("Invalid length of enabled outChannels vector");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,14 +494,14 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config)
|
|||||||
throw runtime_error("Fatal: could normalize channel sensitivity");
|
throw runtime_error("Fatal: could normalize channel sensitivity");
|
||||||
}
|
}
|
||||||
|
|
||||||
CouplingMode cm = inputACCouplingMode[ch] ? CM_AC : CM_DC;
|
CouplingMode cm = inchannel_config.at(ch).ACCouplingMode ? CM_AC : CM_DC;
|
||||||
err = ulAISetConfig(_handle, AI_CFG_CHAN_COUPLING_MODE, ch, cm);
|
err = ulAISetConfig(_handle, AI_CFG_CHAN_COUPLING_MODE, ch, cm);
|
||||||
if (err != ERR_NO_ERROR) {
|
if (err != ERR_NO_ERROR) {
|
||||||
showErr(err);
|
showErr(err);
|
||||||
throw runtime_error("Fatal: could not set AC/DC coupling mode");
|
throw runtime_error("Fatal: could not set AC/DC coupling mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
IepeMode iepe = inputIEPEEnabled[ch] ? IEPE_ENABLED : IEPE_DISABLED;
|
IepeMode iepe = inchannel_config.at(ch).IEPEEnabled ? IEPE_ENABLED : IEPE_DISABLED;
|
||||||
err = ulAISetConfig(_handle, AI_CFG_CHAN_IEPE_MODE, ch, iepe);
|
err = ulAISetConfig(_handle, AI_CFG_CHAN_IEPE_MODE, ch, iepe);
|
||||||
if (err != ERR_NO_ERROR) {
|
if (err != ERR_NO_ERROR) {
|
||||||
showErr(err);
|
showErr(err);
|
||||||
@ -556,3 +585,4 @@ void fillUlDaqDeviceInfo(std::vector<DeviceInfo> &devinfolist) {
|
|||||||
devinfolist.push_back(devinfo);
|
devinfolist.push_back(devinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
16
src/lasp/dsp/CMakeLists.txt
Normal file
16
src/lasp/dsp/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# src/lasp/dsp/CMakeLists.txt
|
||||||
|
|
||||||
|
set(lasp_dsp_files
|
||||||
|
lasp_filter.cpp
|
||||||
|
lasp_siggen.cpp
|
||||||
|
lasp_siggen_impl.cpp
|
||||||
|
lasp_window.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
add_library(lasp_dsp_lib STATIC ${lasp_dsp_files})
|
||||||
|
target_compile_definitions(lasp_dsp_lib PUBLIC "-DARMA_DONT_USE_WRAPPER")
|
||||||
|
|
||||||
|
target_link_libraries(lasp_dsp_lib PRIVATE ${BLAS_LIBRARIES})
|
||||||
|
target_include_directories(lasp_dsp_lib INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
@ -168,7 +168,7 @@ void Sweep::resetImpl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUGTRACE_PRINT(K);
|
DEBUGTRACE_PRINT(K);
|
||||||
DEBUGTRACE_PRINT(K1);
|
DEBUGTRACE_PRINT(k1);
|
||||||
DEBUGTRACE_PRINT(k);
|
DEBUGTRACE_PRINT(k);
|
||||||
DEBUGTRACE_PRINT(E);
|
DEBUGTRACE_PRINT(E);
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ void Sweep::resetImpl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUGTRACE_PRINT(K);
|
DEBUGTRACE_PRINT(K);
|
||||||
DEBUGTRACE_PRINT(K1);
|
DEBUGTRACE_PRINT(k1);
|
||||||
DEBUGTRACE_PRINT(k);
|
DEBUGTRACE_PRINT(k);
|
||||||
DEBUGTRACE_PRINT(E);
|
DEBUGTRACE_PRINT(E);
|
||||||
|
|
@ -35,6 +35,7 @@ class Sine : public Siggen {
|
|||||||
~Sine() = default;
|
~Sine() = default;
|
||||||
virtual vd genSignalUnscaled(const us nframes) override;
|
virtual vd genSignalUnscaled(const us nframes) override;
|
||||||
void setFreq(const d newFreq);
|
void setFreq(const d newFreq);
|
||||||
|
void resetImpl() override { phase=0; }
|
||||||
};
|
};
|
||||||
class Periodic: public Siggen {
|
class Periodic: public Siggen {
|
||||||
protected:
|
protected:
|
@ -6,7 +6,7 @@ from collections import namedtuple
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from dataclasses_json import dataclass_json
|
from dataclasses_json import dataclass_json
|
||||||
from enum import Enum, unique, auto
|
from enum import Enum, unique, auto
|
||||||
from .dsp import Window as wWindow
|
from .lasp_cpp import Window as wWindow
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Common definitions used throughout the code.
|
Common definitions used throughout the code.
|
19
src/lasp/lasp_cpp.cpp
Normal file
19
src/lasp/lasp_cpp.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
void init_dsp(py::module& m);
|
||||||
|
void init_deviceinfo(py::module& m);
|
||||||
|
void init_daqconfiguration(py::module& m);
|
||||||
|
void init_daq(py::module& m);
|
||||||
|
void init_streammgr(py::module& m);
|
||||||
|
|
||||||
|
|
||||||
|
PYBIND11_MODULE(lasp_cpp, m) {
|
||||||
|
|
||||||
|
init_dsp(m);
|
||||||
|
init_deviceinfo(m);
|
||||||
|
init_daqconfiguration(m);
|
||||||
|
init_daq(m);
|
||||||
|
init_streammgr(m);
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user