init
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
*.cmd text eol=crlf
|
||||
*.cmd-base text eol=crlf
|
||||
*.nsi text eol=crlf
|
||||
|
||||
*.m text eol=lf
|
||||
*.sh text eol=lf
|
||||
*.sh-base text eol=lf
|
||||
|
||||
scripts/linux* text eol=lf
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
local-tmp
|
||||
dependencies
|
||||
dependencies_x64
|
||||
scripts/win32-dependencies.cmd
|
||||
dist
|
||||
dist-*
|
||||
build
|
||||
CMakeLists.txt.*
|
||||
CustomCMakeLists.txt
|
||||
.*.swp
|
||||
externals/*/
|
||||
*~
|
||||
*.swp
|
||||
.project
|
||||
.cproject
|
||||
|
||||
#ignore python compile file .pyc
|
||||
# *.pyc
|
||||
# *.*~
|
||||
|
||||
modules/doc-tmp/
|
||||
|
||||
# .build is generated on automated packaging on CI
|
||||
.build
|
||||
# this file can be copied from skeleton, and updated with appropriate credentials
|
||||
scripts/windows-install-dependencies-custom.cmd
|
||||
scripts/windows-install-dependencies-x64-custom.cmd
|
||||
.version
|
||||
|
||||
# Temp & Software Folder
|
||||
.vs/
|
||||
.vscode/
|
||||
+344
@@ -0,0 +1,344 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.4)
|
||||
cmake_policy(SET CMP0026 OLD)
|
||||
cmake_policy(SET CMP0042 OLD)
|
||||
cmake_policy(SET CMP0043 OLD)
|
||||
cmake_policy(SET CMP0045 OLD)
|
||||
cmake_policy(SET CMP0048 OLD)
|
||||
|
||||
PROJECT(OpenVIBE)
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake-modules")
|
||||
SET(CMAKE_INSTALL_LIBDIR lib) # Fix for non debian-based distrib, as it seeems to be a common occurence to name this folder lib32/lib64
|
||||
INCLUDE("Utilities")
|
||||
INCLUDE("SetProjectVersion")
|
||||
set_version()
|
||||
OV_SET_PROJECT_VERSION()
|
||||
MESSAGE(STATUS "BUILDING VERSION OpenViBE SDK: ${OV_GLOBAL_VERSION_STRING} Branch : ${OV_PROJECT_BRANCH}~${OV_PROJECT_COMMITHASH}")
|
||||
|
||||
# Default is to build to dist/. If you wish a custom install, set your own MAKE_INSTALL_PREFIX when you call CMake. Safest to do under a fakeroot.
|
||||
MESSAGE(STATUS "Appending compilation flags...")
|
||||
|
||||
SET(OV_CONFIG_SUBDIR "${PROJECT_NAME}" CACHE STRING "Subdirectory under user directory when configuration and logs will be saved")
|
||||
|
||||
IF(NOT DEFINED OV_CUSTOM_DEPENDENCIES_PATH)
|
||||
IF(WIN32)
|
||||
IF("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
SET(OV_DEPENDENCIES_PLATFORM_FOLDER_NAME "dependencies_x64")
|
||||
ELSEIF("${CMAKE_SIZEOF_VOID_P}" EQUAL "4")
|
||||
SET(OV_DEPENDENCIES_PLATFORM_FOLDER_NAME "dependencies")
|
||||
ELSE()
|
||||
SET(OV_DEPENDENCIES_PLATFORM_FOLDER_NAME "dependencies")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(OV_DEPENDENCIES_PLATFORM_FOLDER_NAME "dependencies")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
SET(OV_CUSTOM_DEPENDENCIES_PATH "${CMAKE_SOURCE_DIR}/${OV_DEPENDENCIES_PLATFORM_FOLDER_NAME}" CACHE STRING "Dependency directory")
|
||||
SET(OV_SOURCE_DEPENDENCIES_PATH "${CMAKE_SOURCE_DIR}/dependencies-source")
|
||||
|
||||
# ----------------------
|
||||
# Build CMake flags
|
||||
# ----------------------
|
||||
SET(BRAND_NAME "OpenViBE" CACHE STRING "Brand with which titles and documentation will be prefixed")
|
||||
string(TIMESTAMP COPYRIGHT_DATE "2012-%Y")
|
||||
IF(BRAND_NAME STREQUAL "NeuroRT")
|
||||
SET(COMPANY_NAME "Mensia Technologies SA")
|
||||
ELSE()
|
||||
SET(COMPANY_NAME "Inria")
|
||||
ENDIF()
|
||||
|
||||
OPTION(Flag_VerboseOutput "Verbose CMake output" OFF)
|
||||
OPTION(OV_DISPLAY_ERROR_LOCATION ON)
|
||||
OPTION(PUBLISH_DOC_ASSETS "Publish plugin documentation assets" ON)
|
||||
|
||||
if(NOT(${Flag_VerboseOutput}))
|
||||
set(CMAKE_INSTALL_MESSAGE LAZY)
|
||||
endif()
|
||||
|
||||
# If OpenMP is available, using it will allow Eigen to use multiple cores in matrix math.
|
||||
IF(NOT(APPLE))
|
||||
INCLUDE("FindOpenMP")
|
||||
IF(OPENMP_FOUND)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
ENDIF(OPENMP_FOUND)
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS("-DOV_CONFIG_SUBDIR=\"${OV_CONFIG_SUBDIR}\"")
|
||||
ADD_DEFINITIONS("-DOV_PROJECT_NAME=\"${PROJECT_NAME}\"")
|
||||
ADD_DEFINITIONS("-DOV_VERSION_MAJOR=\"${OV_GLOBAL_VERSION_MAJOR}\"")
|
||||
ADD_DEFINITIONS("-DOV_VERSION_MINOR=\"${OV_GLOBAL_VERSION_MINOR}\"")
|
||||
ADD_DEFINITIONS("-DOV_VERSION_PATCH=\"${OV_GLOBAL_VERSION_PATCH}\"")
|
||||
|
||||
IF(NOT DEFINED OV_PACKAGE)
|
||||
SET(OV_PACKAGE FALSE)
|
||||
ENDIF(NOT DEFINED OV_PACKAGE)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
IF(WIN32)
|
||||
ADD_DEFINITIONS("-DNOMINMAX -DBOOST_ALL_NO_LIB")
|
||||
# The following is needed to keep OpenMP from hogging all the cores. Note that this works only for VS2013+. On VS2010, it may be better to disable OpenMP.
|
||||
SET(OV_OMP_WAIT_POLICY "PASSIVE")
|
||||
# Disable /MP if you don't like VS using all the cores for compilation
|
||||
|
||||
# Switch /arch:SSE2 enables vectorization. Remove if your CPU/compiler doesn't support it.
|
||||
# x64 build do not provide SSE2 option because 64bit processors always supports SSE vectorization.
|
||||
# So the /arch:SSE2 is not recognized for x64 build we have to only activate it for x86.
|
||||
IF("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
ELSEIF("${CMAKE_SIZEOF_VOID_P}" EQUAL "4")
|
||||
SET(OV_EIGEN_FLAGS "/arch:SSE2")
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4355 /MP ${OV_EIGEN_FLAGS}")
|
||||
SET(OV_WIN32_BOOST_VERSION "1_58")
|
||||
ELSEIF(APPLE)
|
||||
SET(OV_EIGEN_FLAGS "-msse2")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall ${OV_EIGEN_FLAGS}")
|
||||
ELSEIF(UNIX)
|
||||
# Switch -msse2 enables vectorization. Remove if your CPU/compiler doesn't support it.
|
||||
SET(OV_EIGEN_FLAGS "-msse2")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall ${OV_EIGEN_FLAGS}")
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Warning: unknown platform")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/../openvibe-sdk-build/dist-${CMAKE_BUILD_TYPE}")
|
||||
ENDIF()
|
||||
|
||||
# Setup knowledge of GNU-style install path variables
|
||||
INCLUDE("GNUInstallDirs")
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio*")
|
||||
set(MULTI_BUILD TRUE)
|
||||
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_INSTALL_PREFIX}/bin" )
|
||||
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_INSTALL_PREFIX}/lib" )
|
||||
# set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_INSTALL_PREFIX}/archive" )
|
||||
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
|
||||
string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIGU )
|
||||
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIGU} "${CMAKE_INSTALL_PREFIX}/${OUTPUTCONFIG}/bin" )
|
||||
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIGU} "${CMAKE_INSTALL_PREFIX}/${OUTPUTCONFIG}/lib" )
|
||||
# set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "${CMAKE_INSTALL_PREFIX}/${OUTPUTCONFIG}/archive" )
|
||||
string(CONCAT DIST_ROOT ${DIST_ROOT} $<$<CONFIG:${OUTPUTCONFIGU}>:${CMAKE_INSTALL_PREFIX}/${OUTPUTCONFIG}>)
|
||||
endforeach()
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "OV_CMAKE_PATH_ROOT=\"${DIST_ROOT}\"")
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "OV_CMAKE_PATH_BIN=\"${DIST_ROOT}/bin\"")
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "OV_CMAKE_PATH_LIB=\"${DIST_ROOT}/lib\"")
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "OV_CMAKE_PATH_DATA=\"${DIST_ROOT}/share/openvibe\"")
|
||||
set(DIST_BINDIR ${DIST_ROOT}/bin)
|
||||
set(DIST_LIBDIR ${DIST_ROOT}/lib)
|
||||
set(DIST_INCLUDEDIR ${DIST_ROOT}/include)
|
||||
set(DIST_DATADIR ${DIST_ROOT}/share)
|
||||
set(DIST_DOCDIR ${DIST_ROOT}/doc)
|
||||
set(DIST_DOCTMP ${DIST_ROOT}/doc-tmp)
|
||||
|
||||
set(DIST_BINDIR_ABSOLUTE ${DIST_BINDIR})
|
||||
# Also install it on the base dir for convenience
|
||||
install(FILES scripts/AddOpenViBESDKComponents.cmake DESTINATION ${CMAKE_INSTALL_PREFIX}/share)
|
||||
# Install the .install file inside the dists folders
|
||||
install(FILES ${CMAKE_BINARY_DIR}/.install DESTINATION ${DIST_ROOT})
|
||||
elseif(CMAKE_BUILD_TYPE AND OV_PACKAGE)
|
||||
# Add directories that OpenViBE will use to look for its components runtime, unless overridden by environment variables in the launch scripts.
|
||||
# These defines should only be used in "openvibe/ov_directories.h".
|
||||
|
||||
# We use absolute paths to avoid issue for unit and validation tests
|
||||
get_filename_component(DIST_ROOT_ABSOLUTE "." REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||
set(DIST_BINDIR_ABSOLUTE ${DIST_ROOT_ABSOLUTE}/bin)
|
||||
|
||||
set(CMAKE_INSTALL_PREFIX .)
|
||||
|
||||
add_definitions(-DOV_CMAKE_PATH_ROOT="${DIST_ROOT_ABSOLUTE}")
|
||||
add_definitions(-DOV_CMAKE_PATH_BIN="${DIST_ROOT_ABSOLUTE}/bin")
|
||||
add_definitions(-DOV_CMAKE_PATH_LIB="${DIST_ROOT_ABSOLUTE}/lib")
|
||||
add_definitions(-DOV_CMAKE_PATH_DATA="${DIST_ROOT_ABSOLUTE}/share/openvibe")
|
||||
|
||||
set(DIST_ROOT ${CMAKE_INSTALL_PREFIX})
|
||||
set(DIST_BINDIR ${CMAKE_INSTALL_BINDIR})
|
||||
set(DIST_LIBDIR ${CMAKE_INSTALL_LIBDIR})
|
||||
set(DIST_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
set(DIST_DATADIR ${CMAKE_INSTALL_DATADIR})
|
||||
set(DIST_DOCDIR doc)
|
||||
set(DIST_DOCTMP doc-tmp)
|
||||
set(CPACK_GENERATOR "ZIP")
|
||||
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${BRAND_NAME})
|
||||
set(CPACK_PACKAGE_VENDOR "Inria & Mensia Technologies")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.md")
|
||||
set(CPACK_PACKAGE_VERSION ${OV_GLOBAL_VERSION_MAJOR}.${OV_GLOBAL_VERSION_MINOR}.${OV_GLOBAL_VERSION_PATCH}.${OV_GLOBAL_VERSION_BUILD})
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${OV_GLOBAL_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${OV_GLOBAL_VERSION_PATCH})
|
||||
|
||||
if(UNIX)
|
||||
execute_process(
|
||||
COMMAND bash -c "echo -n $(lsb_release -i -s)$(lsb_release -r -s)"
|
||||
OUTPUT_VARIABLE CPACK_SYSTEM_NAME)
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_NAME "OpenViBE-${CMAKE_BUILD_TYPE}")
|
||||
include(CPack)
|
||||
elseif(CMAKE_BUILD_TYPE)
|
||||
# Add directories that OpenViBE will use to look for its components runtime, unless overridden by environment variables in the launch scripts.
|
||||
# These defines should only be used in "openvibe/ov_directories.h".
|
||||
add_definitions(-DOV_CMAKE_PATH_ROOT="${CMAKE_INSTALL_PREFIX}")
|
||||
add_definitions(-DOV_CMAKE_PATH_BIN="${CMAKE_INSTALL_PREFIX}/bin")
|
||||
add_definitions(-DOV_CMAKE_PATH_LIB="${CMAKE_INSTALL_PREFIX}/lib")
|
||||
add_definitions(-DOV_CMAKE_PATH_DATA="${CMAKE_INSTALL_PREFIX}/share/openvibe")
|
||||
|
||||
set(DIST_ROOT ${CMAKE_INSTALL_PREFIX})
|
||||
set(DIST_BINDIR ${CMAKE_INSTALL_FULL_BINDIR})
|
||||
set(DIST_LIBDIR ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
set(DIST_INCLUDEDIR ${CMAKE_INSTALL_FULL_INCLUDEDIR})
|
||||
set(DIST_DATADIR ${CMAKE_INSTALL_FULL_DATADIR})
|
||||
set(DIST_DOCDIR ${DIST_ROOT}/doc)
|
||||
set(DIST_DOCTMP ${DIST_ROOT}/doc-tmp)
|
||||
|
||||
set(DIST_BINDIR_ABSOLUTE ${DIST_BINDIR})
|
||||
else()
|
||||
message(FATAL_ERROR "Build should specify a type or use a multi-type generator (like Visual Studio)")
|
||||
endif()
|
||||
|
||||
# Print the used compilation parameters (for transparency)
|
||||
GET_DIRECTORY_PROPERTY(TMP_DEFINITIONS COMPILE_DEFINITIONS)
|
||||
MESSAGE(STATUS "Compilation flags used at source root: ")
|
||||
MESSAGE(STATUS " COMPILE_DEFINITIONS = '${TMP_DEFINITIONS}'")
|
||||
MESSAGE(STATUS " CMAKE_CXX_FLAGS = '${CMAKE_CXX_FLAGS}'")
|
||||
MESSAGE(STATUS " CMAKE_CXX_FLAGS_RELEASE = '${CMAKE_CXX_FLAGS_RELEASE}'")
|
||||
MESSAGE(STATUS " CMAKE_CXX_FLAGS_DEBUG = '${CMAKE_CXX_FLAGS_DEBUG}'")
|
||||
|
||||
FUNCTION(SET_BUILD_PLATFORM)
|
||||
IF("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
ADD_DEFINITIONS(-DTARGET_ARCHITECTURE_x64)
|
||||
ELSEIF("${CMAKE_SIZEOF_VOID_P}" EQUAL "4")
|
||||
ADD_DEFINITIONS(-DTARGET_ARCHITECTURE_i386)
|
||||
SET(PLATFORM_TARGET "x86")
|
||||
ELSE()
|
||||
ADD_DEFINITIONS(-DTARGET_ARCHITECTURE_Unknown)
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
|
||||
ADD_DEFINITIONS(-DTARGET_OS_Windows)
|
||||
ADD_DEFINITIONS(-DTARGET_COMPILER_VisualStudio)
|
||||
ELSEIF(APPLE)
|
||||
ADD_DEFINITIONS(-fnon-call-exceptions)
|
||||
ADD_DEFINITIONS(-DTARGET_OS_MacOS)
|
||||
# ADD_DEFINITIONS(-DTARGET_ARCHITECTURE_x64)
|
||||
ADD_DEFINITIONS(-DTARGET_COMPILER_LLVM)
|
||||
ELSEIF(UNIX)
|
||||
# ADD_DEFINITIONS(-fvisibility=hidden) # This flag should be present... man gcc
|
||||
ADD_DEFINITIONS(-fnon-call-exceptions)
|
||||
ADD_DEFINITIONS(-DTARGET_OS_Linux)
|
||||
ADD_DEFINITIONS(-DTARGET_COMPILER_GCC)
|
||||
ENDIF()
|
||||
ENDFUNCTION()
|
||||
|
||||
# Custom cmakelist can be used to overwrite the default compilation & packaging parameters
|
||||
# e.g. OEM_DISTRIBUTION
|
||||
IF(EXISTS "${CMAKE_SOURCE_DIR}/CustomCMakeLists.txt")
|
||||
MESSAGE(STATUS "Found custom build settings")
|
||||
INCLUDE("${CMAKE_SOURCE_DIR}/CustomCMakeLists.txt")
|
||||
ENDIF()
|
||||
|
||||
#################################################################
|
||||
string(TOLOWER ${BRAND_NAME} LOWER_BRAND_NAME)
|
||||
ADD_DEFINITIONS(-DBRAND_NAME="${BRAND_NAME}")
|
||||
if(${BRAND_NAME} STREQUAL "NeuroRT")
|
||||
ADD_DEFINITIONS(-DOV_LOCAL_SYMBOLS)
|
||||
endif()
|
||||
|
||||
IF(OV_DISPLAY_ERROR_LOCATION)
|
||||
ADD_DEFINITIONS(-DOV_DISPLAY_ERROR_LOCATION)
|
||||
ENDIF()
|
||||
#################################################################
|
||||
|
||||
SET(OV_LAUNCHER_SOURCE_PATH "${CMAKE_SOURCE_DIR}/cmake-modules/launchers")
|
||||
|
||||
# By setting SKIP[_FOLDER]* you can skip a subtree (example: SKIP_A_B_C skips folder a/b/c and all its subfolders if any)
|
||||
# Skip building documentation
|
||||
# a list of all project which will be filled by the directory traversal. This is needed to generate the documentation.
|
||||
SET_PROPERTY(GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS "")
|
||||
SET_PROPERTY(GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS_BUILD_DIR "")
|
||||
|
||||
# Used by the various Find* scripts to locate OpenViBE modules
|
||||
SET(OV_BASE_DIR ${CMAKE_SOURCE_DIR})
|
||||
SET(OV_BASE_BIN_DIR ${CMAKE_BINARY_DIR})
|
||||
SET(OV_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib)
|
||||
|
||||
# needed for making visual studio projects when this script is called without CMAKE_BUILD_TYPE
|
||||
SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG "TARGET_BUILDTYPE_Debug")
|
||||
SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE "TARGET_BUILDTYPE_Release")
|
||||
SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO "TARGET_BUILDTYPE_Release")
|
||||
|
||||
# OpenViBE-specific helper functions that are used by the CMakeLists of the subprojects.
|
||||
INCLUDE("OvAddProjects")
|
||||
INCLUDE("OvInstallLaunchScript")
|
||||
INCLUDE("OvLinkBoostLib")
|
||||
INCLUDE("OvDelayLoad")
|
||||
|
||||
# Sets the PROJECT_VERSION variable to something, depending on overriding OvSetProjectVersion.cmake files
|
||||
OV_SET_PROJECT_VERSION()
|
||||
|
||||
# Sort target into directories for better visualization in IDE
|
||||
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
SET(APP_FOLDER Applications)
|
||||
SET(KERNEL_FOLDER Kernel)
|
||||
SET(MODULES_FOLDER Modules)
|
||||
SET(PLUGINS_FOLDER Plugins)
|
||||
SET(TESTS_FOLDER Unit-Tests)
|
||||
SET(VALIDATION_FOLDER Validation-Tests)
|
||||
|
||||
# Traverse these directories and build their components
|
||||
ADD_SUBDIRECTORY("build-tool/")
|
||||
|
||||
ADD_SUBDIRECTORY("documentation/")
|
||||
ADD_SUBDIRECTORY("common/")
|
||||
|
||||
IF(NOT(SKIP_OPENVIBE))
|
||||
ADD_SUBDIRECTORY("openvibe/")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT(SKIP_KERNEL))
|
||||
ADD_SUBDIRECTORY("kernel/")
|
||||
ENDIF()
|
||||
|
||||
ADD_SUBDIRECTORY("modules/")
|
||||
|
||||
IF(NOT(SKIP_TOOLKIT))
|
||||
ADD_SUBDIRECTORY("toolkit/")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT(SKIP_PLUGINS))
|
||||
ADD_SUBDIRECTORY("plugins/")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT(SKIP_APPLICATIONS))
|
||||
ADD_SUBDIRECTORY("applications/")
|
||||
ENDIF()
|
||||
|
||||
INSTALL(FILES "${CMAKE_BINARY_DIR}/.install" DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
|
||||
OPTION(BUILD_TESTING "Include and build unit tests" ON)
|
||||
|
||||
IF(BUILD_TESTING)
|
||||
SET(OVT_LOG_DIR "${CMAKE_BINARY_DIR}/test/log" CACHE PATH "Path to directory containing test logs")
|
||||
SET(OVT_TEST_DATA_DIR "${OV_CUSTOM_DEPENDENCIES_PATH}/test-input" CACHE PATH "Path to test input data files")
|
||||
ENDIF()
|
||||
|
||||
# add the scripts to the project so IDEs using the CMake file are aware of them
|
||||
FILE(GLOB_RECURSE script_files scripts/*.cmd scripts/*.sh scripts/*.nsi scripts/*.cmake)
|
||||
INSTALL(FILES scripts/AddOpenViBESDKComponents.cmake DESTINATION ${DIST_DATADIR})
|
||||
ADD_CUSTOM_TARGET(openvibe-scripts SOURCES ${script_files})
|
||||
|
||||
# Enable/Disable unit test
|
||||
SET(BUILD_UNIT_TEST true CACHE BOOL "Set this flag to true/false to enable/disable unit test building")
|
||||
SET(BUILD_VALIDATION_TEST true CACHE BOOL "Set this flag to true/false to enable/disable validation test building")
|
||||
|
||||
IF(BUILD_UNIT_TEST)
|
||||
ADD_SUBDIRECTORY("unit-test/")
|
||||
ENDIF()
|
||||
IF(BUILD_VALIDATION_TEST)
|
||||
ADD_SUBDIRECTORY("validation-test/")
|
||||
ENDIF()
|
||||
@@ -0,0 +1,661 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
@@ -0,0 +1,46 @@
|
||||
# This file is an example configuration of OpenViBE build system
|
||||
# By default all changes are disabled, you can un-comment any that are of interest to you
|
||||
# In order to use the file make a copy of it an rename it "CustomCMakeLists.txt"
|
||||
|
||||
# ----------------------------------
|
||||
# USEFUL ELEMENTS
|
||||
# ----------------------------------
|
||||
|
||||
# Uncomment the following to build documentation
|
||||
# both the global project and the specific projects are affected by this token
|
||||
#SET(SKIP_DOCUMENTATION OFF)
|
||||
|
||||
# ----------------------------------
|
||||
# OPENVIBE
|
||||
# ----------------------------------
|
||||
|
||||
# Optionally skip whole projects
|
||||
#SET(SKIP_KERNEL ON)
|
||||
#SET(SKIP_MODULES ON)
|
||||
#SET(SKIP_OPENVIBE ON)
|
||||
#SET(SKIP_PLUGINS ON)
|
||||
#SET(SKIP_TOOLKIT ON)
|
||||
|
||||
# Optionally disable (or re-enable) Modules
|
||||
#SET(SKIP_MODULES_EBML ON)
|
||||
#SET(SKIP_MODULES_FS ON)
|
||||
#SET(SKIP_MODULES_SOCKET ON)
|
||||
#SET(SKIP_MODULES_STREAM OFF)
|
||||
#SET(SKIP_MODULES_SYSTEM ON)
|
||||
#SET(SKIP_MODULES_XML ON)
|
||||
|
||||
# Optionally skip Processing Plugins
|
||||
#SET(SKIP_PLUGINS_PROCESSING_ACQUISITION ON)
|
||||
#SET(SKIP_PLUGINS_PROCESSING_CLASIFICATION ON)
|
||||
#SET(SKIP_PLUGINS_PROCESSING_EXAMPLES ON)
|
||||
#SET(SKIP_PLUGINS_PROCESSING_FILE-IO ON)
|
||||
#SET(SKIP_PLUGINS_PROCESSING_NETWORK-IO ON)
|
||||
#SET(SKIP_PLUGINS_PROCESSING_SAMPLES ON)
|
||||
#SET(SKIP_PLUGINS_PROCESSING_SIGNAL-PROCESSING ON)
|
||||
#SET(SKIP_PLUGINS_PROCESSING_SIMPLE-VISUALISATION ON)
|
||||
#SET(SKIP_PLUGINS_PROCESSING_STIMULATION ON)
|
||||
#SET(SKIP_PLUGINS_PROCESSING_STREAM-CODECS ON)
|
||||
#SET(SKIP_PLUGINS_PROCESSING_STREAMING ON)
|
||||
#SET(SKIP_PLUGINS_PROCESSING_TOOLS ON)
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
Dependencies
|
||||
============
|
||||
|
||||
Linux Ubuntu (14.04 and 16.04)
|
||||
-----------------------------
|
||||
- Install the dependencies
|
||||
- run `linux-install-dependencies.pl` script; you will require sudo rights
|
||||
- run `unix-get-dependencies.sh` script with an existing `DEPENDENCY_CACHE` environment variable or with --cache parameter (OPTIONAL - for tests),
|
||||
or with `PROXYPASS`
|
||||
|
||||
|
||||
Windows 7 and later
|
||||
-------------------
|
||||
- Install the dependencies:
|
||||
- copy `windows-install-dependencies.cmd` and rename copy to `windows-install-dependencies-custom.cmd`
|
||||
- edit line `set PROXYPASS=XXX:XXX` with appropriate username and password
|
||||
- run it whenever you want to update dependencies.
|
||||
|
||||
|
||||
Install
|
||||
=======
|
||||
|
||||
Linux Ubuntu (14.04)
|
||||
--------------------
|
||||
- Build the sofware
|
||||
- run `unix-build` script, and append `--build-unit` and/or `--build-validation` if you want to build tests
|
||||
- Run unit tests
|
||||
- run `ctest-launcher.sh` from the build directory
|
||||
|
||||
|
||||
Windows 7 and later
|
||||
-------------------
|
||||
- Build the sofware
|
||||
- run `windows-build.cmd` script, and append `--build-unit` and/or `--build-validation` if you want to build tests
|
||||
- Run unit tests
|
||||
- run `ctest-launcher.cmd` from the build directory
|
||||
|
||||
|
||||
Building Documentation
|
||||
======================
|
||||
|
||||
Documentation Dependencies
|
||||
--------------------------
|
||||
|
||||
The documentation is build by the sphinx tool and has following dependencies:
|
||||
|
||||
* Python
|
||||
* sphinx
|
||||
* sphinx_rtd_theme
|
||||
|
||||
The best way to have these dependencies ready is to use a virtualenv in order to make an environment containing these.
|
||||
|
||||
Assuming you have virtualenv installed the commands would be:
|
||||
|
||||
First time:
|
||||
|
||||
mkdir -p ~/virtualenvs
|
||||
virutalenv ~/virtualenvs/openvibe-doc
|
||||
source ~/virtualenvs/openvibe-doc/bin/activate
|
||||
pip install sphinx sphinx_rtd_theme
|
||||
|
||||
or on windows
|
||||
|
||||
md %USERPROFILE%\virtualenvs
|
||||
virtualenv %USERPROFILE%\virtualenvs\openvibe-doc
|
||||
%USERPROFILE%\virtualenvs\openvibe-doc\Scripts\activate.bat
|
||||
pip install sphinx sphinx_rtd_theme
|
||||
|
||||
once the environment is created you only need to execute the third line to activate it.
|
||||
|
||||
Documentation Building
|
||||
----------------------
|
||||
|
||||
The documentation main files reside in documentation/sphinx folder and is constructed in the following fashion:
|
||||
|
||||
1. During the CMake step documentation files are pooled in the dist/doc-tmp/sphinx folder
|
||||
* The files come from the documentation/sphinx folder and from the plugins `boxes` folders
|
||||
2. The documentation will generate a build-documentation script inside the doc-tmp folder which
|
||||
has to be launched manually.
|
||||
3. The documentation will be generated in the `doc-tmp/sphinx/build` folder and moved to
|
||||
`doc/OpenViBE Manual`
|
||||
|
||||
Extending Documentation
|
||||
-----------------------
|
||||
|
||||
If you wish to build a documentation that extends what is already in the SDK you can do so by adding files
|
||||
into the doc-tmp folder and overwriting indexes.
|
||||
|
||||
A few remarks:
|
||||
|
||||
The main index file is in `doc-tmp/sphinx/source/index.rst` and should almost always be overwritten if you
|
||||
need to add something to the documentation.
|
||||
|
||||
Box list is in `doc-tmp/sphinx/source/boxes/index-boxes.rst`. The plugin-inspector can generate this file
|
||||
for you using the `openvibe-plugin-inspector --box-doc-directory <WHERE>` template. It will also generate
|
||||
templates for all boxes that can be loaded by the kernel.
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
OpenViBE SDK is a core software platform for the design, test and use of
|
||||
Brain-Computer Interfaces. It aims to have a certifiable kernel to be used in
|
||||
medical devices.
|
||||
|
||||
Repository organisation
|
||||
=======================
|
||||
|
||||
The project repository is composed of several software modules.
|
||||
The repository basically looks like this :
|
||||
|
||||
```
|
||||
+ <openvibe> (API / specifications)
|
||||
+ <kernel> (kernel implementation)
|
||||
+ <toolkit> (development help components)
|
||||
+ <applications> (OpenViBE user applications)
|
||||
+ <plugins> (OpenViBE plugin collections)
|
||||
+ <samples>
|
||||
+ <acquisition>
|
||||
+ ...
|
||||
+ <modules> (abstraction and portability components)
|
||||
+ <ebml>
|
||||
+ <socket>
|
||||
+ ...
|
||||
+-- cmake-modules (cmake FindXXX and helpers)
|
||||
+ <data>
|
||||
+ <openvibe> (configuration data)
|
||||
+ <resources> (test resources)
|
||||
+ <scripts>
|
||||
+ <unit-test> (code-level unit tests)
|
||||
+ <unit-toolkit> (internal unit testing framework)
|
||||
+ <validation-test> (integration/validation tests)
|
||||
+ <python-toolkit>
|
||||
```
|
||||
|
||||
Each software module is organized as a UNIX-like tree (empty folders not
|
||||
included):
|
||||
|
||||
```
|
||||
+ <bin> (any pre-compiled binaries)
|
||||
+ <include> (target folder for API headers)
|
||||
+ <lib> (any pre-compiled libraries)
|
||||
+ <share> (shared file folder for all data)
|
||||
+ <src> (source code of the module)
|
||||
+ <doc> (documentation files for the module)
|
||||
+ <test> (unit test source code for the module)
|
||||
```
|
||||
|
||||
Copying
|
||||
=======
|
||||
|
||||
Please refer to the COPYING.md file to get details regarding the OpenViBE license.
|
||||
|
||||
Install
|
||||
=======
|
||||
|
||||
Please refer to the INSTALL.md file for instructions on how to build the
|
||||
platform.
|
||||
|
||||
|
||||
Naming rules
|
||||
============
|
||||
|
||||
WARNING: These are the initial naming rules of the project. For an
|
||||
updated version, pleaser refer to OpenViBE Coding Rules.
|
||||
|
||||
#### CMake
|
||||
|
||||
- Openvibe-related variable: OV_MY_VARIABLE
|
||||
- Test-related variable: OVT_MY_VARIABLE
|
||||
|
||||
#### Tools
|
||||
|
||||
- CMake project and target name: openvibe-test-*mytool* (e.g. *openvibe-test-accuracy*)
|
||||
- File name: ovt + OpenViBE naming rules
|
||||
- Main namespace: OpenViBE::Test
|
||||
- Macro naming: OVT_MYMACRO
|
||||
|
||||
#### Unit Tests
|
||||
|
||||
- OpenViBE tested modules: module (e.g. *openvibe-kernel*)
|
||||
- Unit test directory name: module (e.g. *openvibe-kernel*)
|
||||
- CMake target name: module-test (e.g. *openvibe-kernel-test*)
|
||||
- Test file name: uo/ur + test identifier + Test (e.g. *uoKernelContextTest.cpp*)
|
||||
- u = unit
|
||||
- o = open (used for public test transferred from open-source OpenViBE)
|
||||
- r = restricted (used for test implemented within OpenViBE SDK project)
|
||||
- Test name: identical to file name
|
||||
|
||||
#### Validation Tests
|
||||
|
||||
- OpenViBE tested module: module (e.g. *openvibe-plugins-classification*)
|
||||
- Validation test directory: module (e.g. *openvibe-plugins-classification*)
|
||||
- CMake target name: module-test (e.g *openvibe-plugins-classification-test*)
|
||||
- Test name: vo/vr + module identifier + test identifier + Test (e.g. *voClassificationLDATest*)
|
||||
- v = validation
|
||||
- o/r: see Unit Tests
|
||||
|
||||
#### Headers
|
||||
|
||||
Use AGPL-3 header for public tests and confidential header for private tests.
|
||||
|
||||
Contribution
|
||||
============
|
||||
|
||||
### Adding Unit Test
|
||||
|
||||
#### Add Tests to Existing Driver
|
||||
|
||||
To add tests to a module that is already tested, just add the test file and modify the test driver CMakeLists.txt accordingly.
|
||||
|
||||
#### Creating a Test Driver
|
||||
|
||||
If you wish to test a new module, you will have to create a new test driver in unit-test/.
|
||||
|
||||
Create a new directory with some tests and a CMakeLists.txt (just look at other tests to get insights on tests structure).
|
||||
|
||||
Add driver directory to directory to be processed in root directory CMakeLists.txt.
|
||||
|
||||
### Updating CTest Validation Test
|
||||
|
||||
#### Enhance Existing Test
|
||||
|
||||
Just add data in the test directory and modify test CMakeLists.txt accordingly.
|
||||
|
||||
#### Add New Test
|
||||
|
||||
There should be no reason to add ctest validation tests. New validation tests use Robot Framework.
|
||||
@FIXME CERT Rename repository ?
|
||||
Check "Adding Robot Framework Test" section in certivibe-test repository for more details.
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
# Add all the subdirs as projects of the named branch
|
||||
OV_ADD_PROJECTS("APPLICATIONS")
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
# Add all the subdirs as projects of the named branch
|
||||
OV_ADD_PROJECTS("APPLICATIONS_DEVELOPER-TOOLS")
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
PROJECT(openvibe-id-generator)
|
||||
|
||||
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
|
||||
SET(PROJECT_VERSION_MINOR ${OV_GLOBAL_VERSION_MINOR})
|
||||
SET(PROJECT_VERSION_PATCH ${OV_GLOBAL_VERSION_PATCH})
|
||||
SET(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
|
||||
|
||||
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.inl)
|
||||
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILES})
|
||||
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${APP_FOLDER})
|
||||
|
||||
# ---------------------------------
|
||||
# Target macros
|
||||
# Defines target operating system, architecture and compiler
|
||||
# ---------------------------------
|
||||
SET_BUILD_PLATFORM()
|
||||
|
||||
# ----------------------
|
||||
# Generate launch script
|
||||
# ----------------------
|
||||
OV_INSTALL_LAUNCH_SCRIPT(SCRIPT_PREFIX "openvibe-id-generator" EXECUTABLE_NAME "${PROJECT_NAME}" PAUSE)
|
||||
|
||||
# -----------------------------
|
||||
# Install files
|
||||
# -----------------------------
|
||||
INSTALL(TARGETS ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION ${DIST_BINDIR}
|
||||
LIBRARY DESTINATION ${DIST_LIBDIR}
|
||||
ARCHIVE DESTINATION ${DIST_LIBDIR})
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
int main(int /*argc*/, char** /*argv*/)
|
||||
{
|
||||
std::random_device rd;
|
||||
std::default_random_engine rng(rd());
|
||||
std::uniform_int_distribution<size_t> uni(0, std::numeric_limits<size_t>::max() - 1);
|
||||
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
const uint32_t v1 = uni(rng), v2 = uni(rng);
|
||||
std::stringstream ss;
|
||||
ss.fill('0');
|
||||
ss << "(0x" << std::setw(8) << std::hex << v1 << ", 0x" << std::setw(8) << std::hex << v2 << ")";
|
||||
std::cout << "#define OV_ClassId_\t\t\tOpenViBE::CIdentifier" << ss.str() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
#######################################################################
|
||||
# Software License Agreement (AGPL-3 License)
|
||||
#
|
||||
# OpenViBE SDK Test Software
|
||||
# Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
# Copyright (C) Inria, 2015-2017,V1.0
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License version 3,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program.
|
||||
# If not, see <http://www.gnu.org/licenses/>.
|
||||
#######################################################################
|
||||
|
||||
PROJECT(openvibe-plugin-inspector)
|
||||
|
||||
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h)
|
||||
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILES})
|
||||
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${APP_FOLDER})
|
||||
|
||||
INCLUDE("FindOpenViBE")
|
||||
INCLUDE("FindOpenViBECommon")
|
||||
INCLUDE("FindOpenViBEToolkit")
|
||||
INCLUDE("FindOpenViBEModuleSystem")
|
||||
INCLUDE("FindOpenViBEModuleFS")
|
||||
INCLUDE("FindThirdPartyBoost")
|
||||
|
||||
# ---------------------------------
|
||||
# Target macros
|
||||
# Defines target operating system, architecture and compiler
|
||||
# ---------------------------------
|
||||
SET_BUILD_PLATFORM()
|
||||
|
||||
# -----------------------------
|
||||
# Install files
|
||||
# -----------------------------
|
||||
INSTALL(TARGETS ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION ${DIST_BINDIR}
|
||||
LIBRARY DESTINATION ${DIST_LIBDIR}
|
||||
ARCHIVE DESTINATION ${DIST_LIBDIR})
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
#include "ovpiCPluginObjectDescEnum.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace PluginInspector {
|
||||
|
||||
// Enumerate plugins by iterating over a user defined list of descriptors, used for metaboxes
|
||||
bool CPluginObjectDescEnum::enumeratePluginObjectDesc(std::vector<const Plugins::IPluginObjectDesc*>& pod)
|
||||
{
|
||||
for (auto* plugin : pod) { this->callback(*plugin); }
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPluginObjectDescEnum::enumeratePluginObjectDesc(const CIdentifier& parentClassID)
|
||||
{
|
||||
CIdentifier id;
|
||||
while ((id = m_kernelCtx.getPluginManager().getNextPluginObjectDescIdentifier(id, parentClassID)) != CIdentifier::undefined())
|
||||
{
|
||||
this->callback(*m_kernelCtx.getPluginManager().getPluginObjectDesc(id));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string CPluginObjectDescEnum::transform(const std::string& in, const bool removeSlash)
|
||||
{
|
||||
std::string out;
|
||||
bool wasLastASeparator = true;
|
||||
|
||||
for (size_t i = 0; i < in.length(); ++i)
|
||||
{
|
||||
if ((in[i] >= 'a' && in[i] <= 'z') || (in[i] >= 'A' && in[i] <= 'Z') || (in[i] >= '0' && in[i] <= '9') || (!removeSlash && in[i] == '/'))
|
||||
{
|
||||
if (in[i] == '/') { out += "_"; }
|
||||
else
|
||||
{
|
||||
if (wasLastASeparator)
|
||||
{
|
||||
if ('a' <= in[i] && in[i] <= 'z') { out += in[i] + 'A' - 'a'; }
|
||||
else { out += in[i]; }
|
||||
}
|
||||
else { out += in[i]; }
|
||||
}
|
||||
wasLastASeparator = false;
|
||||
}
|
||||
else { wasLastASeparator = true; }
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace PluginInspector
|
||||
} // namespace OpenViBE
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace PluginInspector {
|
||||
class CPluginObjectDescEnum
|
||||
{
|
||||
public:
|
||||
|
||||
explicit CPluginObjectDescEnum(const Kernel::IKernelContext& ctx) : m_kernelCtx(ctx) { }
|
||||
virtual ~CPluginObjectDescEnum() { }
|
||||
|
||||
virtual bool enumeratePluginObjectDesc(std::vector<const Plugins::IPluginObjectDesc*>& pod);
|
||||
virtual bool enumeratePluginObjectDesc(const CIdentifier& parentClassID);
|
||||
|
||||
virtual bool callback(const Plugins::IPluginObjectDesc& pod) = 0;
|
||||
|
||||
static std::string transform(const std::string& in, bool removeSlash = false);
|
||||
|
||||
protected:
|
||||
|
||||
const Kernel::IKernelContext& m_kernelCtx;
|
||||
};
|
||||
} // namespace PluginInspector
|
||||
} // namespace OpenViBE
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
#include "ovpiCPluginObjectDescEnumBoxTemplateGenerator.h"
|
||||
|
||||
#include <system/ovCTime.h>
|
||||
#include <fs/Files.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace PluginInspector {
|
||||
|
||||
static std::map<int, char> indentCharacters = { { 0, '=' }, { 1, '-' }, { 2, '~' }, { 3, '+' } };
|
||||
static std::string generateRstTitle(const std::string& title, const int level)
|
||||
{
|
||||
return title + "\n" + std::string(title.size(), indentCharacters[level]) + "\n";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------
|
||||
bool CPluginObjectDescEnumBoxTemplateGenerator::initialize()
|
||||
{
|
||||
if (!m_kernelCtx.getScenarioManager().createScenario(m_scenarioID)) { return false; }
|
||||
m_scenario = &m_kernelCtx.getScenarioManager().getScenario(m_scenarioID);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------
|
||||
bool CPluginObjectDescEnumBoxTemplateGenerator::uninitialize()
|
||||
{
|
||||
if (!m_kernelCtx.getScenarioManager().releaseScenario(m_scenarioID)) { return false; }
|
||||
|
||||
std::ofstream ofBoxIdx;
|
||||
FS::Files::openOFStream(ofBoxIdx, (m_docTemplateDirectory + "/index-boxes.rst").c_str());
|
||||
|
||||
if (!ofBoxIdx.good())
|
||||
{
|
||||
m_kernelCtx.getLogManager() << Kernel::LogLevel_Error << "Error while trying to open file [" << (m_docTemplateDirectory + "/index-boxes.rst").c_str() <<
|
||||
"]\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
ofBoxIdx << ".. _Doc_BoxAlgorithms:\n\n" << generateRstTitle("Boxes list", 0) << "\nAvailable box algorithms are :\n\n" << generateRstIndex(m_categories) <<
|
||||
" \n";
|
||||
|
||||
if (!m_deprecatedBoxesCategories.empty())
|
||||
{
|
||||
ofBoxIdx << "\n\n" << generateRstTitle("Deprecated boxes list", 0) <<
|
||||
"\nThe following boxes are deprecated, they are hidden in Studio and will be removed soon or later, so you should consider not using them:\n"
|
||||
<< generateRstIndex(m_deprecatedBoxesCategories) << " \n";
|
||||
}
|
||||
|
||||
ofBoxIdx << " \n";
|
||||
ofBoxIdx.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------
|
||||
bool CPluginObjectDescEnumBoxTemplateGenerator::callback(const Plugins::IPluginObjectDesc& pod)
|
||||
{
|
||||
const std::string fileName = "BoxAlgorithm_" + transform(pod.getName().toASCIIString());
|
||||
CIdentifier boxID;
|
||||
|
||||
if (pod.getCreatedClass() == OVP_ClassId_BoxAlgorithm_Metabox)
|
||||
{
|
||||
// insert a box into the scenario, initialize it from the proxy-descriptor from the metabox loader
|
||||
if (!m_scenario->addBox(boxID, dynamic_cast<const Plugins::IBoxAlgorithmDesc&>(pod), CIdentifier::undefined()))
|
||||
{
|
||||
m_kernelCtx.getLogManager() << Kernel::LogLevel_Warning << "Skipped [" << fileName << "] (could not create corresponding box)\n";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (!m_scenario->addBox(boxID, pod.getCreatedClassIdentifier(), CIdentifier::undefined()))
|
||||
{
|
||||
m_kernelCtx.getLogManager() << Kernel::LogLevel_Warning << "Skipped [" << fileName << "] (could not create corresponding box)\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Kernel::IBox& box = *m_scenario->getBoxDetails(boxID);
|
||||
|
||||
m_kernelCtx.getLogManager() << Kernel::LogLevel_Trace << "Working on [" << fileName << "]\n";
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
std::ofstream ofs;
|
||||
FS::Files::openOFStream(ofs, (m_docTemplateDirectory + "/Doc_" + fileName + ".rst-template").c_str());
|
||||
|
||||
if (!ofs.good())
|
||||
{
|
||||
m_kernelCtx.getLogManager() << Kernel::LogLevel_Error << "Error while trying to open file ["
|
||||
<< (m_docTemplateDirectory + "/Doc_" + fileName + ".rst-template").c_str()
|
||||
<< "]\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
ofs << ".. _Doc_" << fileName << ":\n\n" << generateRstTitle(pod.getName().toASCIIString(), 0)
|
||||
<< "\n.. container:: attribution\n\n :Author:\n " << pod.getAuthorName().toASCIIString() << "\n"
|
||||
<< " :Company:\n " << pod.getAuthorCompanyName().toASCIIString() << "\n\n\n"
|
||||
<< ".. todo:: Write general box description...\n\n\n";
|
||||
|
||||
|
||||
if (box.getInputCount())
|
||||
{
|
||||
ofs << ".. _Doc_" << fileName << "_Inputs:\n\n" << generateRstTitle("Inputs", 1).c_str()
|
||||
<< ".. todo:: Write general input description...\n\n.. csv-table::\n :header: \"Input Name\", \"Stream Type\"\n\n";
|
||||
|
||||
std::vector<CString> inputNames(box.getInputCount());
|
||||
for (size_t i = 0; i < box.getInputCount(); ++i)
|
||||
{
|
||||
CIdentifier typeID;
|
||||
box.getInputName(i, inputNames[i]);
|
||||
box.getInputType(i, typeID);
|
||||
CString typeName = m_kernelCtx.getTypeManager().getTypeName(typeID);
|
||||
|
||||
ofs << " \"" << inputNames[i] << "\", \"" << typeName << "\"\n";
|
||||
}
|
||||
size_t index = 1;
|
||||
for (const auto& name : inputNames)
|
||||
{
|
||||
ofs << "\n.. _Doc_" << fileName << "_Input_" << index << ":\n\n" << generateRstTitle(name.toASCIIString(), 2)
|
||||
<< "\n.. todo:: Write input description...\n\n\n";
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (box.getOutputCount())
|
||||
{
|
||||
ofs << ".. _Doc_" << fileName << "_Outputs:\n\n" << generateRstTitle("Outputs", 1)
|
||||
<< "\n.. todo:: Write general output description...\n\n.. csv-table::\n :header: \"Output Name\", \"Stream Type\"\n\n";
|
||||
|
||||
std::vector<CString> outputNames(box.getOutputCount());
|
||||
for (size_t i = 0; i < box.getOutputCount(); ++i)
|
||||
{
|
||||
CIdentifier typeID;
|
||||
box.getOutputName(i, outputNames[i]);
|
||||
box.getOutputType(i, typeID);
|
||||
CString typeName = m_kernelCtx.getTypeManager().getTypeName(typeID);
|
||||
|
||||
ofs << " \"" << outputNames[i] << "\", \"" << typeName << "\"\n";
|
||||
}
|
||||
size_t index = 1;
|
||||
for (const auto& outputName : outputNames)
|
||||
{
|
||||
ofs << "\n.. _Doc_" << fileName << "_Output_" << index << ":\n\n" << generateRstTitle(outputName.toASCIIString(), 2)
|
||||
<< "\n.. todo:: Write output description...\n\n\n";
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (box.getSettingCount())
|
||||
{
|
||||
ofs << ".. _Doc_" << fileName << "_Settings:\n\n" << generateRstTitle("Settings", 1) << "\n"
|
||||
<< ".. todo:: Write settings general description...\n\n.. csv-table::\n :header: \"Setting Name\", \"Type\", \"Default Value\"\n\n";
|
||||
|
||||
std::vector<CString> settingsNames(box.getSettingCount());
|
||||
for (size_t i = 0; i < box.getSettingCount(); ++i)
|
||||
{
|
||||
CIdentifier typeID;
|
||||
CString defaultValue;
|
||||
box.getSettingName(i, settingsNames[i]);
|
||||
box.getSettingType(i, typeID);
|
||||
box.getSettingDefaultValue(i, defaultValue);
|
||||
CString typeName = m_kernelCtx.getTypeManager().getTypeName(typeID);
|
||||
|
||||
ofs << " \"" << settingsNames[i] << "\", \"" << typeName << "\", \"" << defaultValue << "\"\n";
|
||||
}
|
||||
size_t index = 1;
|
||||
for (const auto& name : settingsNames)
|
||||
{
|
||||
ofs << "\n.. _Doc_" << fileName << "_Setting_" << index << ":\n\n" << generateRstTitle(name.toASCIIString(), 2)
|
||||
<< "\n.. todo:: Write setting description... \n\n\n";
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
ofs << ".. _Doc_" << fileName << "_Examples:\n\n" << generateRstTitle("Examples", 1)
|
||||
<< "\n.. todo:: Write example of use...\n\n\n";
|
||||
|
||||
ofs << ".. _Doc_" << fileName << "_Miscellaneous:\n\n" << generateRstTitle("Miscellaneous", 1)
|
||||
<< "\n.. todo:: Write any miscellaneous information...\n\n\n";
|
||||
|
||||
ofs.close();
|
||||
|
||||
// m_categories is used to generate the list of boxes. Documentation for deprecated boxes
|
||||
// should remain available if needed but not be listed
|
||||
if (m_kernelCtx.getPluginManager().isPluginObjectFlaggedAsDeprecated(box.getAlgorithmClassIdentifier()))
|
||||
{
|
||||
m_deprecatedBoxesCategories.push_back(std::pair<std::string, std::string>(pod.getCategory().toASCIIString(), pod.getName().toASCIIString()));
|
||||
}
|
||||
else { m_categories.push_back(std::pair<std::string, std::string>(pod.getCategory().toASCIIString(), pod.getName().toASCIIString())); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------
|
||||
std::string CPluginObjectDescEnumBoxTemplateGenerator::generateRstIndex(std::vector<std::pair<std::string, std::string>> categories) const
|
||||
{
|
||||
std::string res;
|
||||
|
||||
std::string lastCategoryName;
|
||||
std::vector<std::string> lastSplittedCategories;
|
||||
std::sort(categories.begin(), categories.end());
|
||||
|
||||
for (auto& category : categories)
|
||||
{
|
||||
std::string categoryName = category.first;
|
||||
std::string name = category.second;
|
||||
|
||||
if (lastCategoryName != categoryName)
|
||||
{
|
||||
std::vector<std::string> splittedCategories;
|
||||
size_t i = size_t(-1);
|
||||
bool isFinished = false;
|
||||
while (!isFinished)
|
||||
{
|
||||
size_t j = categoryName.find('/', i + 1);
|
||||
if (j == std::string::npos)
|
||||
{
|
||||
j = categoryName.length();
|
||||
isFinished = true;
|
||||
}
|
||||
if (j != i + 1)
|
||||
{
|
||||
splittedCategories.push_back(categoryName.substr(i + 1, j - i - 1));
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
auto itLast = lastSplittedCategories.begin();
|
||||
auto it1 = splittedCategories.begin();
|
||||
for (; itLast != lastSplittedCategories.end() && it1 != splittedCategories.end() && *itLast == *it1; ++itLast, ++it1) { }
|
||||
|
||||
for (; it1 != splittedCategories.end(); ++it1)
|
||||
{
|
||||
size_t level = 1;
|
||||
for (auto it2 = splittedCategories.begin(); it2 != it1; ++it2) { level++; }
|
||||
res += "\n\n" + generateRstTitle(*it1, int(level)) + "\n.. toctree::\n :maxdepth: 1\n\n";
|
||||
}
|
||||
|
||||
lastCategoryName = categoryName;
|
||||
lastSplittedCategories = splittedCategories;
|
||||
}
|
||||
|
||||
res += " Doc_BoxAlgorithm_" + transform(name) + "\n";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace PluginInspector
|
||||
} // namespace OpenViBE
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "ovpiCPluginObjectDescEnum.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace PluginInspector {
|
||||
class CPluginObjectDescEnumBoxTemplateGenerator final : public CPluginObjectDescEnum
|
||||
{
|
||||
public:
|
||||
|
||||
CPluginObjectDescEnumBoxTemplateGenerator(const Kernel::IKernelContext& ctx, const std::string& docTemplateDir)
|
||||
: CPluginObjectDescEnum(ctx), m_docTemplateDirectory(docTemplateDir) {}
|
||||
|
||||
bool callback(const Plugins::IPluginObjectDesc& pod) override;
|
||||
bool initialize();
|
||||
bool uninitialize();
|
||||
|
||||
private:
|
||||
// Return a string that correspond to the indexed categories under rst format
|
||||
std::string generateRstIndex(std::vector<std::pair<std::string, std::string>> categories) const;
|
||||
|
||||
protected:
|
||||
|
||||
std::string m_docTemplateDirectory;
|
||||
std::vector<std::pair<std::string, std::string>> m_categories;
|
||||
std::vector<std::pair<std::string, std::string>> m_deprecatedBoxesCategories;
|
||||
CIdentifier m_scenarioID = CIdentifier::undefined();
|
||||
Kernel::IScenario* m_scenario = nullptr;
|
||||
};
|
||||
} // namespace PluginInspector
|
||||
} // namespace OpenViBE
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
#include "ovpiCPluginObjectDescEnumBoxTemplateGenerator.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
#include <fs/Files.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
/*
|
||||
USAGE:
|
||||
plugin-inspector <plugin1 plugin2 ...>
|
||||
<--box-doc-directory dir>
|
||||
*/
|
||||
|
||||
std::vector<std::string> pluginFilestoLoad;
|
||||
|
||||
std::string docTemplateDir;
|
||||
bool ignoreMetaboxes = false;
|
||||
std::vector<std::string> metaboxExtensionsToLoad;
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0)
|
||||
{
|
||||
std::cout << "[ USAGE ]\n" << "plugin-inspector <plugin1 plugin2 ...>\n" << " <--box-doc-directory dir>\n";
|
||||
return 0;
|
||||
}
|
||||
std::cout << "Analyze parameter: [" << i << " : " << argv[i] << "]." << std::endl;
|
||||
|
||||
if (strcmp(argv[i], "--ignore-metaboxes") == 0) { ignoreMetaboxes = true; }
|
||||
else if (i < argc && strcmp(argv[i], "--box-doc-directory") == 0)
|
||||
{
|
||||
if (++i >= argc)
|
||||
{
|
||||
std::cout << "[ FAILED ] Error while parsing arguments: --box-doc-directory flag found but no path specified afterwards." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
docTemplateDir = argv[i];
|
||||
std::cout << "Templates will be generated in folder: [" << docTemplateDir << "]." << std::endl;
|
||||
}
|
||||
else if (i < argc) { pluginFilestoLoad.push_back(std::string(argv[i])); }
|
||||
}
|
||||
|
||||
OpenViBE::CKernelLoader kernelLoader;
|
||||
|
||||
std::cout << "[ INF ] Created kernel loader, trying to load kernel module" << std::endl;
|
||||
OpenViBE::CString errorMsg;
|
||||
#if defined TARGET_OS_Windows
|
||||
const OpenViBE::CString kernelFile = OpenViBE::Directories::getLibDir() + "/openvibe-kernel.dll";
|
||||
#elif defined TARGET_OS_Linux
|
||||
const OpenViBE::CString kernelFile = OpenViBE::Directories::getLibDir() + "/libopenvibe-kernel.so";
|
||||
#elif defined TARGET_OS_MacOS
|
||||
const OpenViBE::CString kernelFile = OpenViBE::Directories::getLibDir() + "/libopenvibe-kernel.dylib";
|
||||
#endif
|
||||
|
||||
if (!kernelLoader.load(kernelFile, &errorMsg)) { std::cout << "[ FAILED ] Error loading kernel (" << errorMsg << ")" << " from [" << kernelFile << "]\n"; }
|
||||
else
|
||||
{
|
||||
std::cout << "[ INF ] Kernel module loaded, trying to get kernel descriptor" << std::endl;
|
||||
OpenViBE::Kernel::IKernelDesc* kernelDesc = nullptr;
|
||||
kernelLoader.initialize();
|
||||
kernelLoader.getKernelDesc(kernelDesc);
|
||||
if (!kernelDesc) { std::cout << "[ FAILED ] No kernel descriptor" << std::endl; }
|
||||
else
|
||||
{
|
||||
std::cout << "[ INF ] Got kernel descriptor, trying to create kernel" << std::endl;
|
||||
|
||||
OpenViBE::Kernel::IKernelContext* ctx = kernelDesc->createKernel("plugin-inspector", OpenViBE::Directories::getDataDir() + "/kernel/openvibe.conf");
|
||||
if (!ctx) { std::cout << "[ FAILED ] No kernel created by kernel descriptor" << std::endl; }
|
||||
else
|
||||
{
|
||||
ctx->initialize();
|
||||
OpenViBE::Toolkit::initialize(*ctx);
|
||||
|
||||
OpenViBE::Kernel::IConfigurationManager& configurationManager = ctx->getConfigurationManager();
|
||||
|
||||
if (pluginFilestoLoad.empty()) { ctx->getPluginManager().addPluginsFromFiles(configurationManager.expand("${Kernel_Plugins}")); }
|
||||
else
|
||||
{
|
||||
for (const std::string& file : pluginFilestoLoad)
|
||||
{
|
||||
ctx->getPluginManager().addPluginsFromFiles(configurationManager.expand(OpenViBE::CString(file.c_str())));
|
||||
}
|
||||
}
|
||||
|
||||
ctx->getLogManager() << OpenViBE::Kernel::LogLevel_Info << "[ INF ] Generate boxes templates in [" << docTemplateDir << "]\n";
|
||||
|
||||
OpenViBE::PluginInspector::CPluginObjectDescEnumBoxTemplateGenerator boxTemplateGenerator(*ctx, std::string(docTemplateDir));
|
||||
if (!boxTemplateGenerator.initialize())
|
||||
{
|
||||
std::cout << "[ FAILED ] Could not initialize boxTemplateGenerator" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
boxTemplateGenerator.enumeratePluginObjectDesc(OV_ClassId_Plugins_BoxAlgorithmDesc);
|
||||
|
||||
if (!ignoreMetaboxes)
|
||||
{
|
||||
ctx->getLogManager() << OpenViBE::Kernel::LogLevel_Info << "[ INF ] Generate metaboxes templates in [" << docTemplateDir << "]\n";
|
||||
// Do not load the binary metaboxes as they would only be duplicated
|
||||
//ctx->getScenarioManager().unregisterScenarioImporter(OV_ScenarioImportContext_OnLoadMetaboxImport, ".mbb");
|
||||
configurationManager.addOrReplaceConfigurationToken("Kernel_Metabox", "${Path_Data}/metaboxes/");
|
||||
|
||||
ctx->getMetaboxManager().addMetaboxesFromFiles(configurationManager.expand("${Kernel_Metabox}"));
|
||||
|
||||
// Create a list of metabox descriptors from the Map provided by the MetaboxLoader and enumerate all algorithms within
|
||||
std::vector<const OpenViBE::Plugins::IPluginObjectDesc*> metaboxPluginObjectDescriptors;
|
||||
OpenViBE::CIdentifier id;
|
||||
while ((id = ctx->getMetaboxManager().getNextMetaboxObjectDescIdentifier(id)) != OpenViBE::CIdentifier::undefined())
|
||||
{
|
||||
metaboxPluginObjectDescriptors.push_back(ctx->getMetaboxManager().getMetaboxObjectDesc(id));
|
||||
}
|
||||
boxTemplateGenerator.enumeratePluginObjectDesc(metaboxPluginObjectDescriptors);
|
||||
}
|
||||
|
||||
if (!boxTemplateGenerator.uninitialize())
|
||||
{
|
||||
std::cout << "[ FAILED ] Could not uninitialize boxTemplateGenerator" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
ctx->getLogManager() << OpenViBE::Kernel::LogLevel_Info << "Application terminated, releasing allocated objects \n";
|
||||
|
||||
OpenViBE::Toolkit::uninitialize(*ctx);
|
||||
|
||||
kernelDesc->releaseKernel(ctx);
|
||||
}
|
||||
}
|
||||
kernelLoader.uninitialize();
|
||||
kernelLoader.unload();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
+64
@@ -0,0 +1,64 @@
|
||||
#######################################################################
|
||||
# Software License Agreement (AGPL-3 License)
|
||||
#
|
||||
# OpenViBE SDK Test Software
|
||||
# Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
# Copyright (C) Inria, 2015-2017,V1.0
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License version 3,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program.
|
||||
# If not, see <http://www.gnu.org/licenses/>.
|
||||
#######################################################################
|
||||
|
||||
PROJECT(openvibe-scenario-player)
|
||||
|
||||
# ----------------------
|
||||
# Project variables
|
||||
# ----------------------
|
||||
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
|
||||
SET(PROJECT_VERSION_MINOR ${OV_GLOBAL_VERSION_MINOR})
|
||||
SET(PROJECT_VERSION_PATCH ${OV_GLOBAL_VERSION_PATCH})
|
||||
SET(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
|
||||
|
||||
# ----------------------
|
||||
# Add executable
|
||||
# ----------------------
|
||||
ADD_DEFINITIONS( -DPROJECT_VERSION="${PROJECT_VERSION}" )
|
||||
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.hpp)
|
||||
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILES})
|
||||
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${APP_FOLDER})
|
||||
|
||||
# ----------------------
|
||||
# External dependecies
|
||||
# ----------------------
|
||||
|
||||
# To be done after add executable because FindOpenViBEXXX files need a target name
|
||||
INCLUDE("FindOpenViBE")
|
||||
INCLUDE("FindOpenViBECommon")
|
||||
INCLUDE("FindOpenViBEToolkit")
|
||||
INCLUDE("FindOpenViBEModuleSystem")
|
||||
INCLUDE("FindOpenViBEModuleFS")
|
||||
INCLUDE("FindThirdPartyBoost")
|
||||
|
||||
# ---------------------------------
|
||||
# Target macros
|
||||
# Defines target operating system, architecture and compiler
|
||||
# ---------------------------------
|
||||
SET_BUILD_PLATFORM()
|
||||
|
||||
# -----------------------------
|
||||
# Install files
|
||||
# -----------------------------
|
||||
INSTALL(TARGETS ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION ${DIST_BINDIR}
|
||||
LIBRARY DESTINATION ${DIST_LIBDIR}
|
||||
ARCHIVE DESTINATION ${DIST_LIBDIR})
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ovspCKernelFacade.h"
|
||||
#include "ovspCCommand.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
EPlayerReturnCodes SInitCmd::execute(CKernelFacade& kernelFacade) const
|
||||
{
|
||||
std::cout << "About to execute:" << std::endl << *this << std::endl;
|
||||
return kernelFacade.initialize();
|
||||
}
|
||||
|
||||
void SInitCmd::doPrint(std::ostream& os) const
|
||||
{
|
||||
os << "command name: InitCommand" << std::endl;
|
||||
os << "Benchmark: " << (this->benchmark ? std::to_string(this->benchmark.get()) : "not set") << std::endl;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes SLoadKernelCmd::execute(CKernelFacade& kernelFacade) const
|
||||
{
|
||||
std::cout << "About to execute:" << std::endl << *this << std::endl;
|
||||
// default config file is an empty one so it is not problem to give it directly as param
|
||||
return kernelFacade.loadKernel(*this);
|
||||
}
|
||||
|
||||
void SLoadKernelCmd::doPrint(std::ostream& os) const
|
||||
{
|
||||
os << "command name: LoadKernelCommand" << std::endl;
|
||||
os << "ConfigurationFile: " << (this->configFile ? this->configFile.get() : "not set") << std::endl;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes SLoadScenarioCmd::execute(CKernelFacade& kernelFacade) const
|
||||
{
|
||||
std::cout << "About to execute:" << std::endl << *this << std::endl;
|
||||
|
||||
if (!this->scenarioName || !this->scenarioFile)
|
||||
{
|
||||
std::cerr << "Missing required arguments for command" << std::endl;
|
||||
return EPlayerReturnCodes::MissingMandatoryArgument;
|
||||
}
|
||||
|
||||
return kernelFacade.loadScenario(*this);
|
||||
}
|
||||
|
||||
void SLoadScenarioCmd::doPrint(std::ostream& os) const
|
||||
{
|
||||
os << "command name: LoadScenarioCommand" << std::endl;
|
||||
os << "ScenarioName: " << (this->scenarioName ? this->scenarioName.get() : "not set") << std::endl;
|
||||
os << "ScenarioFile: " << (this->scenarioFile ? this->scenarioFile.get() : "not set") << std::endl;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes SUpdateScenarioCmd::execute(CKernelFacade& kernelFacade) const
|
||||
{
|
||||
std::cout << "About to execute:" << std::endl << *this << std::endl;
|
||||
|
||||
if (!this->scenarioName || !this->scenarioFile)
|
||||
{
|
||||
std::cerr << "Missing required arguments for command" << std::endl;
|
||||
return EPlayerReturnCodes::MissingMandatoryArgument;
|
||||
}
|
||||
|
||||
return kernelFacade.updateScenario(*this);
|
||||
}
|
||||
|
||||
void SUpdateScenarioCmd::doPrint(std::ostream& os) const
|
||||
{
|
||||
os << "command name: UpdateScenarioCommand" << std::endl;
|
||||
os << "ScenarioName: " << (this->scenarioName ? this->scenarioName.get() : "not set") << std::endl;
|
||||
os << "ScenarioFile: " << (this->scenarioFile ? this->scenarioFile.get() : "not set") << std::endl;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes SResetCmd::execute(CKernelFacade& /*kernelFacade*/) const
|
||||
{
|
||||
// to be implemented
|
||||
std::cout << "About to execute:" << std::endl << *this << std::endl << "Not implemented yet" << std::endl;
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
void SResetCmd::doPrint(std::ostream& os) const { os << "command name: ResetCommand" << std::endl; }
|
||||
|
||||
EPlayerReturnCodes SRunScenarioCmd::execute(CKernelFacade& kernelFacade) const
|
||||
{
|
||||
std::cout << "About to execute:" << std::endl << *this << std::endl;
|
||||
if (!this->scenarioList)
|
||||
{
|
||||
std::cerr << "Missing required arguments for command: ScenarioList" << std::endl;
|
||||
return EPlayerReturnCodes::MissingMandatoryArgument;
|
||||
}
|
||||
return kernelFacade.runScenarioList(*this);
|
||||
}
|
||||
|
||||
void SRunScenarioCmd::doPrint(std::ostream& os) const
|
||||
{
|
||||
os << "command name: SRunScenarioCmd" << std::endl;
|
||||
|
||||
os << "ScenarioList:";
|
||||
if (this->scenarioList) { for (auto& scenario : this->scenarioList.get()) { os << " " << scenario; } }
|
||||
else { os << " not set"; }
|
||||
os << std::endl;
|
||||
|
||||
os << "PlayMode: ";
|
||||
if (this->playMode)
|
||||
{
|
||||
const std::string modeAsString = (this->playMode == EPlayerPlayMode::Fastfoward) ? "fastforward" : "standard";
|
||||
os << modeAsString;
|
||||
}
|
||||
else { os << "not set"; }
|
||||
os << std::endl;
|
||||
|
||||
os << "MaximumExecutionTime: " << (this->maximumExecutionTime ? std::to_string(this->maximumExecutionTime.get()) : "not set") << std::endl;
|
||||
|
||||
os << "TokenList:";
|
||||
if (this->tokenList) { for (auto& token : this->tokenList.get()) { os << " (" << token.first << "," << token.second << ")"; } }
|
||||
else { os << " not set"; }
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes SSetupScenarioCmd::execute(CKernelFacade& kernelFacade) const
|
||||
{
|
||||
std::cout << "About to execute:" << std::endl << *this << std::endl;
|
||||
if (!this->scenarioName)
|
||||
{
|
||||
std::cerr << "Missing required arguments for command" << std::endl;
|
||||
return EPlayerReturnCodes::MissingMandatoryArgument;
|
||||
}
|
||||
return kernelFacade.setupScenario(*this);
|
||||
}
|
||||
|
||||
void SSetupScenarioCmd::doPrint(std::ostream& os) const
|
||||
{
|
||||
os << "command name: SSetupScenarioCmd" << std::endl;
|
||||
os << "ScenarioName: " << (this->scenarioName ? this->scenarioName.get() : "not set") << std::endl;
|
||||
os << "TokenList:";
|
||||
if (this->tokenList) { for (auto& token : this->tokenList.get()) { os << " (" << token.first << "," << token.second << ")"; } }
|
||||
else { os << " not set"; }
|
||||
os << std::endl;
|
||||
}
|
||||
} // namespace OpenViBE
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ovspICommand.h"
|
||||
#include <boost/optional.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace OpenViBE {
|
||||
/**
|
||||
* \struct SInitCmd
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-26
|
||||
* \brief Command that drives the initialization of the tool
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* InitCommand class contains the following properties:
|
||||
* - Benchmark: Flag to enable benchmark on execute command (optional).
|
||||
*
|
||||
*/
|
||||
struct SInitCmd final : SCommand
|
||||
{
|
||||
// List of properties
|
||||
boost::optional<bool> benchmark;
|
||||
|
||||
EPlayerReturnCodes execute(CKernelFacade& kernelFacade) const override;
|
||||
|
||||
protected:
|
||||
void doPrint(std::ostream& os) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \struct SLoadKernelCmd
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-26
|
||||
* \brief Command that drives kernel loading
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* LoadKernelCommand contains the following properties:
|
||||
* - ConfigurationFile: Path to kernel configuration file (optional)
|
||||
* .
|
||||
*
|
||||
*/
|
||||
struct SLoadKernelCmd final : SCommand
|
||||
{
|
||||
// List of properties
|
||||
boost::optional<std::string> configFile;
|
||||
|
||||
EPlayerReturnCodes execute(CKernelFacade& kernelFacade) const override;
|
||||
|
||||
protected:
|
||||
|
||||
void doPrint(std::ostream& os) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct SLoadScenarioCmd
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-26
|
||||
* \brief Command that drives scenario loading
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* LoadScenarioCommand contains the following properties:
|
||||
* - ScenarioFile: Path to xml scenario file (mandatory)
|
||||
* - ScenarioName: Name of the scenario (mandatory)
|
||||
* .
|
||||
*
|
||||
*/
|
||||
struct SLoadScenarioCmd final : SCommand
|
||||
{
|
||||
// List of properties
|
||||
boost::optional<std::string> scenarioFile;
|
||||
boost::optional<std::string> scenarioName;
|
||||
|
||||
EPlayerReturnCodes execute(CKernelFacade& kernelFacade) const override;
|
||||
|
||||
protected:
|
||||
|
||||
void doPrint(std::ostream& os) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct SUpdateScenarioCmd
|
||||
* \author criou (INRIA)
|
||||
* \date 2018-04-16
|
||||
* \brief Command that drives scenario update and export
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* UpdateScenarioCommand contains the following properties:
|
||||
* - ScenarioFile: Path to xml scenario file (mandatory)
|
||||
* .
|
||||
*
|
||||
*/
|
||||
struct SUpdateScenarioCmd final : SCommand
|
||||
{
|
||||
// List of properties
|
||||
boost::optional<std::string> scenarioFile;
|
||||
boost::optional<std::string> scenarioName;
|
||||
|
||||
EPlayerReturnCodes execute(CKernelFacade& kernelFacade) const override;
|
||||
|
||||
protected:
|
||||
|
||||
void doPrint(std::ostream& os) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct SResetCmd
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-26
|
||||
* \brief Command that drives tool reset to its initial state
|
||||
* \ingroup ScenarioPlayer
|
||||
*/
|
||||
struct SResetCmd final : SCommand
|
||||
{
|
||||
EPlayerReturnCodes execute(CKernelFacade& kernelFacade) const override;
|
||||
|
||||
protected:
|
||||
|
||||
void doPrint(std::ostream& os) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct SRunScenarioCmd
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-26
|
||||
* \brief Command that drives the execution of a list of scenarios
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* SRunScenarioCmd contains the following properties:
|
||||
* - ScenarioList: Names of scenario that must be executed (mandatory)
|
||||
* - PlayMode: 0 for standard, 1 for fastforward (optional)
|
||||
* - MaximumExecutionTime: Scenarios playing execution time limit (optional)
|
||||
* - TokenList: List of global (token,value) pairs (optional)
|
||||
* .
|
||||
*
|
||||
*/
|
||||
struct SRunScenarioCmd final : SCommand
|
||||
{
|
||||
using Token = std::pair<std::string, std::string>;
|
||||
|
||||
// List of properties
|
||||
boost::optional<std::vector<std::string>> scenarioList;
|
||||
boost::optional<EPlayerPlayMode> playMode;
|
||||
boost::optional<double> maximumExecutionTime;
|
||||
boost::optional<std::vector<Token>> tokenList;
|
||||
|
||||
EPlayerReturnCodes execute(CKernelFacade& kernelFacade) const override;
|
||||
|
||||
protected:
|
||||
|
||||
void doPrint(std::ostream& os) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct SSetupScenarioCmd
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-26
|
||||
* \brief Command that drives the setup of a scenario
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* SSetupScenarioCmd contains the following properties:
|
||||
* - ScenarioName: name of the scenario to setup (mandatory)
|
||||
* - TokenList: List of scenario specific tokens (optional)
|
||||
* .
|
||||
*
|
||||
* The token list overwrites the previous token list if the command was already
|
||||
* called on the same scenario (note that an empty token list is allowed).
|
||||
*
|
||||
*/
|
||||
struct SSetupScenarioCmd final : SCommand
|
||||
{
|
||||
using Token = std::pair<std::string, std::string>;
|
||||
|
||||
// List of properties
|
||||
boost::optional<std::string> scenarioName;
|
||||
boost::optional<std::vector<Token>> tokenList;
|
||||
|
||||
|
||||
EPlayerReturnCodes execute(CKernelFacade& kernelFacade) const override;
|
||||
|
||||
protected:
|
||||
|
||||
void doPrint(std::ostream& os) const override;
|
||||
};
|
||||
} // namespace OpenViBE
|
||||
+336
@@ -0,0 +1,336 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ovspCCommand.h"
|
||||
#include "ovspCCommandFileParser.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
|
||||
// should be moved in a utility class/file
|
||||
std::string CommandFileParser::trim(const std::string& str)
|
||||
{
|
||||
// remove leading and trailing space
|
||||
// no use of regex here cause it might be too slow
|
||||
auto begin = str.find_first_not_of(" \t"), end = str.find_last_not_of(" \t");
|
||||
if (begin == std::string::npos) { begin = 0; }
|
||||
if (end == std::string::npos) { end = str.size() - 1; }
|
||||
return str.substr(begin, end - begin + 1);
|
||||
}
|
||||
|
||||
// should be moved in a utility class/file
|
||||
std::pair<std::string, std::string> CommandFileParser::tokenize(const std::string& str)
|
||||
{
|
||||
// given a string of type "token : value", return a pair of (token,value)
|
||||
// split method is not used because only the first delimiter is of interest
|
||||
const auto split = str.find_first_of(':');
|
||||
|
||||
if (split == std::string::npos) { throw std::runtime_error("Impossible to convert " + str + " to token/value pair"); }
|
||||
|
||||
auto token = trim(str.substr(0, split));
|
||||
auto val = trim(str.substr(split + 1, str.size() - split - 1));
|
||||
|
||||
return std::make_pair(token, val);
|
||||
}
|
||||
|
||||
// should be moved in a utility class/file
|
||||
std::vector<std::string> CommandFileParser::split(const std::string& str, const char delimiter)
|
||||
{
|
||||
std::vector<std::string> vec;
|
||||
size_t currentIdx = 0;
|
||||
size_t delimiterIdx = str.find(delimiter);
|
||||
|
||||
auto trimmed = trim(str.substr(currentIdx, delimiterIdx));
|
||||
if (!trimmed.empty()) { vec.push_back(trimmed); }
|
||||
|
||||
while (delimiterIdx != std::string::npos)
|
||||
{
|
||||
// abc,cde,fgh
|
||||
// ^ -> current index points to the first element after a match
|
||||
// ^ -> delimiter index points to next match
|
||||
currentIdx = delimiterIdx + 1;
|
||||
delimiterIdx = str.find(delimiter, currentIdx);
|
||||
|
||||
trimmed = trim(str.substr(currentIdx, delimiterIdx - currentIdx));
|
||||
|
||||
if (!trimmed.empty()) { vec.push_back(trimmed); }
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
// should be moved in a utility class/file
|
||||
bool CommandFileParser::toBool(const std::string& str)
|
||||
{
|
||||
// try to keep same behavior as stoi or stol
|
||||
|
||||
std::string lowerStr;
|
||||
lowerStr.reserve(str.size());
|
||||
std::transform(str.begin(), str.end(), lowerStr.begin(), tolower);
|
||||
|
||||
bool result;
|
||||
if (str == "false" || str == "0") { result = false; }
|
||||
else if (str == "true" || str == "1") { result = true; }
|
||||
else { throw std::runtime_error("Impossible to convert " + str + " to bool"); }
|
||||
return result;
|
||||
}
|
||||
|
||||
// should be moved in a utility class/file
|
||||
// input is expected to be trimmed (by a call to tolenize for example)
|
||||
std::vector<std::string> CommandFileParser::toList(const std::string& str)
|
||||
{
|
||||
std::vector<std::string> vec;
|
||||
// {token1, token2, token3 ...} pattern expected
|
||||
if (str.size() >= 3 && str[0] == '{' && str[str.size() - 1] == '}') { vec = split(str.substr(1, str.length() - 2), ','); }
|
||||
else { throw std::runtime_error("Impossible to convert " + str + " to list"); }
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
// should be moved in a utility class/file
|
||||
// part of this function duplicates code from ProgramOptions.hpp
|
||||
std::vector<CommandFileParser::Token> CommandFileParser::toTokenList(const std::string& str)
|
||||
{
|
||||
std::vector<Token> vec;
|
||||
|
||||
for (auto& rawToken : toList(str))
|
||||
{
|
||||
// rawToken is expected to be trimmed
|
||||
|
||||
const auto split = rawToken.find_first_of(':');
|
||||
const auto size = rawToken.size();
|
||||
|
||||
// (a:b) pattern expected
|
||||
// minimal regex std::regex("\\(.+:.+\\)")
|
||||
if (!(size >= 5 && rawToken[0] == '(' && rawToken[size - 1] == ')') || split == std::string::npos)
|
||||
{
|
||||
throw std::runtime_error("Failed to parse token pair from value: " + rawToken);
|
||||
}
|
||||
|
||||
Token token;
|
||||
token.first = trim(rawToken.substr(1, split - 1));
|
||||
|
||||
// magic 2 numbers is because substr takes a length as second parameter
|
||||
// 2 = remove the last ) + account for the first one
|
||||
token.second = trim(rawToken.substr(split + 1, size - split - 2));
|
||||
|
||||
vec.push_back(token);
|
||||
}
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
void CommandFileParser::initialize()
|
||||
{
|
||||
// using a callback mechanism allows us to implement the core parse() method
|
||||
// very easily (no need to put some if/else blocks everywhere depending on which command is encountered)
|
||||
m_callbacks["Init"] = std::bind(&CommandFileParser::initCommandCb, this, std::placeholders::_1);
|
||||
m_callbacks["Reset"] = std::bind(&CommandFileParser::resetCommandCb, this, std::placeholders::_1);
|
||||
m_callbacks["LoadKernel"] = std::bind(&CommandFileParser::loadKernelCommandCb, this, std::placeholders::_1);
|
||||
m_callbacks["LoadScenario"] = std::bind(&CommandFileParser::loadScenarioCommandCb, this, std::placeholders::_1);
|
||||
m_callbacks["SetupScenario"] = std::bind(&CommandFileParser::setupScenarioCommandCb, this, std::placeholders::_1);
|
||||
m_callbacks["RunScenario"] = std::bind(&CommandFileParser::runScenarioCommandCb, this, std::placeholders::_1);
|
||||
}
|
||||
|
||||
void CommandFileParser::uninitialize()
|
||||
{
|
||||
m_callbacks.clear();
|
||||
m_cmdList.clear();
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CommandFileParser::parse()
|
||||
{
|
||||
std::ifstream fileStream(m_cmdFile);
|
||||
|
||||
if (!fileStream.is_open())
|
||||
{
|
||||
std::cerr << "ERROR: impossible to open file at location: " << m_cmdFile << std::endl;
|
||||
return EPlayerReturnCodes::OpeningFileFailure;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
bool isFillingSection{ false };
|
||||
std::vector<std::string> sectionContent;
|
||||
std::string sectionTag;
|
||||
|
||||
while (std::getline(fileStream, line))
|
||||
{
|
||||
auto trimmedLine = trim(line);
|
||||
const auto size = trimmedLine.size();
|
||||
|
||||
// [a] pattern expected
|
||||
// minimal regex std::regex("^(?!\\#)\\[.+\\])")
|
||||
if (size >= 3 && trimmedLine[0] == '['
|
||||
&& trimmedLine[size - 1] == ']')
|
||||
{
|
||||
if (isFillingSection) // flush the section that was beeing filled
|
||||
{
|
||||
const auto errorCode = this->flush(sectionTag, sectionContent);
|
||||
if (errorCode != EPlayerReturnCodes::Success) { return errorCode; }
|
||||
}
|
||||
|
||||
// use of regex to be confident on tag structure
|
||||
// magic 2 numbers is because substr takes length as second parameter
|
||||
// 2 = remove the last ] + account for the first one
|
||||
sectionTag = trimmedLine.substr(1, size - 2);
|
||||
|
||||
if (m_callbacks.find(sectionTag) == m_callbacks.end())
|
||||
{
|
||||
std::cerr << "ERROR: Unknown command = " << sectionTag << std::endl;
|
||||
return EPlayerReturnCodes::ParsingCommandFailure;
|
||||
}
|
||||
|
||||
isFillingSection = true;
|
||||
sectionContent.clear();
|
||||
}
|
||||
else { sectionContent.push_back(trimmedLine); }
|
||||
}
|
||||
|
||||
if (isFillingSection)
|
||||
{
|
||||
const auto errorCode = this->flush(sectionTag, sectionContent);
|
||||
if (errorCode != EPlayerReturnCodes::Success) { return errorCode; }
|
||||
}
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CommandFileParser::flush(const std::string& sectionTag, const std::vector<std::string>& sectionContent)
|
||||
{
|
||||
try // try block here as some conversions are made with the stl in the callback and might throw
|
||||
{
|
||||
const auto returnCode = m_callbacks[sectionTag](sectionContent);
|
||||
if (returnCode != EPlayerReturnCodes::Success) { return returnCode; }
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << "ERROR: Caught exception while parsing command = " << sectionTag << std::endl;
|
||||
std::cerr << "ERROR: Exception: " << e.what() << std::endl;
|
||||
return EPlayerReturnCodes::ParsingCommandFailure;
|
||||
}
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CommandFileParser::initCommandCb(const std::vector<std::string>& sectionContent)
|
||||
{
|
||||
std::shared_ptr<SInitCmd> command = std::make_shared<SInitCmd>();
|
||||
|
||||
for (const auto& line : sectionContent)
|
||||
{
|
||||
// lines are expected to be trimmed
|
||||
// a:b pattern expected
|
||||
// minimal regex std::regex("^(?!\\#).+:.+")
|
||||
if (!line.empty() && line[0] != '#')
|
||||
{
|
||||
auto param = tokenize(line);
|
||||
|
||||
if (param.first == "Benchmark") { command->benchmark = toBool(param.second); }
|
||||
else { std::cout << "WARNING: Unknown parameter for Init command: " << param.first << std::endl; }
|
||||
}
|
||||
}
|
||||
m_cmdList.push_back(command);
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CommandFileParser::resetCommandCb(const std::vector<std::string>& /*sectionContent*/)
|
||||
{
|
||||
const std::shared_ptr<SResetCmd> command = std::make_shared<SResetCmd>();
|
||||
m_cmdList.push_back(command);
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CommandFileParser::loadKernelCommandCb(const std::vector<std::string>& sectionContent)
|
||||
{
|
||||
std::shared_ptr<SLoadKernelCmd> command = std::make_shared<SLoadKernelCmd>();
|
||||
|
||||
// cf. initCommandCb
|
||||
for (const auto& line : sectionContent)
|
||||
{
|
||||
if (!line.empty() && line[0] != '#')
|
||||
{
|
||||
auto param = tokenize(line);
|
||||
if (param.first == "ConfigurationFile") { command->configFile = param.second; }
|
||||
else { std::cout << "WARNING: Unknown parameter for LoadKernel command: " << param.first << std::endl; }
|
||||
}
|
||||
}
|
||||
m_cmdList.push_back(command);
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CommandFileParser::loadScenarioCommandCb(const std::vector<std::string>& sectionContent)
|
||||
{
|
||||
std::shared_ptr<SLoadScenarioCmd> command = std::make_shared<SLoadScenarioCmd>();
|
||||
|
||||
// cf. initCommandCb
|
||||
for (const auto& line : sectionContent)
|
||||
{
|
||||
if (!line.empty() && line[0] != '#')
|
||||
{
|
||||
auto param = tokenize(line);
|
||||
|
||||
if (param.first == "ScenarioName") { command->scenarioName = param.second; }
|
||||
else if (param.first == "ScenarioFile") { command->scenarioFile = param.second; }
|
||||
else { std::cout << "WARNING: Unknown parameter for LoadScenario command: " << param.first << std::endl; }
|
||||
}
|
||||
}
|
||||
m_cmdList.push_back(command);
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CommandFileParser::setupScenarioCommandCb(const std::vector<std::string>& sectionContent)
|
||||
{
|
||||
std::shared_ptr<SSetupScenarioCmd> command = std::make_shared<SSetupScenarioCmd>();
|
||||
|
||||
// cf. initCommandCb
|
||||
for (const auto& line : sectionContent)
|
||||
{
|
||||
if (!line.empty() && line[0] != '#')
|
||||
{
|
||||
auto param = tokenize(line);
|
||||
|
||||
if (param.first == "ScenarioName") { command->scenarioName = param.second; }
|
||||
else if (param.first == "TokenList") { command->tokenList = toTokenList(param.second); }
|
||||
else { std::cout << "WARNING: Unknown parameter for SetupScenario command: " << param.first << std::endl; }
|
||||
}
|
||||
}
|
||||
m_cmdList.push_back(command);
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CommandFileParser::runScenarioCommandCb(const std::vector<std::string>& sectionContent)
|
||||
{
|
||||
std::shared_ptr<SRunScenarioCmd> command = std::make_shared<SRunScenarioCmd>();
|
||||
|
||||
// cf. initCommandCb
|
||||
for (const auto& line : sectionContent)
|
||||
{
|
||||
if (!line.empty() && line[0] != '#')
|
||||
{
|
||||
auto param = tokenize(line);
|
||||
|
||||
if (param.first == "ScenarioList") { command->scenarioList = toList(param.second); }
|
||||
else if (param.first == "PlayMode") { command->playMode = EPlayerPlayMode(std::stoi(param.second)); }
|
||||
else if (param.first == "MaximumExecutionTime") { command->maximumExecutionTime = std::stod(param.second); }
|
||||
else if (param.first == "TokenList") { command->tokenList = (toTokenList(param.second)); }
|
||||
else { std::cout << "WARNING: Unknown parameter for RunScenario command: " << param.first << std::endl; }
|
||||
}
|
||||
}
|
||||
m_cmdList.push_back(command);
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
} // namespace OpenViBE
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ovsp_defines.h"
|
||||
#include "ovspICommandParser.h"
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace OpenViBE {
|
||||
/**
|
||||
* \class CommandFileParser
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-27
|
||||
* \brief Parser implementation that parses command a file
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* The current implementation retrieves the list of commands from a file.
|
||||
*
|
||||
* Input file format requirements:
|
||||
* - Command names are defined within brackets [InitCommand] on a single line
|
||||
* - Each command parameter is defined on a single line below the command name:
|
||||
* + Single value parameters are defined as: parameterName: value
|
||||
* + Simple list parameters are defined as: parameterName: {val1,val2,...}
|
||||
* + Token list parameters are defined as: parameterName: { (token1:val1),(token2:val2) } (no ',' authorized in (token, value) pair)
|
||||
* .
|
||||
* .
|
||||
*
|
||||
* \todo The implementation uses a lot of string utility functions that need more
|
||||
* testing
|
||||
*
|
||||
* \note Use of regex would simplify the implementation but boost::regex is not header-only and std::regex not implemented in gcc 4.8
|
||||
*
|
||||
*/
|
||||
class CommandFileParser final : public ICommandParser
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
*
|
||||
* \brief Constructor
|
||||
* \param[in] file path to the command file
|
||||
*
|
||||
*/
|
||||
explicit CommandFileParser(const std::string& file) : m_cmdFile(file) { }
|
||||
|
||||
void initialize() override;
|
||||
void uninitialize() override;
|
||||
|
||||
std::vector<std::shared_ptr<SCommand>> getCommandList() const override { return m_cmdList; }
|
||||
|
||||
EPlayerReturnCodes parse() override;
|
||||
|
||||
private:
|
||||
|
||||
using CallbackType = std::function<EPlayerReturnCodes(std::vector<std::string>)>;
|
||||
using Token = std::pair<std::string, std::string>;
|
||||
|
||||
static std::string trim(const std::string& str);
|
||||
static std::pair<std::string, std::string> tokenize(const std::string& str);
|
||||
static std::vector<std::string> split(const std::string& str, char delimiter);
|
||||
static bool toBool(const std::string& str);
|
||||
static std::vector<std::string> toList(const std::string& str);
|
||||
static std::vector<Token> toTokenList(const std::string& str);
|
||||
|
||||
EPlayerReturnCodes flush(const std::string& sectionTag, const std::vector<std::string>& sectionContent);
|
||||
|
||||
EPlayerReturnCodes initCommandCb(const std::vector<std::string>& sectionContent);
|
||||
EPlayerReturnCodes resetCommandCb(const std::vector<std::string>& sectionContent);
|
||||
EPlayerReturnCodes loadKernelCommandCb(const std::vector<std::string>& sectionContent);
|
||||
EPlayerReturnCodes loadScenarioCommandCb(const std::vector<std::string>& sectionContent);
|
||||
EPlayerReturnCodes setupScenarioCommandCb(const std::vector<std::string>& sectionContent);
|
||||
EPlayerReturnCodes runScenarioCommandCb(const std::vector<std::string>& sectionContent);
|
||||
|
||||
std::string m_cmdFile;
|
||||
std::vector<std::shared_ptr<SCommand>> m_cmdList;
|
||||
std::map<std::string, CallbackType> m_callbacks;
|
||||
};
|
||||
} // namespace OpenViBE
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ovspCCommand.h"
|
||||
#include "ovspCCommandLineOptionParser.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
CommandLineOptionParser::CommandLineOptionParser(ProgramOptionParser& parser) : m_parser(parser) { }
|
||||
|
||||
void CommandLineOptionParser::initialize() { } // nothing to do
|
||||
void CommandLineOptionParser::uninitialize() { m_cmdList.clear(); }
|
||||
|
||||
std::vector<std::shared_ptr<SCommand>> CommandLineOptionParser::getCommandList() const { return m_cmdList; }
|
||||
|
||||
EPlayerReturnCodes CommandLineOptionParser::parse()
|
||||
{
|
||||
// parsing consists of building a straightfoward command workflow according to command-line
|
||||
// options.
|
||||
|
||||
// commands have to be pushed in the right order
|
||||
|
||||
// choose a dumb name for the scenario
|
||||
std::string scenarioName = "express-scenario";
|
||||
|
||||
// an init command is always needed
|
||||
m_cmdList.push_back(std::make_shared<SInitCmd>());
|
||||
|
||||
|
||||
// workflow must at least load the kernel
|
||||
std::shared_ptr<SLoadKernelCmd> kernelCmd = std::make_shared<SLoadKernelCmd>();
|
||||
|
||||
if (m_parser.hasOption("config-file")) // optional
|
||||
{
|
||||
kernelCmd->configFile = m_parser.getOptionValue<std::string>("config-file");
|
||||
}
|
||||
|
||||
m_cmdList.push_back(kernelCmd);
|
||||
|
||||
// scenario loading is a mandatory step
|
||||
std::shared_ptr<SLoadScenarioCmd> scenarioCmd = std::make_shared<SLoadScenarioCmd>();
|
||||
|
||||
if (m_parser.hasOption("scenario-file")) // mandatory option
|
||||
{
|
||||
scenarioCmd->scenarioFile = m_parser.getOptionValue<std::string>("scenario-file");
|
||||
|
||||
// set dumb name as it used to recognize scenario in the application
|
||||
scenarioCmd->scenarioName = scenarioName;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "ERROR: mandatory option 'scenario-file' not set" << std::endl;
|
||||
return EPlayerReturnCodes::MissingMandatoryArgument;
|
||||
}
|
||||
|
||||
m_cmdList.push_back(scenarioCmd);
|
||||
|
||||
|
||||
// scenario update option
|
||||
std::shared_ptr<SUpdateScenarioCmd> updateScenarioCmd = std::make_shared<SUpdateScenarioCmd>();
|
||||
|
||||
if (m_parser.hasOption("updated-scenario-file"))
|
||||
{
|
||||
// do not play scenario, just update it.
|
||||
updateScenarioCmd->scenarioFile = m_parser.getOptionValue<std::string>("updated-scenario-file");
|
||||
|
||||
// set dumb name as it used to recognize scenario in the application
|
||||
updateScenarioCmd->scenarioName = scenarioName;
|
||||
|
||||
m_cmdList.push_back(updateScenarioCmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if some scenario setup information has been set
|
||||
if (m_parser.hasOption("ds"))
|
||||
{
|
||||
std::shared_ptr<SSetupScenarioCmd> setupCmd = std::make_shared<SSetupScenarioCmd>();
|
||||
setupCmd->scenarioName = scenarioName;
|
||||
setupCmd->tokenList = m_parser.getOptionValue<std::vector<SSetupScenarioCmd::Token>>("ds");
|
||||
|
||||
m_cmdList.push_back(setupCmd);
|
||||
}
|
||||
|
||||
// last command in the workflow is the run command
|
||||
std::shared_ptr<SRunScenarioCmd> runCmd = std::make_shared<SRunScenarioCmd>();
|
||||
runCmd->scenarioList = std::vector<std::string>{ scenarioName };
|
||||
|
||||
if (m_parser.hasOption("play-mode"))
|
||||
{
|
||||
const auto playMode = m_parser.getOptionValue<std::string>("play-mode");
|
||||
|
||||
if (playMode != "ff" && playMode != "std")
|
||||
{
|
||||
std::cerr << "ERROR: option 'play-mode' must be ff or std" << std::endl;
|
||||
return EPlayerReturnCodes::BadArg;
|
||||
}
|
||||
|
||||
// permissive code here
|
||||
// any other entry than ff leads to standard mode...
|
||||
runCmd->playMode = ((playMode == "ff") ? EPlayerPlayMode::Fastfoward : EPlayerPlayMode::Standard);
|
||||
}
|
||||
|
||||
if (m_parser.hasOption("max-time")) { runCmd->maximumExecutionTime = m_parser.getOptionValue<double>("max-time"); }
|
||||
if (m_parser.hasOption("dg")) { runCmd->tokenList = m_parser.getOptionValue<std::vector<SSetupScenarioCmd::Token>>("dg"); }
|
||||
|
||||
m_cmdList.push_back(runCmd);
|
||||
}
|
||||
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
} // namespace OpenViBE
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ovsp_defines.h"
|
||||
#include "ovspICommandParser.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
/**
|
||||
* \class CommandLineOptionParser
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-27
|
||||
* \brief Parser implementation that parses command from command-line arguments
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* The current implementation retrieves the options from a ProgramOptions parser and
|
||||
* simply builds the commands from the parsed options.
|
||||
*
|
||||
*/
|
||||
class CommandLineOptionParser final : public ICommandParser
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
*
|
||||
* \brief Constructor
|
||||
* \param[in] parser Specific instantiation of ProgramOptions parser
|
||||
*
|
||||
*/
|
||||
explicit CommandLineOptionParser(ProgramOptionParser& parser);
|
||||
|
||||
void initialize() override;
|
||||
void uninitialize() override;
|
||||
|
||||
std::vector<std::shared_ptr<SCommand>> getCommandList() const override;
|
||||
|
||||
EPlayerReturnCodes parse() override;
|
||||
|
||||
private:
|
||||
|
||||
ProgramOptionParser& m_parser;
|
||||
std::vector<std::shared_ptr<SCommand>> m_cmdList;
|
||||
};
|
||||
} // namespace OpenViBE
|
||||
+364
@@ -0,0 +1,364 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ovspCCommand.h"
|
||||
#include "ovsp_base.h"
|
||||
#include "ovspCKernelFacade.h"
|
||||
|
||||
#include <system/ovCTime.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <limits>
|
||||
#include <cassert>
|
||||
|
||||
namespace OpenViBE {
|
||||
|
||||
using TokenList = std::vector<std::pair<std::string, std::string>>;
|
||||
|
||||
static void setConfigTokens(Kernel::IConfigurationManager& configsManager, const TokenList& tokens)
|
||||
{
|
||||
for (const auto& token : tokens) { configsManager.addOrReplaceConfigurationToken(token.first.c_str(), token.second.c_str()); }
|
||||
}
|
||||
|
||||
struct CKernelFacade::SKernelFacadeImpl
|
||||
{
|
||||
CKernelLoader loader;
|
||||
Kernel::IKernelContext* ctx = nullptr;
|
||||
std::map<std::string, CIdentifier> scenarios;
|
||||
std::map<std::string, TokenList> scenarioTokens;
|
||||
};
|
||||
|
||||
CKernelFacade::CKernelFacade() : m_impl(new SKernelFacadeImpl()) { }
|
||||
|
||||
// The destructor is needed in the .cpp file to implement pimpl idiom
|
||||
// with unique_ptr. This is due to the fact that Kernel facade dtor
|
||||
// has to call unique_ptr<KernelFacadeImpl> deleter function that calls the detete function
|
||||
// on KernelFacadeImpl. Therefore it needs to know KernelFacadeImpl implementation.
|
||||
CKernelFacade::~CKernelFacade()
|
||||
{
|
||||
this->unloadKernel();
|
||||
uninitialize();
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CKernelFacade::loadKernel(const SLoadKernelCmd& command) const
|
||||
{
|
||||
if (m_impl->ctx)
|
||||
{
|
||||
std::cout << "WARNING: The kernel is already loaded" << std::endl;
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
#if defined TARGET_OS_Windows
|
||||
const CString kernelFile = Directories::getLibDir() + "/openvibe-kernel.dll";
|
||||
#elif defined TARGET_OS_Linux
|
||||
const CString kernelFile = Directories::getLibDir() + "/libopenvibe-kernel.so";
|
||||
#elif defined TARGET_OS_MacOS
|
||||
const CString kernelFile = Directories::getLibDir() + "/libopenvibe-kernel.dylib";
|
||||
#endif
|
||||
|
||||
CKernelLoader& kernelLoader = m_impl->loader;
|
||||
CString error;
|
||||
|
||||
if (!kernelLoader.load(kernelFile, &error))
|
||||
{
|
||||
std::cerr << "ERROR: impossible to load kernel from file located at: " << kernelFile << std::endl;
|
||||
return EPlayerReturnCodes::KernelLoadingFailure;
|
||||
}
|
||||
|
||||
kernelLoader.initialize();
|
||||
|
||||
Kernel::IKernelDesc* kernelDesc = nullptr;
|
||||
kernelLoader.getKernelDesc(kernelDesc);
|
||||
|
||||
if (!kernelDesc)
|
||||
{
|
||||
std::cerr << "ERROR: impossible to retrieve kernel descriptor " << std::endl;
|
||||
return EPlayerReturnCodes::KernelInvalidDesc;
|
||||
}
|
||||
|
||||
CString configFile;
|
||||
|
||||
if (command.configFile && !command.configFile.get().empty()) { configFile = command.configFile.get().c_str(); }
|
||||
else { configFile = CString(Directories::getDataDir() + "/kernel/openvibe.conf"); }
|
||||
|
||||
|
||||
Kernel::IKernelContext* ctx = kernelDesc->createKernel("scenario-player", configFile);
|
||||
|
||||
if (!ctx)
|
||||
{
|
||||
std::cerr << "ERROR: impossible to create kernel context " << std::endl;
|
||||
return EPlayerReturnCodes::KernelInvalidDesc;
|
||||
}
|
||||
|
||||
ctx->initialize();
|
||||
m_impl->ctx = ctx;
|
||||
Toolkit::initialize(*ctx);
|
||||
|
||||
Kernel::IConfigurationManager& configurationManager = ctx->getConfigurationManager();
|
||||
ctx->getPluginManager().addPluginsFromFiles(configurationManager.expand("${Kernel_Plugins}"));
|
||||
ctx->getMetaboxManager().addMetaboxesFromFiles(configurationManager.expand("${Kernel_Metabox}"));
|
||||
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CKernelFacade::unloadKernel() const
|
||||
{
|
||||
if (m_impl->ctx)
|
||||
{
|
||||
// not releasing the scenario before releasing the kernel
|
||||
// causes a segfault on linux
|
||||
auto& scenarioManager = m_impl->ctx->getScenarioManager();
|
||||
for (auto& scenarioPair : m_impl->scenarios) { scenarioManager.releaseScenario(scenarioPair.second); }
|
||||
|
||||
|
||||
Toolkit::uninitialize(*m_impl->ctx);
|
||||
// m_impl->ctx->uninitialize();
|
||||
Kernel::IKernelDesc* kernelDesc = nullptr;
|
||||
m_impl->loader.getKernelDesc(kernelDesc);
|
||||
kernelDesc->releaseKernel(m_impl->ctx);
|
||||
m_impl->ctx = nullptr;
|
||||
}
|
||||
|
||||
m_impl->loader.uninitialize();
|
||||
m_impl->loader.unload();
|
||||
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CKernelFacade::loadScenario(const SLoadScenarioCmd& command) const
|
||||
{
|
||||
assert(command.scenarioFile && command.scenarioName);
|
||||
|
||||
if (!m_impl->ctx)
|
||||
{
|
||||
std::cerr << "ERROR: Kernel is not loaded" << std::endl;
|
||||
return EPlayerReturnCodes::KernelInternalFailure;
|
||||
}
|
||||
|
||||
const std::string scenarioFile = command.scenarioFile.get();
|
||||
const std::string scenarioName = command.scenarioName.get();
|
||||
|
||||
CIdentifier scenarioID;
|
||||
auto& scenarioManager = m_impl->ctx->getScenarioManager();
|
||||
|
||||
if (!scenarioManager.importScenarioFromFile(scenarioID, scenarioFile.c_str(), OVP_GD_ClassId_Algorithm_XMLScenarioImporter))
|
||||
{
|
||||
std::cerr << "ERROR: failed to create scenario " << std::endl;
|
||||
return EPlayerReturnCodes::KernelInternalFailure;
|
||||
}
|
||||
|
||||
scenarioManager.getScenario(scenarioID).addAttribute(OV_AttributeId_ScenarioFilename, scenarioFile.c_str());
|
||||
|
||||
const auto it = m_impl->scenarios.find(scenarioName);
|
||||
if (it != m_impl->scenarios.end()) { scenarioManager.releaseScenario(it->second); }
|
||||
|
||||
m_impl->scenarios[scenarioName] = scenarioID;
|
||||
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CKernelFacade::updateScenario(const SUpdateScenarioCmd& command) const
|
||||
{
|
||||
assert(command.scenarioFile && command.scenarioName);
|
||||
|
||||
auto& scenarioManager = m_impl->ctx->getScenarioManager();
|
||||
|
||||
const auto scenarioName = command.scenarioName.get();
|
||||
const auto scenarioFile = command.scenarioFile.get();
|
||||
|
||||
if (m_impl->scenarios.find(scenarioName) == m_impl->scenarios.end())
|
||||
{
|
||||
std::cerr << "ERROR: Trying to update a not loaded scenario " << scenarioName << std::endl;
|
||||
return EPlayerReturnCodes::ScenarioNotLoaded;
|
||||
}
|
||||
|
||||
auto& scenario = scenarioManager.getScenario(m_impl->scenarios[scenarioName]);
|
||||
|
||||
// check for boxes to be updated
|
||||
// scenario.checkBoxesRequiringUpdate();
|
||||
|
||||
// update boxes to be updated
|
||||
CIdentifier* listID = nullptr;
|
||||
size_t elemCount = 0;
|
||||
scenario.getOutdatedBoxIdentifierList(&listID, &elemCount);
|
||||
for (size_t i = 0; i < elemCount; ++i) { scenario.updateBox(listID[i]); }
|
||||
|
||||
// export scenario to the destination file
|
||||
if (!scenarioManager.exportScenarioToFile(scenarioFile.c_str(), m_impl->scenarios[scenarioName], OVP_GD_ClassId_Algorithm_XMLScenarioExporter))
|
||||
{
|
||||
std::cerr << "ERROR: failed to create scenario " << std::endl;
|
||||
return EPlayerReturnCodes::KernelInternalFailure;
|
||||
}
|
||||
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CKernelFacade::setupScenario(const SSetupScenarioCmd& command) const
|
||||
{
|
||||
if (!m_impl->ctx)
|
||||
{
|
||||
std::cerr << "ERROR: Kernel is not loaded" << std::endl;
|
||||
return EPlayerReturnCodes::KernelInternalFailure;
|
||||
}
|
||||
|
||||
if (!command.scenarioName)
|
||||
{
|
||||
std::cerr << "ERROR: Missing scenario name for setup" << std::endl;
|
||||
return EPlayerReturnCodes::KernelInternalFailure;
|
||||
}
|
||||
|
||||
const auto name = command.scenarioName.get();
|
||||
|
||||
if (m_impl->scenarios.find(name) == m_impl->scenarios.end())
|
||||
{
|
||||
std::cerr << "ERROR: Trying to configure not loaded scenario " << name << std::endl;
|
||||
return EPlayerReturnCodes::ScenarioNotLoaded;
|
||||
}
|
||||
|
||||
// token list is just stored at this step for further use at runtime
|
||||
// current token list overwrites the previous one
|
||||
if (command.tokenList) { m_impl->scenarioTokens[name] = command.tokenList.get(); }
|
||||
|
||||
return EPlayerReturnCodes::Success;
|
||||
}
|
||||
|
||||
EPlayerReturnCodes CKernelFacade::runScenarioList(const SRunScenarioCmd& command) const
|
||||
{
|
||||
assert(command.scenarioList);
|
||||
|
||||
if (!m_impl->ctx)
|
||||
{
|
||||
std::cerr << "ERROR: Kernel is not loaded" << std::endl;
|
||||
return EPlayerReturnCodes::KernelInternalFailure;
|
||||
}
|
||||
|
||||
auto scenarios = command.scenarioList.get();
|
||||
|
||||
// use of returnCode to store error and achive an RAII-like
|
||||
// behavior by releasing all players at the end
|
||||
EPlayerReturnCodes returnCode = EPlayerReturnCodes::Success;
|
||||
|
||||
// set up global token
|
||||
if (command.tokenList) { setConfigTokens(m_impl->ctx->getConfigurationManager(), command.tokenList.get()); }
|
||||
|
||||
auto& playerManager = m_impl->ctx->getPlayerManager();
|
||||
|
||||
// Keep 2 different containers because identifier information is
|
||||
// not relevant during the performance sensitive loop task.
|
||||
// This might be premature optimization...
|
||||
std::vector<Kernel::IPlayer*> players;
|
||||
std::vector<CIdentifier> playerIDs;
|
||||
|
||||
// attach players to scenario
|
||||
for (auto& pair : m_impl->scenarios)
|
||||
{
|
||||
auto name = pair.first;
|
||||
if (std::find(scenarios.begin(), scenarios.end(), name) == scenarios.end()) { continue; } // not in the list of scenario to run
|
||||
|
||||
CIdentifier id;
|
||||
if (!playerManager.createPlayer(id) || id == CIdentifier::undefined())
|
||||
{
|
||||
std::cerr << "ERROR: impossible to create player" << std::endl;
|
||||
returnCode = EPlayerReturnCodes::KernelInternalFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
Kernel::IPlayer* player = &playerManager.getPlayer(id);
|
||||
|
||||
// player identifier is pushed here to ensure a correct cleanup event if player initialization fails
|
||||
playerIDs.push_back(id);
|
||||
|
||||
CNameValuePairList configTokens;
|
||||
for (auto& token : m_impl->scenarioTokens[name]) { configTokens.setValue(token.first.c_str(), token.second.c_str()); }
|
||||
|
||||
// Scenario attachment with setup of local token
|
||||
if (!player->setScenario(pair.second, &configTokens))
|
||||
{
|
||||
std::cerr << "ERROR: impossible to set player scenario " << name << std::endl;
|
||||
returnCode = EPlayerReturnCodes::KernelInternalFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
if (player->initialize() == Kernel::EPlayerReturnCodes::Success)
|
||||
{
|
||||
if (command.playMode && command.playMode.get() == EPlayerPlayMode::Fastfoward) { player->forward(); }
|
||||
else { player->play(); }
|
||||
|
||||
players.push_back(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "ERROR: impossible to initialize player for scenario " << name << std::endl;
|
||||
returnCode = EPlayerReturnCodes::KernelInternalFailure;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (returnCode == EPlayerReturnCodes::Success)
|
||||
{
|
||||
// loop until timeout
|
||||
const uint64_t startTime = System::Time::zgetTime();
|
||||
uint64_t lastLoopTime = startTime;
|
||||
|
||||
// cannot directly feed secondsToTime with parameters.m_MaximumExecutionTime
|
||||
// because it could overflow
|
||||
const double boundedMaxExecutionTimeInS = CTime::max().toSeconds();
|
||||
|
||||
uint64_t maxExecutionTimeInFixedPoint;
|
||||
if (command.maximumExecutionTime && command.maximumExecutionTime.get() > 0 && command.maximumExecutionTime.get() < boundedMaxExecutionTimeInS)
|
||||
{
|
||||
maxExecutionTimeInFixedPoint = CTime(double(command.maximumExecutionTime.get())).time();
|
||||
}
|
||||
else { maxExecutionTimeInFixedPoint = std::numeric_limits<uint64_t>::max(); }
|
||||
|
||||
bool allStopped{ false };
|
||||
while (!allStopped) // negative condition here because it is easier to reason about it
|
||||
{
|
||||
const uint64_t currentTime = System::Time::zgetTime();
|
||||
allStopped = true;
|
||||
for (auto* p : players)
|
||||
{
|
||||
if (p->getStatus() != Kernel::EPlayerStatus::Stop)
|
||||
{
|
||||
if (!p->loop(currentTime - lastLoopTime, maxExecutionTimeInFixedPoint)) { returnCode = EPlayerReturnCodes::KernelInternalFailure; }
|
||||
}
|
||||
|
||||
if (p->getCurrentSimulatedTime() >= maxExecutionTimeInFixedPoint) { p->stop(); }
|
||||
|
||||
allStopped &= (p->getStatus() == Kernel::EPlayerStatus::Stop);
|
||||
}
|
||||
|
||||
lastLoopTime = currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
// release players
|
||||
for (auto& id : playerIDs)
|
||||
{
|
||||
playerManager.getPlayer(id).uninitialize();
|
||||
playerManager.releasePlayer(id);
|
||||
}
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
} // namespace OpenViBE
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ovsp_defines.h"
|
||||
#include <memory>
|
||||
|
||||
namespace OpenViBE {
|
||||
struct SInitCmd;
|
||||
struct SResetCmd;
|
||||
struct SLoadKernelCmd;
|
||||
struct SLoadScenarioCmd;
|
||||
struct SUpdateScenarioCmd;
|
||||
struct SSetupScenarioCmd;
|
||||
struct SRunScenarioCmd;
|
||||
|
||||
/**
|
||||
* \class CKernelFacade
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-26
|
||||
* \brief Wrapper class used to access Kernel features
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* This class is one-to-many interface used as a central point
|
||||
* to access a subset of Kernel features.
|
||||
*
|
||||
*/
|
||||
class CKernelFacade final
|
||||
{
|
||||
public:
|
||||
|
||||
CKernelFacade();
|
||||
~CKernelFacade();
|
||||
|
||||
/**
|
||||
* \brief Initialize session parameters
|
||||
*/
|
||||
static EPlayerReturnCodes initialize() { return EPlayerReturnCodes::Success; }
|
||||
|
||||
/**
|
||||
* \brief Reset session parameters
|
||||
*/
|
||||
static EPlayerReturnCodes uninitialize() { return EPlayerReturnCodes::Success; }
|
||||
|
||||
/**
|
||||
* \brief Load kernel
|
||||
* \param[in] command command containing all mandatory properties
|
||||
*/
|
||||
EPlayerReturnCodes loadKernel(const SLoadKernelCmd& command) const;
|
||||
|
||||
/**
|
||||
* \brief Unload kernel
|
||||
*/
|
||||
EPlayerReturnCodes unloadKernel() const;
|
||||
|
||||
/**
|
||||
* \brief Load scenario
|
||||
* \param[in] command command containing all mandatory properties
|
||||
*/
|
||||
EPlayerReturnCodes loadScenario(const SLoadScenarioCmd& command) const;
|
||||
|
||||
/**
|
||||
* \brief Update scenario
|
||||
* \param[in] command command containing all mandatory properties
|
||||
*/
|
||||
EPlayerReturnCodes updateScenario(const SUpdateScenarioCmd& command) const;
|
||||
|
||||
/**
|
||||
* \brief Configure scenario
|
||||
* \param[in] command command containing all mandatory properties
|
||||
*/
|
||||
EPlayerReturnCodes setupScenario(const SSetupScenarioCmd& command) const;
|
||||
|
||||
/**
|
||||
* \brief Run one or multiple scenarios
|
||||
* \param[in] command command containing all mandatory properties
|
||||
*/
|
||||
EPlayerReturnCodes runScenarioList(const SRunScenarioCmd& command) const;
|
||||
|
||||
private:
|
||||
|
||||
// disable copy and assignment because it is not meant to used
|
||||
// as a value class event if it is not inheritable
|
||||
CKernelFacade(const CKernelFacade&) = delete;
|
||||
CKernelFacade& operator=(const CKernelFacade&) = delete;
|
||||
|
||||
struct SKernelFacadeImpl;
|
||||
std::unique_ptr<SKernelFacadeImpl> m_impl;
|
||||
};
|
||||
} // namespace OpenViBE
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ovsp_defines.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
class CKernelFacade;
|
||||
|
||||
/**
|
||||
* \struct SCommand
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-26
|
||||
* \brief Base abstract struct for commands
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* A command is an object that encapsulates all necessary information to perform an action later one.
|
||||
* Typically, a command implementation should contain an implementation of CommandInterface interface,
|
||||
* and a list of properties.
|
||||
*
|
||||
*/
|
||||
struct SCommand
|
||||
{
|
||||
SCommand() = default;
|
||||
virtual ~SCommand() = default;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const SCommand& cmd);
|
||||
|
||||
/**
|
||||
* \brief Execute the command
|
||||
* \param[in] kernelFacade the kernel facade that gives access to kernel features
|
||||
*/
|
||||
virtual EPlayerReturnCodes execute(CKernelFacade& kernelFacade) const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
// use of the non-virtual interface pattern to implement printing in the class hierarchy
|
||||
virtual void doPrint(std::ostream& os) const = 0;
|
||||
|
||||
private:
|
||||
|
||||
// disable copy and assignment because it is not meant to used
|
||||
// as a value class
|
||||
SCommand(const SCommand&) = delete;
|
||||
SCommand& operator=(const SCommand&) = delete;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const SCommand& cmd)
|
||||
{
|
||||
cmd.doPrint(os);
|
||||
return os;
|
||||
}
|
||||
} // namespace OpenViBE
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ovsp_defines.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace OpenViBE {
|
||||
struct SCommand;
|
||||
|
||||
/**
|
||||
* \class ICommandParser
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-27
|
||||
* \brief Base abstract class for command parser
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* Command parsers aim at parsing a list of commands from a specific input.
|
||||
*
|
||||
*/
|
||||
class ICommandParser
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~ICommandParser() = default;
|
||||
ICommandParser() = default;
|
||||
|
||||
/**
|
||||
* \brief Initialize parser
|
||||
*
|
||||
*/
|
||||
virtual void initialize() = 0;
|
||||
|
||||
/**
|
||||
* \brief Unitialize parser
|
||||
*
|
||||
*/
|
||||
virtual void uninitialize() = 0;
|
||||
|
||||
/**
|
||||
* \brief Retrieve the list of commands
|
||||
* \pre This method should be called after the parse() method
|
||||
*
|
||||
*/
|
||||
virtual std::vector<std::shared_ptr<SCommand>> getCommandList() const = 0;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Retrieve the list of commands
|
||||
* \pre This method should be called after the initialize() method
|
||||
*
|
||||
*/
|
||||
virtual EPlayerReturnCodes parse() = 0;
|
||||
|
||||
private:
|
||||
|
||||
// disable copy and assignment because it is not meant to used
|
||||
// as a value class
|
||||
ICommandParser(const ICommandParser&) = delete;
|
||||
ICommandParser& operator=(const ICommandParser&) = delete;
|
||||
};
|
||||
} // namespace OpenViBE
|
||||
+461
@@ -0,0 +1,461 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ovsp_defines.h"
|
||||
#include <boost/variant.hpp>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#if defined TARGET_OS_Windows
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
namespace OpenViBE {
|
||||
/**
|
||||
* \struct SProgramOptionsTraits
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-26
|
||||
* \brief Helper class for ProgramOptions type checking
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* This class provides aliases to types currently handled by ProgramOptions class
|
||||
* as well as type checking meta-programming features.
|
||||
*
|
||||
*/
|
||||
struct SProgramOptionsTraits
|
||||
{
|
||||
// add a new type here (type must be default constructible)
|
||||
// and add the corresponding callback in ProgramOptions
|
||||
|
||||
// types handled by ProgramOptions
|
||||
using TokenPair = std::pair<std::string, std::string>;
|
||||
using String = std::string;
|
||||
using Integer = int;
|
||||
using Float = double;
|
||||
|
||||
using StringList = std::vector<std::string>;
|
||||
using IntegerList = std::vector<int>;
|
||||
using FloatList = std::vector<double>;
|
||||
using TokenPairList = std::vector<TokenPair>;
|
||||
};
|
||||
|
||||
namespace ProgramOptionsUtils {
|
||||
// template meta-programming features
|
||||
|
||||
/* Base type that represents a true value at compile-time */
|
||||
struct STrueType
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
/* Base type that represents a false value at compile-time */
|
||||
struct SFalseType
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
/* SIsCompliant is used to statically check if a type is compliant with the handled types */
|
||||
template <typename T>
|
||||
struct SIsCompliant : SFalseType { };
|
||||
|
||||
/* Specialization of the template for compliant types */
|
||||
template <>
|
||||
struct SIsCompliant<SProgramOptionsTraits::TokenPair> : STrueType {};
|
||||
|
||||
/* Specialization of the template for compliant types */
|
||||
template <>
|
||||
struct SIsCompliant<SProgramOptionsTraits::TokenPairList> : STrueType {};
|
||||
|
||||
/* Specialization of the template for compliant types */
|
||||
template <>
|
||||
struct SIsCompliant<SProgramOptionsTraits::String> : STrueType {};
|
||||
|
||||
/* Specialization of the template for compliant types */
|
||||
template <>
|
||||
struct SIsCompliant<SProgramOptionsTraits::StringList> : STrueType {};
|
||||
|
||||
/* Specialization of the template for compliant types */
|
||||
template <>
|
||||
struct SIsCompliant<SProgramOptionsTraits::Integer> : STrueType {};
|
||||
|
||||
/* Specialization of the template for compliant types */
|
||||
template <>
|
||||
struct SIsCompliant<SProgramOptionsTraits::IntegerList> : STrueType {};
|
||||
|
||||
/* Specialization of the template for compliant types */
|
||||
template <>
|
||||
struct SIsCompliant<SProgramOptionsTraits::Float> : STrueType {};
|
||||
|
||||
/* Specialization of the template for compliant types */
|
||||
template <>
|
||||
struct SIsCompliant<SProgramOptionsTraits::FloatList> : STrueType {};
|
||||
|
||||
/* SIsSignatureCompliant is used to statically checked a list of type is compliant with handled type */
|
||||
template <typename... TList>
|
||||
struct SIsSignatureCompliant;
|
||||
|
||||
/* Specialization for empty list */
|
||||
template <>
|
||||
struct SIsSignatureCompliant<> : STrueType {};
|
||||
|
||||
/* Specialization for non-empty list */
|
||||
template <typename THead, typename... TTail>
|
||||
struct SIsSignatureCompliant<THead, TTail...> :
|
||||
std::conditional<SIsCompliant<THead>::value, SIsSignatureCompliant<TTail...>, SFalseType>::type { };
|
||||
|
||||
/* SIsIn is used to statically check if a type T is in a list of types TList*/
|
||||
template <typename T, typename... TList>
|
||||
struct SIsIn; // interface
|
||||
|
||||
/* Specialization for empty list */
|
||||
template <typename T>
|
||||
struct SIsIn<T> : SFalseType {};
|
||||
|
||||
/* Specialization for list where 1st element is a match */
|
||||
template <typename T, typename... TTail>
|
||||
struct SIsIn<T, T, TTail...> : STrueType {};
|
||||
|
||||
/* Specialization for list of many elements */
|
||||
template <typename T, typename THead, typename... TTail>
|
||||
struct SIsIn<T, THead, TTail...> : SIsIn<T, TTail...> {};
|
||||
|
||||
/* SHasDuplicate is used to statically check if a list of types has duplicates*/
|
||||
template <typename... TList>
|
||||
struct SHasDuplicate;
|
||||
|
||||
/* Specialization for empty list */
|
||||
template <>
|
||||
struct SHasDuplicate<> : SFalseType {};
|
||||
|
||||
/* Specialization for 1-element list */
|
||||
template <typename T>
|
||||
struct SHasDuplicate<T> : SFalseType {};
|
||||
|
||||
/* Specialization for list of many elements */
|
||||
template <typename THead, typename... TTail>
|
||||
struct SHasDuplicate<THead, TTail...> : std::conditional<SIsIn<THead, TTail...>::value, STrueType, SHasDuplicate<TTail...>>::type { };
|
||||
} // namespace ProgramOptionsUtils
|
||||
|
||||
/**
|
||||
* \class ProgramOptions
|
||||
* \author cgarraud (INRIA)
|
||||
* \date 2016-01-25
|
||||
* \brief Command-line options parser
|
||||
* \ingroup ScenarioPlayer
|
||||
*
|
||||
* This class is a basic class used to parse program options.
|
||||
* Input format requirements:
|
||||
* - Option prefix must be '-' or '--' e.g. cmd -help or --help
|
||||
* - Option value assignment must be set with '=': e.g. cmd -config=myfile.txt
|
||||
* - Option value that consists of pair are set with (): e.g. cmd -newToken=(key,value)
|
||||
* .
|
||||
*
|
||||
* Template parameters are the list of option types that can be handled by the class.
|
||||
* This list of options must comply to types defined in ProgramOptionsTrait.\n
|
||||
*
|
||||
* Parsing options occurs in 2 steps:
|
||||
* - Populating the list of possible options with simple options (e.g. --help) and value options (e.g. --option=value)
|
||||
* - Parsing options from command line
|
||||
* .
|
||||
*
|
||||
* \todo The parser has only be tested for the player use. It needs more in-depth testing
|
||||
* to be used in another context. Moreover, it should be extended to accept any type.
|
||||
*
|
||||
* \note The implementation is trivial. Prefer the use of robust and fully featured
|
||||
* boost program_options compiled library if possible.
|
||||
*
|
||||
*/
|
||||
template <typename TFirst, typename... TTypes>
|
||||
class ProgramOptions final
|
||||
{
|
||||
public:
|
||||
|
||||
// static assert are used to raise understandable errors at compile time
|
||||
static_assert(!ProgramOptionsUtils::SHasDuplicate<TFirst, TTypes...>::value, "Duplicates in the type list");
|
||||
static_assert(ProgramOptionsUtils::SIsSignatureCompliant<TFirst, TTypes...>::value, "TTypes not handled by ProgramOptions");
|
||||
|
||||
/**
|
||||
* Struct used to store used-defined option parameters.
|
||||
*/
|
||||
struct SOptionDesc // using a struct allows more extensibility than method parameters
|
||||
{
|
||||
/** Option shortname (e.g. h for help) */
|
||||
std::string shortName;
|
||||
/** Option description used for printing option list */
|
||||
std::string desc;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Add global description to the list of options
|
||||
* \param[in] desc the global description in printable format
|
||||
*
|
||||
* The global description is used as additional printable documentation
|
||||
* when printOptionsDesc() is called.
|
||||
*
|
||||
*/
|
||||
void setGlobalDesc(const std::string& desc);
|
||||
|
||||
/**
|
||||
* \brief Add a simple option to the internal dictionary
|
||||
* \param[in] name the option name
|
||||
* \param[in] optionDesc the option description
|
||||
*
|
||||
* Simple options are option withou value (e.g. --help or --version)
|
||||
*
|
||||
*/
|
||||
void addSimpleOption(const std::string& name, const SOptionDesc& optionDesc);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Add a value option to the internal dictionary
|
||||
* \param[in] name the option name
|
||||
* \param[in] optionDesc the option description
|
||||
*
|
||||
* Template paramter T: The type of the option to be added
|
||||
*/
|
||||
template <typename T>
|
||||
void addValueOption(const std::string& name, const SOptionDesc& optionDesc);
|
||||
|
||||
/**
|
||||
* \brief Parse command line options
|
||||
* \pre addSimpleOption and addValueOption must be called to populate options dictionary
|
||||
* \param[in] argc number of arguments
|
||||
* \param[in] argv pointer to the list of arguments
|
||||
* \return: false if an error occurred during parsing, true otherwise
|
||||
*/
|
||||
bool parse(int argc, char** argv);
|
||||
|
||||
/**
|
||||
* \brief Check if an option was parsed or not
|
||||
* \pre Must be called after parse()
|
||||
* \param[in] name the option name
|
||||
* \return: true if the option was parsed, false otherwise
|
||||
*/
|
||||
bool hasOption(const std::string& name) const;
|
||||
|
||||
/**
|
||||
* \brief Get option value
|
||||
* \pre hasOption() should be called to ensure the option is available
|
||||
* \param[in] name the option name
|
||||
* \return the option value (will be the default value if the option was not parsed)
|
||||
*
|
||||
* Template paramter T: the type of the option to retrieve (must match the type used to set
|
||||
* the option with addValueOption())
|
||||
*/
|
||||
template <typename T>
|
||||
T getOptionValue(const std::string& name) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief print all option descriptions
|
||||
*/
|
||||
void printOptionsDesc() const;
|
||||
|
||||
private:
|
||||
|
||||
// The visitor allows us to apply the correct parsing
|
||||
// for any type (see boost::variant documentation for more details).
|
||||
// Presently, it is pretty ugly. This should be refactored for
|
||||
// as there is a lot of behavorial redundancy.
|
||||
class OptionVisitor : public boost::static_visitor<>
|
||||
{
|
||||
public:
|
||||
|
||||
OptionVisitor(std::string& value) : m_value(value) { }
|
||||
|
||||
void operator()(SProgramOptionsTraits::Integer& operand) const { operand = std::stoi(m_value); }
|
||||
void operator()(SProgramOptionsTraits::Float& operand) const { operand = std::stod(m_value); }
|
||||
void operator()(SProgramOptionsTraits::String& operand) const { operand = m_value; }
|
||||
void operator()(SProgramOptionsTraits::TokenPair& operand) const { operand = this->parsePair(m_value); }
|
||||
void operator()(SProgramOptionsTraits::IntegerList& operand) const { operand.push_back(std::stoi(m_value)); }
|
||||
void operator()(SProgramOptionsTraits::FloatList& operand) const { operand.push_back(std::stod(m_value)); }
|
||||
void operator()(SProgramOptionsTraits::StringList& operand) const { operand.push_back(m_value); }
|
||||
void operator()(SProgramOptionsTraits::TokenPairList& operand) const { operand.push_back(this->parsePair(m_value)); }
|
||||
|
||||
private:
|
||||
|
||||
static SProgramOptionsTraits::TokenPair parsePair(const std::string& str);
|
||||
|
||||
std::string& m_value;
|
||||
};
|
||||
|
||||
using OptionValue = boost::variant<TFirst, TTypes...>;
|
||||
|
||||
// the pair contais a boolean to quickly know if an option
|
||||
// is a simple option or a value option
|
||||
using FullOptionDesc = std::pair<bool, SOptionDesc>;
|
||||
|
||||
std::string m_globalDesc;
|
||||
std::map<std::string, FullOptionDesc> m_descs;
|
||||
std::map<std::string, OptionValue> m_values;
|
||||
std::vector<std::string> m_options;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////
|
||||
/////// Definition ProgramOptions /////////
|
||||
///////////////////////////////////////////
|
||||
|
||||
template <typename TFirst, typename... TTypes>
|
||||
void ProgramOptions<TFirst, TTypes...>::setGlobalDesc(const std::string& desc) { m_globalDesc = desc; }
|
||||
|
||||
template <typename TFirst, typename... TTypes>
|
||||
void ProgramOptions<TFirst, TTypes...>::addSimpleOption(const std::string& name, const SOptionDesc& optionDesc)
|
||||
{
|
||||
m_descs[name] = std::make_pair(true, optionDesc);
|
||||
}
|
||||
|
||||
template <typename TFirst, typename... TTypes>
|
||||
template <typename T>
|
||||
void ProgramOptions<TFirst, TTypes...>::addValueOption(const std::string& name, const SOptionDesc& optionDesc)
|
||||
{
|
||||
m_descs[name] = std::make_pair(false, optionDesc);
|
||||
|
||||
T defaultValue{}; // with this implementation, only default constructible type can be added
|
||||
m_values[name] = defaultValue;
|
||||
}
|
||||
|
||||
template <typename TFirst, typename... TTypes>
|
||||
bool ProgramOptions<TFirst, TTypes...>::hasOption(const std::string& name) const
|
||||
{
|
||||
return std::find(m_options.begin(), m_options.end(), name) != m_options.end();
|
||||
}
|
||||
|
||||
template <typename TFirst, typename... TTypes>
|
||||
template <typename T>
|
||||
T ProgramOptions<TFirst, TTypes...>::getOptionValue(const std::string& name) const
|
||||
{
|
||||
T value{};
|
||||
|
||||
try { value = boost::get<T>(m_values.at(name)); }
|
||||
catch (const std::exception& e) { std::cerr << "ERROR: Caught exception during option value retrieval: " << e.what() << std::endl; }
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename TFirst, typename... TTypes>
|
||||
bool ProgramOptions<TFirst, TTypes...>::parse(const int argc, char** argv)
|
||||
{
|
||||
std::vector<std::string> args;
|
||||
#if defined TARGET_OS_Windows
|
||||
int nArg;
|
||||
LPWSTR* argListUtf16 = CommandLineToArgvW(GetCommandLineW(), &nArg);
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
|
||||
for (int i = 0; i < nArg; ++i) { args.push_back(converter.to_bytes(argListUtf16[i])); }
|
||||
#else
|
||||
args = std::vector<std::string>(argv, argv + argc);
|
||||
#endif
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
std::string arg = args[i];
|
||||
const auto argSplit = arg.find_first_of('='); // = is the separator for value option
|
||||
std::string key;
|
||||
|
||||
if (argSplit == std::string::npos) { key = arg; } // simple option
|
||||
else { key = arg.substr(0, argSplit); } // value option
|
||||
|
||||
// first check if the key exists
|
||||
auto keyMatch = std::find_if(m_descs.begin(), m_descs.end(), [&](const std::pair<std::string, FullOptionDesc>& p)
|
||||
{
|
||||
const auto& desc = p.second.second;
|
||||
return (("-" + p.first) == key) || (("--" + p.first) == key) || (("-" + desc.shortName) == key) || (
|
||||
("--" + desc.shortName) == key);
|
||||
}
|
||||
);
|
||||
|
||||
if (keyMatch == m_descs.end())
|
||||
{
|
||||
std::cout << "WARNING: Found unknown option: " << key << std::endl;
|
||||
std::cout << "Skipping..." << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!keyMatch->second.first) // value option
|
||||
{
|
||||
if (key == arg)
|
||||
{
|
||||
std::cerr << "ERROR: No value set for argument: " << key << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string val = arg.substr(argSplit + 1, arg.size() - argSplit - 1); // take value part of the arg
|
||||
|
||||
try { boost::apply_visitor(OptionVisitor(val), m_values[keyMatch->first]); }
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << "ERROR: Caught exception during option parsing: " << e.what() << std::endl;
|
||||
std::cerr << "Could not parse option with key = " << key << " and value = " << val << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_options.push_back(keyMatch->first);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TFirst, typename... TTypes>
|
||||
void ProgramOptions<TFirst, TTypes...>::printOptionsDesc() const
|
||||
{
|
||||
if (!m_globalDesc.empty()) { std::cout << m_globalDesc << std::endl; }
|
||||
|
||||
std::cout << "TList of available options:\n" << std::endl;
|
||||
|
||||
for (auto& option : m_descs)
|
||||
{
|
||||
std::cout << "Option: --" << option.first << std::endl;
|
||||
const auto& desc = option.second.second;
|
||||
if (!desc.shortName.empty()) { std::cout << "Shortname: --" << desc.shortName << std::endl; }
|
||||
std::cout << "Description: " << std::endl;
|
||||
std::cout << desc.desc << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
/////// Definition Internal Visitor ///////
|
||||
///////////////////////////////////////////
|
||||
|
||||
template <typename TFirst, typename... TTypes>
|
||||
SProgramOptionsTraits::TokenPair ProgramOptions<TFirst, TTypes...>::OptionVisitor::parsePair(const std::string& str)
|
||||
{
|
||||
const auto split = str.find_first_of(':');
|
||||
const auto size = str.size();
|
||||
|
||||
// (a:b) pattern expected
|
||||
// minimal regex std::regex("\\(.+:.+\\)")
|
||||
if (!(size >= 5 && str[0] == '(' && str[size - 1] == ')') || split == std::string::npos)
|
||||
{
|
||||
throw std::runtime_error("Failed to parse token pair from value: " + str);
|
||||
}
|
||||
|
||||
// magic 2 numbers is because substr takes a length as second parameter
|
||||
// 2 = remove the last ) + account for the first one
|
||||
return std::make_pair(str.substr(1, split - 1), str.substr(split + 1, size - split - 2));
|
||||
}
|
||||
} // namespace OpenViBE
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
#include "ovsp_defines.h"
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ovspTProgramOptions.hpp"
|
||||
|
||||
namespace OpenViBE {
|
||||
/**
|
||||
* \defgroup ScenarioPlayer Scenario Player
|
||||
*/
|
||||
|
||||
/**
|
||||
* \class EPlayerReturnCodes
|
||||
* \author cgarraud
|
||||
* \date 2016-01-25
|
||||
* \brief Scenario player list of potential return code
|
||||
* \ingroup ScenarioPlayer
|
||||
*/
|
||||
enum class EPlayerReturnCodes
|
||||
{
|
||||
Success = 0, ///< No error during execution */
|
||||
InvalidArg, ///< Invalid command-line options */
|
||||
MissingMandatoryArgument, ///< A mandatory argument is missing */
|
||||
BadArg, ///< An argument is given with a wrong value */
|
||||
OpeningFileFailure, ///< A file could not be opened */
|
||||
ParsingCommandFailure, ///< General parsing command error*/
|
||||
UnkownFailure, ///< Error of unknown type*/
|
||||
KernelLoadingFailure, ///< Kernel loading failed*/
|
||||
KernelInvalidDesc, ///< Invalid kernel descriptor*/
|
||||
KernelInvalidContext, ///< Invalid kernel context*/
|
||||
KernelInternalFailure, ///< Generic error type for kernel internal error*/
|
||||
ScenarioNotLoaded ///< Error triggered when an action is requested on an unknown scenario */
|
||||
};
|
||||
|
||||
/**
|
||||
* \class EPlayerPlayMode
|
||||
* \author cgarraud
|
||||
* \date 2016-01-25
|
||||
* \brief Way of playing a scenario
|
||||
* \ingroup ScenarioPlayer
|
||||
*/
|
||||
enum class EPlayerPlayMode { Standard = 0, Fastfoward };
|
||||
|
||||
/* Define the common parser to be used in the application */
|
||||
using ProgramOptionParser = ProgramOptions<SProgramOptionsTraits::String, SProgramOptionsTraits::Float, SProgramOptionsTraits::TokenPairList>;
|
||||
|
||||
inline std::string toString(const EPlayerReturnCodes code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case EPlayerReturnCodes::Success: return "Success";
|
||||
case EPlayerReturnCodes::InvalidArg: return "Invalid Arg";
|
||||
case EPlayerReturnCodes::MissingMandatoryArgument: return "Missing Mandatory Argument";
|
||||
case EPlayerReturnCodes::BadArg: return "Bad Arg";
|
||||
case EPlayerReturnCodes::OpeningFileFailure: return "Opening File Failure";
|
||||
case EPlayerReturnCodes::ParsingCommandFailure: return "Parsing Command Failure";
|
||||
case EPlayerReturnCodes::UnkownFailure: return "Unkown Failure";
|
||||
case EPlayerReturnCodes::KernelLoadingFailure: return "Kernel Loading Failure";
|
||||
case EPlayerReturnCodes::KernelInvalidDesc: return "Kernel Invalid Desc";
|
||||
case EPlayerReturnCodes::KernelInvalidContext: return "Kernel Invalid Context";
|
||||
case EPlayerReturnCodes::KernelInternalFailure: return "Kernel Internal Failure";
|
||||
case EPlayerReturnCodes::ScenarioNotLoaded: return "Scenario Not Loaded";
|
||||
default: return "Invalid Code";
|
||||
}
|
||||
}
|
||||
} // namespace OpenViBE
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/*********************************************************************
|
||||
* Software License Agreement (AGPL-3 License)
|
||||
*
|
||||
* OpenViBE SDK Test Software
|
||||
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
* Copyright (C) Inria, 2015-2017,V1.0
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "ovsp_defines.h"
|
||||
#include "ovspCKernelFacade.h"
|
||||
#include "ovspCCommand.h"
|
||||
#include "ovspCCommandLineOptionParser.h"
|
||||
#include "ovspCCommandFileParser.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
void initializeParser(ProgramOptionParser& parser)
|
||||
{
|
||||
const std::string desc =
|
||||
R"d(Usage: program options
|
||||
|
||||
Program can be run in express mode to directly execute a scenario
|
||||
Program can be run in command mode to execute list of commands from a file
|
||||
|
||||
)d";
|
||||
parser.setGlobalDesc(desc);
|
||||
|
||||
parser.addSimpleOption("help", { "h", "Help" });
|
||||
parser.addSimpleOption("version", { "v", "Program version" });
|
||||
|
||||
parser.addValueOption<SProgramOptionsTraits::String>("mode", { "m", "Execution mode: 'x' for express, 'c' for command [mandatory]" });
|
||||
|
||||
// express mode options
|
||||
parser.addValueOption<SProgramOptionsTraits::String>("config-file", { "", "Path to configuration file (express mode only)" });
|
||||
parser.addValueOption<SProgramOptionsTraits::String>("scenario-file", { "", "Path to scenario file (express mode only) [mandatory]" });
|
||||
parser.addValueOption<SProgramOptionsTraits::String>("updated-scenario-file", {
|
||||
"",
|
||||
"Enable update process instead of playing scenario. Path to the updated scenario file (express mode only)."
|
||||
});
|
||||
parser.addValueOption<SProgramOptionsTraits::String>("play-mode",
|
||||
{ "", "Play mode: std for standard and ff for fast-foward (express mode only) [default=std]" });
|
||||
parser.addValueOption<SProgramOptionsTraits::Float>("max-time", { "", "Scenarios playing execution time limit (express mode only)" });
|
||||
parser.addValueOption<SProgramOptionsTraits::TokenPairList>("dg", { "", "Global user-defined token: -dg=\"(token:value)\" (express mode only)" });
|
||||
parser.addValueOption<SProgramOptionsTraits::TokenPairList>("ds", { "", "Scenario user-defined token: -ds=\"(token:value)\" (express mode only)" });
|
||||
|
||||
// command mode options
|
||||
parser.addValueOption<SProgramOptionsTraits::String>("command-file", { "", "Path to command file (command mode only) [mandatory]" });
|
||||
}
|
||||
|
||||
} // namespace OpenViBE
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
OpenViBE::ProgramOptionParser optionParser;
|
||||
initializeParser(optionParser);
|
||||
|
||||
if (!optionParser.parse(argc, argv))
|
||||
{
|
||||
std::cerr << "ERROR: Failed to parse arguments" << std::endl;
|
||||
return int(OpenViBE::EPlayerReturnCodes::InvalidArg);
|
||||
}
|
||||
if (optionParser.hasOption("help"))
|
||||
{
|
||||
optionParser.printOptionsDesc();
|
||||
return int(OpenViBE::EPlayerReturnCodes::Success);
|
||||
}
|
||||
if (optionParser.hasOption("version"))
|
||||
{
|
||||
// PROJECT_VERSION is added to definition from cmake
|
||||
std::cout << "version: " << PROJECT_VERSION << std::endl;
|
||||
return int(OpenViBE::EPlayerReturnCodes::Success);
|
||||
}
|
||||
if (optionParser.hasOption("mode") || optionParser.hasOption("updated-scenario-file"))
|
||||
{
|
||||
// command parser type is selected from mode
|
||||
std::unique_ptr<OpenViBE::ICommandParser> commandParser{ nullptr };
|
||||
const auto mode = optionParser.getOptionValue<OpenViBE::SProgramOptionsTraits::String>("mode");
|
||||
|
||||
if (mode == "c")
|
||||
{
|
||||
// check for the mandatory commad file
|
||||
if (optionParser.hasOption("command-file"))
|
||||
{
|
||||
commandParser.reset(new OpenViBE::CommandFileParser(optionParser.getOptionValue<std::string>("command-file")));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "ERROR: mandatory option 'command-file' not set" << std::endl;
|
||||
return int(OpenViBE::EPlayerReturnCodes::MissingMandatoryArgument);
|
||||
}
|
||||
}
|
||||
else if ((mode == "x") || optionParser.hasOption("updated-scenario-file")) { commandParser.reset(new OpenViBE::CommandLineOptionParser(optionParser)); }
|
||||
else
|
||||
{
|
||||
std::cerr << "ERROR: unknown mode set" << std::endl;
|
||||
std::cerr << "Mode must be 'x' or 'c'" << std::endl;
|
||||
return int(OpenViBE::EPlayerReturnCodes::InvalidArg);
|
||||
}
|
||||
|
||||
commandParser->initialize();
|
||||
|
||||
try
|
||||
{
|
||||
auto returnCode = commandParser->parse();
|
||||
|
||||
if (returnCode == OpenViBE::EPlayerReturnCodes::Success)
|
||||
{
|
||||
OpenViBE::CKernelFacade kernel;
|
||||
|
||||
for (auto& cmd : commandParser->getCommandList())
|
||||
{
|
||||
returnCode = cmd->execute(kernel);
|
||||
if (returnCode != OpenViBE::EPlayerReturnCodes::Success) { return int(returnCode); }
|
||||
}
|
||||
}
|
||||
else { return int(returnCode); }
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << "ERROR: received unexpected exception: " << e.what() << std::endl;
|
||||
return int(OpenViBE::EPlayerReturnCodes::UnkownFailure);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "ERROR: mandatory option 'mode' not set" << std::endl;
|
||||
return int(OpenViBE::EPlayerReturnCodes::MissingMandatoryArgument);
|
||||
}
|
||||
|
||||
return int(OpenViBE::EPlayerReturnCodes::Success);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# Add all the subdirs as projects of the named branch
|
||||
OV_ADD_PROJECTS("EXAMPLES")
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
PROJECT(sdk-examples-communication-client-generator)
|
||||
|
||||
SET(SRC_FILES src/main-generator.cpp)
|
||||
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILES})
|
||||
ADD_DEPENDENCIES(${PROJECT_NAME} openvibe-toolkit)
|
||||
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${APP_FOLDER})
|
||||
|
||||
INCLUDE("FindOpenViBE")
|
||||
INCLUDE("FindOpenViBECommon")
|
||||
INCLUDE("FindOpenViBEModuleEBML")
|
||||
INCLUDE("FindOpenViBEModuleSocket")
|
||||
INCLUDE("FindOpenViBEModuleCommunication")
|
||||
|
||||
SET_BUILD_PLATFORM()
|
||||
|
||||
INSTALL(TARGETS ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION ${DIST_BINDIR}
|
||||
LIBRARY DESTINATION ${DIST_LIBDIR}
|
||||
ARCHIVE DESTINATION ${DIST_LIBDIR})
|
||||
|
||||
PROJECT(sdk-examples-communication-client-filter)
|
||||
|
||||
SET(SRC_FILES src/main-filter.cpp)
|
||||
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILES})
|
||||
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${APP_FOLDER})
|
||||
|
||||
INCLUDE("FindOpenViBE")
|
||||
INCLUDE("FindOpenViBECommon")
|
||||
INCLUDE("FindOpenViBEModuleSocket")
|
||||
INCLUDE("FindOpenViBEModuleCommunication")
|
||||
INCLUDE("FindOpenViBEToolkit")
|
||||
|
||||
SET_BUILD_PLATFORM()
|
||||
|
||||
INSTALL(TARGETS ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION ${DIST_BINDIR}
|
||||
LIBRARY DESTINATION ${DIST_LIBDIR}
|
||||
ARCHIVE DESTINATION ${DIST_LIBDIR})
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include <communication/ovCMessagingClient.h>
|
||||
|
||||
static bool didRequestForcedQuit = false;
|
||||
static void signalHandler(int /* signal */) { didRequestForcedQuit = true; }
|
||||
|
||||
int main(const int argc, char** argv)
|
||||
{
|
||||
std::signal(SIGINT, signalHandler);
|
||||
|
||||
std::string connectionID;
|
||||
size_t port = 49687;
|
||||
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
if (std::strcmp(argv[i], "--connection-id") == 0) { if (argc > i + 1) { connectionID = argv[i + 1]; } }
|
||||
else if (std::strcmp(argv[i], "--port") == 0) { if (argc > i + 1) { port = size_t(std::stoi(argv[i + 1])); } }
|
||||
}
|
||||
didRequestForcedQuit = false;
|
||||
|
||||
Communication::MessagingClient client;
|
||||
|
||||
client.setConnectionID(connectionID);
|
||||
|
||||
while (!client.connect("127.0.0.1", port))
|
||||
{
|
||||
const Communication::MessagingClient::ELibraryError error = client.getLastError();
|
||||
|
||||
if (error == Communication::MessagingClient::ELibraryError::Socket_FailedToConnect)
|
||||
{
|
||||
std::cout << "Server not responding\n";
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error " << error << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (didRequestForcedQuit) { exit(EXIT_SUCCESS); }
|
||||
}
|
||||
|
||||
std::cout << "Connected to server\n";
|
||||
|
||||
// Initialize
|
||||
|
||||
for (size_t i = 0; i < client.getInputCount(); ++i)
|
||||
{
|
||||
uint64_t id;
|
||||
uint64_t type;
|
||||
std::string name;
|
||||
|
||||
if (client.getInput(i, id, type, name)) { std::cout << "Input:\n\tIndex: " << id << "\n\tType: " << type << "\n\tName: " << name << "\n\n"; }
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < client.getOutputCount(); ++i)
|
||||
{
|
||||
uint64_t id;
|
||||
uint64_t type;
|
||||
std::string name;
|
||||
|
||||
if (client.getOutput(i, id, type, name)) { std::cout << "Output:\n\tIndex: " << id << "\n\tType: " << type << "\n\tName: " << name << "\n\n"; }
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < client.getParameterCount(); ++i)
|
||||
{
|
||||
uint64_t id;
|
||||
uint64_t type;
|
||||
std::string name;
|
||||
std::string value;
|
||||
|
||||
if (client.getParameter(i, id, type, name, value))
|
||||
{
|
||||
std::cout << "Parameter:\n\tIndex: " << id << "\n\tType: " << type << "\n\tName: " << name << "\n\tValue: " << value << "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Announce to server that the box has finished initializing and wait for acknowledgement
|
||||
while (!client.waitForSyncMessage()) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); }
|
||||
client.pushLog(Communication::LogLevel_Info, "Received Ping");
|
||||
|
||||
client.pushSync();
|
||||
client.pushLog(Communication::LogLevel_Info, "Sent Pong");
|
||||
|
||||
// Process
|
||||
|
||||
while (!didRequestForcedQuit)
|
||||
{
|
||||
if (client.isEndReceived())
|
||||
{
|
||||
std::cout << "End message received!\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!client.isConnected())
|
||||
{
|
||||
std::cout << "Disconnected!\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if (client.isInErrorState())
|
||||
{
|
||||
std::cerr << "Error state " << client.getLastError() << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// EBML
|
||||
|
||||
uint64_t packetId;
|
||||
size_t index;
|
||||
uint64_t startTime;
|
||||
uint64_t endtime;
|
||||
std::shared_ptr<const std::vector<uint8_t>> ebml;
|
||||
|
||||
// We wait for a synchronization message, this means that the client box has finished sending
|
||||
// all of the data it has received during one process() method call.
|
||||
while (!client.waitForSyncMessage())
|
||||
{
|
||||
while (client.popEBML(packetId, index, startTime, endtime, ebml))
|
||||
{
|
||||
// We just push out the received EBML as is
|
||||
if (!client.pushEBML(index, startTime, endtime, ebml))
|
||||
{
|
||||
std::cerr << "Failed to push EBML.\n";
|
||||
std::cerr << "Error " << client.getLastError() << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
/*if (!client.pushLog(Communication::ELogLevel::LogLevel_Info, "EBML received on index: " + std::to_string(index)))
|
||||
{
|
||||
std::cout << "Failed to push log.\n";
|
||||
client.close();
|
||||
exit(EXIT_FAILURE);
|
||||
}*/
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
// Sync message was received, this means that we are now sure that the buffer will not receive
|
||||
// any additional data as the box is blocked until we acknowledge sending all of the processed
|
||||
// data back
|
||||
while (client.popEBML(packetId, index, startTime, endtime, ebml))
|
||||
{
|
||||
if (!client.pushEBML(index, startTime, endtime, ebml))
|
||||
{
|
||||
std::cerr << "Failed to push EBML.\n";
|
||||
std::cerr << "Error " << client.getLastError() << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
/*if (!client.pushLog(Communication::ELogLevel::LogLevel_Info, "EBML received on index: " + std::to_string(index)))
|
||||
{
|
||||
std::cout << "Failed to push log.\n";
|
||||
client.close();
|
||||
exit(EXIT_FAILURE);
|
||||
}*/
|
||||
}
|
||||
|
||||
// Errors
|
||||
|
||||
Communication::EError error;
|
||||
uint64_t guiltyId;
|
||||
|
||||
while (client.popError(packetId, error, guiltyId))
|
||||
{
|
||||
std::cerr << "Error received:\n";
|
||||
std::cerr << "\tError: " << int(error) << "\n";
|
||||
std::cerr << "\tGuilty Id: " << guiltyId << "\n";
|
||||
}
|
||||
|
||||
// Here, we send a sync message to tell to the server that we have no more
|
||||
// data to send and we can move forward. This will unblock the box.
|
||||
if (!client.pushSync()) { return 0; }
|
||||
}
|
||||
|
||||
std::cout << "Processing stopped.\n";
|
||||
|
||||
|
||||
if (!client.close()) { std::cerr << "Failed to close the connection\n"; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
+291
@@ -0,0 +1,291 @@
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
|
||||
#include <ebml/IWriterHelper.h>
|
||||
#include <ebml/IWriter.h>
|
||||
#include <ebml/TWriterCallbackProxy.h>
|
||||
#include <communication/ovCMessagingClient.h>
|
||||
|
||||
#include <toolkit/ovtk_defines.h>
|
||||
#include <openvibe/ovIMemoryBuffer.h>
|
||||
#include <openvibe/CTime.hpp>
|
||||
|
||||
static bool didRequestForcedQuit = false;
|
||||
static void signalHandler(int /* signal */) { didRequestForcedQuit = true; }
|
||||
|
||||
class EBMLWriterCallback
|
||||
{
|
||||
public:
|
||||
void write(const void* buffer, const size_t size)
|
||||
{
|
||||
const uint8_t* data = static_cast<const uint8_t*>(buffer);
|
||||
m_buffer.insert(m_buffer.end(), data, data + size);
|
||||
}
|
||||
|
||||
void clear() { m_buffer.clear(); }
|
||||
|
||||
const std::vector<uint8_t>& data() const { return m_buffer; }
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> m_buffer;
|
||||
};
|
||||
|
||||
int main(const int argc, char** argv)
|
||||
{
|
||||
std::signal(SIGINT, signalHandler);
|
||||
|
||||
std::string connectionID;
|
||||
size_t port = 49687;
|
||||
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
if (std::strcmp(argv[i], "--connection-id") == 0) { if (argc > i + 1) { connectionID = argv[i + 1]; } }
|
||||
else if (std::strcmp(argv[i], "--port") == 0) { if (argc > i + 1) { port = size_t(std::stoi(argv[i + 1])); } }
|
||||
}
|
||||
|
||||
// EBML
|
||||
|
||||
EBMLWriterCallback callback;
|
||||
EBML::TWriterCallbackProxy1<EBMLWriterCallback> callbackProxy(callback, &EBMLWriterCallback::write);
|
||||
EBML::IWriter* writer = createWriter(callbackProxy);
|
||||
EBML::IWriterHelper* helper = EBML::createWriterHelper();
|
||||
helper->connect(writer);
|
||||
|
||||
didRequestForcedQuit = false;
|
||||
|
||||
Communication::MessagingClient client;
|
||||
|
||||
client.setConnectionID(connectionID);
|
||||
|
||||
while (!client.connect("127.0.0.1", port))
|
||||
{
|
||||
const Communication::MessagingClient::ELibraryError error = client.getLastError();
|
||||
|
||||
if (error == Communication::MessagingClient::ELibraryError::Socket_FailedToConnect)
|
||||
{
|
||||
std::cout << "Server not responding\n";
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error " << error << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (didRequestForcedQuit) { exit(EXIT_SUCCESS); }
|
||||
}
|
||||
|
||||
std::cout << "Connected to server\n";
|
||||
|
||||
// Initialize
|
||||
|
||||
if (client.getInputCount() > 0)
|
||||
{
|
||||
std::cerr << "The test generator can not take any inputs, was given " << client.getInputCount() << std::endl;
|
||||
client.close();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < client.getOutputCount(); ++i)
|
||||
{
|
||||
uint64_t id;
|
||||
uint64_t type;
|
||||
std::string name;
|
||||
|
||||
if (client.getOutput(i, id, type, name)) { std::cout << "Output:\n\tIndex: " << id << "\n\tType: " << type << "\n\tName: " << name << "\n\n"; }
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> parameters;
|
||||
|
||||
for (size_t i = 0; i < client.getParameterCount(); ++i)
|
||||
{
|
||||
uint64_t id;
|
||||
uint64_t type;
|
||||
std::string name;
|
||||
std::string value;
|
||||
|
||||
client.getParameter(i, id, type, name, value);
|
||||
parameters[name] = value;
|
||||
}
|
||||
|
||||
if (!(parameters.count("Channel Count")))
|
||||
{
|
||||
std::cerr << "Missing parameter" << std::endl;
|
||||
client.close();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
const size_t nChannel = size_t(std::stoul(parameters.at("Channel Count")));
|
||||
const size_t samplingRate = size_t(std::stoul(parameters.at("Sampling Rate")));
|
||||
const size_t samplesPerBuffer = size_t(std::stoul(parameters.at("Samples Per Buffer")));
|
||||
const size_t samplesToSend = size_t(std::stoul(parameters.at("Amount of Samples to Generate")));
|
||||
|
||||
std::vector<double> matrix;
|
||||
matrix.resize(nChannel * samplesPerBuffer);
|
||||
|
||||
// Announce to server that the box has finished initializing and wait for acknowledgement
|
||||
while (!client.waitForSyncMessage()) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); }
|
||||
client.pushLog(Communication::LogLevel_Info, "Received Ping");
|
||||
|
||||
client.pushSync();
|
||||
client.pushLog(Communication::LogLevel_Info, "Sent Pong");
|
||||
|
||||
// Process
|
||||
|
||||
// Send the header
|
||||
callback.clear();
|
||||
helper->openChild(OVTK_NodeId_Header);
|
||||
{
|
||||
helper->openChild(OVTK_NodeId_Header_StreamType);
|
||||
{
|
||||
helper->setUInt(0);
|
||||
helper->closeChild();
|
||||
}
|
||||
helper->openChild(OVTK_NodeId_Header_StreamVersion);
|
||||
{
|
||||
helper->setUInt(0);
|
||||
helper->closeChild();
|
||||
}
|
||||
|
||||
helper->openChild(OVTK_NodeId_Header_Signal);
|
||||
{
|
||||
helper->openChild(OVTK_NodeId_Header_Signal_Sampling);
|
||||
{
|
||||
helper->setUInt(samplingRate);
|
||||
helper->closeChild();
|
||||
}
|
||||
helper->closeChild();
|
||||
}
|
||||
|
||||
helper->openChild(OVTK_NodeId_Header_StreamedMatrix);
|
||||
{
|
||||
helper->openChild(OVTK_NodeId_Header_StreamedMatrix_DimensionCount);
|
||||
{
|
||||
helper->setUInt(2);
|
||||
helper->closeChild();
|
||||
}
|
||||
helper->openChild(OVTK_NodeId_Header_StreamedMatrix_Dimension);
|
||||
{
|
||||
helper->openChild(OVTK_NodeId_Header_StreamedMatrix_Dimension_Size);
|
||||
{
|
||||
helper->setUInt(nChannel);
|
||||
helper->closeChild();
|
||||
}
|
||||
helper->closeChild();
|
||||
}
|
||||
helper->openChild(OVTK_NodeId_Header_StreamedMatrix_Dimension);
|
||||
{
|
||||
helper->openChild(OVTK_NodeId_Header_StreamedMatrix_Dimension_Size);
|
||||
{
|
||||
helper->setUInt(samplesPerBuffer);
|
||||
helper->closeChild();
|
||||
}
|
||||
helper->closeChild();
|
||||
}
|
||||
helper->closeChild();
|
||||
}
|
||||
helper->closeChild();
|
||||
}
|
||||
if (!client.pushEBML(0, 0, 0, std::make_shared<const std::vector<uint8_t>>(callback.data())))
|
||||
{
|
||||
std::cerr << "Failed to push EBML.\n";
|
||||
std::cerr << "Error " << client.getLastError() << "\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
client.pushSync();
|
||||
|
||||
size_t sentSamples = 0;
|
||||
while (!didRequestForcedQuit || (samplesToSend != 0 && sentSamples < samplesToSend))
|
||||
{
|
||||
if (client.isEndReceived())
|
||||
{
|
||||
std::cout << "End message received!\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!client.isConnected())
|
||||
{
|
||||
std::cout << "Disconnected!\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if (client.isInErrorState())
|
||||
{
|
||||
std::cerr << "Error state " << client.getLastError() << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// Send data
|
||||
|
||||
while (!client.waitForSyncMessage()) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); }
|
||||
|
||||
const uint64_t expectedSamples = OpenViBE::CTime(client.getTime()).toSampleCount(samplingRate);
|
||||
|
||||
while (sentSamples < expectedSamples && (samplesToSend == 0 || sentSamples < samplesToSend))
|
||||
{
|
||||
for (size_t channel = 0; channel < nChannel; ++channel)
|
||||
{
|
||||
for (size_t sample = 0; sample < samplesPerBuffer; ++sample)
|
||||
{
|
||||
matrix[channel * samplesPerBuffer + sample] = sin((sentSamples + sample) / double(samplingRate));
|
||||
}
|
||||
}
|
||||
|
||||
callback.clear();
|
||||
helper->openChild(OVTK_NodeId_Buffer);
|
||||
{
|
||||
helper->openChild(OVTK_NodeId_Buffer_StreamedMatrix);
|
||||
{
|
||||
helper->openChild(OVTK_NodeId_Buffer_StreamedMatrix_RawBuffer);
|
||||
{
|
||||
helper->setBinary(matrix.data(), matrix.size() * sizeof(double));
|
||||
helper->closeChild();
|
||||
}
|
||||
helper->closeChild();
|
||||
}
|
||||
helper->closeChild();
|
||||
}
|
||||
|
||||
|
||||
const uint64_t tStart = OpenViBE::CTime(samplingRate, sentSamples).time();
|
||||
const uint64_t tEnd = OpenViBE::CTime(samplingRate, sentSamples + samplesPerBuffer).time();
|
||||
|
||||
if (!client.pushEBML(0, tStart, tEnd, std::make_shared<const std::vector<uint8_t>>(callback.data())))
|
||||
{
|
||||
std::cerr << "Failed to push EBML.\n";
|
||||
std::cerr << "Error " << client.getLastError() << "\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
sentSamples += samplesPerBuffer;
|
||||
}
|
||||
|
||||
// Errors
|
||||
uint64_t packetId;
|
||||
Communication::EError error;
|
||||
uint64_t guiltyId;
|
||||
|
||||
while (client.popError(packetId, error, guiltyId)) { std::cerr << "Error received:\n\tError: " << int(error) << "\n\tGuilty Id: " << guiltyId << "\n"; }
|
||||
// Here, we send a sync message to tell to the server that we have no more data to send and we can move forward.
|
||||
if (!client.pushSync()) { exit(EXIT_FAILURE); }
|
||||
}
|
||||
|
||||
std::cout << "Processing stopped.\n";
|
||||
|
||||
helper->disconnect();
|
||||
helper->release();
|
||||
writer->release();
|
||||
|
||||
if (!client.close()) { std::cerr << "Failed to close the connection\n"; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
# Add all the subdirs as projects of the named branch
|
||||
OV_ADD_PROJECTS("BUILD_TOOL")
|
||||
@@ -0,0 +1,23 @@
|
||||
PROJECT(openvibe-stimulation-generator)
|
||||
|
||||
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
|
||||
SET(PROJECT_VERSION_MINOR ${OV_GLOBAL_VERSION_MINOR})
|
||||
SET(PROJECT_VERSION_PATCH ${OV_GLOBAL_VERSION_PATCH})
|
||||
SET(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
|
||||
|
||||
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.inl)
|
||||
ADD_EXECUTABLE(openvibe-stimulation-generator ${SRC_FILES})
|
||||
|
||||
# if(UNIX)
|
||||
# SET(stim_generator_path "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "stim_generator_path")
|
||||
# else()
|
||||
# get_property(path_to_target TARGET openvibe-stimulation-generator PROPERTY LOCATION)
|
||||
# SET(stim_generator_path "${path_to_target}" CACHE INTERNAL "stim_generator_path")
|
||||
# MESSAGE(STATUS "MOO ${stim_generator_path}")
|
||||
#endif()
|
||||
|
||||
# ---------------------------------
|
||||
# Target macros
|
||||
# Defines target operating system, architecture and compiler
|
||||
# ---------------------------------
|
||||
SET_BUILD_PLATFORM()
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
#include "ovbt_sg_defines.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
bool CCppCodeGenerator::openFile(const char* filename)
|
||||
{
|
||||
m_file.open(filename, std::ios::out | std::ios::trunc);
|
||||
if (!m_file.is_open()) { return false; }
|
||||
m_file << "#include \"toolkit/ovtk_all.h\"" << std::endl << std::endl;
|
||||
|
||||
m_file << "using namespace OpenViBE;" << std::endl;
|
||||
m_file << "using namespace /*OpenViBE::*/Kernel;" << std::endl;
|
||||
m_file << "using namespace /*OpenViBE::*/Toolkit;" << std::endl << std::endl << std::endl;
|
||||
|
||||
m_file << "bool Toolkit::initializeStimulationList(const Kernel::IKernelContext& ctx)" << std::endl;
|
||||
m_file << "{" << std::endl;
|
||||
m_file << "\tITypeManager& typeManager=ctx.getTypeManager();" << std::endl << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCppCodeGenerator::appendStimulation(SStimulation& stim)
|
||||
{
|
||||
m_file << "\ttypeManager.registerEnumerationEntry(OV_TypeId_Stimulation, \"" << stim.name << "\", " << stim.id << ");" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCppCodeGenerator::closeFile()
|
||||
{
|
||||
m_file << std::endl << "\treturn true;" << std::endl << "}" << std::endl;
|
||||
m_file.close();
|
||||
return true;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#include "ovbt_sg_defines.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
bool CCppDefineGenerator::openFile(const char* filename)
|
||||
{
|
||||
m_file.open(filename, std::ios::out | std::ios::trunc);
|
||||
if (!m_file.is_open()) { return false; }
|
||||
m_file << "#pragma once" << std::endl << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCppDefineGenerator::appendStimulation(SStimulation& stim)
|
||||
{
|
||||
m_file << "#define " << stim.id << " " << stim.hexa << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCppDefineGenerator::closeFile()
|
||||
{
|
||||
m_file << std::endl;
|
||||
m_file.close();
|
||||
return true;
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
struct SStimulation
|
||||
{
|
||||
std::string name;
|
||||
std::string id;
|
||||
std::string hexa;
|
||||
};
|
||||
|
||||
class CFileGeneratorBase
|
||||
{
|
||||
public:
|
||||
virtual ~CFileGeneratorBase() = default;
|
||||
virtual bool openFile(const char* filename) = 0;
|
||||
virtual bool appendStimulation(SStimulation& stim) = 0;
|
||||
virtual bool closeFile() = 0;
|
||||
protected:
|
||||
std::ofstream m_file;
|
||||
};
|
||||
|
||||
|
||||
class CCppDefineGenerator final : public CFileGeneratorBase
|
||||
{
|
||||
public:
|
||||
bool openFile(const char* filename) override;
|
||||
bool appendStimulation(SStimulation& stim) override;
|
||||
bool closeFile() override;
|
||||
};
|
||||
|
||||
class CCppCodeGenerator final : public CFileGeneratorBase
|
||||
{
|
||||
public:
|
||||
bool openFile(const char* filename) override;
|
||||
bool appendStimulation(SStimulation& stim) override;
|
||||
bool closeFile() override;
|
||||
};
|
||||
|
||||
class CMatlabGenerator final : public CFileGeneratorBase
|
||||
{
|
||||
public:
|
||||
bool openFile(const char* filename) override;
|
||||
bool appendStimulation(SStimulation& stim) override;
|
||||
bool closeFile() override;
|
||||
};
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
#include "ovbt_sg_defines.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum class EGenerationTypes { CPP, MATLAB, PYTHON, LUA, UNKNOWN };
|
||||
|
||||
EGenerationTypes parse_argument(std::string option)
|
||||
{
|
||||
if (option == "--cpp") { return EGenerationTypes::CPP; }
|
||||
if (option == "--matlab") { return EGenerationTypes::MATLAB; }
|
||||
if (option == "--python") { return EGenerationTypes::PYTHON; }
|
||||
if (option == "--lua") { return EGenerationTypes::LUA; }
|
||||
return EGenerationTypes::UNKNOWN;
|
||||
}
|
||||
|
||||
int generate_generator_list(std::vector<CFileGeneratorBase*>& list, EGenerationTypes type, int argc, char** argv)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EGenerationTypes::CPP:
|
||||
{
|
||||
if (argc < 4) { return -1; }
|
||||
CFileGeneratorBase* gen = new CCppDefineGenerator();
|
||||
if (!gen->openFile(argv[3]))
|
||||
{
|
||||
std::cerr << "Unable to open " << argv[3] << std::endl;
|
||||
return -1;
|
||||
}
|
||||
list.push_back(gen);
|
||||
|
||||
gen = new CCppCodeGenerator();
|
||||
if (!gen->openFile(argv[4]))
|
||||
{
|
||||
std::cerr << "Unable to open " << argv[4] << std::endl;
|
||||
return -1;
|
||||
}
|
||||
list.push_back(gen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case EGenerationTypes::MATLAB:
|
||||
{
|
||||
CFileGeneratorBase* gen = new CMatlabGenerator();
|
||||
if (!gen->openFile(argv[3]))
|
||||
{
|
||||
std::cerr << "Unable to open " << argv[3] << std::endl;
|
||||
return -1;
|
||||
}
|
||||
list.push_back(gen);
|
||||
return 0;
|
||||
}
|
||||
case EGenerationTypes::PYTHON:
|
||||
case EGenerationTypes::LUA:
|
||||
case EGenerationTypes::UNKNOWN:
|
||||
default:
|
||||
{
|
||||
std::cerr << "Unhandle type. Fatal error" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc < 3) { return -1; }
|
||||
EGenerationTypes type = parse_argument(argv[1]);
|
||||
|
||||
std::vector<SStimulation> stimulations;
|
||||
std::vector<CFileGeneratorBase*> generators;
|
||||
|
||||
std::ifstream file(argv[2]);
|
||||
std::string name, id, hexaCode;
|
||||
while (file >> name >> id >> hexaCode)
|
||||
{
|
||||
SStimulation temp = { name, id, hexaCode };
|
||||
stimulations.push_back(temp);
|
||||
}
|
||||
|
||||
if (generate_generator_list(generators, type, argc, argv)) { return -1; }
|
||||
|
||||
//Now we generate all files that needs to be done
|
||||
for (auto& s : stimulations) { for (auto& g : generators) { g->appendStimulation(s); } }
|
||||
for (auto& g : generators) { g->closeFile(); }
|
||||
|
||||
return 0;
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
#include "ovbt_sg_defines.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
std::string getBrutHexaCode(std::string formatedHexaCode)
|
||||
{
|
||||
std::string res = formatedHexaCode;
|
||||
res.erase(res.begin(), res.begin() + 2);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool CMatlabGenerator::openFile(const char* filename)
|
||||
{
|
||||
m_file.open(filename, std::ios::out | std::ios::trunc);
|
||||
if (!m_file.is_open()) { return false; }
|
||||
m_file << "function OV_stimulations()" << std::endl << std::endl;
|
||||
|
||||
m_file << "global OVTK_StimulationId_LabelStart;" << std::endl;
|
||||
m_file << "OVTK_StimulationId_LabelStart = uint64(hex2dec('00008100'));" << std::endl << std::endl;
|
||||
m_file << "global OVTK_StimulationId_LabelEnd;" << std::endl;
|
||||
m_file << "OVTK_StimulationId_LabelEnd = uint64(hex2dec('000081ff'));" << std::endl << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMatlabGenerator::appendStimulation(SStimulation& stim)
|
||||
{
|
||||
m_file << "\tglobal " << stim.id << ";" << std::endl;
|
||||
m_file << "\t" << stim.id << " = uint64(hex2dec('" << getBrutHexaCode(stim.hexa) << "'));" << std::endl << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMatlabGenerator::closeFile()
|
||||
{
|
||||
m_file << "end" << std::endl;
|
||||
m_file.close();
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
# ---------------------------------
|
||||
# Finds OpenViBE
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
OPTION(DYNAMIC_LINK_OPENVIBE "Dynamically link OpenViBE" ON)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE)
|
||||
ADD_DEFINITIONS(-DOV_Shared)
|
||||
ENDIF(DYNAMIC_LINK_OPENVIBE)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE)
|
||||
SET(OPENVIBE_LINKING "")
|
||||
ELSE(DYNAMIC_LINK_OPENVIBE)
|
||||
SET(OPENVIBE_LINKING "-static")
|
||||
ENDIF(DYNAMIC_LINK_OPENVIBE)
|
||||
|
||||
set(SRC_DIR ${OV_BASE_DIR}/openvibe)
|
||||
|
||||
SET(PATH_OPENVIBE "PATH_OPENVIBE-NOTFOUND")
|
||||
FIND_PATH(PATH_OPENVIBE include/openvibe/ov_all.h PATHS ${SRC_DIR} NO_DEFAULT_PATH)
|
||||
IF(PATH_OPENVIBE)
|
||||
debug_message( " Found OpenViBE... [${PATH_OPENVIBE}]")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE}/include/)
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} openvibe${OPENVIBE_LINKING})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_OpenViBE)
|
||||
ELSE(PATH_OPENVIBE)
|
||||
MESSAGE(WARNING " FAILED to find OpenViBE...")
|
||||
ENDIF(PATH_OPENVIBE)
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# ---------------------------------
|
||||
# Finds OpenViBE common include files
|
||||
# Adds dependency to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
|
||||
SET(PATH_OPENVIBE_COMMON "PATH_OPENVIBE_COMMON-NOTFOUND")
|
||||
FIND_PATH(PATH_OPENVIBE_COMMON ov_common_defines.h PATHS ${OV_BASE_DIR}/common/include NO_DEFAULT_PATH)
|
||||
IF(PATH_OPENVIBE_COMMON)
|
||||
debug_message( " Found openvibe-common...")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE_COMMON})
|
||||
|
||||
ADD_DEPENDENCIES(${PROJECT_NAME} openvibe-common)
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_OpenViBE_Common)
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines)
|
||||
ELSE(PATH_OPENVIBE_COMMON)
|
||||
MESSAGE(WARNING " FAILED to find openvibe-common...")
|
||||
ENDIF(PATH_OPENVIBE_COMMON)
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# ---------------------------------
|
||||
# Finds OpenViBE contributions
|
||||
# Only serves to set up a define for the preprocessor
|
||||
# ---------------------------------
|
||||
|
||||
FIND_PATH(PATH_OPENVIBE_CONTRIBUTIONS common/contribAcquisitionServer.cmake PATHS ${OV_BASE_DIR}/contrib NO_DEFAULT_PATH)
|
||||
IF(PATH_OPENVIBE_CONTRIBUTIONS)
|
||||
debug_message( " Found openvibe-contributions...")
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_OpenViBEContributions)
|
||||
ELSE(PATH_OPENVIBE_CONTRIBUTIONS)
|
||||
MESSAGE(WARNING " FAILED to find openvibe-contributions...")
|
||||
ENDIF(PATH_OPENVIBE_CONTRIBUTIONS)
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# ---------------------------------
|
||||
# Finds module CSV
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
OPTION(DYNAMIC_LINK_OPENVIBE_MODULE_CSV "Dynamically link OpenViBE module CSV" ON)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE_MODULE_CSV)
|
||||
SET(OPENVIBE_MODULE_CSV_LINKING "")
|
||||
ADD_DEFINITIONS(-DCSV_Shared)
|
||||
ELSE()
|
||||
SET(OPENVIBE_MODULE_CSV_LINKING "-static")
|
||||
ADD_DEFINITIONS(-DCSV_Static)
|
||||
ENDIF()
|
||||
|
||||
set(PATH_OPENVIBE_MODULES_CSV "PATH_OPENVIBE_MODULES_CSV-NOTFOUND")
|
||||
set(SRC_DIR ${OV_BASE_DIR}/modules/csv/include)
|
||||
|
||||
FIND_PATH(PATH_OPENVIBE_MODULES_CSV csv/defines.h PATHS ${SRC_DIR} NO_DEFAULT_PATH)
|
||||
|
||||
IF(PATH_OPENVIBE_MODULES_CSV)
|
||||
debug_message( " Found OpenViBE module CSV...")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE_MODULES_CSV}/)
|
||||
debug_message( " Link openvibe-module-csv${OPENVIBE_MODULE_CSV_LINKING}")
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} openvibe-module-csv${OPENVIBE_MODULE_CSV_LINKING})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_CSV)
|
||||
ELSE()
|
||||
MESSAGE(WARNING " FAILED to find OpenViBE module CSV...")
|
||||
ENDIF()
|
||||
@@ -0,0 +1,29 @@
|
||||
# ---------------------------------
|
||||
# Finds module Communication
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
OPTION(DYNAMIC_LINK_OPENVIBE_MODULE_COMMUNICATION "Dynamically link OpenViBE module Communication" ON)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE_MODULE_COMMUNICATION)
|
||||
SET(OPENVIBE_MODULE_COMMUNICATION_LINKING "")
|
||||
ADD_DEFINITIONS(-DCommunication_Shared)
|
||||
ELSE()
|
||||
SET(OPENVIBE_MODULE_COMMUNICATION_LINKING "-static")
|
||||
ADD_DEFINITIONS(-DCommunication_Static)
|
||||
ENDIF()
|
||||
|
||||
set(PATH_OPENVIBE_MODULES_COMMUNICATION "PATH_OPENVIBE_MODULES_COMMUNICATION-NOTFOUND")
|
||||
set(SRC_DIR ${OV_BASE_DIR}/modules/communication/include)
|
||||
|
||||
FIND_PATH(PATH_OPENVIBE_MODULES_COMMUNICATION communication/defines.h PATHS ${SRC_DIR} NO_DEFAULT_PATH)
|
||||
IF(PATH_OPENVIBE_MODULES_COMMUNICATION)
|
||||
MESSAGE(STATUS " Found OpenViBE module Communication... ${PATH_OPENVIBE_MODULE_COMMUNICATION}/openvibe-module-communication${OPENVIBE_MODULE_COMMUNICATION_LINKING}")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE_MODULES_COMMUNICATION}/)
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} openvibe-module-communication${OPENVIBE_MODULE_COMMUNICATION_LINKING})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_COMMUNICATION)
|
||||
ELSE()
|
||||
MESSAGE(WARNING " FAILED to find OpenViBE module Communication...")
|
||||
ENDIF()
|
||||
@@ -0,0 +1,29 @@
|
||||
# ---------------------------------
|
||||
# Finds module Date
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
OPTION(DYNAMIC_LINK_OPENVIBE_MODULE_DATE "Dynamically link OpenViBE module Date" OFF)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE_MODULE_DATE)
|
||||
SET(OPENVIBE_MODULE_DATE_LINKING "")
|
||||
ADD_DEFINITIONS(-DDATE_Shared)
|
||||
ELSE()
|
||||
SET(OPENVIBE_MODULE_DATE_LINKING "-static")
|
||||
ADD_DEFINITIONS(-DDATE_Static)
|
||||
ENDIF()
|
||||
|
||||
set(PATH_OPENVIBE_MODULES_DATE "PATH_OPENVIBE_MODULES_DATE-NOTFOUND")
|
||||
set(SRC_DIR ${OV_BASE_DIR}/modules/date/include)
|
||||
|
||||
FIND_PATH(PATH_OPENVIBE_MODULES_DATE date/defines.h PATHS ${SRC_DIR} NO_DEFAULT_PATH)
|
||||
IF(PATH_OPENVIBE_MODULES_DATE)
|
||||
debug_message( " Found OpenViBE module Date...")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE_MODULES_DATE}/)
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} openvibe-module-date${OPENVIBE_MODULE_DATE_LINKING})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_DATE)
|
||||
ELSE()
|
||||
MESSAGE(WARNING " FAILED to find OpenViBE module Date...")
|
||||
ENDIF()
|
||||
@@ -0,0 +1,29 @@
|
||||
# ---------------------------------
|
||||
# Finds module EBML
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
OPTION(DYNAMIC_LINK_OPENVIBE_MODULE_EBML "Dynamically link OpenViBE module EBML" ON)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE_MODULE_EBML)
|
||||
SET(OPENVIBE_MODULE_EBML_LINKING "")
|
||||
ADD_DEFINITIONS(-DEBML_Shared)
|
||||
ELSE()
|
||||
SET(OPENVIBE_MODULE_EBML_LINKING "-static")
|
||||
ADD_DEFINITIONS(-DEBML_Static)
|
||||
ENDIF()
|
||||
|
||||
set(PATH_OPENVIBE_MODULES_EBML "PATH_OPENVIBE_MODULES_EBML-NOTFOUND")
|
||||
set(SRC_DIR ${OV_BASE_DIR}/modules/ebml/include)
|
||||
|
||||
FIND_PATH(PATH_OPENVIBE_MODULES_EBML ebml/defines.h PATHS ${SRC_DIR} NO_DEFAULT_PATH)
|
||||
IF(PATH_OPENVIBE_MODULES_EBML)
|
||||
debug_message( " Found OpenViBE module EBML...")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE_MODULES_EBML}/)
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} openvibe-module-ebml${OPENVIBE_MODULE_EBML_LINKING})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_EBML)
|
||||
ELSE(PATH_OPENVIBE_MODULES_EBML)
|
||||
MESSAGE(WARNING " FAILED to find OpenViBE module EBML...")
|
||||
ENDIF(PATH_OPENVIBE_MODULES_EBML)
|
||||
@@ -0,0 +1,29 @@
|
||||
# ---------------------------------
|
||||
# Finds module FS
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
OPTION(DYNAMIC_LINK_OPENVIBE_MODULE_FS "Dynamically link OpenViBE module FS" ON)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE_MODULE_FS)
|
||||
SET(OPENVIBE_MODULE_FS_LINKING "")
|
||||
ADD_DEFINITIONS(-DFS_Shared)
|
||||
ELSE()
|
||||
SET(OPENVIBE_MODULE_FS_LINKING "-static")
|
||||
ADD_DEFINITIONS(-DFS_Static)
|
||||
ENDIF()
|
||||
|
||||
set(PATH_OPENVIBE_MODULES_FS "PATH_OPENVIBE_MODULES_FS-NOTFOUND")
|
||||
set(SRC_DIR ${OV_BASE_DIR}/modules/fs/include)
|
||||
|
||||
FIND_PATH(PATH_OPENVIBE_MODULES_FS fs/defines.h PATHS ${SRC_DIR} NO_DEFAULT_PATH)
|
||||
IF(PATH_OPENVIBE_MODULES_FS)
|
||||
debug_message( " Found OpenViBE module FS... openvibe-module-fs${OPENVIBE_MODULE_FS_LINKING}")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE_MODULES_FS}/)
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} openvibe-module-fs${OPENVIBE_MODULE_FS_LINKING})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_FS)
|
||||
ELSE(PATH_OPENVIBE_MODULES_FS)
|
||||
MESSAGE(WARNING " FAILED to find OpenViBE module FS...")
|
||||
ENDIF(PATH_OPENVIBE_MODULES_FS)
|
||||
@@ -0,0 +1,48 @@
|
||||
# ---------------------------------
|
||||
# Finds module Socket
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
OPTION(DYNAMIC_LINK_OPENVIBE_MODULE_SOCKET "Dynamically link OpenViBE module Socket" ON)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE_MODULE_SOCKET)
|
||||
SET(OPENVIBE_MODULE_SOCKET_LINKING "")
|
||||
ADD_DEFINITIONS(-DSocket_Shared)
|
||||
ELSE()
|
||||
SET(OPENVIBE_MODULE_SOCKET_LINKING "-static")
|
||||
ADD_DEFINITIONS(-DSocket_Static)
|
||||
ENDIF()
|
||||
|
||||
set(PATH_OPENVIBE_MODULES_SOCKET "PATH_OPENVIBE_MODULES_SOCKET-NOTFOUND")
|
||||
set(SRC_DIR ${OV_BASE_DIR}/modules/socket/include)
|
||||
|
||||
FIND_PATH(PATH_OPENVIBE_MODULES_SOCKET socket/defines.h PATHS ${SRC_DIR} NO_DEFAULT_PATH)
|
||||
IF(PATH_OPENVIBE_MODULES_SOCKET)
|
||||
debug_message( " Found OpenViBE module Socket... ${PATH_OPENVIBE_MODULE_SOCKET}/openvibe-module-socket${OPENVIBE_MODULE_SOCKET_LINKING}")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE_MODULES_SOCKET}/)
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} openvibe-module-socket${OPENVIBE_MODULE_SOCKET_LINKING})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_Socket)
|
||||
|
||||
# if we link with the module socket in Static, we must link the project with the dependency on win32
|
||||
IF(WIN32 AND NOT DYNAMIC_LINK_OPENVIBE_MODULE_SOCKET)
|
||||
INCLUDE("FindThirdPartyWinsock2")
|
||||
|
||||
# FIND_LIBRARY(LIB_STANDARD_MODULE_WINSOCK ws2_32)
|
||||
# IF(LIB_STANDARD_MODULE_WINSOCK)
|
||||
# debug_message( " Found ws2_32...")
|
||||
# IF(TARGET ${PROJECT_NAME})
|
||||
# TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIB_STANDARD_MODULE_WINSOCK})
|
||||
# ENDIF()
|
||||
# IF(TARGET ${PROJECT_NAME}-static)
|
||||
# TARGET_LINK_LIBRARIES(${PROJECT_NAME}-static ${LIB_STANDARD_MODULE_WINSOCK})
|
||||
# ENDIF()
|
||||
# ELSE(LIB_STANDARD_MODULE_WINSOCK)
|
||||
# debug_message( " FAILED to find ws2_32...")
|
||||
# ENDIF(LIB_STANDARD_MODULE_WINSOCK)
|
||||
ENDIF(WIN32 AND NOT DYNAMIC_LINK_OPENVIBE_MODULE_SOCKET)
|
||||
|
||||
ELSE(PATH_OPENVIBE_MODULES_SOCKET)
|
||||
MESSAGE(WARNING " FAILED to find OpenViBE module Socket...")
|
||||
ENDIF(PATH_OPENVIBE_MODULES_SOCKET)
|
||||
@@ -0,0 +1,30 @@
|
||||
# ---------------------------------
|
||||
# Finds module Stream
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
OPTION(DYNAMIC_LINK_OPENVIBE_MODULE_STREAM "Dynamically link OpenViBE module Stream" ON)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE_MODULE_STREAM)
|
||||
SET(OPENVIBE_MODULE_STREAM_LINKING "")
|
||||
ELSE(DYNAMIC_LINK_OPENVIBE_MODULE_STREAM)
|
||||
SET(OPENVIBE_MODULE_STREAM_LINKING "-static")
|
||||
ENDIF(DYNAMIC_LINK_OPENVIBE_MODULE_STREAM)
|
||||
|
||||
IF(OV_BRANCH_MODULES_STREAM)
|
||||
set(SRC_DIR ${OV_BASE_DIR}/openvibe-modules/stream/${OV_BRANCH_MODULES_STREAM})
|
||||
ELSE(OV_BRANCH_MODULES_STREAM)
|
||||
set(SRC_DIR ${OV_BASE_DIR}/openvibe-modules/stream/${OV_TRUNK})
|
||||
ENDIF(OV_BRANCH_MODULES_STREAM)
|
||||
|
||||
FIND_PATH(PATH_OPENVIBE_MODULES_STREAM src/stream/defines.h PATHS ${OV_BASE_DIR}/openvibe-modules/stream)
|
||||
IF(PATH_OPENVIBE_MODULES_STREAM)
|
||||
debug_message( " Found OpenViBE module Stream...")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE_MODULES_STREAM}/include)
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} openvibe-module-stream${OPENVIBE_MODULE_STREAM_LINKING})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_Stream)
|
||||
ELSE(PATH_OPENVIBE_MODULES_STREAM)
|
||||
MESSAGE(WARNING " FAILED to find OpenViBE module Stream...")
|
||||
ENDIF(PATH_OPENVIBE_MODULES_STREAM)
|
||||
@@ -0,0 +1,29 @@
|
||||
# ---------------------------------
|
||||
# Finds module System
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
OPTION(DYNAMIC_LINK_OPENVIBE_MODULE_SYSTEM "Dynamically link OpenViBE module System" ON)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE_MODULE_SYSTEM)
|
||||
SET(OPENVIBE_MODULE_SYSTEM_LINKING "")
|
||||
ADD_DEFINITIONS(-DSystem_Shared)
|
||||
ELSE()
|
||||
SET(OPENVIBE_MODULE_SYSTEM_LINKING "-static")
|
||||
ADD_DEFINITIONS(-DSystem_Static)
|
||||
ENDIF()
|
||||
|
||||
set(PATH_OPENVIBE_MODULES_SYSTEM "PATH_OPENVIBE_MODULES_SYSTEM-NOTFOUND")
|
||||
set(SRC_DIR ${OV_BASE_DIR}/modules/system/include)
|
||||
|
||||
FIND_PATH(PATH_OPENVIBE_MODULES_SYSTEM system/defines.h PATHS ${SRC_DIR} NO_DEFAULT_PATH)
|
||||
IF(PATH_OPENVIBE_MODULES_SYSTEM)
|
||||
debug_message( " Found OpenViBE module System...")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE_MODULES_SYSTEM}/)
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} openvibe-module-system${OPENVIBE_MODULE_SYSTEM_LINKING})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_System)
|
||||
ELSE(PATH_OPENVIBE_MODULES_SYSTEM)
|
||||
MESSAGE(WARNING " FAILED to find OpenViBE module System...")
|
||||
ENDIF(PATH_OPENVIBE_MODULES_SYSTEM)
|
||||
@@ -0,0 +1,30 @@
|
||||
# ---------------------------------
|
||||
# Finds module XML
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
OPTION(DYNAMIC_LINK_OPENVIBE_MODULE_XML "Dynamically link OpenViBE module XML" ON)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE_MODULE_XML)
|
||||
SET(OPENVIBE_MODULE_XML_LINKING "")
|
||||
ADD_DEFINITIONS(-DXML_Shared)
|
||||
ELSE(DYNAMIC_LINK_OPENVIBE_MODULE_XML)
|
||||
SET(OPENVIBE_MODULE_XML_LINKING "-static")
|
||||
ADD_DEFINITIONS(-DXML_Static)
|
||||
SET(Boost_USE_STATIC_LIBS ON)
|
||||
ENDIF(DYNAMIC_LINK_OPENVIBE_MODULE_XML)
|
||||
|
||||
set(PATH_OPENVIBE_MODULES_XML "PATH_OPENVIBE_MODULES_XML-NOTFOUND")
|
||||
set(SRC_DIR ${OV_BASE_DIR}/modules/xml/include)
|
||||
|
||||
FIND_PATH(PATH_OPENVIBE_MODULES_XML xml/defines.h PATHS ${SRC_DIR} NO_DEFAULT_PATH)
|
||||
IF(PATH_OPENVIBE_MODULES_XML)
|
||||
debug_message( " Found OpenViBE module XML...")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE_MODULES_XML}/)
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} openvibe-module-xml${OPENVIBE_MODULE_XML_LINKING})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_XML)
|
||||
ELSE(PATH_OPENVIBE_MODULES_XML)
|
||||
MESSAGE(WARNING " FAILED to find OpenViBE module XML...")
|
||||
ENDIF(PATH_OPENVIBE_MODULES_XML)
|
||||
@@ -0,0 +1,18 @@
|
||||
# ---------------------------------
|
||||
# Finds OpenViBEPluginsGlobalDefines
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
#
|
||||
# @deprecated Running FindOpenVibeCommon.cmake is sufficient
|
||||
#
|
||||
# ---------------------------------
|
||||
SET(PATH_OpenViBEPluginsGlobalDefines "PATH_OpenViBEPluginsGlobalDefines-NOTFOUND")
|
||||
FIND_PATH(PATH_OpenViBEPluginsGlobalDefines ovp_global_defines.h PATHS ${OV_BASE_DIR}/common/include NO_DEFAULT_PATH)
|
||||
IF(PATH_OpenViBEPluginsGlobalDefines)
|
||||
debug_message( " Found OpenViBE plugins global defines...")
|
||||
INCLUDE_DIRECTORIES(${PATH_OpenViBEPluginsGlobalDefines})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines)
|
||||
ELSE(PATH_OpenViBEPluginsGlobalDefines)
|
||||
MESSAGE(WARNING " FAILED to find OpenViBE plugins global defines")
|
||||
ENDIF(PATH_OpenViBEPluginsGlobalDefines)
|
||||
@@ -0,0 +1,38 @@
|
||||
# ---------------------------------
|
||||
# Finds openvibe-toolkit
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
OPTION(LINK_OPENVIBE_TOOLKIT "By default, link openvibe-toolkit, otherwise only use the includes" ON)
|
||||
OPTION(DYNAMIC_LINK_OPENVIBE_TOOLKIT "Dynamically link openvibe-toolkit" ON)
|
||||
|
||||
IF(DYNAMIC_LINK_OPENVIBE_TOOLKIT)
|
||||
SET(OPENVIBE_TOOLKIT_LINKING "")
|
||||
ADD_DEFINITIONS(-DOVTK_Shared)
|
||||
ELSE()
|
||||
SET(OPENVIBE_TOOLKIT_LINKING "-static")
|
||||
ADD_DEFINITIONS(-DOVTK_Static)
|
||||
ENDIF()
|
||||
|
||||
SET(SRC_DIR ${OV_BASE_DIR}/toolkit/include)
|
||||
|
||||
FIND_PATH(PATH_OPENVIBE_TOOLKIT toolkit/ovtk_all.h PATHS ${SRC_DIR} NO_DEFAULT_PATH)
|
||||
|
||||
IF(PATH_OPENVIBE_TOOLKIT)
|
||||
debug_message( " Found openvibe-toolkit... ${PATH_OPENVIBE_TOOLKIT} ${PATH_OPENVIBE_TOOLKIT_BIN}")
|
||||
INCLUDE_DIRECTORIES(${PATH_OPENVIBE_TOOLKIT})
|
||||
|
||||
# No find path for this directory as content is not generated yet
|
||||
INCLUDE_DIRECTORIES(${OV_BASE_BIN_DIR}/toolkit/include)
|
||||
|
||||
IF(LINK_OPENVIBE_TOOLKIT)
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} openvibe-toolkit${OPENVIBE_TOOLKIT_LINKING})
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_OpenViBEToolkit)
|
||||
ELSE()
|
||||
MESSAGE(FATAL " FAILED to find openvibe-toolkit...")
|
||||
ENDIF()
|
||||
|
||||
|
||||
INCLUDE("FindOpenViBEModuleXML")
|
||||
@@ -0,0 +1,10 @@
|
||||
# ---------------------------------
|
||||
# Finds DSP filters sources
|
||||
# Sets dsp_filters_source_files
|
||||
# Adds appropriate include dir
|
||||
# ---------------------------------
|
||||
|
||||
FILE(GLOB_RECURSE dsp_filters_source_files ${OV_SOURCE_DEPENDENCIES_PATH}/dsp-filters/*.cpp ${OV_SOURCE_DEPENDENCIES_PATH}/dsp-filters/*.c ${OV_SOURCE_DEPENDENCIES_PATH}/dsp-filters/*.h)
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_DSPFilters)
|
||||
INCLUDE_DIRECTORIES("${OV_SOURCE_DEPENDENCIES_PATH}")
|
||||
SET(SRC_FILES "${SRC_FILES};${dsp_filters_source_files}")
|
||||
@@ -0,0 +1,10 @@
|
||||
# ---------------------------------
|
||||
# Finds Lepton sources
|
||||
# Sets lepton_source_files
|
||||
# Adds appropriate include dir
|
||||
# ---------------------------------
|
||||
|
||||
FILE(GLOB_RECURSE lepton_source_files ${OV_SOURCE_DEPENDENCIES_PATH}/lepton/*.cpp ${OV_SOURCE_DEPENDENCIES_PATH}/lepton/*.h)
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_LEPTON)
|
||||
INCLUDE_DIRECTORIES("${OV_SOURCE_DEPENDENCIES_PATH}")
|
||||
SET(SRC_FILES "${SRC_FILES};${lepton_source_files}")
|
||||
@@ -0,0 +1,10 @@
|
||||
# ---------------------------------
|
||||
# Find r8brain sources
|
||||
# Sets r9brain_source_files
|
||||
# Adds appropriate include dir
|
||||
# ---------------------------------
|
||||
|
||||
FILE(GLOB_RECURSE r8brain_source_files ${OV_SOURCE_DEPENDENCIES_PATH}/r8brain/*.cpp ${OV_SOURCE_DEPENDENCIES_PATH}/r8brain/*.h)
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_R8BRAIN)
|
||||
INCLUDE_DIRECTORIES("${OV_SOURCE_DEPENDENCIES_PATH}")
|
||||
SET(SRC_FILES "${SRC_FILES};${r8brain_source_files}")
|
||||
@@ -0,0 +1,10 @@
|
||||
# ---------------------------------
|
||||
# Finds wavelib sources
|
||||
# Sets wavelib_source_files
|
||||
# Adds appropriate include dir
|
||||
# ---------------------------------
|
||||
|
||||
FILE(GLOB_RECURSE wavelib_source_files ${OV_SOURCE_DEPENDENCIES_PATH}/wavelib/src/*.cpp ${OV_SOURCE_DEPENDENCIES_PATH}/wavelib/src/*.c ${OV_SOURCE_DEPENDENCIES_PATH}/wavelib/src/*.h ${OV_SOURCE_DEPENDENCIES_PATH}/wavelib/header/*.h)
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_WAVELIB)
|
||||
INCLUDE_DIRECTORIES("${OV_SOURCE_DEPENDENCIES_PATH}")
|
||||
SET(SRC_FILES "${SRC_FILES};${wavelib_source_files}")
|
||||
@@ -0,0 +1,10 @@
|
||||
# ---------------------------------
|
||||
# Configure RC file
|
||||
# Sets SRC_FILES to add the path to the newly created rc file
|
||||
# Adds appropriate include dir
|
||||
# ---------------------------------
|
||||
IF(WIN32)
|
||||
OV_CONFIGURE_RC(NAME ${PROJECT_NAME})
|
||||
SET(SRC_FILES "${SRC_FILES};${CMAKE_BINARY_DIR}/resource-files/${PROJECT_NAME}.rc")
|
||||
ENDIF()
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# ---------------------------------
|
||||
# Finds third party boost
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
|
||||
SET(PATH_BOOST "PATH_BOOST-NOTFOUND")
|
||||
FIND_PATH(PATH_BOOST "include/boost/config/auto_link.hpp" PATHS ${OV_CUSTOM_DEPENDENCIES_PATH}/boost ${OV_CUSTOM_DEPENDENCIES_PATH} NO_DEFAULT_PATH)
|
||||
FIND_PATH(PATH_BOOST "include/boost/config/auto_link.hpp" PATHS ${OV_CUSTOM_DEPENDENCIES_PATH}/boost)
|
||||
|
||||
IF(PATH_BOOST)
|
||||
debug_message( " Found boost includes...")
|
||||
INCLUDE_DIRECTORIES(${PATH_BOOST}/include)
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_Boost)
|
||||
ELSE(PATH_BOOST)
|
||||
MESSAGE(WARNING " FAILED to find boost includes...")
|
||||
ENDIF(PATH_BOOST)
|
||||
@@ -0,0 +1,31 @@
|
||||
# ---------------------------------
|
||||
# Finds third party boost chrono
|
||||
# Adds a def that its present
|
||||
# ---------------------------------
|
||||
|
||||
FIND_PATH(PATH_BOOST_CHRONO "include/boost/chrono.hpp" PATHS ${OV_CUSTOM_DEPENDENCIES_PATH}/boost ${OV_CUSTOM_DEPENDENCIES_PATH} NO_DEFAULT_PATH)
|
||||
FIND_PATH(PATH_BOOST_CHRONO "include/boost/chrono.hpp" PATHS ${OV_CUSTOM_DEPENDENCIES_PATH}/boost)
|
||||
|
||||
IF(PATH_BOOST_CHRONO)
|
||||
debug_message( " Found boost chrono includes...")
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_Boost_Chrono)
|
||||
ELSE(PATH_BOOST_CHRONO)
|
||||
MESSAGE(WARNING " FAILED to find boost chrono includes...")
|
||||
ENDIF(PATH_BOOST_CHRONO)
|
||||
|
||||
IF(UNIX)
|
||||
FIND_LIBRARY(LIB_Boost_Chrono NAMES "boost_chrono-mt" "boost_chrono" PATHS ${OV_CUSTOM_DEPENDENCIES_PATH}/lib NO_DEFAULT_PATH)
|
||||
FIND_LIBRARY(LIB_Boost_Chrono NAMES "boost_chrono-mt" "boost_chrono" PATHS ${OV_CUSTOM_DEPENDENCIES_PATH}/lib)
|
||||
|
||||
IF(LIB_Boost_Chrono)
|
||||
debug_message( " [ OK ] lib ${LIB_Boost_Chrono}")
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIB_Boost_Chrono} )
|
||||
ELSE(LIB_Boost_Chrono)
|
||||
MESSAGE(WARNING " [FAILED] lib boost_chrono-mt")
|
||||
MESSAGE(WARNING " [FAILED] lib boost_chrono")
|
||||
ENDIF(LIB_Boost_Chrono)
|
||||
ENDIF(UNIX)
|
||||
|
||||
IF(WIN32)
|
||||
OV_LINK_BOOST_LIB("chrono" ${OV_WIN32_BOOST_VERSION})
|
||||
ENDIF(WIN32)
|
||||
@@ -0,0 +1,32 @@
|
||||
# ---------------------------------
|
||||
# Finds third party boost
|
||||
# Adds library to target
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
IF(APPLE)
|
||||
find_package(Boost 1.60.0 COMPONENTS filesystem system)
|
||||
if(Boost_FOUND)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES})
|
||||
endif()
|
||||
ELSEIF(UNIX)
|
||||
find_package(Boost 1.54.0 COMPONENTS filesystem system)
|
||||
if(Boost_FOUND)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES})
|
||||
endif()
|
||||
|
||||
# For Fedora
|
||||
FIND_LIBRARY(LIB_STANDARD_MODULE_PTHREAD pthread)
|
||||
IF(LIB_STANDARD_MODULE_PTHREAD)
|
||||
debug_message( " Found pthread...")
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIB_STANDARD_MODULE_PTHREAD})
|
||||
ELSE(LIB_STANDARD_MODULE_PTHREAD)
|
||||
MESSAGE(WARNING " FAILED to find pthread...")
|
||||
ENDIF(LIB_STANDARD_MODULE_PTHREAD)
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32)
|
||||
OV_LINK_BOOST_LIB("filesystem" ${OV_WIN32_BOOST_VERSION} )
|
||||
OV_LINK_BOOST_LIB("system" ${OV_WIN32_BOOST_VERSION} ) # filesystem depends on system
|
||||
ENDIF(WIN32)
|
||||
@@ -0,0 +1,54 @@
|
||||
# ---------------------------------
|
||||
# Finds Eigen headers
|
||||
#
|
||||
# Adds include path
|
||||
# ---------------------------------
|
||||
|
||||
IF(WIN32)
|
||||
SET(PATH_EIGEN "PATH_EIGEN-NOTFOUND")
|
||||
FIND_PATH(PATH_EIGEN Eigen/Eigen PATHS ${OV_CUSTOM_DEPENDENCIES_PATH}/eigen NO_DEFAULT_PATH)
|
||||
IF(PATH_EIGEN)
|
||||
SET(EIGEN_FOUND TRUE)
|
||||
SET(EIGEN_INCLUDE_DIRS ${PATH_EIGEN})
|
||||
SET(EIGEN_CFLAGS "")
|
||||
#SET(EIGEN_LIBRARIES_RELEASE EIGEN)
|
||||
#SET(EIGEN_LIBRARIES_DEBUG EIGENd)
|
||||
#SET(EIGEN_LIBRARY_DIRS ${PATH_EIGEN}/lib )
|
||||
ENDIF(PATH_EIGEN)
|
||||
ENDIF(WIN32)
|
||||
|
||||
IF(UNIX)
|
||||
|
||||
# @FIXME remove that when an Ubuntu package will be available
|
||||
# Find in priority local library for eigen even if linux package has been installed
|
||||
# reason: package on distri Ubuntu 16.04 is still bugged (eigen 3.2.92)
|
||||
INCLUDE("FindPkgConfig")
|
||||
UNSET(PATH_EIGEN_LOCAL CACHE)
|
||||
FIND_PATH(PATH_EIGEN_LOCAL eigen3 PATHS "/usr/local/include" NO_DEFAULT_PATH)
|
||||
SET(EIGEN_FOUND FALSE)
|
||||
IF (PATH_EIGEN_LOCAL)
|
||||
SET(EIGEN_INCLUDE_DIRS "${PATH_EIGEN_LOCAL}/eigen3")
|
||||
SET(EIGEN_CFLAGS "-I${EIGEN_INCLUDE_DIRS}")
|
||||
SET(EIGEN_FOUND TRUE)
|
||||
ELSE()
|
||||
pkg_check_modules(EIGEN eigen3)
|
||||
ENDIF()
|
||||
|
||||
# @FIXME uncomment that when an Ubuntu package will be available
|
||||
#SET(EIGEN_FOUND FALSE)
|
||||
#INCLUDE("FindPkgConfig")
|
||||
#pkg_check_modules(EIGEN eigen3)
|
||||
|
||||
ENDIF(UNIX)
|
||||
|
||||
IF(EIGEN_FOUND)
|
||||
debug_message( "Found eigen3... [${EIGEN_INCLUDE_DIRS}]")
|
||||
INCLUDE_DIRECTORIES("${EIGEN_INCLUDE_DIRS}")
|
||||
ADD_DEFINITIONS(${EIGEN_CFLAGS})
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_ThirdPartyEIGEN)
|
||||
ELSE(EIGEN_FOUND)
|
||||
MESSAGE(WARNING " FAILED to find eigen3...")
|
||||
ENDIF(EIGEN_FOUND)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# ---------------------------------
|
||||
# Finds EXPAT toolkit
|
||||
#
|
||||
# Sets EXPAT_FOUND
|
||||
# Sets EXPAT_LIBRARIES
|
||||
# Sets EXPAT_LIBRARY_DIRS
|
||||
# Sets EXPAT_LDFLAGS
|
||||
# Sets EXPAT_LDFLAGS_OTHERS
|
||||
# Sets EXPAT_INCLUDE_DIRS
|
||||
# Sets EXPAT_CFLAGS
|
||||
# Sets EXPAT_CFLAGS_OTHERS
|
||||
# ---------------------------------
|
||||
IF(UNIX)
|
||||
SET(EXPAT_expat_INCLUDE_PATH "EXPAT_expat_INCLUDE_PATH-NOTFOUND")
|
||||
FIND_PATH(EXPAT_expat_INCLUDE_PATH "expat.h"
|
||||
PATHS "${OV_CUSTOM_DEPENDENCIES_PATH}/include")
|
||||
FIND_LIBRARY(EXPAT_expat_LIBRARY
|
||||
NAMES expat
|
||||
PATHS "${OV_CUSTOM_DEPENDENCIES_PATH}/lib")
|
||||
ENDIF(UNIX)
|
||||
|
||||
IF(WIN32)
|
||||
SET(EXPAT_expat_INCLUDE_PATH "EXPAT_expat_INCLUDE_PATH-NOTFOUND")
|
||||
FIND_PATH(EXPAT_expat_INCLUDE_PATH "expat.h"
|
||||
PATHS ${OV_CUSTOM_DEPENDENCIES_PATH} PATH_SUFFIXES expat/include expat/Source/lib)
|
||||
FIND_LIBRARY(EXPAT_expat_LIBRARY
|
||||
NAMES libexpat
|
||||
PATHS ${OV_CUSTOM_DEPENDENCIES_PATH} PATH_SUFFIXES expat/Lib expat/Bin)
|
||||
|
||||
FIND_PATH(EXPAT_BIN . PATHS ${OV_CUSTOM_DEPENDENCIES_PATH} PATH_SUFFIXES expat/Bin NO_DEFAULT_PATH)
|
||||
|
||||
INSTALL(
|
||||
DIRECTORY ${EXPAT_BIN}/
|
||||
DESTINATION ${DIST_BINDIR}
|
||||
FILES_MATCHING PATTERN "*.dll")
|
||||
ENDIF(WIN32)
|
||||
|
||||
IF(EXPAT_expat_INCLUDE_PATH)
|
||||
IF(EXPAT_expat_LIBRARY)
|
||||
SET(EXPAT_FOUND TRUE)
|
||||
SET(EXPAT_LIBRARIES ${EXPAT_expat_LIBRARY})
|
||||
SET(EXPAT_LIBRARY_DIRS "")
|
||||
SET(EXPAT_LDFLAGS "")
|
||||
SET(EXPAT_LDFLAGS_OTHERS "")
|
||||
SET(EXPAT_INCLUDE_DIRS ${EXPAT_expat_INCLUDE_PATH})
|
||||
SET(EXPAT_CFLAGS "")
|
||||
SET(EXPAT_CFLAGS_OTHERS "")
|
||||
ENDIF(EXPAT_expat_LIBRARY)
|
||||
ENDIF(EXPAT_expat_INCLUDE_PATH)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
EXPAT_expat_INCLUDE_PATH
|
||||
EXPAT_expat_LIBRARY
|
||||
|
||||
EXPAT_FOUND
|
||||
EXPAT_LIBRARIES
|
||||
EXPAT_LIBRARY_DIRS
|
||||
EXPAT_LDFLAGS
|
||||
EXPAT_LDFLAGS_OTHERS
|
||||
EXPAT_INCLUDE_DIRS
|
||||
EXPAT_CFLAGS
|
||||
EXPAT_CFLAGS_OTHERS
|
||||
)
|
||||
|
||||
IF(EXPAT_FOUND)
|
||||
debug_message( " Found expat...")
|
||||
INCLUDE_DIRECTORIES(${EXPAT_INCLUDE_DIRS})
|
||||
ADD_DEFINITIONS(${EXPAT_CFLAGS})
|
||||
ADD_DEFINITIONS(${EXPAT_CFLAGS_OTHERS})
|
||||
# LINK_DIRECTORIES(${EXPAT_LIBRARY_DIRS})
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${EXPAT_LIBRARIES})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_ThirdPartyExpat)
|
||||
ELSE(EXPAT_FOUND)
|
||||
MESSAGE(WARNING " FAILED to find expat...")
|
||||
ENDIF(EXPAT_FOUND)
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# ---------------------------------
|
||||
# Finds TVicPort toolkit
|
||||
#
|
||||
# Sets TVICPORT_FOUND
|
||||
# Sets TVICPORT_LIBRARIES
|
||||
# Sets TVICPORT_LIBRARY_DIRS
|
||||
# Sets TVICPORT_LDFLAGS
|
||||
# Sets TVICPORT_LDFLAGS_OTHERS
|
||||
# Sets TVICPORT_INCLUDE_DIRS
|
||||
# Sets TVICPORT_CFLAGS
|
||||
# Sets TVICPORT_CFLAGS_OTHERS
|
||||
# ---------------------------------
|
||||
|
||||
IF(WIN32)
|
||||
SET(TVICPORT_tvicport_INCLUDE_PATH "TVICPORT_tvicport_INCLUDE_PATH-NOTFOUND")
|
||||
|
||||
FIND_PATH(TVICPORT_tvicport_INCLUDE_PATH "TVicPort.h"
|
||||
PATHS "${OV_CUSTOM_DEPENDENCIES_PATH}/tvicport/include")
|
||||
|
||||
# FIND_LIBRARY(TVICPORT_tvicport_LIBRARY
|
||||
# NAMES TVicPort
|
||||
# PATHS "${OV_CUSTOM_DEPENDENCIES_PATH}/tvicport/libs")
|
||||
ENDIF(WIN32)
|
||||
|
||||
IF(TVICPORT_tvicport_INCLUDE_PATH)
|
||||
IF(TVICPORT_tvicport_LIBRARY)
|
||||
SET(TVICPORT_FOUND TRUE)
|
||||
#SET(TVICPORT_LIBRARIES ${TVICPORT_tvicport_LIBRARY})
|
||||
#SET(TVICPORT_LIBRARY_DIRS "")
|
||||
SET(TVICPORT_LDFLAGS "")
|
||||
SET(TVICPORT_LDFLAGS_OTHERS "")
|
||||
SET(TVICPORT_INCLUDE_DIRS ${TVICPORT_tvicport_INCLUDE_PATH})
|
||||
SET(TVICPORT_CFLAGS "")
|
||||
SET(TVICPORT_CFLAGS_OTHERS "")
|
||||
ENDIF(TVICPORT_tvicport_LIBRARY)
|
||||
ENDIF(TVICPORT_tvicport_INCLUDE_PATH)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
TVICPORT_tvicport_INCLUDE_PATH
|
||||
TVICPORT_tvicport_LIBRARY
|
||||
|
||||
TVICPORT_FOUND
|
||||
#TVICPORT_LIBRARIES
|
||||
#TVICPORT_LIBRARY_DIRS
|
||||
TVICPORT_LDFLAGS
|
||||
TVICPORT_LDFLAGS_OTHERS
|
||||
TVICPORT_INCLUDE_DIRS
|
||||
TVICPORT_CFLAGS
|
||||
TVICPORT_CFLAGS_OTHERS
|
||||
)
|
||||
|
||||
IF(TVICPORT_FOUND)
|
||||
debug_message( " Found TVicPort...")
|
||||
INCLUDE_DIRECTORIES(${TVICPORT_INCLUDE_DIRS})
|
||||
ADD_DEFINITIONS(${TVICPORT_CFLAGS})
|
||||
ADD_DEFINITIONS(${TVICPORT_CFLAGS_OTHERS})
|
||||
# LINK_DIRECTORIES(${EXPAT_LIBRARY_DIRS})
|
||||
#ARGET_LINK_LIBRARIES(${PROJECT_NAME} ${TVICPORT_LIBRARIES})
|
||||
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_ThirdPartyTVicPort)
|
||||
ELSE(TVICPORT_FOUND)
|
||||
MESSAGE(WARNING " FAILED to find TVicPort...")
|
||||
ENDIF(TVICPORT_FOUND)
|
||||
@@ -0,0 +1,30 @@
|
||||
# ---------------------------------
|
||||
# Finds Xerces dependency
|
||||
# ---------------------------------
|
||||
|
||||
IF(WIN32)
|
||||
FIND_PATH(XERCES_ROOT lib PATHS ${OV_CUSTOM_DEPENDENCIES_PATH} PATH_SUFFIXES xerces-c NO_DEFAULT_PATH)
|
||||
SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${XERCES_ROOT}/include")
|
||||
SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${XERCES_ROOT}/lib")
|
||||
|
||||
INSTALL(
|
||||
DIRECTORY ${XERCES_ROOT}/bin/
|
||||
DESTINATION ${DIST_BINDIR}
|
||||
FILES_MATCHING PATTERN "*.dll")
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(XercesC REQUIRED)
|
||||
|
||||
IF(XercesC_FOUND)
|
||||
debug_message( " Found xerces...")
|
||||
|
||||
INCLUDE_DIRECTORIES(${XercesC_INCLUDE_DIRS})
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${XercesC_LIBRARIES})
|
||||
ADD_DEFINITIONS(-DTARGET_HAS_ThirdPartyXERCES)
|
||||
|
||||
ELSE()
|
||||
MESSAGE(WARNING " FAILED to find xerces...")
|
||||
ENDIF()
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# ---------------------------------
|
||||
# create CMake variables that holds
|
||||
# - latest git commit hash
|
||||
# - branch name
|
||||
# ---------------------------------
|
||||
|
||||
# codename = the name of the current branch
|
||||
EXECUTE_PROCESS(COMMAND git rev-parse --abbrev-ref HEAD
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE PROJECT_BRANCH)
|
||||
# command output may contain carriage return
|
||||
STRING(REGEX REPLACE "\n" "" PROJECT_BRANCH "${PROJECT_BRANCH}")
|
||||
|
||||
# commithash = short hash of latest revision
|
||||
EXECUTE_PROCESS(COMMAND git rev-parse --short HEAD
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE PROJECT_COMMITHASH)
|
||||
# command output may contain carriage return
|
||||
STRING(REGEX REPLACE "\n" "" PROJECT_COMMITHASH "${PROJECT_COMMITHASH}")
|
||||
@@ -0,0 +1,124 @@
|
||||
# Adds the current project to the global properties
|
||||
FUNCTION(OV_ADD_THIS_TO_PROJECT_LIST)
|
||||
# MESSAGE(STATUS "ADDING: ${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
# Add the dir to be parsed for documentation later. We need to do this before adding subdir, in case the subdir is the actual docs dir
|
||||
#GET_PROPERTY(OV_TMP GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS)
|
||||
#SET(OV_TMP "${OV_TMP};${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
#SET_PROPERTY(GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS ${OV_TMP})
|
||||
IF(NOT MULTI_BUILD)
|
||||
IF(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc AND NOT(${SKIP_DOC_OPENVIBE}))
|
||||
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/doc/ DESTINATION ${DIST_DOCTMP}/openvibe FILES_MATCHING PATTERN "*.dox")
|
||||
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/doc/ DESTINATION ${DIST_DOCTMP}/openvibe PATTERN "*.dox" EXCLUDE)
|
||||
ENDIF()
|
||||
|
||||
IF(IS_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/include) AND NOT(${SKIP_DOCUMENTATION}) AND NOT(${SKIP_DOC_OPENVIBE}))
|
||||
FILE(APPEND "${DIST_DOCTMP}/openvibe/source-list.txt" "${CMAKE_CURRENT_SOURCE_DIR}/include\n")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDFUNCTION()
|
||||
|
||||
FUNCTION(OV_SET_CUSTOM_DOCUMENTATION doc_project_name doc_product_name)
|
||||
MESSAGE(STATUS "CUSTOM DOCUMENTATION ENABLED FOR ${doc_project_name}")
|
||||
SET(HAS_CUSTOM_DOCUMENTATION_${doc_project_name} "1" PARENT_SCOPE)
|
||||
IF(${BUILD_DOCUMENTATION})
|
||||
SET(CUSTOM_DOCUMENTATION_PRODUCT_NAME_${doc_project_name} "${doc_product_name}" PARENT_SCOPE)
|
||||
|
||||
# if we need also the sources (e.g. the API is documented with doxygen)
|
||||
SET(ADDITIONAL_FOLDERS_STRING_LIST "")
|
||||
FOREACH(additional_cpp_source ${ARGN})
|
||||
SET(ADDITIONAL_FOLDERS_STRING_LIST "${ADDITIONAL_FOLDERS_STRING_LIST} ${CMAKE_CURRENT_SOURCE_DIR}/${doc_project_name}/${additional_cpp_source}")
|
||||
ENDFOREACH()
|
||||
SET(CUSTOM_DOCUMENTATION_CPP_SOURCES_${doc_project_name} "${ADDITIONAL_FOLDERS_STRING_LIST}" PARENT_SCOPE)
|
||||
ENDIF()
|
||||
ENDFUNCTION()
|
||||
|
||||
#
|
||||
# Adds all directories as subdirectories to the CMake build, using the branch specified (if any) in the root CMakeList.txt or
|
||||
# trunk otherwise.
|
||||
#
|
||||
# The branch variable name that is checked is made up from ${CURRENT_BRANCH_PREFIX}_${DIRNAMEUPPER}.
|
||||
#
|
||||
# The script also adds the directory to the global list of projects.
|
||||
#
|
||||
|
||||
FUNCTION(OV_ADD_PROJECTS CURRENT_FOLDER_PREFIX)
|
||||
|
||||
FILE(GLOB FILENAMES "*")
|
||||
|
||||
FOREACH(FULLPATH ${FILENAMES})
|
||||
IF(IS_DIRECTORY ${FULLPATH} AND EXISTS "${FULLPATH}/CMakeLists.txt")
|
||||
GET_FILENAME_COMPONENT(DIRNAME ${FULLPATH} NAME)
|
||||
|
||||
STRING(TOUPPER ${DIRNAME} DIRNAMEUPPER)
|
||||
SET(SKIP_THIS_FOLDER "SKIP_${CURRENT_FOLDER_PREFIX}_${DIRNAMEUPPER}")
|
||||
SET(SKIP_THIS_CUSTOM_DOCUMENTATION "SKIP_DOC_${CURRENT_FOLDER_PREFIX}_${DIRNAMEUPPER}")
|
||||
|
||||
#MESSAGE(STATUS "Checking SKIP_${CURRENT_FOLDER_PREFIX}_${DIRNAMEUPPER} as branch var ${SKIP_THIS_FOLDER}")
|
||||
|
||||
IF(${SKIP_THIS_FOLDER})
|
||||
MESSAGE(STATUS "Note: ${FULLPATH} has been skipped by setting SKIP_${CURRENT_FOLDER_PREFIX}_${DIRNAMEUPPER}")
|
||||
ELSE()
|
||||
# MESSAGE(STATUS "Inserting folder ${FULLPATH}")
|
||||
|
||||
# Add the dir to be parsed for documentation later. We need to do this before adding subdir, in case the subdir is the actual docs dir
|
||||
GET_PROPERTY(OV_TMP GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS)
|
||||
SET(OV_TMP "${OV_TMP};${FULLPATH}")
|
||||
SET_PROPERTY(GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS ${OV_TMP})
|
||||
|
||||
SET(OV_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/${DIRNAME}")
|
||||
GET_PROPERTY(OV_TMP GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS_BUILD_DIR)
|
||||
SET(OV_TMP "${OV_TMP};${OV_CURRENT_BINARY_DIR}")
|
||||
SET_PROPERTY(GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS_BUILD_DIR ${OV_TMP})
|
||||
|
||||
|
||||
SET(HAS_CUSTOM_DOCUMENTATION "HAS_CUSTOM_DOCUMENTATION_${DIRNAME}")
|
||||
SET(CUSTOM_DOCUMENTATION_PRODUCT_NAME "CUSTOM_DOCUMENTATION_PRODUCT_NAME_${DIRNAME}")
|
||||
SET(CUSTOM_DOCUMENTATION_CPP_SOURCES "${CUSTOM_DOCUMENTATION_CPP_SOURCES_${DIRNAME}}")
|
||||
IF(NOT(${SKIP_DOCUMENTATION}) AND NOT(${SKIP_THIS_CUSTOM_DOCUMENTATION}) AND NOT MULTI_BUILD)
|
||||
IF(NOT(${HAS_CUSTOM_DOCUMENTATION}))
|
||||
IF(${PUBLISH_DOC_ASSETS})
|
||||
IF(IS_DIRECTORY ${FULLPATH}/doc)
|
||||
MESSAGE(STATUS "Documentation files found in ${FULLPATH}/doc")
|
||||
INSTALL(DIRECTORY ${FULLPATH}/doc/ DESTINATION ${DIST_DOCTMP}/openvibe/box-algorithm-doc/dox-part/ FILES_MATCHING PATTERN "*.dox-part" PATTERN "doc/boxes" EXCLUDE)
|
||||
INSTALL(DIRECTORY ${FULLPATH}/doc/ DESTINATION ${DIST_DOCTMP}/openvibe FILES_MATCHING PATTERN "*.dox" PATTERN "doc/boxes" EXCLUDE)
|
||||
INSTALL(DIRECTORY ${FULLPATH}/doc/ DESTINATION ${DIST_DOCTMP}/openvibe
|
||||
PATTERN "doc/boxes" EXCLUDE PATTERN "*.dox-part" EXCLUDE PATTERN "*.dox" EXCLUDE)
|
||||
ENDIF()
|
||||
|
||||
IF(IS_DIRECTORY ${FULLPATH}/include)
|
||||
FILE(APPEND "${DIST_DOCTMP}/openvibe/source-list.txt" "${FULLPATH}/include\n")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Project ${DIRNAME} has custom documentation")
|
||||
|
||||
# we copy the doc files into the temporary folder where everything is built thanks to a cmd script
|
||||
IF(IS_DIRECTORY ${FULLPATH}/doc/)
|
||||
FILE(COPY ${FULLPATH}/doc/ DESTINATION "${DIST_DOCTMP}/${DIRNAME}")
|
||||
ENDIF()
|
||||
|
||||
SET(DOC_PROJECT_NAME ${DIRNAME})
|
||||
SET(DOC_PROJECT_VERSION ${PROJECT_VERSION})
|
||||
SET(DOC_PROJECT_PRODUCT_NAME "${${CUSTOM_DOCUMENTATION_PRODUCT_NAME}}")
|
||||
SET(DOC_PROJECT_COMMITHASH ${PROJECT_COMMITHASH})
|
||||
SET(DOC_PROJECT_BRANCH ${PROJECT_BRANCH})
|
||||
SET(DOC_PROJECT_CPP_SOURCES "${CUSTOM_DOCUMENTATION_CPP_SOURCES}")
|
||||
|
||||
get_directory_property( DirDefs DIRECTORY ${CMAKE_SOURCE_DIR} COMPILE_DEFINITIONS )
|
||||
SET(DOC_DEFINES "")
|
||||
foreach( d ${DirDefs} )
|
||||
#message( STATUS "Found Define: " ${d} )
|
||||
SET(DOC_DEFINES "${DOC_DEFINES} \\\\ \\n ${d}")
|
||||
endforeach()
|
||||
STRING(REPLACE "\"" "\\\"" DOC_DEFINES "${DOC_DEFINES}")
|
||||
|
||||
#message( STATUS ${DOC_DEFINES} )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
add_subdirectory(${FULLPATH})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDFOREACH(FULLPATH ${FILENAMES})
|
||||
|
||||
ENDFUNCTION(OV_ADD_PROJECTS)
|
||||
@@ -0,0 +1,52 @@
|
||||
#
|
||||
# This function is used to add a project to the build in the case where the current directory only contains
|
||||
# 'branches', 'tags' and 'trunk' directories of a single project. The project will be added using the
|
||||
# branch specified (if any) in the root CMakeList.txt or trunk otherwise.
|
||||
#
|
||||
# The branch variable name that is checked is made up from ${CURRENT_BRANCH_PREFIX}_${DIRNAMEUPPER}.
|
||||
#
|
||||
# The script also adds the directory to the global list of projects.
|
||||
#
|
||||
|
||||
FUNCTION(OV_ADD_SINGLE_PROJECT CURRENT_BRANCH_PREFIX)
|
||||
|
||||
SET(BRANCH_VARIABLE_NAME "${CURRENT_BRANCH_PREFIX}")
|
||||
|
||||
# MESSAGE(STATUS "Parts ${CURRENT_BRANCH_PREFIX} Now ${BRANCH_VARIABLE_NAME}")
|
||||
# MESSAGE(STATUS "Value ${${BRANCH_VARIABLE_NAME}}")
|
||||
|
||||
SET(SUBDIR "SUBDIR-NOTFOUND")
|
||||
|
||||
# MESSAGE(STATUS "Checking branch for ${BRANCH_VARIABLE_NAME}")
|
||||
|
||||
IF(${BRANCH_VARIABLE_NAME})
|
||||
SET(BRANCH ${${BRANCH_VARIABLE_NAME}})
|
||||
IF("${BRANCH}" STREQUAL "__SKIPME")
|
||||
MESSAGE(STATUS "Note: ${BRANCH_VARIABLE_NAME} has been disabled by setting it to __SKIPME")
|
||||
ELSE("${BRANCH}" STREQUAL "__SKIPME")
|
||||
SET(SUBDIR "${BRANCH}")
|
||||
ENDIF("${BRANCH}" STREQUAL "__SKIPME")
|
||||
ELSE(${BRANCH_VARIABLE_NAME})
|
||||
# MESSAGE(STATUS "Going for trunk...")
|
||||
SET(SUBDIR "${OV_TRUNK}")
|
||||
ENDIF(${BRANCH_VARIABLE_NAME})
|
||||
|
||||
IF(SUBDIR)
|
||||
# MESSAGE(STATUS "Inserting folder ${SUBDIR}")
|
||||
|
||||
# Add the dir to be parsed for documentation later. We need to do this before adding subdir, in case the subdir is the actual docs dir.
|
||||
GET_PROPERTY(OV_TMP GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS)
|
||||
SET(OV_TMP "${OV_TMP};${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}")
|
||||
SET_PROPERTY(GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS ${OV_TMP})
|
||||
|
||||
# MESSAGE(STATUS "BDIR ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIR}")
|
||||
GET_PROPERTY(OV_TMP GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS_BUILD_DIR)
|
||||
SET(OV_TMP "${OV_TMP};${CMAKE_CURRENT_BINARY_DIR}/${SUBDIR}")
|
||||
SET_PROPERTY(GLOBAL PROPERTY OV_PROP_CURRENT_PROJECTS_BUILD_DIR ${OV_TMP})
|
||||
|
||||
|
||||
ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR})
|
||||
|
||||
ENDIF(SUBDIR)
|
||||
|
||||
ENDFUNCTION(OV_ADD_SINGLE_PROJECT)
|
||||
@@ -0,0 +1,14 @@
|
||||
FUNCTION(OV_DELAY_LOAD TARGET DLL)
|
||||
IF(WIN32)
|
||||
UNSET(FN_LINK_FLAGS)
|
||||
GET_TARGET_PROPERTY(FN_LINK_FLAGS ${TARGET} LINK_FLAGS)
|
||||
IF(FN_LINK_FLAGS)
|
||||
SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_FLAGS "${FN_LINK_FLAGS} /DELAYLOAD:${DLL}")
|
||||
ELSE(FN_LINK_FLAGS)
|
||||
SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_FLAGS "/DELAYLOAD:${DLL}")
|
||||
ENDIF(FN_LINK_FLAGS)
|
||||
TARGET_LINK_LIBRARIES(${TARGET} Delayimp)
|
||||
ELSE(WIN32)
|
||||
MESSAGE(WARNING "Ignored OV_DELAY_LOAD call on non WIN32 platform")
|
||||
ENDIF(WIN32)
|
||||
ENDFUNCTION(OV_DELAY_LOAD)
|
||||
@@ -0,0 +1,86 @@
|
||||
INCLUDE(CMakeParseArguments)
|
||||
#
|
||||
# Creates launch script from a common OpenViBE template (in "cmake-modules/launchers/"), but dedicated to scenarios to be executed with the Designer
|
||||
#
|
||||
# The mandatory 1st argument SCRIPT_PREFIX specifies what the resulting script is called. A platform specific postfix will be added.
|
||||
# The mandatory 2nd argument EXECUTABLE_NAME specifies what the resulting script will called eventually.
|
||||
# The optional 3nd argument ARGV1 specifies some extra argument or switch that is given to the launched executable by the script
|
||||
#
|
||||
FUNCTION(OV_INSTALL_LAUNCH_SCRIPT)
|
||||
SET(options PAUSE)
|
||||
SET(oneValueArgs SCRIPT_PREFIX EXECUTABLE_NAME ICON_PATH)
|
||||
SET(multiValueArgs PARAMETERS)
|
||||
|
||||
CMAKE_PARSE_ARGUMENTS(OV_INSTALL_LAUNCH_SCRIPT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
OV_CONFIGURE_RC(NAME ${OV_INSTALL_LAUNCH_SCRIPT_SCRIPT_PREFIX} ICON_PATH ${OV_INSTALL_LAUNCH_SCRIPT_ICON_PATH})
|
||||
|
||||
# Install executable launcher if install_exe option is set to on, the os is WIN32, and no argument has been specified
|
||||
IF(WIN32 AND INSTALL_EXE AND NOT(OV_INSTALL_LAUNCH_SCRIPT_PAUSE) AND NOT(OV_INSTALL_LAUNCH_SCRIPT_PARAMETERS))
|
||||
# Add the dir to be parsed for documentation later. We need to do this before adding subdir, in case the subdir is the actual docs dir
|
||||
GET_PROPERTY(OV_TMP GLOBAL PROPERTY OV_EXE_PROJECTS_TO_INSTALL)
|
||||
SET(OV_TMP "${OV_TMP};${OV_INSTALL_LAUNCH_SCRIPT_SCRIPT_PREFIX}")
|
||||
SET_PROPERTY(GLOBAL PROPERTY OV_EXE_PROJECTS_TO_INSTALL ${OV_TMP})
|
||||
ELSE()
|
||||
IF(WIN32)
|
||||
SET(SCRIPT_POSTFIX ".cmd")
|
||||
ELSEIF(APPLE)
|
||||
SET(SCRIPT_POSTFIX "-macos.sh")
|
||||
ELSEIF(UNIX)
|
||||
# Debian recommends that extensions such as .sh are not used; On Linux, scripts with such extensions shouldn't be packaged
|
||||
SET(SCRIPT_POSTFIX ".sh")
|
||||
ENDIF()
|
||||
# Extract the filename of the project executable, the variable in the script base will be replaced with it by CONFIGURE_FILE()
|
||||
GET_TARGET_PROPERTY(TMP_PROJECT_TARGET_PATH ${OV_INSTALL_LAUNCH_SCRIPT_EXECUTABLE_NAME} LOCATION)
|
||||
GET_FILENAME_COMPONENT(OV_CMD_EXECUTABLE ${TMP_PROJECT_TARGET_PATH} NAME)
|
||||
|
||||
IF(${OV_CMD_EXECUTABLE} STREQUAL "TMP_PROJECT_TARGET_PATH-NOTFOUND")
|
||||
SET(OV_CMD_EXECUTABLE ${OV_INSTALL_LAUNCH_SCRIPT_EXECUTABLE_NAME})
|
||||
ELSE()
|
||||
IF(WIN32)
|
||||
SET(OV_CMD_EXECUTABLE "%OV_PATH_ROOT%/bin/${OV_CMD_EXECUTABLE}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
SET(SCRIPT_NAME ${OV_INSTALL_LAUNCH_SCRIPT_SCRIPT_PREFIX}${SCRIPT_POSTFIX})
|
||||
SET(OV_CMD_ARGS ${OV_INSTALL_LAUNCH_SCRIPT_PARAMETERS})
|
||||
|
||||
IF(OV_INSTALL_LAUNCH_SCRIPT_PAUSE)
|
||||
SET(OV_PAUSE "PAUSE")
|
||||
ELSE()
|
||||
SET(OV_PAUSE "")
|
||||
ENDIF()
|
||||
|
||||
CONFIGURE_FILE(${OV_LAUNCHER_SOURCE_PATH}/openvibe-launcher${SCRIPT_POSTFIX}-base ${CMAKE_CURRENT_BINARY_DIR}/${SCRIPT_NAME} @ONLY)
|
||||
# IF(MULTI_BUILD) # Replace with generator expression in CMake 3.5+
|
||||
# FOREACH(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
|
||||
# STRING(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIGU)
|
||||
# INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${SCRIPT_NAME} DESTINATION ${DIST_ROOT}/${OUTPUTCONFIG})
|
||||
# ENDFOREACH()
|
||||
# ELSE()
|
||||
# INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${SCRIPT_NAME} DESTINATION ${DIST_ROOT})
|
||||
# ENDIF()
|
||||
INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${SCRIPT_NAME} DESTINATION ${DIST_ROOT})
|
||||
|
||||
ENDIF()
|
||||
ENDFUNCTION()
|
||||
|
||||
FUNCTION(OV_CONFIGURE_RC)
|
||||
SET(options )
|
||||
SET(oneValueArgs NAME ICON_PATH)
|
||||
SET(multiValueArgs )
|
||||
CMAKE_PARSE_ARGUMENTS(OV_CONFIGURE_RC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
SET(GENERATED_RC_FILE "${CMAKE_BINARY_DIR}/resource-files/${OV_CONFIGURE_RC_NAME}.rc")
|
||||
IF(OV_CONFIGURE_RC_ICON_PATH)
|
||||
SET(CONFIGURE_ICON "ID_Icon ICON DISCARDABLE \"${OV_CONFIGURE_RC_ICON_PATH}\"")
|
||||
ENDIF()
|
||||
IF(NOT(PROJECT_PRODUCT_NAME))
|
||||
SET(PROJECT_PRODUCT_NAME "${OV_CONFIGURE_RC_NAME}")
|
||||
ENDIF()
|
||||
SET(FILE_DESCRIPTION "${PROJECT_PRODUCT_NAME} for Win32")
|
||||
|
||||
CONFIGURE_FILE(
|
||||
${OV_LAUNCHER_SOURCE_PATH}/resource-file.rc-base
|
||||
${GENERATED_RC_FILE}
|
||||
@ONLY)
|
||||
ENDFUNCTION()
|
||||
@@ -0,0 +1,55 @@
|
||||
#
|
||||
# Win32 only
|
||||
#
|
||||
# This concoction mainly exists to locate the boost libraries on WIN32 in the case where our dependency/ folder has only a
|
||||
# truncated version of boost and we cannot use find_package(). The background story is that we wish to link explicitly
|
||||
# instead of using automatic linking and specifying a generic boost path to linker before each project definition.
|
||||
#
|
||||
# The downside of this is that it assumes the boost library names to have a particular format and only works for VC90/VC100
|
||||
#
|
||||
# Function: Links specified boost library defined by COMPONENT and BOOST_VERSION to PROJECT_NAME.
|
||||
#
|
||||
|
||||
FUNCTION(OV_LINK_BOOST_LIB BOOST_COMPONENT BOOST_VERSION)
|
||||
|
||||
IF(WIN32)
|
||||
IF(MSVC)
|
||||
IF(MSVC_VERSION EQUAL 1500) # vc9
|
||||
SET(LIB_BOOST "libboost_${BOOST_COMPONENT}-vc90-mt-${BOOST_VERSION}.lib")
|
||||
SET(LIB_BOOST_DEBUG "libboost_${BOOST_COMPONENT}-vc90-mt-gd-${BOOST_VERSION}.lib")
|
||||
ELSEIF(MSVC_VERSION EQUAL 1600) # vc 10
|
||||
SET(LIB_BOOST "libboost_${BOOST_COMPONENT}-vc100-mt-${BOOST_VERSION}.lib")
|
||||
SET(LIB_BOOST_DEBUG "libboost_${BOOST_COMPONENT}-vc100-mt-gd-${BOOST_VERSION}.lib")
|
||||
ELSEIF(MSVC_VERSION EQUAL 1700) # vc 11
|
||||
SET(LIB_BOOST "libboost_${BOOST_COMPONENT}-vc110-mt-${BOOST_VERSION}.lib")
|
||||
SET(LIB_BOOST_DEBUG "libboost_${BOOST_COMPONENT}-vc110-mt-gd-${BOOST_VERSION}.lib")
|
||||
ELSEIF(MSVC_VERSION EQUAL 1800) # vc12
|
||||
SET(LIB_BOOST "libboost_${BOOST_COMPONENT}-vc120-mt-${BOOST_VERSION}.lib")
|
||||
SET(LIB_BOOST_DEBUG "libboost_${BOOST_COMPONENT}-vc120-mt-gd-${BOOST_VERSION}.lib")
|
||||
ENDIF(MSVC_VERSION EQUAL 1500)
|
||||
ENDIF(MSVC)
|
||||
|
||||
SET(LIB_BOOST_PATH "-NOTFOUND")
|
||||
FIND_LIBRARY(LIB_BOOST_PATH NAMES ${LIB_BOOST} PATHS ${OV_CUSTOM_DEPENDENCIES_PATH}/boost/lib NO_DEFAULT_PATH)
|
||||
IF(LIB_BOOST_PATH)
|
||||
debug_message( " [ OK ] lib ${LIB_BOOST_PATH}")
|
||||
IF(TARGET ${PROJECT_NAME})
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} optimized ${LIB_BOOST_PATH})
|
||||
ENDIF()
|
||||
ELSE(LIB_BOOST_PATH)
|
||||
MESSAGE(WARNING " Unable to find boost ${LIB_BOOST}")
|
||||
ENDIF(LIB_BOOST_PATH)
|
||||
|
||||
SET(LIB_BOOST_DEBUG_PATH "-NOTFOUND")
|
||||
FIND_LIBRARY(LIB_BOOST_DEBUG_PATH NAMES ${LIB_BOOST_DEBUG} PATHS ${OV_CUSTOM_DEPENDENCIES_PATH}/boost/lib NO_DEFAULT_PATH)
|
||||
IF(LIB_BOOST_DEBUG_PATH)
|
||||
debug_message( " [ OK ] lib ${LIB_BOOST_DEBUG_PATH}")
|
||||
IF(TARGET ${PROJECT_NAME})
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} debug ${LIB_BOOST_DEBUG_PATH})
|
||||
ENDIF()
|
||||
ELSE(LIB_BOOST_DEBUG_PATH)
|
||||
MESSAGE(WARNING " Unable to find boost ${LIB_BOOST_DEBUG}")
|
||||
ENDIF(LIB_BOOST_DEBUG_PATH)
|
||||
ENDIF(WIN32)
|
||||
|
||||
ENDFUNCTION(OV_LINK_BOOST_LIB)
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
IF(NOT OV_MS_SDK_PATH)
|
||||
GET_FILENAME_COMPONENT(OV_MS_SDK_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Win32SDK\\Directories;Install Dir]" ABSOLUTE CACHE)
|
||||
ENDIF(NOT OV_MS_SDK_PATH)
|
||||
|
||||
IF(NOT OV_MS_SDK_PATH)
|
||||
GET_FILENAME_COMPONENT(OV_MS_SDK_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MicrosoftSDK\\Directories;Install Dir]" ABSOLUTE CACHE)
|
||||
ENDIF(NOT OV_MS_SDK_PATH)
|
||||
|
||||
IF(NOT OV_MS_SDK_PATH)
|
||||
GET_FILENAME_COMPONENT(OV_MS_SDK_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" ABSOLUTE CACHE)
|
||||
ENDIF(NOT OV_MS_SDK_PATH)
|
||||
|
||||
IF(NOT OV_MS_SDK_PATH)
|
||||
MESSAGE(WARNING "Could not find Microsoft Windows SDK")
|
||||
ENDIF(NOT OV_MS_SDK_PATH)
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
#######################################################################
|
||||
# Software License Agreement (AGPL-3 License)
|
||||
#
|
||||
# OpenViBE SDK Test Software
|
||||
# Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
|
||||
# Copyright (C) Inria, 2015-2017,V1.0
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License version 3,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program.
|
||||
# If not, see <http://www.gnu.org/licenses/>.
|
||||
#######################################################################
|
||||
|
||||
# Cmake script used to wrap multiple commands into one.
|
||||
#
|
||||
# Mandatory Input parameters:
|
||||
# -UNQUOTE: set to 1 to unquote commands before processing, 0 otherwise
|
||||
# -CMD1 First commands to execute
|
||||
#
|
||||
# Optional Input parameters:
|
||||
# -CMD2 to CMD5: Other commands to execute
|
||||
#
|
||||
# Example usage:
|
||||
# ADD_TEST(NAME ${TEST_NAME}
|
||||
# COMMAND ${CMAKE_COMMAND}
|
||||
# -DUNQUOTE=1
|
||||
# -DCMD1="Command_1"
|
||||
# -DCMD2="Command_2"
|
||||
# -DCMD3="Command_3"
|
||||
# -P ${OpenViBE_TEST_CMAKE_DIR}/OvtRunMultipleCommand3.cmake)
|
||||
|
||||
# Macro used to execute a command and check the result
|
||||
MACRO(EXEC_CHECK RAW_CMD UNQUOTE_CMD)
|
||||
|
||||
SET(CMD_ARGS_RAW ${RAW_CMD})
|
||||
|
||||
IF(${UNQUOTE_CMD})
|
||||
# First processing to remove enclosing quotes
|
||||
STRING(LENGTH "${RAW_CMD}" CMD_STRING_LENGTH)
|
||||
MATH(EXPR CMD_STRING_LENGTH "${CMD_STRING_LENGTH} - 2")
|
||||
STRING(SUBSTRING "${RAW_CMD}" 1 ${CMD_STRING_LENGTH} CMD_ARGS_RAW)
|
||||
ENDIF()
|
||||
|
||||
# Process arguments to build an arg list
|
||||
SEPARATE_ARGUMENTS(CMD_ARGS WINDOWS_COMMAND ${CMD_ARGS_RAW})
|
||||
|
||||
EXECUTE_PROCESS(COMMAND ${CMD_ARGS} RESULT_VARIABLE ret_var OUTPUT_VARIABLE output_var)
|
||||
|
||||
MESSAGE(STATUS "----------------------------------------------\n")
|
||||
MESSAGE(STATUS "-----------NEW COMMAND EXECUTED-----------\n\n")
|
||||
MESSAGE(STATUS "----------------------------------------------\n\n")
|
||||
|
||||
MESSAGE(STATUS "-----------Command Name & Arguments-----------\n${RAW_CMD}\n\n")
|
||||
MESSAGE(STATUS "-----------Command Output-----------\n${output_var}\n\n")
|
||||
|
||||
IF(ret_var)
|
||||
MESSAGE(FATAL_ERROR "-----------Error-----------\n$Running command failed with code: ${ret_var}\n\n")
|
||||
ENDIF()
|
||||
|
||||
ENDMACRO()
|
||||
|
||||
IF(NOT DEFINED UNQUOTE)
|
||||
MESSAGE(FATAL_ERROR "Missing UNQUOTE parameter")
|
||||
ENDIF()
|
||||
|
||||
IF(DEFINED CMD1)
|
||||
EXEC_CHECK(${CMD1} ${UNQUOTE})
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "At least one command needed in OvtRunMultipleCommand script")
|
||||
ENDIF()
|
||||
|
||||
IF(DEFINED CMD2)
|
||||
EXEC_CHECK(${CMD2} ${UNQUOTE})
|
||||
ENDIF()
|
||||
|
||||
IF(DEFINED CMD3)
|
||||
EXEC_CHECK(${CMD3} ${UNQUOTE})
|
||||
ENDIF()
|
||||
|
||||
IF(DEFINED CMD4)
|
||||
EXEC_CHECK(${CMD4} ${UNQUOTE})
|
||||
ENDIF()
|
||||
|
||||
IF(DEFINED CMD5)
|
||||
EXEC_CHECK(${CMD5} ${UNQUOTE})
|
||||
ENDIF()
|
||||
@@ -0,0 +1,24 @@
|
||||
# Set OpenViBE specific versions.
|
||||
function(OV_SET_PROJECT_VERSION)
|
||||
|
||||
set(OV_GLOBAL_VERSION_MAJOR ${PROJECT_VERSION_MAJOR} PARENT_SCOPE)
|
||||
set(OV_GLOBAL_VERSION_MINOR ${PROJECT_VERSION_MINOR} PARENT_SCOPE)
|
||||
set(OV_GLOBAL_VERSION_PATCH ${PROJECT_VERSION_PATCH} PARENT_SCOPE)
|
||||
set(OV_GLOBAL_VERSION_BUILD ${PROJECT_VERSION_BUILD} PARENT_SCOPE)
|
||||
set(OV_GLOBAL_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.${PROJECT_VERSION_BUILD} PARENT_SCOPE)
|
||||
|
||||
set(OV_PROJECT_BRANCH ${PROJECT_BRANCH} PARENT_SCOPE)
|
||||
set(OV_PROJECT_COMMITHASH ${PROJECT_COMMITHASH} PARENT_SCOPE)
|
||||
|
||||
# Write version to .install file
|
||||
string(TIMESTAMP BUILD_DATE "%d/%m/%y %H:%M:%S")
|
||||
set(INSTALL_MANIFEST_STR "[Package]=${PROJECT_NAME}\
|
||||
\n[Version]=${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.${PROJECT_VERSION_BUILD}\
|
||||
\n[BuildHash]=${PROJECT_COMMITHASH}\
|
||||
\n[BuildBranch]=${PROJECT_BRANCH}\
|
||||
\n[BuildDate]=${BUILD_DATE}"
|
||||
)
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/.install "${INSTALL_MANIFEST_STR}")
|
||||
|
||||
endfunction()
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
function(debug_message)
|
||||
if(${Flag_VerboseOutput})
|
||||
message(STATUS "${ARGV}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Set version based on git tag.
|
||||
# If current commit is tagged, use the tag as it is, and add build number based on content of .build file, written by Jenkins
|
||||
# Else use last tag major and minor number and set patch number to 99
|
||||
#
|
||||
# This function should remain generic to be usable in every projects.
|
||||
function(set_version)
|
||||
find_package(Git)
|
||||
if(EXISTS ${CMAKE_SOURCE_DIR}/.version)
|
||||
|
||||
# These versions are used by the subprojects by default.
|
||||
# If you wish to maintain specific version numbers for a subproject, please do so in the projects CMakeLists.txt
|
||||
file(READ ${CMAKE_SOURCE_DIR}/.version PROJECT_VERSION)
|
||||
string(STRIP ${PROJECT_VERSION} PROJECT_VERSION)
|
||||
string(REPLACE "." ";" VERSION_LIST ${PROJECT_VERSION})
|
||||
list(GET VERSION_LIST 0 PROJECT_VERSION_MAJOR)
|
||||
list(GET VERSION_LIST 1 PROJECT_VERSION_MINOR)
|
||||
list(GET VERSION_LIST 2 PROJECT_VERSION_PATCH)
|
||||
|
||||
elseif(NOT GIT_FOUND)
|
||||
message(WARNING "Git not found, set version to 0.0.0")
|
||||
set(PROJECT_VERSION "0.0.0")
|
||||
set(PROJECT_BRANCH_STRING "unknown")
|
||||
set(PROJECT_COMMITHASH_STRING "0")
|
||||
else()
|
||||
debug_message("Found Git: ${GIT_EXECUTABLE}")
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} describe
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE PROJECT_VERSION
|
||||
ERROR_VARIABLE ERROR)
|
||||
if(ERROR)
|
||||
set(PROJECT_VERSION "0.0.0")
|
||||
message(WARNING "No tags found, set version to 0.0.0")
|
||||
else()
|
||||
# codename = the name of the current branch
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE PROJECT_BRANCH_STRING)
|
||||
# command output may contain carriage return
|
||||
string(STRIP ${PROJECT_BRANCH_STRING} PROJECT_BRANCH_STRING)
|
||||
|
||||
# commithash = short hash of latest revision
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE PROJECT_COMMITHASH_STRING)
|
||||
# command output may contain carriage return
|
||||
string(STRIP ${PROJECT_COMMITHASH_STRING} PROJECT_COMMITHASH_STRING)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# if current commit is not tagged result is formed as: "major.minor.patch-number of commits since last tag-hash"
|
||||
string(STRIP ${PROJECT_VERSION} PROJECT_VERSION)
|
||||
string(REPLACE "-" ";" version_list ${PROJECT_VERSION})
|
||||
list(LENGTH version_list version_list_length)
|
||||
if(${version_list_length} EQUAL 3) # if result is formed as "major.minor.patch-number of commits since last tag-hash" set patch as 99
|
||||
list(GET version_list 0 PROJECT_VERSION)
|
||||
set(PROJECT_VERSION_PATCH 99)
|
||||
endif()
|
||||
|
||||
string(REPLACE "." ";" version_list ${PROJECT_VERSION})
|
||||
list(GET version_list 0 PROJECT_VERSION_MAJOR)
|
||||
list(GET version_list 1 PROJECT_VERSION_MINOR)
|
||||
if(NOT PROJECT_VERSION_PATCH)
|
||||
list(GET version_list 2 PROJECT_VERSION_PATCH)
|
||||
endif()
|
||||
|
||||
# These versions are used by the subprojects by default.
|
||||
# If you wish to maintain specific version numbers for a subproject, please do so in the projects CMakeLists.txt
|
||||
if(EXISTS ${CMAKE_SOURCE_DIR}/.build)
|
||||
file(READ ${CMAKE_SOURCE_DIR}/.build PROJECT_VERSION_BUILD)
|
||||
string(STRIP ${PROJECT_VERSION_BUILD} PROJECT_VERSION_BUILD)
|
||||
else()
|
||||
set(PROJECT_VERSION_BUILD 0)
|
||||
endif()
|
||||
|
||||
set(PROJECT_BRANCH ${PROJECT_BRANCH_STRING} PARENT_SCOPE)
|
||||
set(PROJECT_COMMITHASH ${PROJECT_COMMITHASH_STRING} PARENT_SCOPE)
|
||||
|
||||
set(PROJECT_VERSION_MAJOR ${PROJECT_VERSION_MAJOR} PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_MINOR ${PROJECT_VERSION_MINOR} PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_PATCH ${PROJECT_VERSION_PATCH} PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_BUILD ${PROJECT_VERSION_BUILD} PARENT_SCOPE)
|
||||
set(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} PARENT_SCOPE)
|
||||
endfunction()
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This script is meant to be launched from inside an OpenViBE application (such as a scenario in Designer)
|
||||
#
|
||||
|
||||
CALLCMD=$1
|
||||
shift
|
||||
|
||||
ov_run_bg=0
|
||||
if [ "$1" == "--run-bg" ]; then
|
||||
ov_run_bg=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ "$OV_PATH_ROOT" == "" ]; then
|
||||
SOURCE="${BASH_SOURCE[0]}"
|
||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||
OV_PATH_ROOT="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
SOURCE="$(readlink "$SOURCE")"
|
||||
[[ $SOURCE != /* ]] && SOURCE="$OV_PATH_ROOT/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||
done
|
||||
OV_PATH_ROOT="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
fi
|
||||
if [ "$OV_PATH_BIN" == "" ]; then
|
||||
OV_PATH_BIN="$OV_PATH_ROOT/bin"
|
||||
fi
|
||||
|
||||
|
||||
ret_code=0
|
||||
|
||||
if [ $ov_run_bg == 0 ]; then
|
||||
eval "$OV_PATH_BIN/$CALLCMD" @OV_CMD_ARGS@ $*
|
||||
ret_code=$?
|
||||
else
|
||||
"$OV_PATH_BIN/$CALLCMD" @OV_CMD_ARGS@ $* &
|
||||
fi
|
||||
|
||||
exit $ret_code
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
@echo off
|
||||
|
||||
REM
|
||||
REM This script is meant to be launched from an environment with the OV_PATH_BIN env variable set externally
|
||||
REM
|
||||
|
||||
SET "OV_RUN_APP=%1"
|
||||
SHIFT
|
||||
|
||||
SET OV_RUN_IN_BG=
|
||||
IF /i "%1"=="--run-bg" (
|
||||
REM Run in background. The first arg to START is the app title.
|
||||
SET OV_RUN_IN_BG=START "%OV_RUN_APP%"
|
||||
SHIFT
|
||||
)
|
||||
|
||||
%OV_RUN_IN_BG% "%OV_PATH_BIN%\%OV_RUN_APP%" %1 %2 %3 %4 %5
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
|
||||
## By default, paths specified by CMake install will be used to locate OpenViBE components. If defined, these ENV variables can override the CMake defines.
|
||||
#export OV_PATH_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
#export OV_PATH_BIN="$OV_PATH_ROOT/bin"
|
||||
#export OV_PATH_LIB="$OV_PATH_ROOT/lib"
|
||||
#export OV_PATH_DATA="$OV_PATH_ROOT/share/openvibe"
|
||||
|
||||
# Tries to locate matlab executable from $PATH, and set the library path to the corresponding matlab libs.
|
||||
if [ "`which matlab`" != "" ] ; then
|
||||
MATLAB_ROOT=`matlab -e | grep "^MATLAB=" | sed -e "s/^MATLAB=//"`
|
||||
MATLAB_ARCH=`matlab -e | grep "^ARCH=" | sed -e "s/^ARCH=//"`
|
||||
MATLAB_LIBPATH="$MATLAB_ROOT/bin/$MATLAB_ARCH"
|
||||
# echo Matlab libs expected at $MATLAB_LIBPATH
|
||||
export DYLD_LIBRARY_PATH="$MATLAB_LIBPATH:$DYLD_LIBRARY_PATH"
|
||||
fi
|
||||
|
||||
if [ "$OV_PATH_ROOT" == "" ]; then
|
||||
SOURCE="${BASH_SOURCE[0]}"
|
||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||
OV_PATH_ROOT="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
SOURCE="$(readlink "$SOURCE")"
|
||||
[[ $SOURCE != /* ]] && SOURCE="$OV_PATH_ROOT/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||
done
|
||||
OV_PATH_ROOT="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
fi
|
||||
|
||||
export DYLD_LIBRARY_PATH="$OV_PATH_LIB:@CMAKE_SOURCE_DIR@/dependencies/lib:$DYLD_LIBRARY_PATH"
|
||||
export LC_ALL=C
|
||||
|
||||
export GTK_PATH=/usr/local/lib/gtk-2.0
|
||||
|
||||
export LUA_CPATH="$OV_PATH_LIB/lib?.dylib;`echo 'print(package.cpath)' | lua - `"
|
||||
export LUA_PATH="$OV_PATH_BIN/?.lua;`echo 'print(package.path)' | lua - `"
|
||||
|
||||
# The following line is there to help in cases where OpenViBE can consume excessive
|
||||
# amounts of CPU or grind the swap. You can remove it if you know what you're doing.
|
||||
renice 19 $$
|
||||
|
||||
ov_debugger=
|
||||
if [ "$1" == "--debug" ]; then
|
||||
ov_debugger="gdb --args"
|
||||
shift
|
||||
fi
|
||||
ov_run_bg=0
|
||||
if [ "$1" == "--run-bg" ]; then
|
||||
ov_run_bg=1
|
||||
shift
|
||||
fi
|
||||
|
||||
ret_code=0
|
||||
|
||||
if [ $ov_run_bg == 0 ]; then
|
||||
eval $ov_debugger "$OV_PATH_BIN/@OV_CMD_EXECUTABLE@" @OV_CMD_ARGS@ $*
|
||||
ret_code=$?
|
||||
else
|
||||
$ov_debugger "$OV_PATH_BIN/@OV_CMD_EXECUTABLE@" @OV_CMD_ARGS@ $* &
|
||||
fi
|
||||
|
||||
exit $ret_code
|
||||
@@ -0,0 +1,65 @@
|
||||
@ECHO OFF
|
||||
SETLOCAL EnableExtensions
|
||||
SETLOCAL EnableDelayedExpansion
|
||||
|
||||
REM If not set to PASSIVE, OpenMP (Eigen) boxes may load the cores fully even if there's little to do.
|
||||
SET "OMP_WAIT_POLICY=@OV_OMP_WAIT_POLICY@"
|
||||
|
||||
REM Get the directory location of this script, assume it contains the OpenViBE dist tree. These variables will be used by OpenViBE executables.
|
||||
SET "OV_PATH_ROOT=%~dp0"
|
||||
SET "OV_PATH_BIN=%OV_PATH_ROOT%\bin"
|
||||
SET "OV_PATH_LIB=%OV_PATH_ROOT%\bin"
|
||||
SET "OV_PATH_DATA=%OV_PATH_ROOT%\share\openvibe"
|
||||
|
||||
REM Default behavior
|
||||
SET OV_PAUSE=@OV_PAUSE@
|
||||
SET OV_RUN_IN_BG=
|
||||
|
||||
REM Parse out Windows specific args ...
|
||||
SET "ARGS="
|
||||
SET EMPTY=
|
||||
:loop
|
||||
SET "STRIPPEDARG=%~1"
|
||||
if NOT !STRIPPEDARG! == !EMPTY! (
|
||||
IF /i "!STRIPPEDARG!" == "--no-pause" (
|
||||
SET OV_PAUSE=
|
||||
goto found:
|
||||
)
|
||||
IF /i "!STRIPPEDARG!" == "--pause" (
|
||||
SET OV_PAUSE=PAUSE
|
||||
goto found:
|
||||
)
|
||||
IF /i "!STRIPPEDARG!" == "--run-bg" (
|
||||
REM Run in background, disable pause. The second parameter below is because CMD requires a 'title'
|
||||
SET OV_RUN_IN_BG=START "@OV_CMD_EXECUTABLE@"
|
||||
SET OV_PAUSE=
|
||||
goto found:
|
||||
)
|
||||
|
||||
REM Pass the non-stripped arg to the launched application...
|
||||
SET ARGS=%ARGS% %1
|
||||
|
||||
:found
|
||||
SHIFT
|
||||
goto loop:
|
||||
)
|
||||
|
||||
REM Set dependency paths etc...
|
||||
REM SET "OV_ENVIRONMENT_FILE=%OV_PATH_ROOT%\bin\OpenViBE-set-env.cmd"
|
||||
|
||||
REM IF NOT EXIST "%OV_ENVIRONMENT_FILE%" (
|
||||
REM ECHO Error: "%OV_ENVIRONMENT_FILE%" was not found
|
||||
REM GOTO EndOfScript
|
||||
REM )
|
||||
REM CALL "%OV_ENVIRONMENT_FILE%"
|
||||
|
||||
SET PATH=%OV_PATH_LIB%;%PATH%
|
||||
|
||||
|
||||
REM cmake variable OV_CMD_ARGS below may specify additional arguments outside this script
|
||||
|
||||
%OV_RUN_IN_BG% "@OV_CMD_EXECUTABLE@" @OV_CMD_ARGS@ %ARGS%
|
||||
|
||||
:EndOfScript
|
||||
|
||||
%OV_PAUSE%
|
||||
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
## By default, paths specified by CMake install will be used to locate OpenViBE components. If defined, these ENV variables can override the CMake defines.
|
||||
#export OV_PATH_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
#export OV_PATH_BIN="$OV_PATH_ROOT/bin"
|
||||
#export OV_PATH_LIB="$OV_PATH_ROOT/lib"
|
||||
#export OV_PATH_DATA="$OV_PATH_ROOT/share/openvibe"
|
||||
|
||||
if [ "$OV_PATH_ROOT" == "" ]; then
|
||||
SOURCE="${BASH_SOURCE[0]}"
|
||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||
OV_PATH_ROOT="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
SOURCE="$(readlink "$SOURCE")"
|
||||
[[ $SOURCE != /* ]] && SOURCE="$OV_PATH_ROOT/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||
done
|
||||
OV_PATH_ROOT="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
fi
|
||||
|
||||
export LD_LIBRARY_PATH="$OV_PATH_LIB:@CMAKE_SOURCE_DIR@/dependencies/lib:$LD_LIBRARY_PATH"
|
||||
export LC_ALL=C
|
||||
|
||||
# The following line is there to help in cases where OpenViBE can consume excessive
|
||||
# amounts of CPU or grind the swap. You can remove it if you know what you're doing.
|
||||
renice 19 $$
|
||||
|
||||
ov_debugger=
|
||||
if [ "$1" == "--debug" ]; then
|
||||
ov_debugger="gdb --args"
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ "$1" == "--memcheck" ]; then
|
||||
ov_debugger="valkyrie "
|
||||
#ov_debugger="valgrind --tool=memcheck --log-file='valgrind_@OV_CMD_EXECUTABLE@_%p.log'"
|
||||
shift
|
||||
fi
|
||||
ov_run_bg=0
|
||||
if [ "$1" == "--run-bg" ]; then
|
||||
ov_run_bg=1
|
||||
shift
|
||||
fi
|
||||
|
||||
ret_code=0
|
||||
|
||||
if [ $ov_run_bg == 0 ]; then
|
||||
eval $ov_debugger "$OV_PATH_BIN/@OV_CMD_EXECUTABLE@" @OV_CMD_ARGS@ $*
|
||||
ret_code=$?
|
||||
else
|
||||
$ov_debugger "$OV_PATH_BIN/@OV_CMD_EXECUTABLE@" @OV_CMD_ARGS@ $* &
|
||||
fi
|
||||
|
||||
exit $ret_code
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "winres.h"
|
||||
|
||||
@CONFIGURE_ICON@
|
||||
|
||||
// Language is US English
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
|
||||
|
||||
#ifndef DEBUG
|
||||
#define VER_DEBUG 0
|
||||
#else
|
||||
#define VER_DEBUG VS_FF_DEBUG
|
||||
#endif
|
||||
|
||||
// Add version information
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION @OV_GLOBAL_VERSION_MAJOR@,@OV_GLOBAL_VERSION_MINOR@,@OV_GLOBAL_VERSION_PATCH@,@OV_GLOBAL_VERSION_BUILD@
|
||||
PRODUCTVERSION @OV_GLOBAL_VERSION_MAJOR@,@OV_GLOBAL_VERSION_MINOR@,@OV_GLOBAL_VERSION_PATCH@,@OV_GLOBAL_VERSION_BUILD@
|
||||
FILEOS VOS__WINDOWS32
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "@COMPANY_NAME@"
|
||||
VALUE "FileDescription", "@FILE_DESCRIPTION@"
|
||||
VALUE "FileVersion", "@OV_GLOBAL_VERSION_STRING@"
|
||||
VALUE "InternalName", "@PROJECT_NAME@"
|
||||
VALUE "LegalCopyright", "Copyright - @COMPANY_NAME@ @COPYRIGHT_DATE@"
|
||||
VALUE "OriginalFilename", "@PROJECT_NAME@"
|
||||
VALUE "ProductName", "@PROJECT_PRODUCT_NAME@"
|
||||
VALUE "ProductVersion", "@OV_GLOBAL_VERSION_STRING@"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
// Indicates that Software is translated in US English in the Windows ANSI codepage (1252).
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
PROJECT(openvibe-common)
|
||||
|
||||
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
|
||||
SET(PROJECT_VERSION_MINOR ${OV_GLOBAL_VERSION_MINOR})
|
||||
SET(PROJECT_VERSION_PATCH ${OV_GLOBAL_VERSION_PATCH})
|
||||
SET(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
|
||||
|
||||
FILE(GLOB_RECURSE SRC_FILES src/*.h src/*.cpp include/*.h include/*.hpp)
|
||||
INCLUDE_DIRECTORIES(include)
|
||||
|
||||
# A headers-only project, the executable is a NOP having some static asserts, not to be installed.
|
||||
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILES})
|
||||
INCLUDE("FindThirdPartyBoost")
|
||||
|
||||
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
FOLDER ${KERNEL_FOLDER})
|
||||
|
||||
# ---------------------------------
|
||||
# Target macros
|
||||
# Defines target operating system, architecture and compiler
|
||||
# ---------------------------------
|
||||
SET_BUILD_PLATFORM()
|
||||
|
||||
# -----------------------------
|
||||
# Install files
|
||||
# -----------------------------
|
||||
|
||||
INSTALL(DIRECTORY include/ DESTINATION ${DIST_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h" PATTERN "doc" EXCLUDE)
|
||||
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Common {
|
||||
namespace Converter {
|
||||
|
||||
#if defined TARGET_OS_Windows
|
||||
// Returns the wstring (ie the utf16 formatted string) version of an utf8 string
|
||||
static std::wstring Utf8ToUtf16(const std::string& utf8)
|
||||
{
|
||||
std::vector<unsigned long> unicode;
|
||||
size_t i = 0;
|
||||
while (i < utf8.size())
|
||||
{
|
||||
unsigned long uni;
|
||||
size_t todo;
|
||||
unsigned char ch = utf8[i++];
|
||||
if (ch <= 0x7F)
|
||||
{
|
||||
uni = ch;
|
||||
todo = 0;
|
||||
}
|
||||
else if (ch <= 0xBF) { throw std::logic_error("not a UTF-8 string"); }
|
||||
else if (ch <= 0xDF)
|
||||
{
|
||||
uni = ch & 0x1F;
|
||||
todo = 1;
|
||||
}
|
||||
else if (ch <= 0xEF)
|
||||
{
|
||||
uni = ch & 0x0F;
|
||||
todo = 2;
|
||||
}
|
||||
else if (ch <= 0xF7)
|
||||
{
|
||||
uni = ch & 0x07;
|
||||
todo = 3;
|
||||
}
|
||||
else { throw std::logic_error("not a UTF-8 string"); }
|
||||
for (size_t j = 0; j < todo; ++j)
|
||||
{
|
||||
if (i == utf8.size()) { throw std::logic_error("not a UTF-8 string"); }
|
||||
ch = utf8[i++];
|
||||
if (ch < 0x80 || ch > 0xBF) { throw std::logic_error("not a UTF-8 string"); }
|
||||
uni <<= 6;
|
||||
uni += ch & 0x3F;
|
||||
}
|
||||
if (uni >= 0xD800 && uni <= 0xDFFF) { throw std::logic_error("not a UTF-8 string"); }
|
||||
if (uni > 0x10FFFF) { throw std::logic_error("not a UTF-8 string"); }
|
||||
unicode.push_back(uni);
|
||||
}
|
||||
std::wstring utf16;
|
||||
for (i = 0; i < unicode.size(); ++i)
|
||||
{
|
||||
unsigned long uni = unicode[i];
|
||||
if (uni <= 0xFFFF) { utf16 += wchar_t(uni); }
|
||||
else
|
||||
{
|
||||
uni -= 0x10000;
|
||||
utf16 += wchar_t((uni >> 10) + 0xD800);
|
||||
utf16 += wchar_t((uni & 0x3FF) + 0xDC00);
|
||||
}
|
||||
}
|
||||
return utf16;
|
||||
}
|
||||
#endif // TARGET_OS_Windows
|
||||
|
||||
} // namespace Converter
|
||||
} // namespace Common
|
||||
@@ -0,0 +1,422 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
#include <r8brain/CDSPResampler.h>
|
||||
|
||||
namespace Common {
|
||||
namespace Resampler {
|
||||
|
||||
enum class EResamplerStoreModes { ChannelWise, SampleWise };
|
||||
|
||||
template <class TFloat, EResamplerStoreModes TStoreMode>
|
||||
class TResampler
|
||||
{
|
||||
public:
|
||||
|
||||
class ICallback
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~ICallback() { }
|
||||
virtual void processResampler(const TFloat* pSample, const size_t nChannel) const = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
TResampler(const TResampler<TFloat, TStoreMode>&) = default;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary> Constructor, with default values for real-time processing. </summary>
|
||||
TResampler()
|
||||
{
|
||||
this->clear();
|
||||
switch (TStoreMode)
|
||||
{
|
||||
case EResamplerStoreModes::ChannelWise:
|
||||
m_fpResample = &TResampler<TFloat, TStoreMode>::resampleChannelWise;
|
||||
m_fpResampleDirect = &TResampler<TFloat, TStoreMode>::resampleChannelWise;
|
||||
break;
|
||||
case EResamplerStoreModes::SampleWise:
|
||||
m_fpResample = &TResampler<TFloat, TStoreMode>::resampleSampleWise;
|
||||
m_fpResampleDirect = &TResampler<TFloat, TStoreMode>::resampleSampleWise;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~TResampler() { this->clear(); }
|
||||
|
||||
void clear()
|
||||
{
|
||||
for (size_t j = 0; j < m_resamplers.size(); ++j) { delete m_resamplers[j]; }
|
||||
m_resamplers.clear();
|
||||
|
||||
m_nChannel = 0;
|
||||
m_iSampling = 0;
|
||||
m_oSampling = 0;
|
||||
m_nFractionalDelayFilterSample = 6;
|
||||
m_iMaxNSampleIn = 1024;
|
||||
m_transitionBandPercent = 45;
|
||||
m_stopBandAttenuation = 49;
|
||||
}
|
||||
|
||||
/// <summary> Specifies the number of samples (taps) each fractional delay filter should have.\n
|
||||
///
|
||||
/// This must be an even value.To achieve a higher resampling precision,
|
||||
/// the oversampling should be used in the first place instead of using a higher FractionalDelayFilterSampleCount value.
|
||||
/// The lower this value is the lower the signal - to - noise performance of the interpolator will be.
|
||||
/// Each FractionalDelayFilterSampleCount decrease by 2 decreases SNR by approximately 12 to 14 decibels. </summary>
|
||||
/// <param name="n">The fractional delay (Between 6 and 30, and default = 6).</param>
|
||||
/// <returns> <c>true</c> if even and between 6 and 30, <c>false</c> otherwise. </returns>
|
||||
/// <remarks>For real-time processing, n = 6. </remarks>
|
||||
bool setFractionalDelayFilterSampleCount(const int n = 6)
|
||||
{
|
||||
if (n < 6 || 30 < n || n % 2 == 1) { return false; } // false if odd value
|
||||
m_nFractionalDelayFilterSample = n;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Maximal planned length of the input buffer (in samples) that will be passed to the resampler.
|
||||
/// Input buffers longer than this value should never be supplied to the resampler.
|
||||
/// The resampler relies on this value as it allocates intermediate buffers. </summary>
|
||||
/// <param name="n">The maximal input sample count.</param>
|
||||
/// <returns> <c>true</c> if between 8 and 2048, <c>false</c> otherwise. </returns>
|
||||
/// <remarks> Note that the resampler may use the input buffer itself for intermediate sample data storage. </remarks>
|
||||
bool setMaxNSampleIn(const int n = 8)
|
||||
{
|
||||
if (n < 8 || 2048 < n) { return false; }
|
||||
m_iMaxNSampleIn = n;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Transition band, in percent of the spectral space of the input signal
|
||||
/// (or the output signal if downsampling is performed) between filter's -3 dB point and the Nyquist frequency. </summary>
|
||||
/// <param name="n">The Transition band (Between 0.5% and 45%, and default = 10.).</param>
|
||||
/// <returns> <c>true</c> if between 0.5 and 45, <c>false</c> otherwise. </returns>
|
||||
/// <remarks>For real-time processing, n = 45. </remarks>
|
||||
bool setTransitionBand(const double n = 10)
|
||||
{
|
||||
if (n < r8b::CDSPFIRFilter::getLPMinTransBand() || r8b::CDSPFIRFilter::getLPMaxTransBand() < n) { return false; }
|
||||
m_transitionBandPercent = n;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Stop-band attenuation in decibel.\n
|
||||
///
|
||||
/// The general formula is 6.02 * Bits + 40, where "Bits" is the bit resolution(e.g. 16, 24),
|
||||
/// "40" is an added resolution for stationary signals, this value can be decreased to 20 to 10
|
||||
/// if the signal being resampled is mostly non - stationary(e.g.impulse response). </summary>
|
||||
/// <param name="n">The Stop-band attenuation in decibel (Between 49 and 218, and default = 49 is given by the general formula).</param>
|
||||
/// <returns> <c>true</c> if between 49 and 218, <c>false</c> otherwise. </returns>
|
||||
/// <remarks>For real-time processing, n = 49. </remarks>
|
||||
bool setStopBandAttenuation(const double n = 49)
|
||||
{
|
||||
if (n < r8b::CDSPFIRFilter::getLPMinAtten() || r8b::CDSPFIRFilter::getLPMaxAtten() < n) { return false; }
|
||||
m_stopBandAttenuation = n;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> This fonction initializes the vector of Resampler, using the number of channels, the input and the output sampling rates. </summary>
|
||||
/// <param name="nChannel"> The number of channel. </param>
|
||||
/// <param name="iSampling"> The input sampling. </param>
|
||||
/// <param name="oSampling"> The output sampling. </param>
|
||||
/// <returns> <c>true</c> if success, <c>false</c> otherwise. </returns>
|
||||
bool reset(const size_t nChannel, const size_t iSampling, const size_t oSampling)
|
||||
{
|
||||
if (nChannel == 0 || iSampling == 0 || oSampling == 0) { return false; }
|
||||
m_iSampling = iSampling;
|
||||
m_oSampling = oSampling;
|
||||
|
||||
m_nChannel = nChannel;
|
||||
for (size_t i = 0; i < m_resamplers.size(); ++i) { delete m_resamplers[i]; }
|
||||
m_resamplers.clear();
|
||||
m_resamplers.resize(m_nChannel);
|
||||
|
||||
const double in = double(iSampling), out = double(oSampling);
|
||||
const double stopBandAttenuation = m_stopBandAttenuation == 0
|
||||
? std::min(6.02 * m_nFractionalDelayFilterSample + 40, r8b::CDSPFIRFilter::getLPMaxAtten())
|
||||
: m_stopBandAttenuation;
|
||||
#define NEW_SAMPLER(Len, Fracs)\
|
||||
new r8b::CDSPResampler<r8b::CDSPFracInterpolator<Len, Fracs>>(in, out, m_iMaxNSampleIn,\
|
||||
m_transitionBandPercent, stopBandAttenuation,r8b::EDSPFilterPhaseResponse(0), false)
|
||||
|
||||
for (size_t j = 0; j < m_nChannel; ++j)
|
||||
{
|
||||
switch (m_nFractionalDelayFilterSample) // it defines iFractionalDelayPositionCount
|
||||
{
|
||||
case 6:
|
||||
m_resamplers[j] = NEW_SAMPLER(6, 11);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
m_resamplers[j] = NEW_SAMPLER(8, 17);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
m_resamplers[j] = NEW_SAMPLER(10, 23);
|
||||
break;
|
||||
|
||||
case 12:
|
||||
m_resamplers[j] = NEW_SAMPLER(12, 41);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
//stopBandAttenuation = 109.56;
|
||||
m_resamplers[j] = NEW_SAMPLER(14, 67);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
m_resamplers[j] = NEW_SAMPLER(16, 97);
|
||||
break;
|
||||
|
||||
case 18:
|
||||
//stopBandAttenuation = 136.45;
|
||||
m_resamplers[j] = NEW_SAMPLER(18, 137);
|
||||
break;
|
||||
|
||||
case 20:
|
||||
m_resamplers[j] = NEW_SAMPLER(20, 211);
|
||||
break;
|
||||
|
||||
case 22:
|
||||
m_resamplers[j] = NEW_SAMPLER(22, 353);
|
||||
break;
|
||||
|
||||
case 24:
|
||||
//stopBandAttenuation = 180.15;
|
||||
m_resamplers[j] = NEW_SAMPLER(24, 673);
|
||||
break;
|
||||
|
||||
case 26:
|
||||
m_resamplers[j] = NEW_SAMPLER(26, 1051);
|
||||
break;
|
||||
|
||||
case 28:
|
||||
m_resamplers[j] = NEW_SAMPLER(28, 1733);
|
||||
break;
|
||||
|
||||
case 30:
|
||||
m_resamplers[j] = NEW_SAMPLER(30, 2833);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#undef NEW_SAMPLER(Len, Fracs)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Gets the latency.\n
|
||||
///
|
||||
/// This value is usually zero if the DSP processor "consumes" the latency automatically. (from CDSPProcessor.h) </summary>
|
||||
/// <returns> Latency. </returns>
|
||||
virtual int getLatency() const { return m_resamplers[0]->getLatency(); }
|
||||
|
||||
/// <summary> Gets the Fractional latency.
|
||||
///
|
||||
/// Fractional latency, in samples, which is present in the output signal.
|
||||
/// This value is usually zero if a linear - phase filtering is used.
|
||||
/// With minimum - phase filters in use, this value can be non - zero even if the getLatency() function returns zero. (from CDSPProcessor.h)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <returns> Fractionnal Latency. </returns>
|
||||
virtual double getLatencyFrac() const { return m_resamplers[0]->getLatencyFrac(); }
|
||||
|
||||
/// <summary> Gets the cumulative number of samples that should be passed to *this object before the actual output starts.
|
||||
/// This value includes latencies induced by all processors which run after *this processor in chain. </summary>
|
||||
/// <param name="nextInLen"> The number of input samples required before the output starts on the next resampling step. (from CDSPProcessor.h) </param>
|
||||
/// <returns> the cumulative number of samples. </returns>
|
||||
virtual int getInLenBeforeOutStart(const int nextInLen) const { return m_resamplers[0]->getInLenBeforeOutStart(nextInLen); }
|
||||
|
||||
/// <summary> Gets the maximal length of the output buffer required when processing the "maxInLen" number of input samples. </summary>
|
||||
/// <param name="maxInLen"> The number of samples planned to process at once, at most. (from CDSPProcessor.h). </param>
|
||||
/// <returns> The length. </returns>
|
||||
virtual int getMaxOutLen(const int maxInLen) const { return m_resamplers[0]->getMaxOutLen(maxInLen); }
|
||||
|
||||
double getBuiltInLatency() const { return (m_iSampling != 0) ? (1.0 * m_resamplers[0]->getInLenBeforeOutStart(0) / m_iSampling) : 0.0; }
|
||||
|
||||
size_t resample(const ICallback& callback, const TFloat* iSample, const size_t nInSample) { return (this->*m_fpResample)(callback, iSample, nInSample); }
|
||||
|
||||
size_t downsample(const ICallback& callback, const TFloat* iSample, const size_t nInSample) { return (this->*m_fpResample)(callback, iSample, nInSample); }
|
||||
|
||||
private:
|
||||
|
||||
/// <summary> This function resamples the signal assuming the input samples are ordered this way :
|
||||
/// - sample 1 of channel 1, sample 1 of channel 2, ..., sample 1 of channel nChannel,
|
||||
/// - sample 2 of channel 1, sample 2 of channel 2, ..., sample 2 of channel nChannel,
|
||||
/// - ...
|
||||
/// - sample nInSample of channel 1, sample nInSample of channel 2, ..., sample nInSample of channel nChannel,\n
|
||||
///
|
||||
/// This is convenient for resampling at the acquisition level. </summary>
|
||||
/// <param name="callback">The callback.</param>
|
||||
/// <param name="iSample">The input sample.</param>
|
||||
/// <param name="nInSample">The n input sample.</param>
|
||||
/// <returns> the number of sample process in last channel. </returns>
|
||||
size_t resampleChannelWise(const ICallback& callback, const TFloat* iSample, const size_t nInSample)
|
||||
{
|
||||
int nI = 0;
|
||||
bool isFirstChannel = true;
|
||||
|
||||
std::vector<double> iBuffers(nInSample);
|
||||
std::vector<TFloat> oBuffers;
|
||||
|
||||
for (size_t j = 0; j < m_nChannel; ++j)
|
||||
{
|
||||
for (size_t k = 0; k < nInSample; ++k) { iBuffers[k] = double(iSample[k * m_nChannel + j]); }
|
||||
|
||||
double* resamplerOutputBuffer;
|
||||
nI = m_resamplers[j]->process(&iBuffers[0], int(nInSample), resamplerOutputBuffer);
|
||||
|
||||
if (isFirstChannel)
|
||||
{
|
||||
oBuffers.resize(nI * m_nChannel);
|
||||
isFirstChannel = false;
|
||||
}
|
||||
|
||||
for (int k = 0; k < nI; ++k) { oBuffers[k * m_nChannel + j] = TFloat(resamplerOutputBuffer[k]); }
|
||||
}
|
||||
|
||||
for (int k = 0; k < nI; ++k) { callback.processResampler(&oBuffers[k * m_nChannel], m_nChannel); }
|
||||
|
||||
return nI;
|
||||
}
|
||||
|
||||
/// <summary> This function resamples the signal assuming the input samples are ordered this way :
|
||||
/// - sample 1 of channel 1, sample 2 of channel 1, ..., sample nInSample of channel 1,
|
||||
/// - sample 1 of channel 2, sample 2 of channel 2, ..., sample nInSample of channel 2,
|
||||
/// - ...
|
||||
/// - sample 1 of channel nChannel, sample 2 of channel nChannel, ..., sample nInSample of channel nChannel,
|
||||
///
|
||||
/// This is convenient for resampling at the signal-processing level. </summary>
|
||||
/// <param name="callback">The callback.</param>
|
||||
/// <param name="iSample">The input sample.</param>
|
||||
/// <param name="nInSample">The n input sample.</param>
|
||||
/// <returns> the number of sample process in last channel. </returns>
|
||||
size_t resampleSampleWise(const ICallback& callback, const TFloat* iSample, const size_t nInSample)
|
||||
{
|
||||
int nI = 0;
|
||||
bool isFirstChannel = true;
|
||||
|
||||
std::vector<double> iBuffers(nInSample);
|
||||
std::vector<TFloat> oBuffers;
|
||||
|
||||
for (size_t j = 0; j < m_nChannel; ++j)
|
||||
{
|
||||
for (size_t k = 0; k < nInSample; ++k) { iBuffers[k] = double(iSample[j * nInSample + k]); }
|
||||
|
||||
double* resamplerOutputBuffer;
|
||||
nI = m_resamplers[j]->process(&iBuffers[0], int(nInSample), resamplerOutputBuffer);
|
||||
|
||||
if (isFirstChannel)
|
||||
{
|
||||
oBuffers.resize(nI * m_nChannel);
|
||||
isFirstChannel = false;
|
||||
}
|
||||
|
||||
for (int k = 0; k < nI; ++k) { oBuffers[k * m_nChannel + j] = TFloat(resamplerOutputBuffer[k]); }
|
||||
}
|
||||
|
||||
for (int k = 0; k < nI; ++k) { callback.processResampler(&oBuffers[k * m_nChannel], m_nChannel); }
|
||||
|
||||
return nI;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/// <summary> Trivial channel wise callback implementation. </summary>
|
||||
class CCallbackChannelWise final : public ICallback
|
||||
{
|
||||
public:
|
||||
CCallbackChannelWise(TFloat* oSample) : m_OutputSample(oSample) { }
|
||||
|
||||
void processResampler(const TFloat* sample, const size_t nChannel) const override
|
||||
{
|
||||
for (size_t i = 0; i < nChannel; ++i)
|
||||
{
|
||||
*m_OutputSample = *sample;
|
||||
++m_OutputSample;
|
||||
++sample;
|
||||
}
|
||||
}
|
||||
|
||||
mutable TFloat* m_OutputSample;
|
||||
};
|
||||
|
||||
/// <summary> Trivial sample wise callback implementation. </summary>
|
||||
class CCallbackSampleWise final : public ICallback
|
||||
{
|
||||
public:
|
||||
CCallbackSampleWise(TFloat* oSample, const size_t nOutSample) : m_OutputSample(oSample), m_NOutputSample(nOutSample) { }
|
||||
|
||||
void processResampler(const TFloat* sample, const size_t nChannel) const override
|
||||
{
|
||||
for (size_t i = 0; i < nChannel; ++i) { m_OutputSample[i * m_NOutputSample + m_OutputSampleIdx] = sample[i]; }
|
||||
m_OutputSampleIdx++;
|
||||
m_OutputSampleIdx %= m_NOutputSample;
|
||||
}
|
||||
|
||||
TFloat* const m_OutputSample;
|
||||
size_t m_NOutputSample = 0;
|
||||
mutable size_t m_OutputSampleIdx = 0;
|
||||
};
|
||||
|
||||
size_t resampleChannelWise(TFloat* oSample, const TFloat* iSample, const size_t nInSample, const size_t /*nOutSample*/)
|
||||
{
|
||||
return this->resample(CCallbackChannelWise(oSample), iSample, nInSample);
|
||||
}
|
||||
|
||||
size_t resampleSampleWise(TFloat* oSample, const TFloat* iSample, const size_t nInSample, const size_t nOutSample)
|
||||
{
|
||||
return this->resample(CCallbackSampleWise(oSample, nOutSample), iSample, nInSample);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
size_t resample(TFloat* oSample, const TFloat* iSample, const size_t nInSample, const size_t nOutSample = 1)
|
||||
{
|
||||
return (this->*m_fpResampleDirect)(oSample, iSample, nInSample, nOutSample);
|
||||
}
|
||||
|
||||
size_t downsample(TFloat* oSample, const TFloat* iSample, const size_t nInSample, const size_t nOutSample = 1)
|
||||
{
|
||||
return resample(oSample, iSample, nInSample, nOutSample);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
size_t m_nChannel = 0;
|
||||
size_t m_iSampling = 0;
|
||||
size_t m_oSampling = 0;
|
||||
|
||||
int m_nFractionalDelayFilterSample = 6;
|
||||
int m_iMaxNSampleIn = 1024;
|
||||
double m_transitionBandPercent = 45;
|
||||
double m_stopBandAttenuation = 49;
|
||||
|
||||
std::vector<r8b::CDSPProcessor*> m_resamplers;
|
||||
|
||||
size_t (TResampler<TFloat, TStoreMode>::*m_fpResample)(const ICallback& callback, const TFloat* iSample, const size_t nInSample);
|
||||
size_t (TResampler<TFloat, TStoreMode>::*m_fpResampleDirect)(TFloat* oSample, const TFloat* iSample, const size_t nInSample, const size_t nOutSample);
|
||||
};
|
||||
|
||||
typedef TResampler<float, EResamplerStoreModes::SampleWise> CResamplerSf;
|
||||
typedef TResampler<float, EResamplerStoreModes::ChannelWise> CResamplerCf;
|
||||
typedef TResampler<double, EResamplerStoreModes::SampleWise> CResamplerSd;
|
||||
typedef TResampler<double, EResamplerStoreModes::ChannelWise> CResamplerCd;
|
||||
|
||||
typedef TResampler<float, EResamplerStoreModes::SampleWise> CDownsamplerSf;
|
||||
typedef TResampler<float, EResamplerStoreModes::ChannelWise> CDownsamplerCf;
|
||||
typedef TResampler<double, EResamplerStoreModes::SampleWise> CDownsamplerSd;
|
||||
typedef TResampler<double, EResamplerStoreModes::ChannelWise> CDownsamplerCd;
|
||||
|
||||
} // namespace Resampler
|
||||
} // namespace Common
|
||||
@@ -0,0 +1,149 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib> // For Unix Compatibility (size_t)
|
||||
#include <cstdint> // For Uint standard
|
||||
|
||||
//
|
||||
// This file checks the presence of several defines that are supposed to
|
||||
// be set by the build system. In addition, it defines some additional ones.
|
||||
//
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// We need some magic to get #warning behavior on MSVC
|
||||
#define STRINGISE(N) #N
|
||||
#define EXPAND_THEN_STRINGISE(N) STRINGISE(N)
|
||||
#define __LINE_STR__ EXPAND_THEN_STRINGISE(__LINE__)
|
||||
|
||||
// Format #pragma message
|
||||
#define __LOC__ __FILE__ "(" __LINE_STR__ ")"
|
||||
#define __OUTPUT_FORMAT__(type) __LOC__ " : " type " : "
|
||||
|
||||
// Actual warning message type
|
||||
#define __WARNING__ __OUTPUT_FORMAT__("Warning")
|
||||
#endif
|
||||
|
||||
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
// Operating System identification //
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
|
||||
#if !(defined(TARGET_OS_Windows) || defined(TARGET_OS_Linux) || defined(TARGET_OS_MacOS))
|
||||
#if defined(_MSC_VER)
|
||||
#pragma message( __WARNING__ "No known target OS specified!")
|
||||
#else
|
||||
#warning "No known target OS specified!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
// Build type identification //
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
|
||||
#if !(defined(TARGET_BUILDTYPE_Debug) || defined(TARGET_BUILDTYPE_Release))
|
||||
#if defined(_MSC_VER)
|
||||
#pragma message( __WARNING__ "No known build type defined!")
|
||||
#else
|
||||
#warning "No known build type defined!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
// Compiler software identification //
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
|
||||
#if !(defined(TARGET_COMPILER_GCC) || defined(TARGET_COMPILER_VisualStudio) || defined(TARGET_COMPILER_LLVM))
|
||||
#if defined(_MSC_VER)
|
||||
#pragma message( __WARNING__ "No known compiler defined!")
|
||||
#else
|
||||
#warning "No known compiler defined!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
// API Definition //
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
|
||||
// Taken from
|
||||
// - http://people.redhat.com/drepper/dsohowto.pdf
|
||||
// - http://www.nedprod.com/programs/gccvisibility.html
|
||||
#if defined OV_Shared
|
||||
#if defined TARGET_OS_Windows
|
||||
#define OV_API_Export __declspec(dllexport)
|
||||
#define OV_API_Import __declspec(dllimport)
|
||||
#elif defined TARGET_OS_Linux || defined TARGET_OS_MacOS
|
||||
#define OV_API_Export __attribute__((visibility("default")))
|
||||
#define OV_API_Import __attribute__((visibility("default")))
|
||||
#else
|
||||
#define OV_API_Export
|
||||
#define OV_API_Import
|
||||
#endif
|
||||
#else
|
||||
#define OV_API_Export
|
||||
#define OV_API_Import
|
||||
#endif
|
||||
|
||||
#if defined OV_Exports
|
||||
#define OV_API OV_API_Export
|
||||
#else
|
||||
#define OV_API OV_API_Import
|
||||
#endif
|
||||
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
// API Definition for plugins //
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
|
||||
|
||||
// Taken from
|
||||
// - http://people.redhat.com/drepper/dsohowto.pdf
|
||||
// - http://www.nedprod.com/programs/gccvisibility.html
|
||||
#if defined OVP_Shared
|
||||
#if defined TARGET_OS_Windows
|
||||
#define OVP_API_Export __declspec(dllexport)
|
||||
#define OVP_API_Import __declspec(dllimport)
|
||||
#elif defined TARGET_OS_Linux || defined TARGET_OS_MacOS
|
||||
#define OVP_API_Export __attribute__((visibility("default")))
|
||||
#define OPV_API_Import __attribute__((visibility("default")))
|
||||
#else
|
||||
#define OVP_API_Export
|
||||
#define OVP_API_Import
|
||||
#endif
|
||||
#else
|
||||
# define OVP_API_Export
|
||||
# define OVP_API_Import
|
||||
#endif
|
||||
|
||||
#if defined OVP_Exports
|
||||
# define OVP_API OVP_API_Export
|
||||
#else
|
||||
# define OVP_API OVP_API_Import
|
||||
#endif
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
// NULL Definition //
|
||||
//___________________________________________________________________//
|
||||
// //
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) && (__cplusplus >= 201402L)
|
||||
#define OV_DEPRECATED(since) [[deprecated("Since " #since)]]
|
||||
#define OV_DEPRECATED_FOR(since, replacement) [[deprecated("Since " #since "; use " #replacement)]]
|
||||
#elif defined(_MSC_VER)
|
||||
#define OV_DEPRECATED(since) __declspec(deprecated("Since " # since))
|
||||
#define OV_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
|
||||
#else
|
||||
#define OV_DEPRECATED(since) __attribute__((__deprecated__))
|
||||
#define OV_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
|
||||
#endif
|
||||
@@ -0,0 +1,278 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
// -----------------------------------------------------
|
||||
// XML Scenario importer
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_XMLScenarioImporter OpenViBE::CIdentifier(0xe80c3ea2, 0x149c4a05)
|
||||
#define OVP_GD_ClassId_Algorithm_XMLScenarioExporter OpenViBE::CIdentifier(0x53693531, 0xb136cf3f)
|
||||
#define OVP_GD_TypeId_ClassificationPairwiseStrategy OpenViBE::CIdentifier(0x0DD51C74, 0x3C4E74C9)
|
||||
#define OVP_GD_TypeId_OneVsOne_DecisionAlgorithms OpenViBE::CIdentifier(0x0DEC1510, 0x0DEC1510)
|
||||
#define OVP_GD_ClassId_Algorithm_PairwiseStrategy_PKPD OpenViBE::CIdentifier(0x26EF6DDA, 0xF137053C)
|
||||
#define OVP_GD_ClassId_Algorithm_PairwiseDecision_Voting OpenViBE::CIdentifier(0xA111B830, 0x4679BAFD)
|
||||
#define OVP_GD_ClassId_Algorithm_PairwiseDecision_HT OpenViBE::CIdentifier(0xD24F7F19, 0xA744FAD2)
|
||||
|
||||
// Algorithm OVMatrixFileReader
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_OVMatrixFileReader OpenViBE::CIdentifier(0x10661A33, 0x0B0F44A7)
|
||||
#define OVP_GD_ClassId_Algorithm_OVMatrixFileReaderDesc OpenViBE::CIdentifier(0x0E873B5E, 0x0A287FCB)
|
||||
|
||||
|
||||
#define OVP_GD_Algorithm_OVMatrixFileReader_InputParameterId_Filename OpenViBE::CIdentifier(0x28F87B29, 0x0B09737E)
|
||||
#define OVP_GD_Algorithm_OVMatrixFileReader_OutputParameterId_Matrix OpenViBE::CIdentifier(0x2F9521E0, 0x027D789F)
|
||||
#define OVP_GD_Algorithm_OVMatrixFileReader_InputTriggerId_Open OpenViBE::CIdentifier(0x2F996376, 0x2A942485)
|
||||
#define OVP_GD_Algorithm_OVMatrixFileReader_InputTriggerId_Load OpenViBE::CIdentifier(0x22841807, 0x102D681C)
|
||||
#define OVP_GD_Algorithm_OVMatrixFileReader_InputTriggerId_Close OpenViBE::CIdentifier(0x7FDE77DA, 0x384A0B3D)
|
||||
#define OVP_GD_Algorithm_OVMatrixFileReader_OutputTriggerId_Error OpenViBE::CIdentifier(0x6D4F2F4B, 0x05EC6CB9)
|
||||
#define OVP_GD_Algorithm_OVMatrixFileReader_OutputTriggerId_DataProduced OpenViBE::CIdentifier(0x76F46051, 0x003B6FE8)
|
||||
|
||||
// -----------------------------------------------------
|
||||
// EBML stream encoder
|
||||
// -----------------------------------------------------
|
||||
#define OVP_GD_ClassId_Algorithm_StreamStructureDecoder OpenViBE::CIdentifier(0xA7EF3E8B, 0x4CF70B74)
|
||||
#define OVP_GD_ClassId_Algorithm_StreamStructureDecoderDesc OpenViBE::CIdentifier(0x2E361099, 0xCBE828A7)
|
||||
|
||||
#define OVP_GD_Algorithm_StreamStructureDecoder_InputParameterId_MemoryBufferToDecode OpenViBE::CIdentifier(0x2F98EA3C, 0xFB0BE096)
|
||||
#define OVP_GD_Algorithm_StreamStructureDecoder_OutputTriggerId_ReceivedHeader OpenViBE::CIdentifier(0x815234BF, 0xAABAE5F2)
|
||||
#define OVP_GD_Algorithm_StreamStructureDecoder_OutputTriggerId_ReceivedBuffer OpenViBE::CIdentifier(0xAA2738BF, 0xF7FE9FC3)
|
||||
#define OVP_GD_Algorithm_StreamStructureDecoder_OutputTriggerId_ReceivedEnd OpenViBE::CIdentifier(0xC4AA114C, 0x628C2D77)
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Streamed matrix stream encoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_StreamedMatrixEncoder OpenViBE::CIdentifier(0x5cb32c71, 0x576f00a6)
|
||||
#define OVP_GD_Algorithm_StreamedMatrixEncoder_InputParameterId_Matrix OpenViBE::CIdentifier(0xa3e9e5b0, 0xae756303)
|
||||
#define OVP_GD_Algorithm_StreamedMatrixEncoder_OutputParameterId_EncodedMemoryBuffer OpenViBE::CIdentifier(0xa3d8b171, 0xf8734734)
|
||||
#define OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeBuffer OpenViBE::CIdentifier(0x1b7076fd, 0x449bc70a)
|
||||
#define OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeEnd OpenViBE::CIdentifier(0x3fc23508, 0x806753d8)
|
||||
#define OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeHeader OpenViBE::CIdentifier(0x878eaf60, 0xf9d5303f)
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Experiment information stream decoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_ExperimentInfoDecoder OpenViBE::CIdentifier(0x6fa7d52b, 0x80e2abd6)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_InputParameterId_MemoryBufferToDecode OpenViBE::CIdentifier(0x2f98ea3c, 0xfb0be096)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_SubjectName OpenViBE::CIdentifier(0x3d3826ea, 0xe8883815)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_ExperimentID OpenViBE::CIdentifier(0x40259641, 0x478c73de)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_LaboratoryName OpenViBE::CIdentifier(0x5ca80fa5, 0x774f01cb)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_SubjectGender OpenViBE::CIdentifier(0x7d5059e8, 0xe4d8b38d)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_SubjectID OpenViBE::CIdentifier(0x97c5d20d, 0x203e65b3)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_TechnicianName OpenViBE::CIdentifier(0xb8a94b68, 0x389393d9)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_ExperimentDate OpenViBE::CIdentifier(0xbc0266a2, 0x9c2935f1)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_SubjectAge OpenViBE::CIdentifier(0xc36c6b08, 0x5227380a)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_TechnicianID OpenViBE::CIdentifier(0xc8ecfbbc, 0x0dcda310)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_LaboratoryID OpenViBE::CIdentifier(0xe761d3d4, 0x44ba1ebf)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedHeader OpenViBE::CIdentifier(0x815234bf, 0xaabae5f2)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedBuffer OpenViBE::CIdentifier(0xaa2738bf, 0xf7fe9fc3)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedEnd OpenViBE::CIdentifier(0xc4aa114c, 0x628c2d77)
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Channel localisation stream encoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_ChannelLocalisationEncoder OpenViBE::CIdentifier(0xc4aa738a, 0x2368c0ea)
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationEncoder_InputParameterId_Matrix OpenViBE::CIdentifier(0xa3e9e5b0, 0xae756303) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputParameterId_Matrix
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationEncoder_InputParameterId_Dynamic OpenViBE::CIdentifier(0xcf5dd4f8, 0xc2ff2878)
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationEncoder_OutputParameterId_EncodedMemoryBuffer OpenViBE::CIdentifier(0xa3d8b171, 0xf8734734) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_OutputParameterId_EncodedMemoryBuffer
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationEncoder_InputTriggerId_EncodeBuffer OpenViBE::CIdentifier(0x1b7076fd, 0x449bc70a) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeBuffer
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationEncoder_InputTriggerId_EncodeEnd OpenViBE::CIdentifier(0x3fc23508, 0x806753d8) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeEnd
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationEncoder_InputTriggerId_EncodeHeader OpenViBE::CIdentifier(0x878eaf60, 0xf9d5303f) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeHeader
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Signal stream decoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_SignalDecoder OpenViBE::CIdentifier(0x7237c149, 0x0ca66da7)
|
||||
#define OVP_GD_Algorithm_SignalDecoder_InputParameterId_MemoryBufferToDecode OpenViBE::CIdentifier(0x2f98ea3c, 0xfb0be096) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_InputParameterId_MemoryBufferToDecode
|
||||
#define OVP_GD_Algorithm_SignalDecoder_OutputParameterId_Sampling OpenViBE::CIdentifier(0x363d8d79, 0xeefb912c)
|
||||
#define OVP_GD_Algorithm_SignalDecoder_OutputParameterId_Matrix OpenViBE::CIdentifier(0x79ef3123, 0x35e3ea4d)
|
||||
#define OVP_GD_Algorithm_SignalDecoder_OutputTriggerId_ReceivedHeader OpenViBE::CIdentifier(0x815234bf, 0xaabae5f2) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedHeader
|
||||
#define OVP_GD_Algorithm_SignalDecoder_OutputTriggerId_ReceivedBuffer OpenViBE::CIdentifier(0xaa2738bf, 0xf7fe9fc3) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedBuffer
|
||||
#define OVP_GD_Algorithm_SignalDecoder_OutputTriggerId_ReceivedEnd OpenViBE::CIdentifier(0xc4aa114c, 0x628c2d77) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedEnd
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Spectrum stream encoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_SpectrumEncoder OpenViBE::CIdentifier(0xb3e252db, 0xc3214498)
|
||||
#define OVP_GD_Algorithm_SpectrumEncoder_InputParameterId_Matrix OpenViBE::CIdentifier(0xa3e9e5b0, 0xae756303) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputParameterId_Matrix
|
||||
#define OVP_GD_Algorithm_SpectrumEncoder_InputParameterId_FrequencyAbscissa OpenViBE::CIdentifier(0x05C91BD6, 0x2D8C4083)
|
||||
#define OVP_GD_Algorithm_SpectrumEncoder_InputParameterId_Sampling OpenViBE::CIdentifier(0x02D25E1B, 0x76A1019B)
|
||||
#define OVP_GD_Algorithm_SpectrumEncoder_OutputParameterId_EncodedMemoryBuffer OpenViBE::CIdentifier(0xa3d8b171, 0xf8734734) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_OutputParameterId_EncodedMemoryBuffer
|
||||
#define OVP_GD_Algorithm_SpectrumEncoder_InputTriggerId_EncodeBuffer OpenViBE::CIdentifier(0x1b7076fd, 0x449bc70a) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeBuffer
|
||||
#define OVP_GD_Algorithm_SpectrumEncoder_InputTriggerId_EncodeEnd OpenViBE::CIdentifier(0x3fc23508, 0x806753d8) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeEnd
|
||||
#define OVP_GD_Algorithm_SpectrumEncoder_InputTriggerId_EncodeHeader OpenViBE::CIdentifier(0x878eaf60, 0xf9d5303f) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeHeader
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Acquisition stream decoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_AcquisitionDecoder OpenViBE::CIdentifier(0x1e0812b7, 0x3f686dd4)
|
||||
#define OVP_GD_Algorithm_AcquisitionDecoder_InputParameterId_MemoryBufferToDecode OpenViBE::CIdentifier(0x2f98ea3c, 0xfb0be096) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_InputParameterId_MemoryBufferToDecode
|
||||
#define OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_StimulationStream OpenViBE::CIdentifier(0x08fc3c12, 0x86a07bf7)
|
||||
#define OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_ChannelUnitsStream OpenViBE::CIdentifier(0x11b93981, 0x6e5da9b0)
|
||||
#define OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_SignalStream OpenViBE::CIdentifier(0x42c0d7bd, 0xbbcea3f3)
|
||||
#define OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_ChannelLocalisationStream OpenViBE::CIdentifier(0x4eb92f81, 0x6ecda6b9)
|
||||
#define OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_BufferDuration OpenViBE::CIdentifier(0x7527d6e5, 0xb7a70339)
|
||||
#define OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_ExperimentInfoStream OpenViBE::CIdentifier(0xa7f1d539, 0xec708539)
|
||||
#define OVP_GD_Algorithm_AcquisitionDecoder_OutputTriggerId_ReceivedHeader OpenViBE::CIdentifier(0x815234bf, 0xaabae5f2) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedHeader
|
||||
#define OVP_GD_Algorithm_AcquisitionDecoder_OutputTriggerId_ReceivedBuffer OpenViBE::CIdentifier(0xaa2738bf, 0xf7fe9fc3) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedBuffer
|
||||
#define OVP_GD_Algorithm_AcquisitionDecoder_OutputTriggerId_ReceivedEnd OpenViBE::CIdentifier(0xc4aa114c, 0x628c2d77) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedEnd
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_MasterAcquisitionEncoder OpenViBE::CIdentifier(0x2d15e00b, 0x51414eb6)
|
||||
#define OVP_GD_ClassId_Algorithm_MasterAcquisitionEncoderDesc OpenViBE::CIdentifier(0xe6ec841d, 0x9e75a8fb)
|
||||
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputParameterId_EncodeChannelUnitData OpenViBE::CIdentifier(0x19dc533c, 0x56301d0b)
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputParameterId_ChannelLocalisation OpenViBE::CIdentifier(0x227e13f0, 0x206b44f9)
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputParameterId_EncodeChannelLocalisationData OpenViBE::CIdentifier(0x26ee1f81, 0x3db00d5d)
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputParameterId_StimulationSet OpenViBE::CIdentifier(0x5b728d37, 0xfd088887)
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputParameterId_ChannelUnits OpenViBE::CIdentifier(0x740060c2, 0x7d2b4f57)
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputParameterId_SubjectAge OpenViBE::CIdentifier(0x9ef355e4, 0xc8531112)
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputParameterId_SubjectGender OpenViBE::CIdentifier(0xa9056ae3, 0x57fe6af0)
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputParameterId_SignalSampling OpenViBE::CIdentifier(0xb84ad0ca, 0x4f316dd3)
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputParameterId_SubjectID OpenViBE::CIdentifier(0xd5bb5231, 0x59389b72)
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputParameterId_BufferDuration OpenViBE::CIdentifier(0xe1fc7385, 0x586a4f3f)
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputParameterId_SignalMatrix OpenViBE::CIdentifier(0xe9ac8077, 0xe369a51d)
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_OutputParameterId_EncodedMemoryBuffer OpenViBE::CIdentifier(0xa3d8b171, 0xf8734734) // Duplicate of OVP_GD_Algorit hm_AcquisitionStreamEncoder_OutputParameterId_EncodedMemoryBuffer
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputTriggerId_EncodeBuffer OpenViBE::CIdentifier(0x1b7076fd, 0x449bc70a) // Duplicate of OVP_GD_Algorit hm_AcquisitionStreamEncoder_InputTriggerId_EncodeBuffer
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputTriggerId_EncodeEnd OpenViBE::CIdentifier(0x3fc23508, 0x806753d8) // Duplicate of OVP_GD_Algorit hm_AcquisitionStreamEncoder_InputTriggerId_EncodeEnd
|
||||
#define OVP_GD_Algorithm_MasterAcquisitionEncoder_InputTriggerId_EncodeHeader OpenViBE::CIdentifier(0x878eaf60, 0xf9d5303f) // Duplicate of OVP_GD_Algorit hm_AcquisitionStreamEncoder_InputTriggerId_EncodeHeader
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Spectrum stream decoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_SpectrumDecoder OpenViBE::CIdentifier(0x128202db, 0x449fc7a6)
|
||||
#define OVP_GD_Algorithm_SpectrumDecoder_InputParameterId_MemoryBufferToDecode OpenViBE::CIdentifier(0x2f98ea3c, 0xfb0be096) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_InputParameterId_MemoryBufferToDecode
|
||||
#define OVP_GD_Algorithm_SpectrumDecoder_OutputParameterId_FrequencyAbscissa OpenViBE::CIdentifier(0x14A572E4, 0x5C405C8E)
|
||||
#define OVP_GD_Algorithm_SpectrumDecoder_OutputParameterId_Sampling OpenViBE::CIdentifier(0x68442C12, 0x0D9A46DE)
|
||||
#define OVP_GD_Algorithm_SpectrumDecoder_OutputParameterId_Matrix OpenViBE::CIdentifier(0x79ef3123, 0x35e3ea4d) // Duplicate of OVP_GD_Algorithm_SignalDecoder_OutputParameterId_Matrix
|
||||
#define OVP_GD_Algorithm_SpectrumDecoder_OutputTriggerId_ReceivedHeader OpenViBE::CIdentifier(0x815234bf, 0xaabae5f2) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedHeader
|
||||
#define OVP_GD_Algorithm_SpectrumDecoder_OutputTriggerId_ReceivedBuffer OpenViBE::CIdentifier(0xaa2738bf, 0xf7fe9fc3) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedBuffer
|
||||
#define OVP_GD_Algorithm_SpectrumDecoder_OutputTriggerId_ReceivedEnd OpenViBE::CIdentifier(0xc4aa114c, 0x628c2d77) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedEnd
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Stimulation stream decoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_StimulationDecoder OpenViBE::CIdentifier(0xc8807f2b, 0x0813c5b1)
|
||||
#define OVP_GD_Algorithm_StimulationDecoder_InputParameterId_MemoryBufferToDecode OpenViBE::CIdentifier(0x2f98ea3c, 0xfb0be096) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_InputParameterId_MemoryBufferToDecode
|
||||
#define OVP_GD_Algorithm_StimulationDecoder_OutputParameterId_StimulationSet OpenViBE::CIdentifier(0xf46d0c19, 0x47306bea)
|
||||
#define OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedHeader OpenViBE::CIdentifier(0x815234bf, 0xaabae5f2) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedHeader
|
||||
#define OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedBuffer OpenViBE::CIdentifier(0xaa2738bf, 0xf7fe9fc3) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedBuffer
|
||||
#define OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedEnd OpenViBE::CIdentifier(0xc4aa114c, 0x628c2d77) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedEnd
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Streamed matrix stream decoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_StreamedMatrixDecoder OpenViBE::CIdentifier(0x7359d0db, 0x91784b21)
|
||||
#define OVP_GD_Algorithm_StreamedMatrixDecoder_InputParameterId_MemoryBufferToDecode OpenViBE::CIdentifier(0x2f98ea3c, 0xfb0be096) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_InputParameterId_MemoryBufferToDecode
|
||||
#define OVP_GD_Algorithm_StreamedMatrixDecoder_OutputParameterId_Matrix OpenViBE::CIdentifier(0x79ef3123, 0x35e3ea4d) // Duplicate of OVP_GD_Algorithm_SignalDecoder_OutputParameterId_Matrix
|
||||
#define OVP_GD_Algorithm_StreamedMatrixDecoder_OutputTriggerId_ReceivedHeader OpenViBE::CIdentifier(0x815234bf, 0xaabae5f2) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedHeader
|
||||
#define OVP_GD_Algorithm_StreamedMatrixDecoder_OutputTriggerId_ReceivedBuffer OpenViBE::CIdentifier(0xaa2738bf, 0xf7fe9fc3) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedBuffer
|
||||
#define OVP_GD_Algorithm_StreamedMatrixDecoder_OutputTriggerId_ReceivedEnd OpenViBE::CIdentifier(0xc4aa114c, 0x628c2d77) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedEnd
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Feature vector stream decoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_FeatureVectorDecoder OpenViBE::CIdentifier(0xc2689ecc, 0x43b335c1)
|
||||
#define OVP_GD_Algorithm_FeatureVectorDecoder_InputParameterId_MemoryBufferToDecode OpenViBE::CIdentifier(0x2f98ea3c, 0xfb0be096) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_InputParameterId_MemoryBufferToDecode
|
||||
#define OVP_GD_Algorithm_FeatureVectorDecoder_OutputParameterId_Matrix OpenViBE::CIdentifier(0x79ef3123, 0x35e3ea4d) // Duplicate of OVP_GD_Algorithm_SignalDecoder_OutputParameterId_Matrix
|
||||
#define OVP_GD_Algorithm_FeatureVectorDecoder_OutputTriggerId_ReceivedHeader OpenViBE::CIdentifier(0x815234bf, 0xaabae5f2) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedHeader
|
||||
#define OVP_GD_Algorithm_FeatureVectorDecoder_OutputTriggerId_ReceivedBuffer OpenViBE::CIdentifier(0xaa2738bf, 0xf7fe9fc3) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedBuffer
|
||||
#define OVP_GD_Algorithm_FeatureVectorDecoder_OutputTriggerId_ReceivedEnd OpenViBE::CIdentifier(0xc4aa114c, 0x628c2d77) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedEnd
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Channel localisation stream decoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_ChannelLocalisationDecoder OpenViBE::CIdentifier(0x8222f065, 0xb05d35cf)
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationDecoder_InputParameterId_MemoryBufferToDecode OpenViBE::CIdentifier(0x2f98ea3c, 0xfb0be096) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_InputParameterId_MemoryBufferToDecode
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationDecoder_OutputParameterId_Matrix OpenViBE::CIdentifier(0x79ef3123, 0x35e3ea4d) // Duplicate of OVP_GD_Algorithm_SignalDecoder_OutputParameterId_Matrix
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationDecoder_OutputParameterId_Dynamic OpenViBE::CIdentifier(0xd20991fd, 0xa3153651)
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationDecoder_OutputTriggerId_ReceivedHeader OpenViBE::CIdentifier(0x815234bf, 0xaabae5f2) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedHeader
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationDecoder_OutputTriggerId_ReceivedBuffer OpenViBE::CIdentifier(0xaa2738bf, 0xf7fe9fc3) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedBuffer
|
||||
#define OVP_GD_Algorithm_ChannelLocalisationDecoder_OutputTriggerId_ReceivedEnd OpenViBE::CIdentifier(0xc4aa114c, 0x628c2d77) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedEnd
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Channel units stream decoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_ChannelUnitsDecoder OpenViBE::CIdentifier(0x5f973ddf, 0x4a582daf)
|
||||
#define OVP_GD_Algorithm_ChannelUnitsDecoder_InputParameterId_MemoryBufferToDecode OpenViBE::CIdentifier(0x2f98ea3c, 0xfb0be096) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_InputParameterId_MemoryBufferToDecode
|
||||
#define OVP_GD_Algorithm_ChannelUnitsDecoder_OutputParameterId_Dynamic OpenViBE::CIdentifier(0x31cf1c7a, 0x17475323)
|
||||
#define OVP_GD_Algorithm_ChannelUnitsDecoder_OutputParameterId_Matrix OpenViBE::CIdentifier(0x79ef3123, 0x35e3ea4d) // Duplicate of OVP_GD_Algorithm_SignalDecoder_OutputParameterId_Matrix
|
||||
#define OVP_GD_Algorithm_ChannelUnitsDecoder_OutputTriggerId_ReceivedHeader OpenViBE::CIdentifier(0x815234bf, 0xaabae5f2) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedHeader
|
||||
#define OVP_GD_Algorithm_ChannelUnitsDecoder_OutputTriggerId_ReceivedBuffer OpenViBE::CIdentifier(0xaa2738bf, 0xf7fe9fc3) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedBuffer
|
||||
#define OVP_GD_Algorithm_ChannelUnitsDecoder_OutputTriggerId_ReceivedEnd OpenViBE::CIdentifier(0xc4aa114c, 0x628c2d77) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputTriggerId_ReceivedEnd
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Experiment information stream encoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_ExperimentInfoEncoder OpenViBE::CIdentifier(0x56b354fe, 0xbf175468)
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputParameterId_SubjectName OpenViBE::CIdentifier(0x3d3826ea, 0xe8883815) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_SubjectName
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputParameterId_ExperimentID OpenViBE::CIdentifier(0x40259641, 0x478c73de) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_ExperimentID
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputParameterId_LaboratoryName OpenViBE::CIdentifier(0x5ca80fa5, 0x774f01cb) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_LaboratoryName
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputParameterId_SubjectGender OpenViBE::CIdentifier(0x7d5059e8, 0xe4d8b38d) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_SubjectGender
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputParameterId_SubjectID OpenViBE::CIdentifier(0x97c5d20d, 0x203e65b3) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_SubjectID
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputParameterId_TechnicianName OpenViBE::CIdentifier(0xb8a94b68, 0x389393d9) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_TechnicianName
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputParameterId_ExperimentDate OpenViBE::CIdentifier(0xbc0266a2, 0x9c2935f1) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_ExperimentDate
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputParameterId_SubjectAge OpenViBE::CIdentifier(0xc36c6b08, 0x5227380a) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_SubjectAge
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputParameterId_TechnicianID OpenViBE::CIdentifier(0xc8ecfbbc, 0x0dcda310) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_TechnicianID
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputParameterId_LaboratoryID OpenViBE::CIdentifier(0xe761d3d4, 0x44ba1ebf) // Duplicate of OVP_GD_Algorithm_ExperimentInfoDecoder_OutputParameterId_LaboratoryID
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_OutputParameterId_EncodedMemoryBuffer OpenViBE::CIdentifier(0xa3d8b171, 0xf8734734) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_OutputParameterId_EncodedMemoryBuffer
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputTriggerId_EncodeBuffer OpenViBE::CIdentifier(0x1b7076fd, 0x449bc70a) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeBuffer
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputTriggerId_EncodeEnd OpenViBE::CIdentifier(0x3fc23508, 0x806753d8) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeEnd
|
||||
#define OVP_GD_Algorithm_ExperimentInfoEncoder_InputTriggerId_EncodeHeader OpenViBE::CIdentifier(0x878eaf60, 0xf9d5303f) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeHeader
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Feature vector stream encoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_FeatureVectorEncoder OpenViBE::CIdentifier(0x7ebe049d, 0xf777a602)
|
||||
#define OVP_GD_Algorithm_FeatureVectorEncoder_InputParameterId_Matrix OpenViBE::CIdentifier(0xa3e9e5b0, 0xae756303) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputParameterId_Matrix
|
||||
#define OVP_GD_Algorithm_FeatureVectorEncoder_OutputParameterId_EncodedMemoryBuffer OpenViBE::CIdentifier(0xa3d8b171, 0xf8734734) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_OutputParameterId_EncodedMemoryBuffer
|
||||
#define OVP_GD_Algorithm_FeatureVectorEncoder_InputTriggerId_EncodeBuffer OpenViBE::CIdentifier(0x1b7076fd, 0x449bc70a) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeBuffer
|
||||
#define OVP_GD_Algorithm_FeatureVectorEncoder_InputTriggerId_EncodeEnd OpenViBE::CIdentifier(0x3fc23508, 0x806753d8) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeEnd
|
||||
#define OVP_GD_Algorithm_FeatureVectorEncoder_InputTriggerId_EncodeHeader OpenViBE::CIdentifier(0x878eaf60, 0xf9d5303f) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeHeader
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Stimulation stream encoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_StimulationEncoder OpenViBE::CIdentifier(0x6e86f7d5, 0xa4668108)
|
||||
#define OVP_GD_Algorithm_StimulationEncoder_InputParameterId_StimulationSet OpenViBE::CIdentifier(0x8565254c, 0x3a49268e)
|
||||
#define OVP_GD_Algorithm_StimulationEncoder_OutputParameterId_EncodedMemoryBuffer OpenViBE::CIdentifier(0xa3d8b171, 0xf8734734) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_OutputParameterId_EncodedMemoryBuffer
|
||||
#define OVP_GD_Algorithm_StimulationEncoder_InputTriggerId_EncodeBuffer OpenViBE::CIdentifier(0x1b7076fd, 0x449bc70a) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeBuffer
|
||||
#define OVP_GD_Algorithm_StimulationEncoder_InputTriggerId_EncodeEnd OpenViBE::CIdentifier(0x3fc23508, 0x806753d8) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeEnd
|
||||
#define OVP_GD_Algorithm_StimulationEncoder_InputTriggerId_EncodeHeader OpenViBE::CIdentifier(0x878eaf60, 0xf9d5303f) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeHeader
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Channel units stream encoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_ChannelUnitsEncoder OpenViBE::CIdentifier(0x2ca034fd, 0x5c051e86)
|
||||
#define OVP_GD_Algorithm_ChannelUnitsEncoder_InputParameterId_Dynamic OpenViBE::CIdentifier(0x615f03b9, 0x4f6a320a)
|
||||
#define OVP_GD_Algorithm_ChannelUnitsEncoder_InputParameterId_Matrix OpenViBE::CIdentifier(0xa3e9e5b0, 0xae756303) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputParameterId_Matrix
|
||||
#define OVP_GD_Algorithm_ChannelUnitsEncoder_OutputParameterId_EncodedMemoryBuffer OpenViBE::CIdentifier(0xa3d8b171, 0xf8734734) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_OutputParameterId_EncodedMemoryBuffer
|
||||
#define OVP_GD_Algorithm_ChannelUnitsEncoder_InputTriggerId_EncodeBuffer OpenViBE::CIdentifier(0x1b7076fd, 0x449bc70a) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeBuffer
|
||||
#define OVP_GD_Algorithm_ChannelUnitsEncoder_InputTriggerId_EncodeEnd OpenViBE::CIdentifier(0x3fc23508, 0x806753d8) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeEnd
|
||||
#define OVP_GD_Algorithm_ChannelUnitsEncoder_InputTriggerId_EncodeHeader OpenViBE::CIdentifier(0x878eaf60, 0xf9d5303f) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeHeader
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Signal stream encoder
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define OVP_GD_ClassId_Algorithm_SignalEncoder OpenViBE::CIdentifier(0xc488ad3c, 0xeb2e36bf)
|
||||
#define OVP_GD_Algorithm_SignalEncoder_InputParameterId_Sampling OpenViBE::CIdentifier(0x998710ff, 0x2c5cca82)
|
||||
#define OVP_GD_Algorithm_SignalEncoder_InputParameterId_Matrix OpenViBE::CIdentifier(0xa3e9e5b0, 0xae756303) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputParameterId_Matrix
|
||||
#define OVP_GD_Algorithm_SignalEncoder_OutputParameterId_EncodedMemoryBuffer OpenViBE::CIdentifier(0xa3d8b171, 0xf8734734) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_OutputParameterId_EncodedMemoryBuffer
|
||||
#define OVP_GD_Algorithm_SignalEncoder_InputTriggerId_EncodeBuffer OpenViBE::CIdentifier(0x1b7076fd, 0x449bc70a) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeBuffer
|
||||
#define OVP_GD_Algorithm_SignalEncoder_InputTriggerId_EncodeEnd OpenViBE::CIdentifier(0x3fc23508, 0x806753d8) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeEnd
|
||||
#define OVP_GD_Algorithm_SignalEncoder_InputTriggerId_EncodeHeader OpenViBE::CIdentifier(0x878eaf60, 0xf9d5303f) // Duplicate of OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeHeader
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Appeasing Intellisense by including the following
|
||||
#include "ov_common_defines.h"
|
||||
#include <cstdint>
|
||||
|
||||
int main()
|
||||
{
|
||||
#if defined(WIN32) || (defined(LINUX) && defined(__GXX_EXPERIMENTAL_CXX0X__))
|
||||
static_assert(sizeof(uint64_t) >= 8, "uint64_t is not at least 8 bytes");
|
||||
static_assert(sizeof(uint32_t) >= 4, "uint32_t is not at least 4 bytes");
|
||||
static_assert(sizeof(uint16_t) >= 2, "uint16_t is not at least 2 bytes");
|
||||
static_assert(sizeof(uint8_t) >= 1, "uint8_t is not at least 1 byte");
|
||||
|
||||
static_assert(sizeof(int64_t) >= 8, "int64_t is not at least 8 bytes");
|
||||
static_assert(sizeof(int) >= 4, "int is not at least 4 bytes");
|
||||
static_assert(sizeof(int16_t) >= 2, "int16_t is not at least 2 bytes");
|
||||
static_assert(sizeof(int8_t) >= 1, "int8_t is not at least 1 byte");
|
||||
|
||||
#if defined(LINUX)
|
||||
static_assert(sizeof(long double)>=10, "long double is not at least 10 bytes");
|
||||
#endif
|
||||
// Float80 seems to be the same size as double on Win at the time of writing, but its not widely used in openvibe.
|
||||
static_assert(sizeof(double) >= 8, "double is not at least 8 bytes");
|
||||
static_assert(sizeof(float) >= 4, "float is not at least 4 bytes");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/*******************************************************************************
|
||||
|
||||
"A Collection of Useful C++ Classes for Digital Signal Processing"
|
||||
By Vinnie Falco
|
||||
|
||||
Official project location:
|
||||
https://github.com/vinniefalco/DSPFilters
|
||||
|
||||
See Documentation.cpp for contact information, notes, and bibliography.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
License: MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
Copyright (c) 2009 by Vinnie Falco
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "Common.h"
|
||||
#include "Bessel.h"
|
||||
#include "RootFinder.h"
|
||||
|
||||
namespace Dsp
|
||||
{
|
||||
namespace Bessel
|
||||
{
|
||||
|
||||
// returns fact(n) = n!
|
||||
static double fact(const int n)
|
||||
{
|
||||
if (n == 0) { return 1; }
|
||||
double res = 1;
|
||||
for (int i = 2; i <= n; ++i) { res *= i; }
|
||||
return res;
|
||||
}
|
||||
|
||||
// returns the k-th zero based coefficient of the reverse bessel polynomial of degree n
|
||||
static double reversebessel(const int k, const int n) { return fact(2 * n - k) / ((fact(n - k) * fact(k)) * pow(2., n - k)); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void AnalogLowPass::design(const int numPoles, WorkspaceBase* w)
|
||||
{
|
||||
if (m_numPoles != numPoles)
|
||||
{
|
||||
m_numPoles = numPoles;
|
||||
|
||||
reset();
|
||||
|
||||
RootFinderBase& solver(w->roots);
|
||||
for (int i = 0; i < numPoles + 1; ++i) { solver.coef()[i] = reversebessel(i, numPoles); }
|
||||
solver.solve(numPoles);
|
||||
|
||||
const int pairs = numPoles / 2;
|
||||
for (int i = 0; i < pairs; ++i)
|
||||
{
|
||||
complex_t c = solver.root()[i];
|
||||
addPoleZeroConjugatePairs(c, infinity());
|
||||
}
|
||||
|
||||
if (numPoles & 1) { add(solver.root()[pairs].real(), infinity()); }
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
AnalogLowShelf::AnalogLowShelf()
|
||||
: m_numPoles(-1) { setNormal(doublePi, 1); }
|
||||
|
||||
void AnalogLowShelf::design(int numPoles,
|
||||
double gainDb,
|
||||
WorkspaceBase* w)
|
||||
{
|
||||
if (m_numPoles != numPoles ||
|
||||
m_gainDb != gainDb)
|
||||
{
|
||||
m_numPoles = numPoles;
|
||||
m_gainDb = gainDb;
|
||||
|
||||
reset();
|
||||
|
||||
const double G = pow(10., gainDb / 20) - 1;
|
||||
|
||||
RootFinderBase& poles(w->roots);
|
||||
for (int i = 0; i < numPoles + 1; ++i) { poles.coef()[i] = reversebessel(i, numPoles); }
|
||||
poles.solve(numPoles);
|
||||
|
||||
RootFinder<50> zeros;
|
||||
for (int i = 0; i < numPoles + 1; ++i) { zeros.coef()[i] = reversebessel(i, numPoles); }
|
||||
double a0 = reversebessel(0, numPoles);
|
||||
zeros.coef()[0] += G * a0;
|
||||
zeros.solve(numPoles);
|
||||
|
||||
const int pairs = numPoles / 2;
|
||||
for (int i = 0; i < pairs; ++i)
|
||||
{
|
||||
complex_t p = poles.root()[i];
|
||||
complex_t z = zeros.root()[i];
|
||||
addPoleZeroConjugatePairs(p, z);
|
||||
}
|
||||
|
||||
if (numPoles & 1) { add(poles.root()[pairs].real(), zeros.root()[pairs].real()); }
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void LowPassBase::setup(int order,
|
||||
double sampleRate,
|
||||
double cutoffFrequency,
|
||||
WorkspaceBase* w)
|
||||
{
|
||||
m_analogProto.design(order, w);
|
||||
|
||||
LowPassTransform(cutoffFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
|
||||
void HighPassBase::setup(int order,
|
||||
double sampleRate,
|
||||
double cutoffFrequency,
|
||||
WorkspaceBase* w)
|
||||
{
|
||||
m_analogProto.design(order, w);
|
||||
|
||||
HighPassTransform(cutoffFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
|
||||
void BandPassBase::setup(int order,
|
||||
double sampleRate,
|
||||
double centerFrequency,
|
||||
double widthFrequency,
|
||||
WorkspaceBase* w)
|
||||
{
|
||||
m_analogProto.design(order, w);
|
||||
|
||||
BandPassTransform(centerFrequency / sampleRate,
|
||||
widthFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
|
||||
void BandStopBase::setup(int order,
|
||||
double sampleRate,
|
||||
double centerFrequency,
|
||||
double widthFrequency,
|
||||
WorkspaceBase* w)
|
||||
{
|
||||
m_analogProto.design(order, w);
|
||||
|
||||
BandStopTransform(centerFrequency / sampleRate,
|
||||
widthFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
|
||||
void LowShelfBase::setup(int order,
|
||||
double sampleRate,
|
||||
double cutoffFrequency,
|
||||
double gainDb,
|
||||
WorkspaceBase* w)
|
||||
{
|
||||
m_analogProto.design(order, gainDb, w);
|
||||
|
||||
LowPassTransform(cutoffFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
} // namespace Bessel
|
||||
} // namespace Dsp
|
||||
@@ -0,0 +1,350 @@
|
||||
/*******************************************************************************
|
||||
|
||||
"A Collection of Useful C++ Classes for Digital Signal Processing"
|
||||
By Vinnie Falco
|
||||
|
||||
Official project location:
|
||||
https://github.com/vinniefalco/DSPFilters
|
||||
|
||||
See Documentation.cpp for contact information, notes, and bibliography.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
License: MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
Copyright (c) 2009 by Vinnie Falco
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef DSPFILTERS_BESSEL_H
|
||||
#define DSPFILTERS_BESSEL_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Cascade.h"
|
||||
#include "Design.h"
|
||||
#include "Filter.h"
|
||||
#include "PoleFilter.h"
|
||||
#include "RootFinder.h"
|
||||
|
||||
namespace Dsp
|
||||
{
|
||||
|
||||
/*
|
||||
* Filters with Bessel response characteristics
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Bessel
|
||||
{
|
||||
|
||||
// A Workspace is necessary to find roots
|
||||
|
||||
struct WorkspaceBase
|
||||
{
|
||||
WorkspaceBase(RootFinderBase* rootsBase)
|
||||
: roots(*rootsBase) { }
|
||||
|
||||
RootFinderBase& roots;
|
||||
|
||||
private:
|
||||
WorkspaceBase(WorkspaceBase&);
|
||||
WorkspaceBase& operator=(WorkspaceBase&);
|
||||
};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct Workspace : WorkspaceBase
|
||||
{
|
||||
Workspace() : WorkspaceBase(&m_roots) { }
|
||||
|
||||
private:
|
||||
RootFinder<MaxOrder> m_roots;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Half-band analog prototypes (s-plane)
|
||||
|
||||
class AnalogLowPass : public LayoutBase
|
||||
{
|
||||
public:
|
||||
AnalogLowPass() : m_numPoles(-1) { setNormal(0, 1); }
|
||||
|
||||
void design(int numPoles, WorkspaceBase* w);
|
||||
|
||||
private:
|
||||
int m_numPoles = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class AnalogLowShelf : public LayoutBase
|
||||
{
|
||||
public:
|
||||
AnalogLowShelf();
|
||||
|
||||
void design(int numPoles, double gainDb, WorkspaceBase* w);
|
||||
|
||||
private:
|
||||
int m_numPoles = 0;
|
||||
double m_gainDb = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Factored implementations to reduce template instantiations
|
||||
|
||||
struct LowPassBase : PoleFilterBase<AnalogLowPass>
|
||||
{
|
||||
void setup(int order, double sampleRate, double cutoffFrequency, WorkspaceBase* w);
|
||||
};
|
||||
|
||||
struct HighPassBase : PoleFilterBase<AnalogLowPass>
|
||||
{
|
||||
void setup(int order, double sampleRate, double cutoffFrequency, WorkspaceBase* w);
|
||||
};
|
||||
|
||||
struct BandPassBase : PoleFilterBase<AnalogLowPass>
|
||||
{
|
||||
void setup(int order, double sampleRate, double centerFrequency, double widthFrequency, WorkspaceBase* w);
|
||||
};
|
||||
|
||||
struct BandStopBase : PoleFilterBase<AnalogLowPass>
|
||||
{
|
||||
void setup(int order, double sampleRate, double centerFrequency, double widthFrequency, WorkspaceBase* w);
|
||||
};
|
||||
|
||||
struct LowShelfBase : PoleFilterBase<AnalogLowShelf>
|
||||
{
|
||||
void setup(int order, double sampleRate, double cutoffFrequency, double gainDb, WorkspaceBase* w);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Raw filters
|
||||
//
|
||||
|
||||
template <int MaxOrder>
|
||||
struct LowPass : PoleFilter<LowPassBase, MaxOrder>
|
||||
{
|
||||
void setup(int order, double sampleRate, double cutoffFrequency)
|
||||
{
|
||||
Workspace<MaxOrder> w;
|
||||
LowPassBase::setup(order, sampleRate, cutoffFrequency, &w);
|
||||
}
|
||||
};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct HighPass : PoleFilter<HighPassBase, MaxOrder>
|
||||
{
|
||||
void setup(int order, double sampleRate, double cutoffFrequency)
|
||||
{
|
||||
Workspace<MaxOrder> w;
|
||||
HighPassBase::setup(order, sampleRate, cutoffFrequency, &w);
|
||||
}
|
||||
};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct BandPass : PoleFilter<BandPassBase, MaxOrder, MaxOrder * 2>
|
||||
{
|
||||
void setup(int order, double sampleRate, double centerFrequency, double widthFrequency)
|
||||
{
|
||||
Workspace<MaxOrder> w;
|
||||
BandPassBase::setup(order, sampleRate, centerFrequency, widthFrequency, &w);
|
||||
}
|
||||
};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct BandStop : PoleFilter<BandStopBase, MaxOrder, MaxOrder * 2>
|
||||
{
|
||||
void setup(int order, double sampleRate, double centerFrequency, double widthFrequency)
|
||||
{
|
||||
Workspace<MaxOrder> w;
|
||||
BandStopBase::setup(order, sampleRate, centerFrequency, widthFrequency, &w);
|
||||
}
|
||||
};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct LowShelf : PoleFilter<LowShelfBase, MaxOrder, MaxOrder * 2>
|
||||
{
|
||||
void setup(int order, double sampleRate, double cutoffFrequency, double gainDb)
|
||||
{
|
||||
Workspace<MaxOrder> w;
|
||||
LowShelfBase::setup(order, sampleRate, cutoffFrequency, gainDb, &w);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Gui-friendly Design layer
|
||||
//
|
||||
|
||||
namespace Design
|
||||
{
|
||||
struct TypeIBase : DesignBase
|
||||
{
|
||||
enum
|
||||
{
|
||||
NumParams = 3
|
||||
};
|
||||
|
||||
static int getNumParams() { return 3; }
|
||||
|
||||
static ParamInfo getParamInfo_2() { return ParamInfo::defaultCutoffFrequencyParam(); }
|
||||
};
|
||||
|
||||
template <class FilterClass>
|
||||
struct TypeI : TypeIBase, FilterClass
|
||||
{
|
||||
void setParams(const Params& params) { FilterClass::setup(int(params[1]), params[0], params[2]); }
|
||||
};
|
||||
|
||||
struct TypeIIBase : DesignBase
|
||||
{
|
||||
enum
|
||||
{
|
||||
NumParams = 4
|
||||
};
|
||||
|
||||
static int getNumParams() { return 4; }
|
||||
|
||||
static ParamInfo getParamInfo_2() { return ParamInfo::defaultCenterFrequencyParam(); }
|
||||
|
||||
static ParamInfo getParamInfo_3() { return ParamInfo::defaultBandwidthHzParam(); }
|
||||
};
|
||||
|
||||
template <class FilterClass>
|
||||
struct TypeII : TypeIIBase, FilterClass
|
||||
{
|
||||
void setParams(const Params& params) { FilterClass::setup(int(params[1]), params[0], params[2], params[3]); }
|
||||
};
|
||||
|
||||
struct TypeIIIBase : DesignBase
|
||||
{
|
||||
enum
|
||||
{
|
||||
NumParams = 4
|
||||
};
|
||||
|
||||
static int getNumParams() { return 4; }
|
||||
static ParamInfo getParamInfo_2() { return ParamInfo::defaultCutoffFrequencyParam(); }
|
||||
static ParamInfo getParamInfo_3() { return ParamInfo::defaultGainParam(); }
|
||||
};
|
||||
|
||||
template <class FilterClass>
|
||||
struct TypeIII : TypeIIIBase, FilterClass
|
||||
{
|
||||
void setParams(const Params& params) { FilterClass::setup(int(params[1]), params[0], params[2], params[3]); }
|
||||
};
|
||||
|
||||
struct TypeIVBase : DesignBase
|
||||
{
|
||||
enum
|
||||
{
|
||||
NumParams = 5
|
||||
};
|
||||
|
||||
static int getNumParams() { return 5; }
|
||||
static ParamInfo getParamInfo_2() { return ParamInfo::defaultCenterFrequencyParam(); }
|
||||
static ParamInfo getParamInfo_3() { return ParamInfo::defaultBandwidthHzParam(); }
|
||||
static ParamInfo getParamInfo_4() { return ParamInfo::defaultGainParam(); }
|
||||
};
|
||||
|
||||
template <class FilterClass>
|
||||
struct TypeIV : TypeIVBase, FilterClass
|
||||
{
|
||||
void setParams(const Params& params) { FilterClass::setup(int(params[1]), params[0], params[2], params[3], params[4]); }
|
||||
};
|
||||
|
||||
// Factored kind and name
|
||||
|
||||
struct LowPassDescription
|
||||
{
|
||||
static Kind getKind() { return kindLowPass; }
|
||||
static const char* getName() { return "Bessel Low Pass"; }
|
||||
};
|
||||
|
||||
struct HighPassDescription
|
||||
{
|
||||
static Kind getKind() { return kindHighPass; }
|
||||
static const char* getName() { return "Bessel High Pass"; }
|
||||
};
|
||||
|
||||
struct BandPassDescription
|
||||
{
|
||||
static Kind getKind() { return kindHighPass; }
|
||||
static const char* getName() { return "Bessel Band Pass"; }
|
||||
};
|
||||
|
||||
struct BandStopDescription
|
||||
{
|
||||
static Kind getKind() { return kindHighPass; }
|
||||
static const char* getName() { return "Bessel Band Stop"; }
|
||||
};
|
||||
|
||||
struct LowShelfDescription
|
||||
{
|
||||
static Kind getKind() { return kindLowShelf; }
|
||||
static const char* getName() { return "Bessel Low Shelf"; }
|
||||
};
|
||||
|
||||
// This glues on the Order parameter
|
||||
template <int MaxOrder, template <class> class TypeClass, template <int> class FilterClass>
|
||||
struct OrderBase : TypeClass<FilterClass<MaxOrder>>
|
||||
{
|
||||
const ParamInfo getParamInfo_1() const
|
||||
{
|
||||
return ParamInfo(idOrder, "Order", "Order", 1, MaxOrder, 2, &ParamInfo::Int_toControlValue, &ParamInfo::Int_toNativeValue,
|
||||
&ParamInfo::Int_toString);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Gui-friendly Design layer
|
||||
//
|
||||
|
||||
template <int MaxOrder>
|
||||
struct LowPass : OrderBase<MaxOrder, TypeI, Bessel::LowPass>, LowPassDescription {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct HighPass : OrderBase<MaxOrder, TypeI, Bessel::HighPass>, HighPassDescription {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct BandPass : OrderBase<MaxOrder, TypeII, Bessel::BandPass>, BandPassDescription {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct BandStop : OrderBase<MaxOrder, TypeII, Bessel::BandStop>, BandStopDescription {};
|
||||
|
||||
/*
|
||||
* NOT IMPLEMENTED
|
||||
*
|
||||
*/
|
||||
template <int MaxOrder>
|
||||
struct LowShelf : OrderBase<MaxOrder, TypeIII, Bessel::LowShelf>, LowShelfDescription {};
|
||||
} // namespace Design
|
||||
} // namespace Bessel
|
||||
} // namespace Dsp
|
||||
|
||||
#endif
|
||||
|
||||
/* This is a test of svn:external */
|
||||
@@ -0,0 +1,226 @@
|
||||
/*******************************************************************************
|
||||
|
||||
"A Collection of Useful C++ Classes for Digital Signal Processing"
|
||||
By Vinnie Falco
|
||||
|
||||
Official project location:
|
||||
https://github.com/vinniefalco/DSPFilters
|
||||
|
||||
See Documentation.cpp for contact information, notes, and bibliography.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
License: MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
Copyright (c) 2009 by Vinnie Falco
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "Common.h"
|
||||
#include "MathSupplement.h"
|
||||
#include "Biquad.h"
|
||||
|
||||
namespace Dsp
|
||||
{
|
||||
BiquadPoleState::BiquadPoleState(const BiquadBase& s)
|
||||
{
|
||||
const double a0 = s.getA0();
|
||||
const double a1 = s.getA1();
|
||||
const double a2 = s.getA2();
|
||||
const double b0 = s.getB0();
|
||||
const double b1 = s.getB1();
|
||||
const double b2 = s.getB2();
|
||||
|
||||
if (a2 == 0 && b2 == 0)
|
||||
{
|
||||
// single pole
|
||||
poles.first = -a1;
|
||||
zeros.first = -b0 / b1;
|
||||
poles.second = 0;
|
||||
zeros.second = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
const complex_t c = sqrt(complex_t(a1 * a1 - 4 * a0 * a2, 0));
|
||||
double d = 2. * a0;
|
||||
poles.first = -(a1 + c) / d;
|
||||
poles.second = (c - a1) / d;
|
||||
assert(!poles.is_nan());
|
||||
}
|
||||
|
||||
{
|
||||
const complex_t c = sqrt(complex_t(b1 * b1 - 4 * b0 * b2, 0));
|
||||
double d = 2. * b0;
|
||||
zeros.first = -(b1 + c) / d;
|
||||
zeros.second = (c - b1) / d;
|
||||
assert(!zeros.is_nan());
|
||||
}
|
||||
}
|
||||
|
||||
gain = b0 / a0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
complex_t BiquadBase::response(double normalizedFrequency) const
|
||||
{
|
||||
const double a0 = getA0();
|
||||
const double a1 = getA1();
|
||||
const double a2 = getA2();
|
||||
const double b0 = getB0();
|
||||
const double b1 = getB1();
|
||||
const double b2 = getB2();
|
||||
|
||||
const double w = 2 * doublePi * normalizedFrequency;
|
||||
const complex_t czn1 = std::polar(1., -w);
|
||||
const complex_t czn2 = std::polar(1., -2 * w);
|
||||
complex_t ch(1);
|
||||
complex_t cbot(1);
|
||||
|
||||
complex_t ct(b0 / a0);
|
||||
complex_t cb(1);
|
||||
ct = addmul(ct, b1 / a0, czn1);
|
||||
ct = addmul(ct, b2 / a0, czn2);
|
||||
cb = addmul(cb, a1 / a0, czn1);
|
||||
cb = addmul(cb, a2 / a0, czn2);
|
||||
ch *= ct;
|
||||
cbot *= cb;
|
||||
|
||||
return ch / cbot;
|
||||
}
|
||||
|
||||
std::vector<PoleZeroPair> BiquadBase::getPoleZeros() const
|
||||
{
|
||||
std::vector<PoleZeroPair> vpz;
|
||||
BiquadPoleState bps(*this);
|
||||
vpz.push_back(bps);
|
||||
return vpz;
|
||||
}
|
||||
|
||||
void BiquadBase::setCoefficients(double a0, double a1, double a2,
|
||||
double b0, double b1, double b2)
|
||||
{
|
||||
assert(!Dsp::is_nan (a0) && !Dsp::is_nan (a1) && !Dsp::is_nan (a2) &&
|
||||
!Dsp::is_nan (b0) && !Dsp::is_nan (b1) && !Dsp::is_nan (b2));
|
||||
|
||||
m_a0 = a0;
|
||||
m_a1 = a1 / a0;
|
||||
m_a2 = a2 / a0;
|
||||
m_b0 = b0 / a0;
|
||||
m_b1 = b1 / a0;
|
||||
m_b2 = b2 / a0;
|
||||
}
|
||||
|
||||
void BiquadBase::setOnePole(complex_t pole, complex_t zero)
|
||||
{
|
||||
#if 0
|
||||
pole = adjust_imag (pole);
|
||||
zero = adjust_imag (zero);
|
||||
#else
|
||||
assert(pole.imag() == 0);
|
||||
assert(zero.imag() == 0);
|
||||
#endif
|
||||
|
||||
const double a0 = 1;
|
||||
const double a1 = -pole.real();
|
||||
const double a2 = 0;
|
||||
const double b0 = 1;
|
||||
const double b1 = -zero.real();
|
||||
const double b2 = 0;
|
||||
|
||||
setCoefficients(a0, a1, a2, b0, b1, b2);
|
||||
}
|
||||
|
||||
void BiquadBase::setTwoPole(complex_t pole1, complex_t zero1,
|
||||
complex_t pole2, complex_t zero2)
|
||||
{
|
||||
#if 0
|
||||
pole1 = adjust_imag (pole1);
|
||||
pole2 = adjust_imag (pole2);
|
||||
zero1 = adjust_imag (zero1);
|
||||
zero2 = adjust_imag (zero2);
|
||||
#endif
|
||||
|
||||
const double a0 = 1;
|
||||
double a1;
|
||||
double a2;
|
||||
|
||||
if (pole1.imag() != 0)
|
||||
{
|
||||
assert(pole2 == std::conj (pole1));
|
||||
|
||||
a1 = -2 * pole1.real();
|
||||
a2 = std::norm(pole1);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(pole2.imag() == 0);
|
||||
|
||||
a1 = -(pole1.real() + pole2.real());
|
||||
a2 = pole1.real() * pole2.real();
|
||||
}
|
||||
|
||||
const double b0 = 1;
|
||||
double b1;
|
||||
double b2;
|
||||
|
||||
if (zero1.imag() != 0)
|
||||
{
|
||||
assert(zero2 == std::conj (zero1));
|
||||
|
||||
b1 = -2 * zero1.real();
|
||||
b2 = std::norm(zero1);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(zero2.imag() == 0);
|
||||
|
||||
b1 = -(zero1.real() + zero2.real());
|
||||
b2 = zero1.real() * zero2.real();
|
||||
}
|
||||
|
||||
setCoefficients(a0, a1, a2, b0, b1, b2);
|
||||
}
|
||||
|
||||
void BiquadBase::setPoleZeroForm(const BiquadPoleState& bps)
|
||||
{
|
||||
setPoleZeroPair(bps);
|
||||
applyScale(bps.gain);
|
||||
}
|
||||
|
||||
void BiquadBase::setIdentity() { setCoefficients(1, 0, 0, 1, 0, 0); }
|
||||
|
||||
void BiquadBase::applyScale(double scale)
|
||||
{
|
||||
m_b0 *= scale;
|
||||
m_b1 *= scale;
|
||||
m_b2 *= scale;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Biquad::Biquad() {}
|
||||
|
||||
// Construct a second order section from a pair of poles and zeroes
|
||||
Biquad::Biquad(const BiquadPoleState& bps) { setPoleZeroForm(bps); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
} // namespace Dsp
|
||||
@@ -0,0 +1,206 @@
|
||||
/*******************************************************************************
|
||||
|
||||
"A Collection of Useful C++ Classes for Digital Signal Processing"
|
||||
By Vinnie Falco
|
||||
|
||||
Official project location:
|
||||
https://github.com/vinniefalco/DSPFilters
|
||||
|
||||
See Documentation.cpp for contact information, notes, and bibliography.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
License: MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
Copyright (c) 2009 by Vinnie Falco
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef DSPFILTERS_BIQUAD_H
|
||||
#define DSPFILTERS_BIQUAD_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "MathSupplement.h"
|
||||
#include "Types.h"
|
||||
|
||||
namespace Dsp
|
||||
{
|
||||
struct BiquadPoleState;
|
||||
|
||||
/*
|
||||
* Holds coefficients for a second order Infinite Impulse Response
|
||||
* digital filter. This is the building block for all IIR filters.
|
||||
*
|
||||
*/
|
||||
|
||||
// Factored interface to prevent outsiders from fiddling
|
||||
class BiquadBase
|
||||
{
|
||||
public:
|
||||
template <class StateType>
|
||||
struct State : StateType, private DenormalPrevention
|
||||
{
|
||||
template <typename Sample>
|
||||
Sample process(const Sample in, const BiquadBase& b) { return Sample(StateType::process1(in, b, ac())); }
|
||||
};
|
||||
|
||||
// Calculate filter response at the given normalized frequency.
|
||||
complex_t response(double normalizedFrequency) const;
|
||||
|
||||
std::vector<PoleZeroPair> getPoleZeros() const;
|
||||
|
||||
double getA0() const { return m_a0; }
|
||||
double getA1() const { return m_a1 * m_a0; }
|
||||
double getA2() const { return m_a2 * m_a0; }
|
||||
double getB0() const { return m_b0 * m_a0; }
|
||||
double getB1() const { return m_b1 * m_a0; }
|
||||
double getB2() const { return m_b2 * m_a0; }
|
||||
|
||||
// Process a block of samples in the given form
|
||||
template <class StateType, typename Sample>
|
||||
void process(int nSamples, Sample* dest, StateType& state) const
|
||||
{
|
||||
while (--nSamples >= 0)
|
||||
{
|
||||
*dest = state.process(*dest, *this);
|
||||
++dest;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
//
|
||||
// These are protected so you can't mess with RBJ biquads
|
||||
//
|
||||
|
||||
void setCoefficients(double a0, double a1, double a2, double b0, double b1, double b2);
|
||||
|
||||
void setOnePole(complex_t pole, complex_t zero);
|
||||
|
||||
void setTwoPole(complex_t pole1, complex_t zero1, complex_t pole2, complex_t zero2);
|
||||
|
||||
void setPoleZeroPair(const PoleZeroPair& pair)
|
||||
{
|
||||
if (pair.isSinglePole()) { setOnePole(pair.poles.first, pair.zeros.first); }
|
||||
else { setTwoPole(pair.poles.first, pair.zeros.first, pair.poles.second, pair.zeros.second); }
|
||||
}
|
||||
|
||||
void setPoleZeroForm(const BiquadPoleState& bps);
|
||||
|
||||
void setIdentity();
|
||||
|
||||
void applyScale(double scale);
|
||||
|
||||
public:
|
||||
double m_a0 = 0;
|
||||
double m_a1 = 0;
|
||||
double m_a2 = 0;
|
||||
double m_b1 = 0;
|
||||
double m_b2 = 0;
|
||||
double m_b0 = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Expresses a biquad as a pair of pole/zeros, with gain
|
||||
// values so that the coefficients can be reconstructed precisely.
|
||||
struct BiquadPoleState : PoleZeroPair
|
||||
{
|
||||
BiquadPoleState() { }
|
||||
|
||||
explicit BiquadPoleState(const BiquadBase& s);
|
||||
|
||||
double gain = 0;
|
||||
};
|
||||
|
||||
// More permissive interface for fooling around
|
||||
class Biquad : public BiquadBase
|
||||
{
|
||||
public:
|
||||
Biquad();
|
||||
|
||||
explicit Biquad(const BiquadPoleState& bps);
|
||||
|
||||
// Process a block of samples, interpolating from the old section's coefficients
|
||||
// to this section's coefficients, over nSamples. This implements smooth
|
||||
// parameter changes.
|
||||
|
||||
template <class StateType, typename Sample>
|
||||
void smoothProcess1(int nSamples, Sample* dest, StateType& state, Biquad sectionPrev) const
|
||||
{
|
||||
double t = 1. / nSamples;
|
||||
double da1 = (m_a1 - sectionPrev.m_a1) * t;
|
||||
double da2 = (m_a2 - sectionPrev.m_a2) * t;
|
||||
double db0 = (m_b0 - sectionPrev.m_b0) * t;
|
||||
double db1 = (m_b1 - sectionPrev.m_b1) * t;
|
||||
double db2 = (m_b2 - sectionPrev.m_b2) * t;
|
||||
|
||||
while (--nSamples >= 0)
|
||||
{
|
||||
sectionPrev.m_a1 += da1;
|
||||
sectionPrev.m_a2 += da2;
|
||||
sectionPrev.m_b0 += db0;
|
||||
sectionPrev.m_b1 += db1;
|
||||
sectionPrev.m_b2 += db2;
|
||||
|
||||
*dest = state.process(*dest, sectionPrev);
|
||||
++dest;
|
||||
}
|
||||
}
|
||||
|
||||
// Process a block of samples, interpolating from the old section's pole/zeros
|
||||
// to this section's pole/zeros, over nSamples. The interpolation is done
|
||||
// in the z-plane using polar coordinates.
|
||||
template <class StateType, typename Sample>
|
||||
void smoothProcess2(int nSamples,
|
||||
Sample* dest,
|
||||
StateType& state,
|
||||
BiquadPoleState zPrev) const
|
||||
{
|
||||
BiquadPoleState z(*this);
|
||||
double t = 1. / nSamples;
|
||||
complex_t dp0 = (z.poles.first - zPrev.poles.first) * t;
|
||||
complex_t dp1 = (z.poles.second - zPrev.poles.second) * t;
|
||||
complex_t dz0 = (z.zeros.first - zPrev.zeros.first) * t;
|
||||
complex_t dz1 = (z.zeros.second - zPrev.zeros.second) * t;
|
||||
double dg = (z.gain - zPrev.gain) * t;
|
||||
|
||||
while (--nSamples >= 0)
|
||||
{
|
||||
zPrev.poles.first += dp0;
|
||||
zPrev.poles.second += dp1;
|
||||
zPrev.zeros.first += dz0;
|
||||
zPrev.zeros.second += dz1;
|
||||
zPrev.gain += dg;
|
||||
|
||||
*dest = state.process(*dest, Biquad(zPrev));
|
||||
++dest;
|
||||
}
|
||||
}
|
||||
|
||||
// Export these as public
|
||||
|
||||
void setOnePole(complex_t pole, complex_t zero) { BiquadBase::setOnePole(pole, zero); }
|
||||
void setTwoPole(complex_t pole1, complex_t zero1, complex_t pole2, complex_t zero2) { BiquadBase::setTwoPole(pole1, zero1, pole2, zero2); }
|
||||
void setPoleZeroPair(const PoleZeroPair& pair) { BiquadBase::setPoleZeroPair(pair); }
|
||||
void applyScale(double scale) { BiquadBase::applyScale(scale); }
|
||||
};
|
||||
} // namespace Dsp
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,204 @@
|
||||
/*******************************************************************************
|
||||
|
||||
"A Collection of Useful C++ Classes for Digital Signal Processing"
|
||||
By Vinnie Falco
|
||||
|
||||
Official project location:
|
||||
https://github.com/vinniefalco/DSPFilters
|
||||
|
||||
See Documentation.cpp for contact information, notes, and bibliography.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
License: MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
Copyright (c) 2009 by Vinnie Falco
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "Common.h"
|
||||
#include "Butterworth.h"
|
||||
|
||||
namespace Dsp
|
||||
{
|
||||
namespace Butterworth
|
||||
{
|
||||
AnalogLowPass::AnalogLowPass()
|
||||
: m_numPoles(-1) { setNormal(0, 1); }
|
||||
|
||||
void AnalogLowPass::design(int numPoles)
|
||||
{
|
||||
if (m_numPoles != numPoles)
|
||||
{
|
||||
m_numPoles = numPoles;
|
||||
|
||||
reset();
|
||||
|
||||
const double n2 = 2 * numPoles;
|
||||
const int pairs = numPoles / 2;
|
||||
for (int i = 0; i < pairs; ++i)
|
||||
{
|
||||
complex_t c = std::polar(1., doublePi_2 + (2 * i + 1) * doublePi / n2);
|
||||
addPoleZeroConjugatePairs(c, infinity());
|
||||
}
|
||||
|
||||
if (numPoles & 1) { add(-1, infinity()); }
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
AnalogLowShelf::AnalogLowShelf()
|
||||
: m_numPoles(-1) { setNormal(doublePi, 1); }
|
||||
|
||||
void AnalogLowShelf::design(int numPoles, double gainDb)
|
||||
{
|
||||
if (m_numPoles != numPoles ||
|
||||
m_gainDb != gainDb)
|
||||
{
|
||||
m_numPoles = numPoles;
|
||||
m_gainDb = gainDb;
|
||||
|
||||
reset();
|
||||
|
||||
const double n2 = numPoles * 2;
|
||||
const double g = pow(pow(10., gainDb / 20), 1. / n2);
|
||||
const double gp = -1. / g;
|
||||
const double gz = -g;
|
||||
|
||||
const int pairs = numPoles / 2;
|
||||
for (int i = 1; i <= pairs; ++i)
|
||||
{
|
||||
const double theta = doublePi * (0.5 - (2 * i - 1) / n2);
|
||||
addPoleZeroConjugatePairs(std::polar(gp, theta), std::polar(gz, theta));
|
||||
}
|
||||
|
||||
if (numPoles & 1) { add(gp, gz); }
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void LowPassBase::setup(int order,
|
||||
double sampleRate,
|
||||
double cutoffFrequency)
|
||||
{
|
||||
m_analogProto.design(order);
|
||||
|
||||
LowPassTransform(cutoffFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
|
||||
void HighPassBase::setup(int order,
|
||||
double sampleRate,
|
||||
double cutoffFrequency)
|
||||
{
|
||||
m_analogProto.design(order);
|
||||
|
||||
HighPassTransform(cutoffFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
|
||||
void BandPassBase::setup(int order,
|
||||
double sampleRate,
|
||||
double centerFrequency,
|
||||
double widthFrequency)
|
||||
{
|
||||
m_analogProto.design(order);
|
||||
|
||||
BandPassTransform(centerFrequency / sampleRate,
|
||||
widthFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
|
||||
#include "ButterworthSynthesisCpp.inl"
|
||||
|
||||
void BandStopBase::setup(int order,
|
||||
double sampleRate,
|
||||
double centerFrequency,
|
||||
double widthFrequency)
|
||||
{
|
||||
m_analogProto.design(order);
|
||||
|
||||
BandStopTransform(centerFrequency / sampleRate,
|
||||
widthFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
|
||||
void LowShelfBase::setup(int order,
|
||||
double sampleRate,
|
||||
double cutoffFrequency,
|
||||
double gainDb)
|
||||
{
|
||||
m_analogProto.design(order, gainDb);
|
||||
|
||||
LowPassTransform(cutoffFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
|
||||
void HighShelfBase::setup(int order,
|
||||
double sampleRate,
|
||||
double cutoffFrequency,
|
||||
double gainDb)
|
||||
{
|
||||
m_analogProto.design(order, gainDb);
|
||||
|
||||
HighPassTransform(cutoffFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
|
||||
void BandShelfBase::setup(int order,
|
||||
double sampleRate,
|
||||
double centerFrequency,
|
||||
double widthFrequency,
|
||||
double gainDb)
|
||||
{
|
||||
m_analogProto.design(order, gainDb);
|
||||
|
||||
BandPassTransform(centerFrequency / sampleRate,
|
||||
widthFrequency / sampleRate,
|
||||
m_digitalProto,
|
||||
m_analogProto);
|
||||
|
||||
// HACK!
|
||||
m_digitalProto.setNormal(((centerFrequency / sampleRate) < 0.25) ? doublePi : 0, 1);
|
||||
|
||||
setLayout(m_digitalProto);
|
||||
}
|
||||
} // namespace Butterworth
|
||||
} // namespace Dsp
|
||||
@@ -0,0 +1,314 @@
|
||||
/*******************************************************************************
|
||||
|
||||
"A Collection of Useful C++ Classes for Digital Signal Processing"
|
||||
By Vinnie Falco
|
||||
|
||||
Official project location:
|
||||
https://github.com/vinniefalco/DSPFilters
|
||||
|
||||
See Documentation.cpp for contact information, notes, and bibliography.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
License: MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
Copyright (c) 2009 by Vinnie Falco
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "Common.h"
|
||||
#include "Cascade.h"
|
||||
#include "Design.h"
|
||||
#include "Filter.h"
|
||||
#include "PoleFilter.h"
|
||||
|
||||
namespace Dsp
|
||||
{
|
||||
|
||||
/*
|
||||
* Filters with Butterworth response characteristics
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Butterworth
|
||||
{
|
||||
|
||||
// Half-band analog prototypes (s-plane)
|
||||
|
||||
class AnalogLowPass : public LayoutBase
|
||||
{
|
||||
public:
|
||||
AnalogLowPass();
|
||||
|
||||
void design(int numPoles);
|
||||
|
||||
private:
|
||||
int m_numPoles = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class AnalogLowShelf : public LayoutBase
|
||||
{
|
||||
public:
|
||||
AnalogLowShelf();
|
||||
|
||||
void design(int numPoles, double gainDb);
|
||||
|
||||
private:
|
||||
int m_numPoles = 0;
|
||||
double m_gainDb = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Factored implementations to reduce template instantiations
|
||||
|
||||
struct LowPassBase : PoleFilterBase<AnalogLowPass>
|
||||
{
|
||||
void setup(int order, double sampleRate, double cutoffFrequency);
|
||||
};
|
||||
|
||||
struct HighPassBase : PoleFilterBase<AnalogLowPass>
|
||||
{
|
||||
void setup(int order, double sampleRate, double cutoffFrequency);
|
||||
};
|
||||
|
||||
struct BandPassBase : PoleFilterBase<AnalogLowPass>
|
||||
{
|
||||
void setup(int order, double sampleRate, double centerFrequency, double widthFrequency);
|
||||
|
||||
#include "ButterworthSynthesisH.inl"
|
||||
};
|
||||
|
||||
struct BandStopBase : PoleFilterBase<AnalogLowPass>
|
||||
{
|
||||
void setup(int order, double sampleRate, double centerFrequency, double widthFrequency);
|
||||
};
|
||||
|
||||
struct LowShelfBase : PoleFilterBase<AnalogLowShelf>
|
||||
{
|
||||
void setup(int order, double sampleRate, double cutoffFrequency, double gainDb);
|
||||
};
|
||||
|
||||
struct HighShelfBase : PoleFilterBase<AnalogLowShelf>
|
||||
{
|
||||
void setup(int order, double sampleRate, double cutoffFrequency, double gainDb);
|
||||
};
|
||||
|
||||
struct BandShelfBase : PoleFilterBase<AnalogLowShelf>
|
||||
{
|
||||
void setup(int order, double sampleRate, double centerFrequency, double widthFrequency, double gainDb);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Raw filters
|
||||
//
|
||||
|
||||
template <int MaxOrder>
|
||||
struct LowPass : PoleFilter<LowPassBase, MaxOrder> {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct HighPass : PoleFilter<HighPassBase, MaxOrder> {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct BandPass : PoleFilter<BandPassBase, MaxOrder, MaxOrder * 2> {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct BandStop : PoleFilter<BandStopBase, MaxOrder, MaxOrder * 2> {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct LowShelf : PoleFilter<LowShelfBase, MaxOrder> {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct HighShelf : PoleFilter<HighShelfBase, MaxOrder> {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct BandShelf : PoleFilter<BandShelfBase, MaxOrder, MaxOrder * 2> {};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Gui-friendly Design layer
|
||||
//
|
||||
|
||||
namespace Design
|
||||
{
|
||||
struct TypeIBase : DesignBase
|
||||
{
|
||||
enum
|
||||
{
|
||||
NumParams = 3
|
||||
};
|
||||
|
||||
static int getNumParams() { return 3; }
|
||||
static ParamInfo getParamInfo_2() { return ParamInfo::defaultCutoffFrequencyParam(); }
|
||||
};
|
||||
|
||||
template <class FilterClass>
|
||||
struct TypeI : TypeIBase, FilterClass
|
||||
{
|
||||
void setParams(const Params& params) { FilterClass::setup(int(params[1]), params[0], params[2]); }
|
||||
};
|
||||
|
||||
struct TypeIIBase : DesignBase
|
||||
{
|
||||
enum
|
||||
{
|
||||
NumParams = 4
|
||||
};
|
||||
|
||||
static int getNumParams() { return 4; }
|
||||
static ParamInfo getParamInfo_2() { return ParamInfo::defaultCenterFrequencyParam(); }
|
||||
static ParamInfo getParamInfo_3() { return ParamInfo::defaultBandwidthHzParam(); }
|
||||
};
|
||||
|
||||
template <class FilterClass>
|
||||
struct TypeII : TypeIIBase, FilterClass
|
||||
{
|
||||
void setParams(const Params& params) { FilterClass::setup(int(params[1]), params[0], params[2], params[3]); }
|
||||
|
||||
#include "ButterworthSynthesisH2.inl"
|
||||
};
|
||||
|
||||
struct TypeIIIBase : DesignBase
|
||||
{
|
||||
enum
|
||||
{
|
||||
NumParams = 4
|
||||
};
|
||||
|
||||
static int getNumParams() { return 4; }
|
||||
static ParamInfo getParamInfo_2() { return ParamInfo::defaultCutoffFrequencyParam(); }
|
||||
static ParamInfo getParamInfo_3() { return ParamInfo::defaultGainParam(); }
|
||||
};
|
||||
|
||||
template <class FilterClass>
|
||||
struct TypeIII : TypeIIIBase, FilterClass
|
||||
{
|
||||
void setParams(const Params& params) { FilterClass::setup(int(params[1]), params[0], params[2], params[3]); }
|
||||
};
|
||||
|
||||
struct TypeIVBase : DesignBase
|
||||
{
|
||||
enum
|
||||
{
|
||||
NumParams = 5
|
||||
};
|
||||
|
||||
static int getNumParams() { return 5; }
|
||||
static ParamInfo getParamInfo_2() { return ParamInfo::defaultCenterFrequencyParam(); }
|
||||
static ParamInfo getParamInfo_3() { return ParamInfo::defaultBandwidthHzParam(); }
|
||||
static ParamInfo getParamInfo_4() { return ParamInfo::defaultGainParam(); }
|
||||
};
|
||||
|
||||
template <class FilterClass>
|
||||
struct TypeIV : TypeIVBase, FilterClass
|
||||
{
|
||||
void setParams(const Params& params) { FilterClass::setup(int(params[1]), params[0], params[2], params[3], params[4]); }
|
||||
};
|
||||
|
||||
// Factored kind and name
|
||||
|
||||
struct LowPassDescription
|
||||
{
|
||||
static Kind getKind() { return kindLowPass; }
|
||||
static const char* getName() { return "Butterworth Low Pass"; }
|
||||
};
|
||||
|
||||
struct HighPassDescription
|
||||
{
|
||||
static Kind getKind() { return kindHighPass; }
|
||||
static const char* getName() { return "Butterworth High Pass"; }
|
||||
};
|
||||
|
||||
struct BandPassDescription
|
||||
{
|
||||
static Kind getKind() { return kindHighPass; }
|
||||
static const char* getName() { return "Butterworth Band Pass"; }
|
||||
};
|
||||
|
||||
struct BandStopDescription
|
||||
{
|
||||
static Kind getKind() { return kindHighPass; }
|
||||
static const char* getName() { return "Butterworth Band Stop"; }
|
||||
};
|
||||
|
||||
struct LowShelfDescription
|
||||
{
|
||||
static Kind getKind() { return kindLowShelf; }
|
||||
static const char* getName() { return "Butterworth Low Shelf"; }
|
||||
};
|
||||
|
||||
struct HighShelfDescription
|
||||
{
|
||||
static Kind getKind() { return kindHighShelf; }
|
||||
static const char* getName() { return "Butterworth High Shelf"; }
|
||||
};
|
||||
|
||||
struct BandShelfDescription
|
||||
{
|
||||
static Kind getKind() { return kindBandShelf; }
|
||||
static const char* getName() { return "Butterworth Band Shelf"; }
|
||||
};
|
||||
|
||||
// This glues on the Order parameter
|
||||
template <int MaxOrder, template <class> class TypeClass, template <int> class FilterClass>
|
||||
struct OrderBase : TypeClass<FilterClass<MaxOrder>>
|
||||
{
|
||||
const ParamInfo getParamInfo_1() const
|
||||
{
|
||||
return ParamInfo(idOrder, "Order", "Order", 1, MaxOrder, 2, &ParamInfo::Int_toControlValue, &ParamInfo::Int_toNativeValue,
|
||||
&ParamInfo::Int_toString);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Design filters
|
||||
//
|
||||
|
||||
template <int MaxOrder>
|
||||
struct LowPass : OrderBase<MaxOrder, TypeI, Butterworth::LowPass>, LowPassDescription {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct HighPass : OrderBase<MaxOrder, TypeI, Butterworth::HighPass>, HighPassDescription {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct BandPass : OrderBase<MaxOrder, TypeII, Butterworth::BandPass>, BandPassDescription {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct BandStop : OrderBase<MaxOrder, TypeII, Butterworth::BandStop>, BandStopDescription {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct LowShelf : OrderBase<MaxOrder, TypeIII, Butterworth::LowShelf>, LowShelfDescription {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct HighShelf : OrderBase<MaxOrder, TypeIII, Butterworth::HighShelf>, HighShelfDescription {};
|
||||
|
||||
template <int MaxOrder>
|
||||
struct BandShelf : OrderBase<MaxOrder, TypeIV, Butterworth::BandShelf>, BandShelfDescription {};
|
||||
} // namespace Design
|
||||
} // namespace Butterworth
|
||||
} // namespace Dsp
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
|
||||
void BandPassBase::setupSynthesis (int order,
|
||||
double sampleRate,
|
||||
double centerFrequency,
|
||||
double widthFrequency)
|
||||
{
|
||||
m_analogProto.design (order);
|
||||
|
||||
BandPassTransform (centerFrequency / sampleRate, widthFrequency / sampleRate, m_digitalProto, m_analogProto);
|
||||
|
||||
// inversion of the numerator and denominator digital coefficients
|
||||
Cascade::setLayoutSynthesis (m_digitalProto);
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
|
||||
void setupSynthesis (int order,
|
||||
double sampleRate,
|
||||
double centerFrequency,
|
||||
double widthFrequency);
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
|
||||
void setParamsSynthesis (const Params& params)
|
||||
{
|
||||
FilterClass::setupSynthesis (int(params[1]), params[0], params[2], params[3]);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user