init
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
PROJECT(openvibe-plugins-games)
|
||||
|
||||
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
|
||||
SET(PROJECT_VERSION ${OV_GLOBAL_VERSION_STRING})
|
||||
|
||||
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.hpp src/*.h src/*.inl src/*.c)
|
||||
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
FOLDER ${PLUGINS_FOLDER}
|
||||
COMPILE_FLAGS "-DOVP_Exports -DOVP_Shared -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE")
|
||||
|
||||
# ---------------------------------
|
||||
INCLUDE_DIRECTORIES("src")
|
||||
|
||||
# OpenViBE Base
|
||||
INCLUDE("FindOpenViBE")
|
||||
INCLUDE("FindOpenViBECommon")
|
||||
|
||||
# OpenViBE Third Party
|
||||
INCLUDE("FindThirdPartyBoost")
|
||||
INCLUDE("FindThirdPartyBoost_System")
|
||||
INCLUDE("FindThirdPartyLSL")
|
||||
|
||||
# ---------------------------------
|
||||
# Target macros
|
||||
# Defines target operating system, architecture, compiler
|
||||
# ---------------------------------
|
||||
SET_BUILD_PLATFORM()
|
||||
|
||||
#so that boost won't need to link against DateTime when using the interprocess communication library shared memory writer box
|
||||
#ADD_DEFINITIONS(-DBOOST_DATE_TIME_NO_LIB)
|
||||
|
||||
# -----------------------------
|
||||
# Install files
|
||||
# -----------------------------
|
||||
INSTALL(TARGETS ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION ${DIST_BINDIR}
|
||||
LIBRARY DESTINATION ${DIST_LIBDIR}
|
||||
ARCHIVE DESTINATION ${DIST_LIBDIR})
|
||||
|
||||
SET(SUB_DIR_NAME Games)
|
||||
INSTALL(DIRECTORY box-tutorials/ DESTINATION ${DIST_DATADIR}/openvibe/scenarios/box-tutorials/${SUB_DIR_NAME})
|
||||
|
||||
# ---------------------------------
|
||||
# Test applications
|
||||
# ---------------------------------
|
||||
#IF(OV_COMPILE_TESTS)
|
||||
#ADD_SUBDIRECTORY(test)
|
||||
#ENDIF()
|
||||
+530
@@ -0,0 +1,530 @@
|
||||
<OpenViBE-Scenario>
|
||||
<FormatVersion>2</FormatVersion>
|
||||
<Creator>OpenViBE Designer</Creator>
|
||||
<CreatorVersion>3.0.0</CreatorVersion>
|
||||
<Settings></Settings>
|
||||
<Inputs></Inputs>
|
||||
<Outputs></Outputs>
|
||||
<Boxes>
|
||||
<Box>
|
||||
<Identifier>(0x000006bc, 0x0000724a)</Identifier>
|
||||
<Name>Stimulation listener</Name>
|
||||
<AlgorithmClassIdentifier>(0x65731e1d, 0x47de5276)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Stimulation stream 1</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0xa88b3667, 0x0871638c)</TypeIdentifier>
|
||||
<Name>Log level to use</Name>
|
||||
<DefaultValue>Information</DefaultValue>
|
||||
<Value>Information</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>512</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>896</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0xf451ad91, 0x14c75f86)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x000006bc, 0x0000724b)</Identifier>
|
||||
<Name>Stimulation listener</Name>
|
||||
<AlgorithmClassIdentifier>(0x65731e1d, 0x47de5276)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Stimulation stream 1</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0xa88b3667, 0x0871638c)</TypeIdentifier>
|
||||
<Name>Log level to use</Name>
|
||||
<DefaultValue>Information</DefaultValue>
|
||||
<Value>Information</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>512</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>1024</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0xf451ad91, 0x14c75f86)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x00001d83, 0x00005bb9)</Identifier>
|
||||
<Name>Clock stimulator</Name>
|
||||
<AlgorithmClassIdentifier>(0x4f756d3f, 0x29ff0b96)</AlgorithmClassIdentifier>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Generated stimulations</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Interstimulation interval (in sec)</Name>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
<Value>5.000000</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
|
||||
<Name>Stimulation</Name>
|
||||
<DefaultValue>OVTK_StimulationId_Label_00</DefaultValue>
|
||||
<Value>OVTK_StimulationId_Label_00</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>368</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>928</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x27b3ee3c, 0xc50527e6)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x00003316, 0x000057c7)</Identifier>
|
||||
<Name>Matrix Display</Name>
|
||||
<AlgorithmClassIdentifier>(0x54f0796d, 0x3ede2cc0)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
|
||||
<Name>Matrix</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x3d3c7c7f, 0xef0e7129)</TypeIdentifier>
|
||||
<Name>Color gradient</Name>
|
||||
<DefaultValue>0:2,36,58; 50:100,100,100; 100:83,17,20</DefaultValue>
|
||||
<Value>0:2,36,58; 50:100,100,100; 100:83,17,20</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Steps</Name>
|
||||
<DefaultValue>100</DefaultValue>
|
||||
<Value>100</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Symetric min/max</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Real time min/max</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>512</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>784</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x4ff49bdb, 0x9dcf6788)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>4</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x00003552, 0x000054ad)</Identifier>
|
||||
<Name>Time signal</Name>
|
||||
<AlgorithmClassIdentifier>(0x28a5e7ff, 0x530095de)</AlgorithmClassIdentifier>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Generated signal</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Sampling frequency</Name>
|
||||
<DefaultValue>512</DefaultValue>
|
||||
<Value>256</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Generated epoch sample count</Name>
|
||||
<DefaultValue>32</DefaultValue>
|
||||
<Value>1</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>320</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>832</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x9e5ca01e, 0x30a4d8c3)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x0000629e, 0x000034f6)</Identifier>
|
||||
<Name>Simple DSP</Name>
|
||||
<AlgorithmClassIdentifier>(0x00e26fa1, 0x1dbab1b2)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Input - A</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Output</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Equation</Name>
|
||||
<DefaultValue>x</DefaultValue>
|
||||
<Value>sin(x)</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>368</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>832</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x21889dc4, 0x1126497e)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x000077e6, 0x00007175)</Identifier>
|
||||
<Name>Hello Bidirectionnal Game</Name>
|
||||
<AlgorithmClassIdentifier>(0x47616d65, 0x42696469)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Input signal</Name>
|
||||
</Input>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Input stimulations</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
|
||||
<Name>Output matrix</Name>
|
||||
</Output>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Output stimulations</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>432</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>832</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0xf916e69e, 0x8bfebe7a)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
</Boxes>
|
||||
<Links>
|
||||
<Link>
|
||||
<Identifier>(0x000003dc, 0x000048bc)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00003552, 0x000054ad)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x0000629e, 0x000034f6)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x000016aa, 0x00005cf5)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x000077e6, 0x00007175)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x00003316, 0x000057c7)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x00002fe9, 0x00005b2e)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00001d83, 0x00005bb9)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x000006bc, 0x0000724b)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x00003882, 0x00002272)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x000077e6, 0x00007175)</BoxIdentifier>
|
||||
<BoxOutputIndex>1</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x000006bc, 0x0000724a)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x00004d3e, 0x00005caa)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x0000629e, 0x000034f6)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x000077e6, 0x00007175)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x00005a84, 0x0000720a)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00001d83, 0x00005bb9)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x000077e6, 0x00007175)</BoxIdentifier>
|
||||
<BoxInputIndex>1</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
</Links>
|
||||
<Comments>
|
||||
<Comment>
|
||||
<Identifier>(0x00000a8d, 0x000047b4)</Identifier>
|
||||
<Text><b>Remarques : </b> :
|
||||
Le Jeu doit être lancé en premier
|
||||
pour eviter des retards dans OpenViBE du fait de la recherche de canaux LSL.
|
||||
Unity gère mieux la recherche continue de canaux LSL.
|
||||
|
||||
<b> Remarks: </b>:
|
||||
The Game must be launched first
|
||||
to avoid delays in OpenViBE due to LSL channel search.
|
||||
Unity better manages the continuous search for LSL channels. </Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>512</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>416</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
<Comment>
|
||||
<Identifier>(0x00006a65, 0x00005977)</Identifier>
|
||||
<Text>Signal = Sin(time)
|
||||
Game is available in the Repository : https://gitlab.inria.fr/openvibe/unity-games/hello-bidirectionnal</Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>832</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>272</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
</Comments>
|
||||
<Metadata>
|
||||
<Entry>
|
||||
<Identifier>(0x00003414, 0x00007f3b)</Identifier>
|
||||
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
|
||||
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":320,"identifier":"(0x00000cf5, 0x00000b02)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":480},{"boxIdentifier":"(0x00003316, 0x000057c7)","childCount":0,"identifier":"(0x00001b1d, 0x00004d15)","parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00003657, 0x00003658)","index":0,"name":"Default tab","parentIdentifier":"(0x00000cf5, 0x00000b02)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x000018fe, 0x00004f01)","index":0,"name":"Empty","parentIdentifier":"(0x00003657, 0x00003658)","type":0}]</Data>
|
||||
</Entry>
|
||||
</Metadata>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x079d1f09, 0x667c7871)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x60bc58ab, 0x7a1b4d83)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x790d75b8, 0x3bb90c33)</Identifier>
|
||||
<Value>Thibaut Monseigne</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7a3a1558, 0xf12c63c2)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x84009d7c, 0x3c4e763b)</Identifier>
|
||||
<Value>Light scenario that works with Hello World game</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x8c1fc55b, 0x7b433dc2)</Identifier>
|
||||
<Value>1.0</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x9f5c4075, 0x4a0d3666)</Identifier>
|
||||
<Value>Hello World Game</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
|
||||
<Value>Games</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
|
||||
<Value>Inria</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</OpenViBE-Scenario>
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
<OpenViBE-Scenario>
|
||||
<FormatVersion>2</FormatVersion>
|
||||
<Creator>OpenViBE Designer</Creator>
|
||||
<CreatorVersion>2.2.0</CreatorVersion>
|
||||
<Settings></Settings>
|
||||
<Inputs></Inputs>
|
||||
<Outputs></Outputs>
|
||||
<Boxes>
|
||||
<Box>
|
||||
<Identifier>(0x00000050, 0x00007f60)</Identifier>
|
||||
<Name>Hello Sender Game</Name>
|
||||
<AlgorithmClassIdentifier>(0x4cbf4237, 0x24f54a7c)</AlgorithmClassIdentifier>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
|
||||
<Name>Output matrix</Name>
|
||||
</Output>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Output stimulations</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>240</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>752</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0xcdc02a11, 0x9a816677)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x00002498, 0x000035c7)</Identifier>
|
||||
<Name>Matrix Display</Name>
|
||||
<AlgorithmClassIdentifier>(0x54f0796d, 0x3ede2cc0)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
|
||||
<Name>Matrix</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x3d3c7c7f, 0xef0e7129)</TypeIdentifier>
|
||||
<Name>Color gradient</Name>
|
||||
<DefaultValue>0:2,36,58; 50:100,100,100; 100:83,17,20</DefaultValue>
|
||||
<Value>0:2,36,58; 50:100,100,100; 100:83,17,20</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Steps</Name>
|
||||
<DefaultValue>100</DefaultValue>
|
||||
<Value>100</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Symetric min/max</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Real time min/max</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>336</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>688</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x4ff49bdb, 0x9dcf6788)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>4</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x000066c9, 0x00005cd9)</Identifier>
|
||||
<Name>Stimulation listener</Name>
|
||||
<AlgorithmClassIdentifier>(0x65731e1d, 0x47de5276)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Stimulation stream 1</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0xa88b3667, 0x0871638c)</TypeIdentifier>
|
||||
<Name>Log level to use</Name>
|
||||
<DefaultValue>Information</DefaultValue>
|
||||
<Value>Information</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>336</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>800</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0xf451ad91, 0x14c75f86)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
</Boxes>
|
||||
<Links>
|
||||
<Link>
|
||||
<Identifier>(0x000070d3, 0x000045e2)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00000050, 0x00007f60)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x00002498, 0x000035c7)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x00007ec0, 0x000065a9)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00000050, 0x00007f60)</BoxIdentifier>
|
||||
<BoxOutputIndex>1</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x000066c9, 0x00005cd9)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
</Links>
|
||||
<Comments>
|
||||
<Comment>
|
||||
<Identifier>(0x00000a8d, 0x000047b4)</Identifier>
|
||||
<Text><b>Remarks</b> :
|
||||
It is currently impossible to send and receive information by LSL in the same scenario.
|
||||
Indeed, the LSL library waits to receive its flow (or gives up) before moving on.
|
||||
In addition, OpenViBE is not multi-process.
|
||||
It blocks until it has received its flow (or gives up).
|
||||
It is therefore advisable to launch the transmitter before the receive
|
||||
or plan for a shorter but repeated stream search after launch in the event of a startup failure.</Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>1152</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>288</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
<Comment>
|
||||
<Identifier>(0x00006a65, 0x00005977)</Identifier>
|
||||
<Text>Game is available in the Repository : https://gitlab.inria.fr/openvibe/unity-games/hello-sender
|
||||
Run the Game before the Script</Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>768</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>176</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
</Comments>
|
||||
<Metadata>
|
||||
<Entry>
|
||||
<Identifier>(0x00003414, 0x00007f3b)</Identifier>
|
||||
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
|
||||
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":320,"identifier":"(0x00000cf5, 0x00000b02)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":480},{"boxIdentifier":"(0x00002498, 0x000035c7)","childCount":0,"identifier":"(0x00005d08, 0x00001914)","parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00003657, 0x00003658)","index":0,"name":"Default tab","parentIdentifier":"(0x00000cf5, 0x00000b02)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x000018fe, 0x00004f01)","index":0,"name":"Empty","parentIdentifier":"(0x00003657, 0x00003658)","type":0}]</Data>
|
||||
</Entry>
|
||||
</Metadata>
|
||||
</OpenViBE-Scenario>
|
||||
+326
@@ -0,0 +1,326 @@
|
||||
<OpenViBE-Scenario>
|
||||
<FormatVersion>2</FormatVersion>
|
||||
<Creator>OpenViBE Designer</Creator>
|
||||
<CreatorVersion>2.2.0</CreatorVersion>
|
||||
<Settings></Settings>
|
||||
<Inputs></Inputs>
|
||||
<Outputs></Outputs>
|
||||
<Boxes>
|
||||
<Box>
|
||||
<Identifier>(0x00001d83, 0x00005bb9)</Identifier>
|
||||
<Name>Clock stimulator</Name>
|
||||
<AlgorithmClassIdentifier>(0x4f756d3f, 0x29ff0b96)</AlgorithmClassIdentifier>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Generated stimulations</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Interstimulation interval (in sec)</Name>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
<Value>5.000000</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
|
||||
<Name>Stimulation</Name>
|
||||
<DefaultValue>OVTK_StimulationId_Label_00</DefaultValue>
|
||||
<Value>OVTK_StimulationId_Label_00</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>368</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>928</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x27b3ee3c, 0xc50527e6)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x000029cc, 0x00007eba)</Identifier>
|
||||
<Name>Hello World Game</Name>
|
||||
<AlgorithmClassIdentifier>(0x46705bc3, 0x3058a939)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Input signal</Name>
|
||||
</Input>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Input stimulations</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>432</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>832</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0xcb293370, 0xee8027f2)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x00003552, 0x000054ad)</Identifier>
|
||||
<Name>Time signal</Name>
|
||||
<AlgorithmClassIdentifier>(0x28a5e7ff, 0x530095de)</AlgorithmClassIdentifier>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Generated signal</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Sampling frequency</Name>
|
||||
<DefaultValue>512</DefaultValue>
|
||||
<Value>256</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Generated epoch sample count</Name>
|
||||
<DefaultValue>32</DefaultValue>
|
||||
<Value>1</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>320</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>832</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x9e5ca01e, 0x30a4d8c3)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x0000629e, 0x000034f6)</Identifier>
|
||||
<Name>Simple DSP</Name>
|
||||
<AlgorithmClassIdentifier>(0x00e26fa1, 0x1dbab1b2)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Input - A</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Output</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Equation</Name>
|
||||
<DefaultValue>x</DefaultValue>
|
||||
<Value>sin(x)</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>368</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>832</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x21889dc4, 0x1126497e)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
</Boxes>
|
||||
<Links>
|
||||
<Link>
|
||||
<Identifier>(0x000003dc, 0x000048bc)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00003552, 0x000054ad)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x0000629e, 0x000034f6)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x00000e9b, 0x00001c1a)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x0000629e, 0x000034f6)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x000029cc, 0x00007eba)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x000031d4, 0x00003e9b)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00001d83, 0x00005bb9)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x000029cc, 0x00007eba)</BoxIdentifier>
|
||||
<BoxInputIndex>1</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
</Links>
|
||||
<Comments>
|
||||
<Comment>
|
||||
<Identifier>(0x00000a8d, 0x000047b4)</Identifier>
|
||||
<Text><b>Remarks</b> :
|
||||
It is currently impossible to send and receive information by LSL in the same scenario.
|
||||
Indeed, the LSL library waits to receive its flow (or gives up) before moving on.
|
||||
In addition, OpenViBE is not multi-process.
|
||||
It blocks until it has received its flow (or gives up).
|
||||
It is therefore advisable to launch the transmitter before the receiver.
|
||||
Or plan for a shorter but repeated stream search after launch in the event of a startup failure.</Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>496</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>384</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
<Comment>
|
||||
<Identifier>(0x00006a65, 0x00005977)</Identifier>
|
||||
<Text>Signal = Sin(time)
|
||||
Game is available in the Repository : https://gitlab.inria.fr/openvibe/unity-games/hello-world</Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>832</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>272</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
</Comments>
|
||||
<Metadata>
|
||||
<Entry>
|
||||
<Identifier>(0x00003414, 0x00007f3b)</Identifier>
|
||||
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
|
||||
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":320,"identifier":"(0x00000cf5, 0x00000b02)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":480},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00003657, 0x00003658)","index":0,"name":"Default tab","parentIdentifier":"(0x00000cf5, 0x00000b02)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x000018fe, 0x00004f01)","index":0,"name":"Empty","parentIdentifier":"(0x00003657, 0x00003658)","type":0}]</Data>
|
||||
</Entry>
|
||||
</Metadata>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x079d1f09, 0x667c7871)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x60bc58ab, 0x7a1b4d83)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x790d75b8, 0x3bb90c33)</Identifier>
|
||||
<Value>Thibaut Monseigne</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7a3a1558, 0xf12c63c2)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x84009d7c, 0x3c4e763b)</Identifier>
|
||||
<Value>Light scenario that works with Hello World game</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x8c1fc55b, 0x7b433dc2)</Identifier>
|
||||
<Value>1.0</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x9f5c4075, 0x4a0d3666)</Identifier>
|
||||
<Value>Hello World Game</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
|
||||
<Value>Games</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
|
||||
<Value>Inria</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</OpenViBE-Scenario>
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* \page BoxAlgorithm_HelloBidirectionnalGames Hello Bidirectionnal Games
|
||||
__________________________________________________________________
|
||||
|
||||
Detailed description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloBidirectionnalGames_Description|
|
||||
This box forwards the signals and stimulations it gets to two corresponding LabStreamingLayer (LSL) streams and receive back The size of cube in game and a Beep Stimulation from the Unity Game.
|
||||
|
||||
This stream can be read by the Unity Games Hello Bidirectionnal here : https://gitlab.inria.fr/openvibe/unity-games/hello-bidirectionnal
|
||||
|
||||
Remarks : It is recommanded to run the Unity App Before to avoid "too big" lag in OpenViBE with continuous search of stream. Unity can support that easily.
|
||||
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloBidirectionnalGames_Description|
|
||||
__________________________________________________________________
|
||||
|
||||
Inputs description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloBidirectionnalGames_Inputs|
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloBidirectionnalGames_Inputs|
|
||||
*
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloBidirectionnalGames_Input1|
|
||||
The signal input stream.
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloBidirectionnalGames_Input1|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloBidirectionnalGames_Input2|
|
||||
The stimulation input stream.
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloBidirectionnalGames_Input2|
|
||||
__________________________________________________________________
|
||||
|
||||
Outputs description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloSenderGames_Outputs|
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloSenderGames_Outputs|
|
||||
*
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloSenderGames_Output1|
|
||||
The size of the Cube in Unity App.
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloSenderGames_Output1|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloSenderGames_Output2|
|
||||
The Beep stimulation from the Unity App.
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloSenderGames_Output2|
|
||||
__________________________________________________________________
|
||||
|
||||
Settings description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloBidirectionnalGames_Settings|
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloBidirectionnalGames_Settings|
|
||||
*
|
||||
__________________________________________________________________
|
||||
|
||||
Examples description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloBidirectionnalGames_Examples|
|
||||
Easiest way to test the box is to use a time signal box with a simple DSP sin(x) and a Clock Stimulation with stimulation `OVTK_StimulationId_Label_00` for inputs and just a display matrix and a stimulation listener for output.
|
||||
Run the Game, next run the Scenario.
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloBidirectionnalGames_Examples|
|
||||
__________________________________________________________________
|
||||
|
||||
Miscellaneous description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloBidirectionnalGames_Miscellaneous|
|
||||
The box creates each LSL stream at the beginning of the playback, after it has received its corresponding OpenViBE stream header information. Hence, if either signal or stimulus socket
|
||||
of the box is not connected or does not receive a header, the box will not create the corresponding LSL stream.
|
||||
The reception LSL streams are searched during each process to create inlet when stream are available.
|
||||
|
||||
Stream formats: The signal stream is continuous float. The stimulation stream is noncontinuous int, and each 64bit OpenViBE stimulation is truncated to an int marker.
|
||||
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloBidirectionnalGames_Miscellaneous|
|
||||
*/
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* \page BoxAlgorithm_HelloSenderGames Hello Sender Games
|
||||
__________________________________________________________________
|
||||
|
||||
Detailed description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloSenderGames_Description|
|
||||
This box receives the signals and stimulations it gets from two corresponding LabStreamingLayer (LSL) streams.
|
||||
|
||||
These streams can be read by the Unity Games Hello Sender here : https://gitlab.inria.fr/openvibe/unity-games/hello-sender
|
||||
|
||||
Remarks : It is currently impossible to send and receive information by LSL in the same scenario.
|
||||
Indeed, the LSL library waits to receive its flow (or gives up) before moving on. In addition, OpenViBE is not multi-process.
|
||||
It blocks until it has received its flow (or gives up).
|
||||
It is therefore advisable to launch the transmitter before the receiver or plan for a shorter but repeated stream search after launch in the event of a startup failure.
|
||||
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloSenderGames_Description|
|
||||
__________________________________________________________________
|
||||
|
||||
Outputs description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloSenderGames_Outputs|
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloSenderGames_Outputs|
|
||||
*
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloSenderGames_Output1|
|
||||
The matrix output stream.
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloSenderGames_Output1|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloSenderGames_Output2|
|
||||
The stimulation output stream.
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloSenderGames_Output2|
|
||||
|
||||
__________________________________________________________________
|
||||
|
||||
Settings description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloSenderGames_Settings|
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloSenderGames_Settings|
|
||||
*
|
||||
__________________________________________________________________
|
||||
|
||||
Examples description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloSenderGames_Examples|
|
||||
Run the Game, next run the Scenario.
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloSenderGames_Examples|
|
||||
__________________________________________________________________
|
||||
|
||||
Miscellaneous description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloSenderGames_Miscellaneous|
|
||||
The box creates each LSL stream at the beginning of the playback, the Process is stopped until available stream are found.
|
||||
|
||||
Stream formats: The matrix stream is noncontinuous float. The stimulation stream is noncontinuous int.
|
||||
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloSenderGames_Miscellaneous|
|
||||
*/
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* \page BoxAlgorithm_HelloWorldGames Hello World Games
|
||||
__________________________________________________________________
|
||||
|
||||
Detailed description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloWorldGames_Description|
|
||||
This box forwards the signals and stimulations it gets to two corresponding LabStreamingLayer (LSL) streams.
|
||||
|
||||
This stream can be read by the Unity Games Hello World here : https://gitlab.inria.fr/openvibe/unity-games/hello-world
|
||||
|
||||
Remarks : It is currently impossible to send and receive information by LSL in the same scenario.
|
||||
Indeed, the LSL library waits to receive its flow (or gives up) before moving on. In addition, OpenViBE is not multi-process.
|
||||
It blocks until it has received its flow (or gives up).
|
||||
It is therefore advisable to launch the transmitter before the receiver.
|
||||
Or plan for a shorter but repeated stream search after launch in the event of a startup failure.
|
||||
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloWorldGames_Description|
|
||||
__________________________________________________________________
|
||||
|
||||
Inputs description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloWorldGames_Inputs|
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloWorldGames_Inputs|
|
||||
*
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloWorldGames_Input1|
|
||||
The signal input stream.
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloWorldGames_Input1|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloWorldGames_Input2|
|
||||
The stimulation input stream.
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloWorldGames_Input2|
|
||||
|
||||
__________________________________________________________________
|
||||
|
||||
Settings description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloWorldGames_Settings|
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloWorldGames_Settings|
|
||||
*
|
||||
__________________________________________________________________
|
||||
|
||||
Examples description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloWorldGames_Examples|
|
||||
Easiest way to test the box is to use a time signal box with a simple DSP sin(x) and a Clock Stimulation with stimulation `OVTK_StimulationId_Label_00`. Run the Scenario, next run the Game.
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloWorldGames_Examples|
|
||||
__________________________________________________________________
|
||||
|
||||
Miscellaneous description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_HelloWorldGames_Miscellaneous|
|
||||
The box creates each LSL stream at the beginning of the playback, after it has received its corresponding OpenViBE stream header information. Hence, if either signal or stimulus socket
|
||||
of the box is not connected or does not receive a header, the box will not create the corresponding LSL stream.
|
||||
|
||||
Stream formats: The signal stream is continuous float. The stimulation stream is noncontinuous int, and each 64bit OpenViBE stimulation is truncated to an int marker.
|
||||
|
||||
* |OVP_DocEnd_BoxAlgorithm_HelloWorldGames_Miscellaneous|
|
||||
*/
|
||||
+232
@@ -0,0 +1,232 @@
|
||||
#ifdef TARGET_HAS_ThirdPartyLSL
|
||||
|
||||
#include "CBoxAlgorithmHelloBidirectionnalGame.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Games {
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloBidirectionnalGame::initialize()
|
||||
{
|
||||
//---------- Initialize Input/Output ----------
|
||||
m_signalDecoder.initialize(*this, 0);
|
||||
m_stimDecoder.initialize(*this, 1);
|
||||
m_iMatrix = m_signalDecoder.getOutputMatrix();
|
||||
m_iStimSet = m_stimDecoder.getOutputStimulationSet();
|
||||
|
||||
m_signalEncoder.initialize(*this, 0);
|
||||
m_stimEncoder.initialize(*this, 1);
|
||||
m_oMatrix = m_signalEncoder.getInputMatrix();
|
||||
m_oStimSet = m_stimEncoder.getInputStimulationSet();
|
||||
|
||||
//---------- Initialize LSL Stream (to Unity) ----------
|
||||
// These are supposed to be unique, so we don't have them in the box config
|
||||
m_outSignalID = CIdentifier::random().str();
|
||||
m_outMarkerID = CIdentifier::random().str();
|
||||
|
||||
while (m_outMarkerID == m_outSignalID) { m_outMarkerID = CIdentifier::random().str(); } // very unlikely
|
||||
|
||||
this->getLogManager() << Kernel::LogLevel_Trace << "We Will create signal stream [" << m_outSignalName << ", id " << m_outSignalID
|
||||
<< "] and stimulation stream [" << m_outMarkerName << ", id " << m_outMarkerID << "]\n";
|
||||
|
||||
//---------- Create Headers for Output ----------
|
||||
// Matrix Header
|
||||
m_oMatrix->resize(1, 1);
|
||||
m_signalEncoder.encodeHeader();
|
||||
|
||||
// Stimulation Header
|
||||
m_oStimSet->setStimulationCount(0); // reset stimulation output
|
||||
m_stimEncoder.encodeHeader();
|
||||
|
||||
Kernel::IBoxIO& boxCtx = this->getDynamicBoxContext();
|
||||
boxCtx.markOutputAsReadyToSend(0, m_lastMatrixTime, m_lastMatrixTime); // Makes the output available
|
||||
boxCtx.markOutputAsReadyToSend(1, m_lastStimTime, m_lastStimTime); // Makes the output available
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloBidirectionnalGame::uninitialize()
|
||||
{
|
||||
//---------- Uninitialize Input/Output ----------
|
||||
m_signalDecoder.uninitialize();
|
||||
m_stimDecoder.uninitialize();
|
||||
m_signalEncoder.uninitialize();
|
||||
m_stimEncoder.uninitialize();
|
||||
|
||||
//---------- Delete LSL Stream Inlet/Outlet ----------
|
||||
if (m_signalOutlet)
|
||||
{
|
||||
delete m_signalOutlet;
|
||||
m_signalOutlet = nullptr;
|
||||
}
|
||||
if (m_stimOutlet)
|
||||
{
|
||||
delete m_stimOutlet;
|
||||
m_stimOutlet = nullptr;
|
||||
}
|
||||
|
||||
if (m_signalInlet)
|
||||
{
|
||||
m_signalInlet->close_stream();
|
||||
delete m_signalInlet;
|
||||
m_signalInlet = nullptr;
|
||||
}
|
||||
|
||||
if (m_stimInlet)
|
||||
{
|
||||
m_stimInlet->close_stream();
|
||||
delete m_stimInlet;
|
||||
m_stimInlet = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloBidirectionnalGame::processInput(const size_t /*index*/)
|
||||
{
|
||||
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloBidirectionnalGame::process()
|
||||
{
|
||||
// the dynamic box context describes the current state of the box inputs and outputs (i.e. the chunks)
|
||||
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
|
||||
const uint64_t currentTime = getPlayerContext().getCurrentTime();
|
||||
|
||||
//---------- Emission Part ----------
|
||||
// Process signals
|
||||
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
|
||||
{
|
||||
m_signalDecoder.decode(i);
|
||||
if (m_signalDecoder.isHeaderReceived() && !m_signalOutlet)
|
||||
{
|
||||
const size_t samplesPerBlock = m_signalDecoder.getOutputMatrix()->getDimensionSize(1);
|
||||
const size_t frequency = m_signalDecoder.getOutputSamplingRate();
|
||||
|
||||
lsl::stream_info signalInfo = createSignalStreamInfo(m_outSignalName, m_outSignalID, m_signalDecoder.getOutputMatrix(), frequency);
|
||||
// make a new outlet
|
||||
try { m_signalOutlet = new lsl::stream_outlet(signalInfo, int(samplesPerBlock)); }
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << "Unable to create signal outlet\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (m_signalDecoder.isBufferReceived())
|
||||
{
|
||||
sendSignal(m_signalOutlet, m_iMatrix, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
|
||||
}
|
||||
//if (m_signalDecoder.isEndReceived()) { }
|
||||
}
|
||||
|
||||
// Process stimuli -> LSL markers.
|
||||
// Note that stimuli with identifiers not fitting to int will be mangled by a static cast.
|
||||
for (size_t i = 0; i < boxContext.getInputChunkCount(1); ++i)
|
||||
{
|
||||
m_stimDecoder.decode(i);
|
||||
if (m_stimDecoder.isHeaderReceived() && !m_stimOutlet)
|
||||
{
|
||||
// Open a stimulus stream
|
||||
lsl::stream_info info = createStimulationStreamInfo(m_outMarkerName, m_outMarkerID);
|
||||
|
||||
try { m_stimOutlet = new lsl::stream_outlet(info); }
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << "Unable to create marker outlet\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (m_stimDecoder.isBufferReceived()) { sendStimulation(m_stimOutlet, m_iStimSet); }
|
||||
//if (m_stimDecoder.isEndReceived()) { }
|
||||
}
|
||||
|
||||
|
||||
//---------- Reception Part ----------
|
||||
if (!m_signalInlet) // We don't have a signal inlet
|
||||
{
|
||||
const lsl::stream_info signalInfo = findStreamInfo(m_inSignalName, "", 0); // timeout of 0 to avoid blocking OpenViBE
|
||||
if (signalInfo.name() == m_inSignalName)
|
||||
{
|
||||
m_signalInlet = new lsl::stream_inlet(signalInfo);
|
||||
try { m_signalInlet->open_stream(); }
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Failed to open signal stream with name [" << signalInfo.name() << "]\n";
|
||||
return false;
|
||||
}
|
||||
this->getLogManager() << Kernel::LogLevel_Trace << "We have open stream [" << signalInfo.name() << "]\n";
|
||||
}
|
||||
}
|
||||
if (m_signalInlet) // We have a signal inlet
|
||||
{
|
||||
double time;
|
||||
// Signal
|
||||
try { time = m_signalInlet->pull_sample(&m_bufferLSL, 1, 0.0); } // 2 element timeout to 0.0 to avoid lag (OpenViBE can't have background task)
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Failed to get signal sample\n";
|
||||
return false;
|
||||
}
|
||||
if (std::abs(time) > 0.0)
|
||||
{
|
||||
m_oMatrix->getBuffer()[0] = double(m_bufferLSL);
|
||||
m_signalEncoder.encodeBuffer(); // Buffer encoded
|
||||
boxContext.markOutputAsReadyToSend(0, m_lastMatrixTime, currentTime); // Makes the output available
|
||||
m_lastMatrixTime = currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_stimInlet) // We haven't a stimulation inlet
|
||||
{
|
||||
const lsl::stream_info stimInfo = findStreamInfo(m_inMarkerName, "", 0); // timeout of 0 to avoid blocking OpenViBE
|
||||
if (stimInfo.name() == m_inMarkerName)
|
||||
{
|
||||
m_stimInlet = new lsl::stream_inlet(stimInfo);
|
||||
try { m_stimInlet->open_stream(); }
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Failed to open marker stream with name [" << stimInfo.name() << "]\n";
|
||||
return false;
|
||||
}
|
||||
this->getLogManager() << Kernel::LogLevel_Trace << "We have open stream [" << stimInfo.name() << "]\n";
|
||||
}
|
||||
}
|
||||
if (m_stimInlet) // We have a stimulation inlet
|
||||
{
|
||||
double time;
|
||||
try { time = m_stimInlet->pull_sample(&m_bufferLSL, 1, 0.0); } // 1 element timeout to 0.0 to avoid lag (OpenViBE can't have background task)
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Failed to get stimulation sample\n";
|
||||
return false;
|
||||
}
|
||||
if (std::abs(time) > 0.0)
|
||||
{
|
||||
m_oStimSet->setStimulationCount(0); // reset stimulation output
|
||||
m_oStimSet->appendStimulation(uint64_t(m_bufferLSL), currentTime, 0);
|
||||
m_stimEncoder.encodeBuffer(); // Buffer encoded
|
||||
boxContext.markOutputAsReadyToSend(1, m_lastStimTime, currentTime); // Makes the output available
|
||||
m_lastStimTime = currentTime;
|
||||
this->getLogManager() << Kernel::LogLevel_Info << "Stim received with time " << time << "s in the unity app\n";
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Games
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
|
||||
#endif // TARGET_HAS_ThirdPartyLSL
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
///-------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// \file CBoxAlgorithmHelloBidirectionnalGame.hpp
|
||||
/// \brief Class of the box that communicates with Hello Bidirectionnal Game.
|
||||
/// \author Thibaut Monseigne (Inria).
|
||||
/// \version 1.0.
|
||||
/// \date 24/02/2021
|
||||
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
|
||||
///
|
||||
///-------------------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef TARGET_HAS_ThirdPartyLSL
|
||||
|
||||
#include "defines.hpp"
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
#include <lsl_cpp.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Games {
|
||||
|
||||
/// <summary> The class CBoxAlgorithmHelloBidirectionnalGame describes the box that sends value in LSL. </summary>
|
||||
class CBoxAlgorithmHelloBidirectionnalGame final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
|
||||
{
|
||||
public:
|
||||
void release() override { delete this; }
|
||||
|
||||
bool initialize() override;
|
||||
bool uninitialize() override;
|
||||
|
||||
bool processInput(const size_t index) override;
|
||||
|
||||
bool process() override;
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, Game_Box_Hello_Bidirectionnal)
|
||||
|
||||
protected:
|
||||
|
||||
// Encoder / Decoder
|
||||
Toolkit::TStimulationDecoder<CBoxAlgorithmHelloBidirectionnalGame> m_stimDecoder;
|
||||
Toolkit::TSignalDecoder<CBoxAlgorithmHelloBidirectionnalGame> m_signalDecoder;
|
||||
Toolkit::TStimulationEncoder<CBoxAlgorithmHelloBidirectionnalGame> m_stimEncoder;
|
||||
Toolkit::TSignalEncoder<CBoxAlgorithmHelloBidirectionnalGame> m_signalEncoder;
|
||||
|
||||
// Input/ Output
|
||||
CMatrix *m_iMatrix = nullptr, *m_oMatrix = nullptr;
|
||||
IStimulationSet *m_iStimSet = nullptr, *m_oStimSet = nullptr;
|
||||
uint64_t m_lastMatrixTime = 0, m_lastStimTime = 0;
|
||||
|
||||
// LSL Stream
|
||||
lsl::stream_outlet *m_signalOutlet = nullptr, *m_stimOutlet = nullptr;
|
||||
lsl::stream_inlet *m_signalInlet = nullptr, *m_stimInlet = nullptr;
|
||||
const std::string m_outSignalName = "ovOutSignal", m_outMarkerName = "ovOutMarkers";
|
||||
const std::string m_inSignalName = "ovInSignal", m_inMarkerName = "ovInMarkers";
|
||||
std::string m_outSignalID, m_outMarkerID;
|
||||
float m_bufferLSL = 0.0;
|
||||
};
|
||||
|
||||
|
||||
/// <summary> Descriptor of the box Hello Bidirectionnal Game. </summary>
|
||||
class CBoxAlgorithmHelloBidirectionnalGameDesc final : virtual public IBoxAlgorithmDesc
|
||||
{
|
||||
public:
|
||||
|
||||
void release() override { }
|
||||
|
||||
CString getName() const override { return "Hello Bidirectionnal Game"; }
|
||||
CString getAuthorName() const override { return "Thibaut Monseigne"; }
|
||||
CString getAuthorCompanyName() const override { return "Inria"; }
|
||||
CString getShortDescription() const override
|
||||
{
|
||||
return "Send input stream via LabStreamingLayer (LSL) to the unity game Hello Bidirectionnal and receive back matrix and stimulation.";
|
||||
}
|
||||
CString getDetailedDescription() const override
|
||||
{
|
||||
return "The Unity Game is in the OpenViBE Unity Game Set of Repository (https://gitlab.inria.fr/openvibe/unity-games/hello-bidirectionnal).\n";
|
||||
}
|
||||
CString getCategory() const override { return "Games"; }
|
||||
CString getVersion() const override { return "0.1"; }
|
||||
CString getStockItemName() const override { return "gtk-connect"; }
|
||||
|
||||
CIdentifier getCreatedClass() const override { return Game_Box_Hello_Bidirectionnal; }
|
||||
IPluginObject* create() override { return new CBoxAlgorithmHelloBidirectionnalGame; }
|
||||
|
||||
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
|
||||
{
|
||||
prototype.addInput("Input signal", OV_TypeId_Signal);
|
||||
prototype.addInput("Input stimulations", OV_TypeId_Stimulations);
|
||||
prototype.addOutput("Output matrix", OV_TypeId_StreamedMatrix);
|
||||
prototype.addOutput("Output stimulations", OV_TypeId_Stimulations);
|
||||
return true;
|
||||
}
|
||||
|
||||
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, Game_Box_Hello_Bidirectionnal_Desc)
|
||||
};
|
||||
|
||||
} // namespace Games
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
|
||||
#endif // TARGET_HAS_ThirdPartyLSL
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
#ifdef TARGET_HAS_ThirdPartyLSL
|
||||
|
||||
#include "CBoxAlgorithmHelloSenderGame.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Games {
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloSenderGame::initialize()
|
||||
{
|
||||
m_signalInlet = nullptr;
|
||||
m_stimInlet = nullptr;
|
||||
|
||||
m_signalEncoder.initialize(*this, 0);
|
||||
m_stimEncoder.initialize(*this, 1);
|
||||
m_oMatrix = m_signalEncoder.getInputMatrix();
|
||||
m_oStimSet = m_stimEncoder.getInputStimulationSet();
|
||||
|
||||
// Signal Stream
|
||||
const lsl::stream_info signalInfo = findStreamInfo(m_signalName);
|
||||
if (signalInfo.name() != m_signalName)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Error getting signal stream info for [" << signalInfo.name() << "]\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_signalInlet = new lsl::stream_inlet(signalInfo);
|
||||
if (!m_signalInlet)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Error getting signal inlet for [" << signalInfo.name() << "]\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
try { m_signalInlet->open_stream(); }
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Failed to open signal stream with name [" << signalInfo.name() << "]\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Stimulation Stream
|
||||
const lsl::stream_info stimInfo = findStreamInfo(m_markerName);
|
||||
if (stimInfo.name() != m_markerName)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Error getting marker stream info for [" << stimInfo.name() << "]\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_stimInlet = new lsl::stream_inlet(stimInfo);
|
||||
if (!m_stimInlet)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Error getting marker inlet for [" << stimInfo.name() << "]\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
try { m_stimInlet->open_stream(); }
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Failed to open marker stream with name [" << stimInfo.name() << "]\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloSenderGame::uninitialize()
|
||||
{
|
||||
m_signalEncoder.uninitialize();
|
||||
m_stimEncoder.uninitialize();
|
||||
|
||||
if (m_signalInlet)
|
||||
{
|
||||
m_signalInlet->close_stream();
|
||||
delete m_signalInlet;
|
||||
m_signalInlet = nullptr;
|
||||
}
|
||||
|
||||
if (m_stimInlet)
|
||||
{
|
||||
m_stimInlet->close_stream();
|
||||
delete m_stimInlet;
|
||||
m_stimInlet = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloSenderGame::processClock(Kernel::CMessageClock& /*msg*/)
|
||||
{
|
||||
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloSenderGame::process()
|
||||
{
|
||||
// the dynamic box context describes the current state of the box inputs and outputs (i.e. the chunks)
|
||||
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
|
||||
const uint64_t currentTime = getPlayerContext().getCurrentTime();
|
||||
|
||||
// Header
|
||||
if (!m_headerSent)
|
||||
{
|
||||
m_buffer = new float[2];
|
||||
|
||||
// Matrix Header
|
||||
m_oMatrix->resize(2, 1);
|
||||
m_signalEncoder.encodeHeader();
|
||||
|
||||
// Stimulation Header
|
||||
m_oStimSet->setStimulationCount(0); // reset stimulation output
|
||||
m_stimEncoder.encodeHeader();
|
||||
|
||||
boxContext.markOutputAsReadyToSend(0, m_lastMatrixTime, m_lastMatrixTime); // Makes the output available
|
||||
boxContext.markOutputAsReadyToSend(1, m_lastStimTime, m_lastStimTime); // Makes the output available
|
||||
m_headerSent = true;
|
||||
this->getLogManager() << Kernel::LogLevel_Info << "Header created\n";
|
||||
}
|
||||
|
||||
// Core
|
||||
double time;
|
||||
// Signal
|
||||
try { time = m_signalInlet->pull_sample(m_buffer, 2, 0.0); } // 2 element timeout to 0.0 to avoid lag (OpenViBE can't have background task)
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Failed to get signal sample\n";
|
||||
return false;
|
||||
}
|
||||
if (std::abs(time) > 0.0)
|
||||
{
|
||||
double* buffer = m_oMatrix->getBuffer();
|
||||
buffer[0] = double(m_buffer[0]);
|
||||
buffer[1] = double(m_buffer[1]);
|
||||
m_signalEncoder.encodeBuffer(); // Buffer encoded
|
||||
boxContext.markOutputAsReadyToSend(0, m_lastMatrixTime, currentTime); // Makes the output available
|
||||
m_lastMatrixTime = currentTime;
|
||||
}
|
||||
|
||||
// Stimulation
|
||||
try { time = m_stimInlet->pull_sample(m_buffer, 1, 0.0); } // 1 element timeout to 0.0 to avoid lag (OpenViBE can't have background task)
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Failed to get stimulation sample\n";
|
||||
return false;
|
||||
}
|
||||
if (std::abs(time) > 0.0)
|
||||
{
|
||||
m_oStimSet->setStimulationCount(0); // reset stimulation output
|
||||
m_oStimSet->appendStimulation(uint64_t(m_buffer[0]), currentTime, 0);
|
||||
m_stimEncoder.encodeBuffer(); // Buffer encoded
|
||||
boxContext.markOutputAsReadyToSend(1, m_lastStimTime, currentTime); // Makes the output available
|
||||
m_lastStimTime = currentTime;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
} // namespace Games
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
|
||||
|
||||
#endif // TARGET_HAS_ThirdPartyLSL
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
///-------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// \file CBoxAlgorithmHelloSenderGame.hpp
|
||||
/// \brief Class of the box that communicate with Hello Sender Game.
|
||||
/// \author Thibaut Monseigne (Inria).
|
||||
/// \version 1.0.
|
||||
/// \date 12/03/2020.
|
||||
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
|
||||
///
|
||||
///-------------------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef TARGET_HAS_ThirdPartyLSL
|
||||
|
||||
#include "defines.hpp"
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
#include <lsl_cpp.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Games {
|
||||
|
||||
/// <summary> The class CBoxAlgorithmHelloSenderGame describes the box that send value in LSL. </summary>
|
||||
class CBoxAlgorithmHelloSenderGame final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
|
||||
{
|
||||
public:
|
||||
void release() override { delete this; }
|
||||
|
||||
uint64_t getClockFrequency() override { return 64LL << 32; }
|
||||
bool initialize() override;
|
||||
bool uninitialize() override;
|
||||
|
||||
bool processClock(Kernel::CMessageClock& msg) override;
|
||||
|
||||
bool process() override;
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, Game_Box_Hello_Sender)
|
||||
|
||||
protected:
|
||||
|
||||
// Decoders
|
||||
Toolkit::TStimulationEncoder<CBoxAlgorithmHelloSenderGame> m_stimEncoder;
|
||||
Toolkit::TSignalEncoder<CBoxAlgorithmHelloSenderGame> m_signalEncoder;
|
||||
CMatrix* m_oMatrix = nullptr;
|
||||
IStimulationSet* m_oStimSet = nullptr;
|
||||
float* m_buffer = nullptr;
|
||||
bool m_headerSent = false;
|
||||
uint64_t m_lastMatrixTime = 0;
|
||||
uint64_t m_lastStimTime = 0;
|
||||
|
||||
lsl::stream_inlet *m_signalInlet = nullptr, *m_stimInlet = nullptr;
|
||||
const std::string m_signalName = "ovSignal", m_markerName = "ovMarker";
|
||||
};
|
||||
|
||||
|
||||
/// <summary> Descriptor of the box Hello Sender Game. </summary>
|
||||
class CBoxAlgorithmHelloSenderGameDesc final : virtual public IBoxAlgorithmDesc
|
||||
{
|
||||
public:
|
||||
|
||||
void release() override { }
|
||||
|
||||
CString getName() const override { return "Hello Sender Game"; }
|
||||
CString getAuthorName() const override { return "Thibaut Monseigne"; }
|
||||
CString getAuthorCompanyName() const override { return "Inria"; }
|
||||
CString getShortDescription() const override { return "Receive stream via LabStreamingLayer (LSL) from the unity game Hello Sender."; }
|
||||
CString getDetailedDescription() const override
|
||||
{
|
||||
return "The Unity Game is in the OpenViBE Unity Game Set of Repository (https://gitlab.inria.fr/openvibe/unity-games/hello-sender).\n";
|
||||
}
|
||||
CString getCategory() const override { return "Games"; }
|
||||
CString getVersion() const override { return "0.1"; }
|
||||
CString getStockItemName() const override { return "gtk-connect"; }
|
||||
|
||||
CIdentifier getCreatedClass() const override { return Game_Box_Hello_Sender; }
|
||||
IPluginObject* create() override { return new CBoxAlgorithmHelloSenderGame; }
|
||||
|
||||
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
|
||||
{
|
||||
prototype.addOutput("Output matrix", OV_TypeId_StreamedMatrix);
|
||||
prototype.addOutput("Output stimulations", OV_TypeId_Stimulations);
|
||||
return true;
|
||||
}
|
||||
|
||||
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, Game_Box_Hello_Sender_Desc)
|
||||
};
|
||||
|
||||
} // namespace Games
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
|
||||
|
||||
#endif // TARGET_HAS_ThirdPartyLSL
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
#ifdef TARGET_HAS_ThirdPartyLSL
|
||||
|
||||
#include "CBoxAlgorithmHelloWorldGame.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Games {
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloWorldGame::initialize()
|
||||
{
|
||||
m_signalOutlet = nullptr;
|
||||
m_stimOutlet = nullptr;
|
||||
|
||||
m_signalDecoder.initialize(*this, 0);
|
||||
m_stimDecoder.initialize(*this, 1);
|
||||
m_iMatrix = m_signalDecoder.getOutputMatrix();
|
||||
m_iStimSet = m_stimDecoder.getOutputStimulationSet();
|
||||
|
||||
// These are supposed to be unique, so we don't have them in the box config
|
||||
m_signalID = CIdentifier::random().str();
|
||||
m_markerID = CIdentifier::random().str();
|
||||
|
||||
while (m_markerID == m_signalID) { m_markerID = CIdentifier::random().str(); } // very unlikely
|
||||
|
||||
this->getLogManager() << Kernel::LogLevel_Trace << "We Will create streams [" << m_signalName << ", id " << m_signalID
|
||||
<< "] and [" << m_markerName << ", id " << m_markerID << "]\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloWorldGame::uninitialize()
|
||||
{
|
||||
m_signalDecoder.uninitialize();
|
||||
m_stimDecoder.uninitialize();
|
||||
|
||||
if (m_signalOutlet)
|
||||
{
|
||||
delete m_signalOutlet;
|
||||
m_signalOutlet = nullptr;
|
||||
}
|
||||
if (m_stimOutlet)
|
||||
{
|
||||
delete m_stimOutlet;
|
||||
m_stimOutlet = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloWorldGame::processInput(const size_t /*index*/)
|
||||
{
|
||||
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
bool CBoxAlgorithmHelloWorldGame::process()
|
||||
{
|
||||
// the dynamic box context describes the current state of the box inputs and outputs (i.e. the chunks)
|
||||
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
|
||||
|
||||
// Process signals
|
||||
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
|
||||
{
|
||||
m_signalDecoder.decode(i);
|
||||
if (m_signalDecoder.isHeaderReceived() && !m_signalOutlet)
|
||||
{
|
||||
const size_t samplesPerBlock = m_signalDecoder.getOutputMatrix()->getDimensionSize(1);
|
||||
const size_t frequency = m_signalDecoder.getOutputSamplingRate();
|
||||
|
||||
lsl::stream_info signalInfo = createSignalStreamInfo(m_signalName, m_signalID, m_signalDecoder.getOutputMatrix(), frequency);
|
||||
// make a new outlet
|
||||
try { m_signalOutlet = new lsl::stream_outlet(signalInfo, int(samplesPerBlock)); }
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << "Unable to create signal outlet\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (m_signalDecoder.isBufferReceived())
|
||||
{
|
||||
sendSignal(m_signalOutlet, m_iMatrix, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
|
||||
}
|
||||
//if (m_signalDecoder.isEndReceived()) { }
|
||||
}
|
||||
|
||||
// Process stimuli -> LSL markers.
|
||||
// Note that stimuli with identifiers not fitting to int will be mangled by a static cast.
|
||||
for (size_t i = 0; i < boxContext.getInputChunkCount(1); ++i)
|
||||
{
|
||||
m_stimDecoder.decode(i);
|
||||
if (m_stimDecoder.isHeaderReceived() && !m_stimOutlet)
|
||||
{
|
||||
// Open a stimulus stream
|
||||
lsl::stream_info info = createStimulationStreamInfo(m_markerName, m_markerID);
|
||||
|
||||
try { m_stimOutlet = new lsl::stream_outlet(info); }
|
||||
catch (...)
|
||||
{
|
||||
this->getLogManager() << "Unable to create marker outlet\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (m_stimDecoder.isBufferReceived()) { sendStimulation(m_stimOutlet, m_iStimSet); }
|
||||
//if (m_stimDecoder.isEndReceived()) { }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Games
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
|
||||
#endif // TARGET_HAS_ThirdPartyLSL
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
///-------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// \file CBoxAlgorithmHelloWorldGame.hpp
|
||||
/// \brief Class of the box that communicate with Hello World Game.
|
||||
/// \author Thibaut Monseigne (Inria).
|
||||
/// \version 1.0.
|
||||
/// \date 12/03/2020.
|
||||
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
|
||||
///
|
||||
///-------------------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef TARGET_HAS_ThirdPartyLSL
|
||||
|
||||
#include "defines.hpp"
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
#include <lsl_cpp.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Games {
|
||||
|
||||
/// <summary> The class CBoxAlgorithmHelloWorldGame describes the box that send value in LSL. </summary>
|
||||
class CBoxAlgorithmHelloWorldGame final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
|
||||
{
|
||||
public:
|
||||
void release() override { delete this; }
|
||||
|
||||
bool initialize() override;
|
||||
bool uninitialize() override;
|
||||
|
||||
bool processInput(const size_t index) override;
|
||||
|
||||
bool process() override;
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, Game_Box_Hello_World)
|
||||
|
||||
protected:
|
||||
|
||||
// Decoders
|
||||
Toolkit::TStimulationDecoder<CBoxAlgorithmHelloWorldGame> m_stimDecoder;
|
||||
Toolkit::TSignalDecoder<CBoxAlgorithmHelloWorldGame> m_signalDecoder;
|
||||
CMatrix* m_iMatrix = nullptr;
|
||||
IStimulationSet* m_iStimSet = nullptr;
|
||||
|
||||
lsl::stream_outlet *m_signalOutlet = nullptr, *m_stimOutlet = nullptr;
|
||||
const std::string m_signalName = "ovSignal", m_markerName = "ovMarkers";
|
||||
std::string m_signalID, m_markerID;
|
||||
};
|
||||
|
||||
|
||||
/// <summary> Descriptor of the box Hello World Game. </summary>
|
||||
class CBoxAlgorithmHelloWorldGameDesc final : virtual public IBoxAlgorithmDesc
|
||||
{
|
||||
public:
|
||||
|
||||
void release() override { }
|
||||
|
||||
CString getName() const override { return "Hello World Game"; }
|
||||
CString getAuthorName() const override { return "Thibaut Monseigne"; }
|
||||
CString getAuthorCompanyName() const override { return "Inria"; }
|
||||
CString getShortDescription() const override { return "Send input stream via LabStreamingLayer (LSL) to the unity game Hello World."; }
|
||||
CString getDetailedDescription() const override
|
||||
{
|
||||
return "The Unity Game is in the OpenViBE Unity Game Set of Repository (https://gitlab.inria.fr/openvibe/unity-games/hello-world).\n";
|
||||
}
|
||||
CString getCategory() const override { return "Games"; }
|
||||
CString getVersion() const override { return "0.1"; }
|
||||
CString getStockItemName() const override { return "gtk-connect"; }
|
||||
|
||||
CIdentifier getCreatedClass() const override { return Game_Box_Hello_World; }
|
||||
IPluginObject* create() override { return new CBoxAlgorithmHelloWorldGame; }
|
||||
|
||||
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
|
||||
{
|
||||
prototype.addInput("Input signal", OV_TypeId_Signal);
|
||||
prototype.addInput("Input stimulations", OV_TypeId_Stimulations);
|
||||
return true;
|
||||
}
|
||||
|
||||
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, Game_Box_Hello_World_Desc)
|
||||
};
|
||||
|
||||
} // namespace Games
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
|
||||
#endif // TARGET_HAS_ThirdPartyLSL
|
||||
@@ -0,0 +1,21 @@
|
||||
///-------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// \file defines.hpp
|
||||
/// \brief Defines list for Setting, Shortcut Macro and const.
|
||||
/// \author Thibaut Monseigne (Inria).
|
||||
/// \version 1.0.
|
||||
/// \date 12/03/2020.
|
||||
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
|
||||
///
|
||||
///-------------------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
// Boxes
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
#define Game_Box_Hello_World OpenViBE::CIdentifier(0x46705bc3, 0x3058a939)
|
||||
#define Game_Box_Hello_World_Desc OpenViBE::CIdentifier(0x3f921b93, 0xadb2b2ec)
|
||||
#define Game_Box_Hello_Sender OpenViBE::CIdentifier(0x4cbf4237, 0x24f54a7c)
|
||||
#define Game_Box_Hello_Sender_Desc OpenViBE::CIdentifier(0x5730a8f1, 0x96a608cc)
|
||||
#define Game_Box_Hello_Bidirectionnal OpenViBE::CIdentifier(0x47616d65, 0x42696469)
|
||||
#define Game_Box_Hello_Bidirectionnal_Desc OpenViBE::CIdentifier(0x47616d65, 0x42696464)
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <openvibe/ov_all.h>
|
||||
//#include "defines.hpp"
|
||||
|
||||
// Boxes Includes
|
||||
#include "boxes/CBoxAlgorithmHelloWorldGame.hpp"
|
||||
#include "boxes/CBoxAlgorithmHelloSenderGame.hpp"
|
||||
#include "boxes/CBoxAlgorithmHelloBidirectionnalGame.hpp"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Games {
|
||||
|
||||
OVP_Declare_Begin()
|
||||
#ifdef TARGET_HAS_ThirdPartyLSL
|
||||
// Register boxes
|
||||
OVP_Declare_New(CBoxAlgorithmHelloWorldGameDesc)
|
||||
OVP_Declare_New(CBoxAlgorithmHelloSenderGameDesc)
|
||||
OVP_Declare_New(CBoxAlgorithmHelloBidirectionnalGameDesc)
|
||||
#endif // TARGET_HAS_ThirdPartyLSL
|
||||
OVP_Declare_End()
|
||||
|
||||
} // namespace Games
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
@@ -0,0 +1,91 @@
|
||||
#include <iostream>
|
||||
#ifdef TARGET_HAS_ThirdPartyLSL
|
||||
|
||||
#include "utils.hpp"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
lsl::stream_info createSignalStreamInfo(const std::string& name, const std::string& id, const OpenViBE::CMatrix* matrix, const size_t frequency)
|
||||
{
|
||||
const size_t nChannel = matrix->getDimensionSize(0);
|
||||
|
||||
// Open a signal stream
|
||||
lsl::stream_info res(name, "signal", int(nChannel), double(frequency), lsl::cf_float32, id);
|
||||
|
||||
lsl::xml_element channels = res.desc().append_child("channels");
|
||||
for (size_t c = 0; c < nChannel; ++c)
|
||||
{
|
||||
const std::string tmp = matrix->getDimensionLabel(0, c);
|
||||
channels.append_child("channel").append_child_value("label", tmp).append_child_value("unit", "unknown").append_child_value("type", "signal");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
lsl::stream_info createStimulationStreamInfo(const std::string& name, const std::string& id)
|
||||
{
|
||||
lsl::stream_info res(name, "Markers", 1, lsl::IRREGULAR_RATE, lsl::cf_int32, id);
|
||||
res.desc().append_child("channels").append_child("channel").append_child_value("label", "Stimulations").append_child_value("type", "marker");
|
||||
return res;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
void sendSignal(lsl::stream_outlet* outlet, const OpenViBE::CMatrix* matrix, const uint64_t startTime, const uint64_t endTime)
|
||||
{
|
||||
if (outlet->have_consumers())
|
||||
{
|
||||
const size_t nChannel = matrix->getDimensionSize(0);
|
||||
const size_t nSamples = matrix->getDimensionSize(1);
|
||||
const double* iBuffer = matrix->getBuffer();
|
||||
std::vector<float> buffer(nChannel);
|
||||
|
||||
// note: the step computed below should be exactly the same as could be obtained from the sampling rate
|
||||
const double start = OpenViBE::CTime(startTime).toSeconds();
|
||||
const double step = OpenViBE::CTime(endTime - startTime).toSeconds() / double(nSamples);
|
||||
|
||||
for (size_t s = 0; s < nSamples; ++s)
|
||||
{
|
||||
for (size_t c = 0; c < nChannel; ++c) { buffer[c] = float(iBuffer[c * nSamples + s]); }
|
||||
outlet->push_sample(buffer, start + double(s) * step);
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
void sendStimulation(lsl::stream_outlet* outlet, const OpenViBE::IStimulationSet* stimSet)
|
||||
{
|
||||
if (outlet->have_consumers())
|
||||
{
|
||||
for (size_t s = 0; s < stimSet->getStimulationCount(); ++s)
|
||||
{
|
||||
const int code = int(stimSet->getStimulationIdentifier(s));
|
||||
const double date = OpenViBE::CTime(stimSet->getStimulationDate(s)).toSeconds();
|
||||
|
||||
outlet->push_sample(&code, date);
|
||||
}
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
lsl::stream_info findStreamInfo(const std::string& name, const std::string& id, const int timeout)
|
||||
{
|
||||
// Find the signal stream
|
||||
const std::vector<lsl::stream_info> infos = lsl::resolve_stream("name", name, 1, timeout);
|
||||
if (infos.empty())
|
||||
{
|
||||
if (timeout != 0) { std::cerr << "Failed to find stream with name [" << name << "]\n"; } // Avoid a print if timeout is 0
|
||||
return lsl::stream_info();
|
||||
}
|
||||
|
||||
for (const auto& i : infos)
|
||||
{
|
||||
if (i.source_id() == id) { return i; } // This is the best one
|
||||
}
|
||||
return infos[0];
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
#endif // TARGET_HAS_ThirdPartyLSL
|
||||
@@ -0,0 +1,62 @@
|
||||
///-------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// \file utils.hpp
|
||||
/// \brief Defines some function to facilitate Box Management.
|
||||
/// \author Thibaut Monseigne (Inria).
|
||||
/// \version 1.0.
|
||||
/// \date 12/03/2020.
|
||||
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
|
||||
///
|
||||
///-------------------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef TARGET_HAS_ThirdPartyLSL
|
||||
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <lsl_cpp.h>
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Sending
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary> Create the stream information for signals.</summary>
|
||||
/// <param name="name"> The name of the stream. </param>
|
||||
/// <param name="id"> The identifier of the stream. </param>
|
||||
/// <param name="matrix"> The matrix to get infos (channel number and label).</param>
|
||||
/// <param name="frequency"> The signal frequency.</param>
|
||||
/// <returns> the stream info. </returns>
|
||||
lsl::stream_info createSignalStreamInfo(const std::string& name, const std::string& id, const OpenViBE::CMatrix* matrix, const size_t frequency);
|
||||
|
||||
/// <summary> Create the stream information for stimulations.</summary>
|
||||
/// <param name="name"> The name of the stream. </param>
|
||||
/// <param name="id"> The identifier of the stream. </param>
|
||||
/// <returns> the stream info. </returns>
|
||||
lsl::stream_info createStimulationStreamInfo(const std::string& name, const std::string& id);
|
||||
|
||||
/// <summary> Send Signal in LSL outlet. </summary>
|
||||
/// <param name="outlet"> The LSL outlet. </param>
|
||||
/// <param name="matrix"> The matrix with the signal to send. </param>
|
||||
/// <param name="startTime"> The start time of the signal. </param>
|
||||
/// <param name="endTime"> The end time of the signal. </param>
|
||||
void sendSignal(lsl::stream_outlet* outlet, const OpenViBE::CMatrix* matrix, const uint64_t startTime, const uint64_t endTime);
|
||||
|
||||
/// <summary> Send the stimulation in LSL outlet. </summary>
|
||||
/// <param name="outlet"> The LSL outlet. </param>
|
||||
/// <param name="stimSet">The stimulation set to send. </param>
|
||||
void sendStimulation(lsl::stream_outlet* outlet, const OpenViBE::IStimulationSet* stimSet);
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Receiving
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary> Finds the stream information with the function <c>lsl::resolve_stream</c>. </summary>
|
||||
/// <param name="name"> The expected name of the stream. </param>
|
||||
/// <param name="id"> Optionally The expected ID of the stream in addition of the name. </param>
|
||||
/// <param name="timeout"> Optionally a timeout of the operation, in seconds (default: no timeout).
|
||||
/// If the timeout expires, a default stream info is returned. </param>
|
||||
/// <returns></returns>
|
||||
lsl::stream_info findStreamInfo(const std::string& name, const std::string& id = "", const int timeout = LSL_FOREVER);
|
||||
|
||||
#endif // TARGET_HAS_ThirdPartyLSL
|
||||
Reference in New Issue
Block a user