This commit is contained in:
2021-10-14 13:47:35 +02:00
commit 6625a8dfaa
4026 changed files with 844291 additions and 0 deletions
@@ -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
View File
@@ -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()
+661
View File
@@ -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.
+132
View File
@@ -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")
@@ -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})
@@ -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;
}
@@ -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})
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
}
@@ -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})
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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"
@@ -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
@@ -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")
@@ -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})
@@ -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;
}
@@ -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()
@@ -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;
}
@@ -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;
}
@@ -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;
};
@@ -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;
}
@@ -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()
@@ -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
@@ -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
@@ -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
View File
@@ -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
View File
@@ -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
@@ -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);
}
@@ -0,0 +1,5 @@
void setupSynthesis (int order,
double sampleRate,
double centerFrequency,
double widthFrequency);
@@ -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