init
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
PROJECT(openvibe-plugins-sdk-tools)
|
||||
|
||||
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
|
||||
SET(PROJECT_VERSION_MINOR ${OV_GLOBAL_VERSION_MINOR})
|
||||
SET(PROJECT_VERSION_PATCH ${OV_GLOBAL_VERSION_PATCH})
|
||||
SET(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
|
||||
|
||||
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.hpp src/*.inl)
|
||||
INCLUDE("FindSourceRCProperties")
|
||||
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")
|
||||
|
||||
INCLUDE("FindOpenViBE")
|
||||
INCLUDE("FindOpenViBECommon")
|
||||
INCLUDE("FindOpenViBEToolkit")
|
||||
INCLUDE("FindOpenViBEModuleEBML")
|
||||
INCLUDE("FindOpenViBEModuleSystem")
|
||||
INCLUDE("FindOpenViBEModuleFS")
|
||||
INCLUDE("FindOpenViBEModuleSocket")
|
||||
INCLUDE("FindOpenViBEModuleCommunication")
|
||||
|
||||
# ---------------------------------
|
||||
# Target macros
|
||||
# Defines target operating system, architecture and compiler
|
||||
# ---------------------------------
|
||||
SET_BUILD_PLATFORM()
|
||||
|
||||
# -----------------------------
|
||||
# Install files
|
||||
# -----------------------------
|
||||
INSTALL(TARGETS ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION ${DIST_BINDIR}
|
||||
LIBRARY DESTINATION ${DIST_LIBDIR}
|
||||
ARCHIVE DESTINATION ${DIST_LIBDIR})
|
||||
|
||||
INSTALL(DIRECTORY share/ DESTINATION ${DIST_DATADIR}/openvibe/plugins/tools)
|
||||
INSTALL(DIRECTORY box-tutorials DESTINATION ${DIST_DATADIR}/openvibe/scenarios/)
|
||||
|
||||
+520
@@ -0,0 +1,520 @@
|
||||
<OpenViBE-Scenario>
|
||||
<FormatVersion>1</FormatVersion>
|
||||
<Creator>OpenVIBE</Creator>
|
||||
<CreatorVersion>0.4.99</CreatorVersion>
|
||||
<Settings></Settings>
|
||||
<Inputs></Inputs>
|
||||
<Outputs></Outputs>
|
||||
<Boxes>
|
||||
<Box>
|
||||
<Identifier>(0x14bf05c0, 0x09128ae5)</Identifier>
|
||||
<Name>External Processing</Name>
|
||||
<AlgorithmClassIdentifier>(0x15422959, 0x16304449)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>New input</Name>
|
||||
</Input>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>New input</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>New output</Name>
|
||||
</Output>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>New output</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Launch third party program</Name>
|
||||
<DefaultValue>true</DefaultValue>
|
||||
<Value>true</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
|
||||
<Name>Executable path</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value>${Path_Bin}/sdk-examples-communication-client-filter</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Arguments</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value></Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Port</Name>
|
||||
<DefaultValue>59595</DefaultValue>
|
||||
<Value>0</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Automatic connection identifier</Name>
|
||||
<DefaultValue>true</DefaultValue>
|
||||
<Value>true</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Custom connection identifier</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value></Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Incoming connection timeout</Name>
|
||||
<DefaultValue>10</DefaultValue>
|
||||
<Value>10</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Generator</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>176</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>528</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x6410533a, 0x11ff9fa8)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x61d11811, 0x71e65362)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>8</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf191c1c8, 0xa0123976)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x1b8eb320, 0x35920803)</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>512</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Generated epoch sample count</Name>
|
||||
<DefaultValue>32</DefaultValue>
|
||||
<Value>32</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>32</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>464</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>(0x2b2c676e, 0x1f9f8ed4)</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>96</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>464</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>(0x6a37098c, 0x4353fccf)</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>1.0</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>80</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>576</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>(0x6db580a4, 0x2710c742)</Identifier>
|
||||
<Name>Continuous Oscilloscope</Name>
|
||||
<AlgorithmClassIdentifier>(0x0842bcd1, 0xd53c1c89)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Matrix</Name>
|
||||
</Input>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Markers</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
|
||||
<Name>Channel Localisation</Name>
|
||||
<DefaultValue>${AdvancedViz_ChannelLocalisation}</DefaultValue>
|
||||
<Value>${AdvancedViz_ChannelLocalisation}</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x8f02e3f6, 0xffb00f4b)</TypeIdentifier>
|
||||
<Name>Temporal Coherence</Name>
|
||||
<DefaultValue>Time Locked</DefaultValue>
|
||||
<Value>Time Locked</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Time Scale</Name>
|
||||
<DefaultValue>20</DefaultValue>
|
||||
<Value>20</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Matrix Count</Name>
|
||||
<DefaultValue>50</DefaultValue>
|
||||
<Value>50</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Positive Data Only ?</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Gain</Name>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
<Value>1</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Caption</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value></Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Translucency</Name>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
<Value>1</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x7f45a2a9, 0x7db12219)</TypeIdentifier>
|
||||
<Name>Color</Name>
|
||||
<DefaultValue>${AdvancedViz_DefaultColor}</DefaultValue>
|
||||
<Value>${AdvancedViz_DefaultColor}</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>256</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>528</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x35390ab5, 0x7b926078)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>9</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
</Boxes>
|
||||
<Links>
|
||||
<Link>
|
||||
<Identifier>(0x47d63853, 0x410bf5fe)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x14bf05c0, 0x09128ae5)</BoxIdentifier>
|
||||
<BoxOutputIndex>1</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x6db580a4, 0x2710c742)</BoxIdentifier>
|
||||
<BoxInputIndex>1</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x4c81cafe, 0x0de678a1)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x1b8eb320, 0x35920803)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x2b2c676e, 0x1f9f8ed4)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x5135bc4a, 0x1edcc7ee)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x14bf05c0, 0x09128ae5)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x6db580a4, 0x2710c742)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x58190761, 0x23a1c7ca)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x2b2c676e, 0x1f9f8ed4)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x14bf05c0, 0x09128ae5)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x63ab5412, 0x051c9cde)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x6a37098c, 0x4353fccf)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x14bf05c0, 0x09128ae5)</BoxIdentifier>
|
||||
<BoxInputIndex>1</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
</Links>
|
||||
<Comments>
|
||||
<Comment>
|
||||
<Identifier>(0x09b97cf8, 0x27678b7b)</Identifier>
|
||||
<Text>Illustration of the usage of the <b>External Processing Box</b>.
|
||||
|
||||
This box launches an external program and connects to it via TCP/IP.
|
||||
|
||||
This particular example uses the example program given with the OpenViBE SDK,
|
||||
it will take any number of inputs and echo them on respective outputs.</Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>160</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>80</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
<Comment>
|
||||
<Identifier>(0x1fbd3f8e, 0x02fc93b2)</Identifier>
|
||||
<Text>Important options the box takes are:
|
||||
|
||||
<b>Launch Third Party Program</b> - OpenViBE will start the
|
||||
external program by itself if this setting is true.
|
||||
|
||||
<b>Executable Path</b> - Program to launch. The path can
|
||||
be an absolute path to a program, or a name of a program
|
||||
in system PATH.
|
||||
|
||||
<b>Arguments</b> - Arguments to pass to the external program.
|
||||
|
||||
<b>Port</b> - The port through which the program will communicate
|
||||
with openvibe. If the program is launched by OpenViBE this port will
|
||||
be automatically passed to it using argument <tt>--port &lt;port&gt;</tt>
|
||||
If the port is set to 0, an available one will be chosen automatically.
|
||||
|
||||
<b>Generator</b> - Should be set to true if the box does not need to
|
||||
process data synchronously. This usually means that it does not have
|
||||
any inputs.</Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>160</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>352</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
</Comments>
|
||||
<Metadata>
|
||||
<Entry>
|
||||
<Identifier>(0x205c8363, 0x19b5e92f)</Identifier>
|
||||
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
|
||||
<Data>[{"boxIdentifier":"(0x6db580a4, 0x2710c742)","childCount":0,"identifier":"(0x3e899070, 0x3969c924)","parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":1,"identifier":"(0x51e57212, 0x2ea425c0)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":1},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x1aaa3685, 0x1ce16371)","index":0,"name":"Default tab","parentIdentifier":"(0x51e57212, 0x2ea425c0)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x11475ce0, 0x64227efd)","index":0,"name":"Empty","parentIdentifier":"(0x1aaa3685, 0x1ce16371)","type":0}]</Data>
|
||||
</Entry>
|
||||
</Metadata>
|
||||
</OpenViBE-Scenario>
|
||||
+608
@@ -0,0 +1,608 @@
|
||||
<OpenViBE-Scenario>
|
||||
<FormatVersion>1</FormatVersion>
|
||||
<Creator>OpenVIBE</Creator>
|
||||
<CreatorVersion>0.4.99</CreatorVersion>
|
||||
<Settings></Settings>
|
||||
<Inputs></Inputs>
|
||||
<Outputs></Outputs>
|
||||
<Boxes>
|
||||
<Box>
|
||||
<Identifier>(0x14bf05c0, 0x09128ae5)</Identifier>
|
||||
<Name>External Processing</Name>
|
||||
<AlgorithmClassIdentifier>(0x15422959, 0x16304449)</AlgorithmClassIdentifier>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>New output</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Launch third party program</Name>
|
||||
<DefaultValue>true</DefaultValue>
|
||||
<Value>true</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
|
||||
<Name>Executable path</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value>${Path_Bin}/sdk-examples-communication-client-generator</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Arguments</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value></Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Port</Name>
|
||||
<DefaultValue>59595</DefaultValue>
|
||||
<Value>0</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Automatic connection identifier</Name>
|
||||
<DefaultValue>true</DefaultValue>
|
||||
<Value>true</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Custom connection identifier</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value></Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Incoming connection timeout</Name>
|
||||
<DefaultValue>10</DefaultValue>
|
||||
<Value>10</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Generator</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>true</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Channel Count</Name>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
<Value>4</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Sampling Rate</Name>
|
||||
<DefaultValue>128</DefaultValue>
|
||||
<Value>128</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Samples Per Buffer</Name>
|
||||
<DefaultValue>16</DefaultValue>
|
||||
<Value>16</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Amount of Samples to Generate</Name>
|
||||
<DefaultValue>512</DefaultValue>
|
||||
<Value>512</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>160</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>512</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x6410533a, 0x11ff9fa8)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x61d11811, 0x71e65362)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>8</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf191c1c8, 0xa0123976)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x14bf05c0, 0x09128ae6)</Identifier>
|
||||
<Name>External Processing</Name>
|
||||
<AlgorithmClassIdentifier>(0x15422959, 0x16304449)</AlgorithmClassIdentifier>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>New output</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Launch third party program</Name>
|
||||
<DefaultValue>true</DefaultValue>
|
||||
<Value>true</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
|
||||
<Name>Executable path</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value>${Path_Bin}/sdk-examples-communication-client-generator</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Arguments</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value></Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Port</Name>
|
||||
<DefaultValue>59595</DefaultValue>
|
||||
<Value>0</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Automatic connection identifier</Name>
|
||||
<DefaultValue>true</DefaultValue>
|
||||
<Value>true</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Custom connection identifier</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value></Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Incoming connection timeout</Name>
|
||||
<DefaultValue>10</DefaultValue>
|
||||
<Value>10</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Generator</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>true</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Channel Count</Name>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
<Value>5</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Sampling Rate</Name>
|
||||
<DefaultValue>128</DefaultValue>
|
||||
<Value>128</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Samples Per Buffer</Name>
|
||||
<DefaultValue>16</DefaultValue>
|
||||
<Value>16</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Amount of Samples to Generate</Name>
|
||||
<DefaultValue>512</DefaultValue>
|
||||
<Value>512</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>160</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>720</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x6410533a, 0x11ff9fa8)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x61d11811, 0x71e65362)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>8</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xf191c1c8, 0xa0123976)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x6db580a4, 0x2710c742)</Identifier>
|
||||
<Name>4 Channels</Name>
|
||||
<AlgorithmClassIdentifier>(0x0842bcd1, 0xd53c1c89)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Matrix</Name>
|
||||
</Input>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Markers</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
|
||||
<Name>Channel Localisation</Name>
|
||||
<DefaultValue>${AdvancedViz_ChannelLocalisation}</DefaultValue>
|
||||
<Value>${AdvancedViz_ChannelLocalisation}</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x8f02e3f6, 0xffb00f4b)</TypeIdentifier>
|
||||
<Name>Temporal Coherence</Name>
|
||||
<DefaultValue>Time Locked</DefaultValue>
|
||||
<Value>Time Locked</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Time Scale</Name>
|
||||
<DefaultValue>20</DefaultValue>
|
||||
<Value>20</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Matrix Count</Name>
|
||||
<DefaultValue>50</DefaultValue>
|
||||
<Value>50</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Positive Data Only ?</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Gain</Name>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
<Value>1</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Caption</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value></Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Translucency</Name>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
<Value>1</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x7f45a2a9, 0x7db12219)</TypeIdentifier>
|
||||
<Name>Color</Name>
|
||||
<DefaultValue>${AdvancedViz_DefaultColor}</DefaultValue>
|
||||
<Value>${AdvancedViz_DefaultColor}</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>240</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>512</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x35390ab5, 0x7b926078)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>9</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x6db580a4, 0x2710c743)</Identifier>
|
||||
<Name>5 Channels</Name>
|
||||
<AlgorithmClassIdentifier>(0x0842bcd1, 0xd53c1c89)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
|
||||
<Name>Matrix</Name>
|
||||
</Input>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Markers</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
|
||||
<Name>Channel Localisation</Name>
|
||||
<DefaultValue>${AdvancedViz_ChannelLocalisation}</DefaultValue>
|
||||
<Value>${AdvancedViz_ChannelLocalisation}</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x8f02e3f6, 0xffb00f4b)</TypeIdentifier>
|
||||
<Name>Temporal Coherence</Name>
|
||||
<DefaultValue>Time Locked</DefaultValue>
|
||||
<Value>Time Locked</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Time Scale</Name>
|
||||
<DefaultValue>20</DefaultValue>
|
||||
<Value>20</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Matrix Count</Name>
|
||||
<DefaultValue>50</DefaultValue>
|
||||
<Value>50</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Positive Data Only ?</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Gain</Name>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
<Value>1</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Caption</Name>
|
||||
<DefaultValue></DefaultValue>
|
||||
<Value></Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
|
||||
<Name>Translucency</Name>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
<Value>1</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x7f45a2a9, 0x7db12219)</TypeIdentifier>
|
||||
<Name>Color</Name>
|
||||
<DefaultValue>${AdvancedViz_DefaultColor}</DefaultValue>
|
||||
<Value>${AdvancedViz_DefaultColor}</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>240</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>720</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x35390ab5, 0x7b926078)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>9</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
</Boxes>
|
||||
<Links>
|
||||
<Link>
|
||||
<Identifier>(0x5135bc4a, 0x1edcc7ee)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x14bf05c0, 0x09128ae5)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x6db580a4, 0x2710c742)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x5135bc4a, 0x1edcc7ef)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x14bf05c0, 0x09128ae6)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x6db580a4, 0x2710c743)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
</Links>
|
||||
<Comments>
|
||||
<Comment>
|
||||
<Identifier>(0x020f409a, 0x2e82d6c9)</Identifier>
|
||||
<Text>The generator example program can take the following settings:
|
||||
|
||||
|
||||
<b>Channel Count</b>
|
||||
<b>Sampling Rate</b>
|
||||
<b>Samples Per Buffer</b>
|
||||
<b>Samples To Generate</b> - The program will stop after this many samples
|
||||
</Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>640</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>400</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
<Comment>
|
||||
<Identifier>(0x09b97cf8, 0x27678b7b)</Identifier>
|
||||
<Text>Illustration of the usage of the <b>External Processing Box</b>.
|
||||
|
||||
This box launches an external program and connects to it via TCP/IP.
|
||||
|
||||
This particular example uses the <b>generator</b> example program given with the OpenViBE SDK.
|
||||
|
||||
It will generate several sinus signals with a custom sampling rate and epoching.
|
||||
|
||||
Optionally it can stop generating samples after a period of time.</Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>144</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>80</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
<Comment>
|
||||
<Identifier>(0x1fbd3f8e, 0x02fc93b2)</Identifier>
|
||||
<Text>Important options the box takes are:
|
||||
|
||||
<b>Launch Third Party Program</b> - OpenViBE will start the
|
||||
external program by itself if this setting is true.
|
||||
|
||||
<b>Executable Path</b> - Program to launch. The path can
|
||||
be an absolute path to a program, or a name of a program
|
||||
in system PATH.
|
||||
|
||||
<b>Arguments</b> - Arguments to pass to the external program.
|
||||
|
||||
<b>Port</b> - The port through which the program will communicate
|
||||
with openvibe. If the program is launched by OpenViBE this port will
|
||||
be automatically passed to it using argument <tt>--port &lt;port&gt;</tt>
|
||||
If the port is set to 0, an available one will be chosen automatically.
|
||||
|
||||
<b>Generator</b> - Should be set to true if the box does not need to
|
||||
process data synchronously. This usually means that it does not have
|
||||
any inputs. In this scenario this is the case!</Text>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
|
||||
<Value>192</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
|
||||
<Value>368</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Comment>
|
||||
</Comments>
|
||||
<Metadata>
|
||||
<Entry>
|
||||
<Identifier>(0x205c8363, 0x19b5e92f)</Identifier>
|
||||
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
|
||||
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":490,"identifier":"(0x51e57212, 0x2ea425c0)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":791},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x1aaa3685, 0x1ce16371)","index":0,"name":"Default tab","parentIdentifier":"(0x51e57212, 0x2ea425c0)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":2,"dividerPosition":383,"identifier":"(0x3def082e, 0x180223c7)","index":0,"maxDividerPosition":771,"name":"Horizontal split","parentIdentifier":"(0x1aaa3685, 0x1ce16371)","type":5},{"boxIdentifier":"(0x6db580a4, 0x2710c742)","childCount":0,"identifier":"(0x3e899070, 0x3969c924)","index":0,"parentIdentifier":"(0x3def082e, 0x180223c7)","type":3},{"boxIdentifier":"(0x6db580a4, 0x2710c743)","childCount":0,"identifier":"(0x4de25e08, 0x488b872b)","index":1,"parentIdentifier":"(0x3def082e, 0x180223c7)","type":3}]</Data>
|
||||
</Entry>
|
||||
</Metadata>
|
||||
</OpenViBE-Scenario>
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
* \page BoxAlgorithm_EBMLStreamSpy EBML stream spy
|
||||
__________________________________________________________________
|
||||
|
||||
Detailed description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_EBMLStreamSpy_Description|
|
||||
* The purpose of this box is to spy an EBML stream and decode
|
||||
* its structure to the log manager. In order to do so, the box
|
||||
* has to know a list of expected EBML node identifiers and EBML
|
||||
* node types. If you don't know what EBML is, you should check
|
||||
* the \ref Doc_WhatIsEBML page. The list of expected node
|
||||
* identifiers and types is collected from a configuration file.
|
||||
* Also, the author is able to chose which log level to use
|
||||
* in order to output the information.
|
||||
*
|
||||
* Such box is mostly usefull for debug purpose. It allows
|
||||
* a developper to check what arrives to a box in a human
|
||||
* readable way.
|
||||
* |OVP_DocEnd_BoxAlgorithm_EBMLStreamSpy_Description|
|
||||
__________________________________________________________________
|
||||
|
||||
Inputs description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_EBMLStreamSpy_Inputs|
|
||||
* This box can receive as many input as necessary. All the inputs
|
||||
* will be of type \ref Doc_Streams_EBMLStream in order to
|
||||
* be parsed by this the reader.
|
||||
* |OVP_DocEnd_BoxAlgorithm_EBMLStreamSpy_Inputs|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_EBMLStreamSpy_Input1|
|
||||
* This is the default input of this box.
|
||||
* |OVP_DocEnd_BoxAlgorithm_EBMLStreamSpy_Input1|
|
||||
__________________________________________________________________
|
||||
|
||||
Settings description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_EBMLStreamSpy_Settings|
|
||||
* |OVP_DocEnd_BoxAlgorithm_EBMLStreamSpy_Settings|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_EBMLStreamSpy_Setting1|
|
||||
* This first setting indicates where to find the configuration file.
|
||||
* The box comes with a default configuration file containing all the
|
||||
* default node identifiers of BRAND_NAME. You should extend this
|
||||
* configuration in order to add your own EBML nodes in case you
|
||||
* have created new EBML stream types.
|
||||
* |OVP_DocEnd_BoxAlgorithm_EBMLStreamSpy_Setting1|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_EBMLStreamSpy_Setting2|
|
||||
* This second settings indicates what log level will be used to
|
||||
* print the EBML stream structure.
|
||||
* |OVP_DocEnd_BoxAlgorithm_EBMLStreamSpy_Setting2|
|
||||
__________________________________________________________________
|
||||
|
||||
Examples description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_EBMLStreamSpy_Examples|
|
||||
* As an example, we could connect an EBML stream spy to a sinus
|
||||
* oscillator. Leave the default sinus oscillator settings to their
|
||||
* default, except the sample count per buffer can be set to 8 for the
|
||||
* example. Chose an appropriate log level for the EBML stream spy and
|
||||
* press 'start'. You will probably notice that a lot of text is sent
|
||||
* to the log manager, making the use of this box difficult in real time.
|
||||
* Once again, consider it as a debugging box.
|
||||
*
|
||||
* The output should look like this :
|
||||
\verbatim
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy> For input Spied EBML stream 1 of type EBML stream :
|
||||
[ INF ] <Box algorithm::EBML stream spy> For chunk [id:0 (0x0)] at [time:(0x00000000, 0x00000000),(0x00000000, 0x00000000)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x002b395f, 0x108adfae)]-[name:OVTK_NodeId_Header]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00cdd0f7, 0x46b0278d)]-[name:OVTK_NodeId_Header_StreamType]-[type:uinteger]-[value:0 (0x0)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x006f5a08, 0x7796ebc5)]-[name:OVTK_NodeId_Header_StreamVersion]-[type:uinteger]-[value:0 (0x0)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x007855de, 0x3748d375)]-[name:OVTK_NodeId_Header_Signal]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00141c43, 0x0c37006b)]-[name:OVTK_NodeId_Header_Signal_Sampling]-[type:uinteger]-[value:512 (0x200)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x0072f560, 0x7ed2cbed)]-[name:OVTK_NodeId_Header_StreamedMatrix]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x003febd4, 0x2725d428)]-[name:OVTK_NodeId_Header_StreamedMatrix_DimensionCount]-[type:uinteger]-[value:2 (0x2)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x0000e3c0, 0x3a7d5141)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x001302f7, 0x36d8438a)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Size]-[type:uinteger]-[value:4 (0x4)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:Channel 0]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:Channel 1]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:Channel 2]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:Channel 3]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x0000e3c0, 0x3a7d5141)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x001302f7, 0x36d8438a)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Size]-[type:uinteger]-[value:8 (0x8)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy> For input Spied EBML stream 1 of type EBML stream :
|
||||
[ INF ] <Box algorithm::EBML stream spy> For chunk [id:0 (0x0)] at [time:(0x00000000, 0x00000000),(0x00000000, 0x04000000)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00cf2101, 0x02375310)]-[name:OVTK_NodeId_Buffer]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00120663, 0x08fbc165)]-[name:OVTK_NodeId_Buffer_StreamedMatrix]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00b18c10, 0x427d098c)]-[name:OVTK_NodeId_Buffer_StreamedMatrix_RawBuffer]-[type:binary]-[bytes:256 (0x100)]
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy> For input Spied EBML stream 1 of type EBML stream :
|
||||
[ INF ] <Box algorithm::EBML stream spy> For chunk [id:0 (0x0)] at [time:(0x00000000, 0x04000000),(0x00000000, 0x08000000)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00cf2101, 0x02375310)]-[name:OVTK_NodeId_Buffer]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00120663, 0x08fbc165)]-[name:OVTK_NodeId_Buffer_StreamedMatrix]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00b18c10, 0x427d098c)]-[name:OVTK_NodeId_Buffer_StreamedMatrix_RawBuffer]-[type:binary]-[bytes:256 (0x100)]
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy> For input Spied EBML stream 1 of type EBML stream :
|
||||
[ INF ] <Box algorithm::EBML stream spy> For chunk [id:0 (0x0)] at [time:(0x00000000, 0x08000000),(0x00000000, 0x0c000000)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00cf2101, 0x02375310)]-[name:OVTK_NodeId_Buffer]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00120663, 0x08fbc165)]-[name:OVTK_NodeId_Buffer_StreamedMatrix]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00b18c10, 0x427d098c)]-[name:OVTK_NodeId_Buffer_StreamedMatrix_RawBuffer]-[type:binary]-[bytes:256 (0x100)]
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
...
|
||||
\endverbatim
|
||||
*
|
||||
* Now let's try to understand what is produced. First we notice a clear
|
||||
* separation between the different chunk the box receives. In each chunk, we
|
||||
* have an EBML hierarchy with the different nodes. Here we analyse a signal
|
||||
* stream so we have a header followed by multiple buffers.
|
||||
*
|
||||
* Concerning the header, we can focuse on the signal header part and
|
||||
* the streamed matrix header part. In the first one, we can see that the sampling
|
||||
* rate node appears as an integer with value 512 (the default sinus oscillator
|
||||
* sampling frequency). The second one contains the description of the streamed
|
||||
* matrix. The matrix has two dimensions (electrodes and sample count per buffer).
|
||||
* The first dimension has a size of 4 (the default sinus oscillator channel count)
|
||||
* and each of this channel has a label (channel 0-3). Finally, the second dimension
|
||||
* has a size of 8 (the sample count per buffer you manually put in the sinus
|
||||
* oscillator configuration) and the samples themselves do not have a name.
|
||||
*
|
||||
* Now looking at the buffer, we only have the streamed matrix part (signal
|
||||
* stream do not produce signal specific buffer). The buffer content can not
|
||||
* be displayed in the console (it could be a huge amount of binary non human
|
||||
* readable data, so it is not relevant to print it). But you have an information
|
||||
* of the size of this buffer. 256 is exactly the number of channels (4) multiplied
|
||||
* by the number of samples per buffer (8) multiplied by the size of a single sample
|
||||
* (8 because a sample is coded on a 64 bits float).
|
||||
*
|
||||
* When familiar with EBML and OpenViBE streams, this box is a strong tool
|
||||
* to analyze what is sent from a box to another.
|
||||
* |OVP_DocEnd_BoxAlgorithm_EBMLStreamSpy_Examples|
|
||||
__________________________________________________________________
|
||||
|
||||
Miscellaneous description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_EBMLStreamSpy_Miscellaneous|
|
||||
* The syntax of the configuration file is simple. Each line of the file
|
||||
* should contain 3 fields. The first field is the name of the EBML node
|
||||
* that should be printed in the log manager (this is human readable).
|
||||
* The second field is the EBML node identifier. The last field is the node
|
||||
* type. Several types are supported :
|
||||
* - \e master : this means that this node does not have data attached but has
|
||||
* several children. Any non master node is a leaf, so can contain data.
|
||||
* - \e integer : this means that this node contains a signed integer value
|
||||
* - \e uinteger : this means that this node contains an unsigned integer value
|
||||
* - \e string : this means that this node contains an ASCII string value
|
||||
* - \e float : this means that this node contains a floating point value
|
||||
* - \e binary : this means that this node contains a raw buffer of elements.
|
||||
* In such case, only the size of the buffer is printed. The content of the
|
||||
* buffer is not printed.
|
||||
*
|
||||
* Any node identifier found in the stream and not present in the configuration
|
||||
* file will be considered of type \e unknown and treated as if it was a \e binary
|
||||
* node.
|
||||
*
|
||||
* Following is a part of the sample configuration file to illustrate the syntax :
|
||||
\verbatim
|
||||
...
|
||||
|
||||
OVTK_NodeId_Header_StreamedMatrix EBML::CIdentifier(0x0072F560, 0x7ED2CBED) master
|
||||
OVTK_NodeId_Header_StreamedMatrix_DimensionCount EBML::CIdentifier(0x003FEBD4, 0x2725D428) uinteger
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension EBML::CIdentifier(0x0000E3C0, 0x3A7D5141) master
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension_Size EBML::CIdentifier(0x001302F7, 0x36D8438A) uinteger
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension_Label EBML::CIdentifier(0x00153E40, 0x190227E0) string
|
||||
OVTK_NodeId_Buffer_StreamedMatrix EBML::CIdentifier(0x00120663, 0x08FBC165) master
|
||||
OVTK_NodeId_Buffer_StreamedMatrix_RawBuffer EBML::CIdentifier(0x00B18C10, 0x427D098C) binary
|
||||
|
||||
OVTK_NodeId_Header_Signal EBML::CIdentifier(0x007855DE, 0x3748D375) master
|
||||
OVTK_NodeId_Header_Signal_Sampling EBML::CIdentifier(0x00141C43, 0x0C37006B) uinteger
|
||||
|
||||
...
|
||||
\endverbatim
|
||||
* |OVP_DocEnd_BoxAlgorithm_EBMLStreamSpy_Miscellaneous|
|
||||
*/
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* \page BoxAlgorithm_ExternalProcessing External Processing
|
||||
__________________________________________________________________
|
||||
|
||||
Detailed description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_ExternalProcessing_Description|
|
||||
This box allows to externalize data processing into an external program. It sends EBML data in chunks
|
||||
according to a specified protocol, the external application must respond with an EBML response following
|
||||
this same protocol.
|
||||
|
||||
A SDK for C++ and Python 3 (Python NeuroRT Box) are provided in order to simplify the development of
|
||||
external boxes.
|
||||
|
||||
This box can work in two modes, either it launches the external program itself, or it will wait for client
|
||||
connections during the initialize step.
|
||||
|
||||
* |OVP_DocEnd_BoxAlgorithm_ExternalProcessing_Description|
|
||||
|
||||
__________________________________________________________________
|
||||
|
||||
Settings description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_ExternalProcessing_Settings|
|
||||
|
||||
The External Processing box has several settings. The first eight parameters are reserved for the
|
||||
box. Any additional parameters will be passed to the external program.
|
||||
|
||||
* |OVP_DocEnd_BoxAlgorithm_ExternalProcessing_Settings|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_ExternalProcessing_Setting1|
|
||||
If true, the box will attempt to start the external program automatically. If this setting is false, then the box will stop
|
||||
during the initialize step and wait for the external program to connect during the time speficied by the Connection Timeout setting.
|
||||
* |OVP_DocEnd_BoxAlgorithm_ExternalProcessing_Setting1|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_ExternalProcessing_Setting2|
|
||||
Path to the executable to run. This parameter is only used if the first parameter is activated.
|
||||
|
||||
Example: OpenViBE SDK comes with two example programs, one can be found in ${Path_Bin}/sdk-examples-communication-client-filter
|
||||
Example: In the case you want to run a Python script on Windows, the program you are running is python, e.g: C:/Python35/python.exe
|
||||
* |OVP_DocEnd_BoxAlgorithm_ExternalProcessing_Setting2|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_ExternalProcessing_Setting3|
|
||||
Arguments passed to the third party program, if any are necessary. This parameter is only used if the first parameter is activated.
|
||||
|
||||
This parameter will be given to the third party program as is, thus it is necessary to quote any arguments that contain spaces.
|
||||
|
||||
Example: In the case you want to run a Python script on Windows, the parameter is the absolute path to the script that you want to run, e.g.: "C:/MyProject/myprogram.py" or "-m mylibrary.mymodule.mybox".
|
||||
|
||||
* |OVP_DocEnd_BoxAlgorithm_ExternalProcessing_Setting3|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_ExternalProcessing_Setting4|
|
||||
The TCP port that the box is listening. It must be in the range 49152-65535 or it can be 0, in which case the port will be chosen
|
||||
automatically.
|
||||
|
||||
The box acts as a Socket server and the external program as a client. If you have several External Processing boxes in the same scenario
|
||||
each has to work on a different port.
|
||||
|
||||
An argument, with the value of the port, will be given to the third party program (after the Arguments parameter ) as: --port PORT
|
||||
|
||||
This means that your external program must accept the --port parameter and use it to connect to this box.
|
||||
* |OVP_DocEnd_BoxAlgorithm_ExternalProcessing_Setting4|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_ExternalProcessing_Setting5|
|
||||
Whether or not to generate of a connection identifier for the connection. See the next setting for explanation.
|
||||
* |OVP_DocEnd_BoxAlgorithm_ExternalProcessing_Setting5|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_ExternalProcessing_Setting6|
|
||||
This argument will be passed to the external program as a command line parameter: `--connection-id CONNECTIONID` and will be communicated to your
|
||||
program through the protocol as well. You should check that the two are matching in order to avoid a clash if two boxes would be using the same
|
||||
port.
|
||||
|
||||
We advise you to use an automatic identifier generation in production. Choose your custom connection identifier is however necessary when running
|
||||
the external program explicitly.
|
||||
* |OVP_DocEnd_BoxAlgorithm_ExternalProcessing_Setting6|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_ExternalProcessing_Setting7|
|
||||
A timeout, in seconds, for the incoming connection acceptance.
|
||||
* |OVP_DocEnd_BoxAlgorithm_ExternalProcessing_Setting7|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_ExternalProcessing_Setting8|
|
||||
This setting changes how often the box will process data. Each data processing requires that the box will
|
||||
wait until it has received a response from the external program. Too many of these synchronisations can
|
||||
induce a severe performance penalty.
|
||||
|
||||
If the box is a generator, then it will wait for the external program on each step. If the scenario is
|
||||
played in real-time, then the box will poll the external program at 16Hz. If the scenario is in fast-forward
|
||||
the refresh frequency of this box is 1Hz.
|
||||
|
||||
If this setting is set to false, the box will send all data it receives into the external program and wait
|
||||
until it processes it and sends it back.
|
||||
* |OVP_DocEnd_BoxAlgorithm_ExternalProcessing_Setting8|
|
||||
__________________________________________________________________
|
||||
|
||||
Miscellaneous description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_ExternalProcessing_Miscellaneous|
|
||||
This box requires synchronization with the external program in order to process data correctly and in order.
|
||||
As the synchronization is a relatively slow process with regards to the duration of one update cycle (62ms) it
|
||||
is better to try to limit the number of chunks that are send between the box and the client application.
|
||||
|
||||
If you find that your scenario is too slow, try using time based epoching in front of it to make chunks of data
|
||||
larger.
|
||||
* |OVP_DocEnd_BoxAlgorithm_ExternalProcessing_Miscellaneous|
|
||||
|
||||
*/
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* \page BoxAlgorithm_MatrixValidityChecker Matrix validity checker
|
||||
__________________________________________________________________
|
||||
|
||||
Detailed description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MatrixValidityChecker_Description|
|
||||
Ensures values stored in a matrix are valid, i.e. regular floating point values as opposed to NaN (not a number) or infinite.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MatrixValidityChecker_Description|
|
||||
__________________________________________________________________
|
||||
|
||||
Inputs description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MatrixValidityChecker_Inputs|
|
||||
* |OVP_DocEnd_BoxAlgorithm_MatrixValidityChecker_Inputs|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MatrixValidityChecker_Input1|
|
||||
* |OVP_DocEnd_BoxAlgorithm_MatrixValidityChecker_Input1|
|
||||
__________________________________________________________________
|
||||
|
||||
Settings description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MatrixValidityChecker_Settings|
|
||||
* |OVP_DocEnd_BoxAlgorithm_MatrixValidityChecker_Settings|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MatrixValidityChecker_Setting1|
|
||||
Log level of messages to be printed whenever Nan or infinite values are found in input matrix.
|
||||
* |OVP_DocEnd_BoxAlgorithm_MatrixValidityChecker_Setting1|
|
||||
__________________________________________________________________
|
||||
|
||||
Examples description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MatrixValidityChecker_Examples|
|
||||
* |OVP_DocEnd_BoxAlgorithm_MatrixValidityChecker_Examples|
|
||||
|
||||
__________________________________________________________________
|
||||
|
||||
Miscellaneous description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_MatrixValidityChecker_Miscellaneous|
|
||||
* |OVP_DocEnd_BoxAlgorithm_MatrixValidityChecker_Miscellaneous|
|
||||
*/
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* \page BoxAlgorithm_StimulationListener Stimulation listener
|
||||
__________________________________________________________________
|
||||
|
||||
Detailed description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_StimulationListener_Description|
|
||||
* The stimulation listener is a debugging purpose box, with
|
||||
* the same idea as the \ref Doc_BoxAlgorithm_EBMLStreamSpy box
|
||||
* but dedicated to stimulation streams. The idea is to dramatically
|
||||
* reduce the log verbosity so the output may be followed realtime
|
||||
* if necessary.
|
||||
* |OVP_DocEnd_BoxAlgorithm_StimulationListener_Description|
|
||||
__________________________________________________________________
|
||||
|
||||
Inputs description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_StimulationListener_Inputs|
|
||||
* This box can receive as many input as necessary. All the inputs
|
||||
* will be of type \ref Doc_Streams_Stimulation in order to
|
||||
* be parsed by this the reader.
|
||||
* |OVP_DocEnd_BoxAlgorithm_StimulationListener_Inputs|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_StimulationListener_Input1|
|
||||
* This is the default input of this box.
|
||||
* |OVP_DocEnd_BoxAlgorithm_StimulationListener_Input1|
|
||||
__________________________________________________________________
|
||||
|
||||
Settings description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_StimulationListener_Settings|
|
||||
* |OVP_DocEnd_BoxAlgorithm_StimulationListener_Settings|
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_StimulationListener_Setting1|
|
||||
* This setting indicates what log level will be used to
|
||||
* print the the received stimulations.
|
||||
* |OVP_DocEnd_BoxAlgorithm_StimulationListener_Setting1|
|
||||
__________________________________________________________________
|
||||
|
||||
Examples description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_StimulationListener_Examples|
|
||||
* As an example, we could connect a clock stimulator to a
|
||||
* stimulation listener. Leave the default settings of the
|
||||
* clock stimulator, so it sends an \e OVTK_StimulationId_Label_00
|
||||
* stimulation every second. Now chose an appropriate log level
|
||||
* for the stimulation listener and press 'start'. If you're
|
||||
* familiar to what \ref Doc_BoxAlgorithm_EBMLStreamSpy produces,
|
||||
* you may feel more confortable with what is produced here for
|
||||
* stimulations.
|
||||
*
|
||||
* The output should look like this :
|
||||
\verbatim
|
||||
...
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 4294967296 (0x100000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 8589934592 (0x200000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 12884901888 (0x300000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 17179869184 (0x400000000) and duration 0 (0x0)
|
||||
...
|
||||
\endverbatim
|
||||
*
|
||||
* Now let's try to understand what is produced. Each line represents
|
||||
* received stimulation. The input index which received the stimulation
|
||||
* is printed. Then follow the stimulation code, its date and its duration.
|
||||
* The stimulation name is retrieved from the type manager when correctly
|
||||
* registered. Here, you can see that an \e OVTK_StimulationId_Label_00 is
|
||||
* received every second.
|
||||
*
|
||||
* More tests could be done with another clock stimulator with different
|
||||
* timings and stimulation codes. You will want to add inputs to the stimulation
|
||||
* listener box in order to get proper results. For example with one more box
|
||||
* sending \e OVTK_StimulationId_Label_01 every half second, the output would
|
||||
* look like this :
|
||||
\verbatim
|
||||
...
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 2147483648 (0x80000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 4294967296 (0x100000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 4294967296 (0x100000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 6442450944 (0x180000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 8589934592 (0x200000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 8589934592 (0x200000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 10737418240 (0x280000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 12884901888 (0x300000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 12884901888 (0x300000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 15032385536 (0x380000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 17179869184 (0x400000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 17179869184 (0x400000000) and duration 0 (0x0)
|
||||
...
|
||||
\endverbatim
|
||||
* |OVP_DocEnd_BoxAlgorithm_StimulationListener_Examples|
|
||||
|
||||
__________________________________________________________________
|
||||
|
||||
Miscellaneous description
|
||||
__________________________________________________________________
|
||||
|
||||
* |OVP_DocBegin_BoxAlgorithm_StimulationListener_Miscellaneous|
|
||||
* |OVP_DocEnd_BoxAlgorithm_StimulationListener_Miscellaneous|
|
||||
*/
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
.. _Doc_BoxAlgorithm_EBMLStreamSpy:
|
||||
|
||||
EBML stream spy
|
||||
===============
|
||||
|
||||
.. container:: attribution
|
||||
|
||||
:Author:
|
||||
Yann Renard
|
||||
:Company:
|
||||
INRIA/IRISA
|
||||
|
||||
.. image:: images/Doc_BoxAlgorithm_EBMLStreamSpy.png
|
||||
|
||||
This sample EBML stream analyzer prints the EBML tree structure to the console
|
||||
|
||||
The purpose of this box is to spy an EBML stream and decode its structure to
|
||||
the log manager. In order to do so, the box has to know a list of expected EBML
|
||||
node identifiers and EBML node types. If you don't know what EBML is, you
|
||||
should check the `EBML Documentation
|
||||
<https://github.com/Matroska-Org/ebml-specification>`_ page. The list of
|
||||
expected node identifiers and types is collected from a configuration file.
|
||||
Also, the author is able to chose which log level to use in order to output the
|
||||
information.
|
||||
|
||||
Such box is mostly useful for debug purpose. It allows
|
||||
a developper to check what arrives to a box in a human
|
||||
readable way.
|
||||
|
||||
Inputs
|
||||
------
|
||||
|
||||
.. csv-table::
|
||||
:header: "Input Name", "Stream Type"
|
||||
|
||||
"Spied EBML stream 1", "EBML stream"
|
||||
|
||||
This box can receive as many input as necessary. All the inputs
|
||||
will be of type :ref:`Doc_Streams_EBML` in order to
|
||||
be parsed by this the reader.
|
||||
|
||||
Spied EBML stream 1
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is the default input of this box.
|
||||
|
||||
.. _Doc_BoxAlgorithm_EBMLStreamSpy_Settings:
|
||||
|
||||
Settings
|
||||
--------
|
||||
|
||||
.. csv-table::
|
||||
:header: "Setting Name", "Type", "Default Value"
|
||||
|
||||
"EBML nodes description", "Filename", "${Path_Data}/plugins/tools/config-ebml-stream-spy.txt"
|
||||
"Log level to use", "Log level", "Information"
|
||||
"Expand binary blocks", "Boolean", "false"
|
||||
"Number of values in expanded blocks", "Integer", "4"
|
||||
|
||||
EBML nodes description
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This first setting indicates where to find the configuration file.
|
||||
The box comes with a default configuration file containing all the
|
||||
default node identifiers of NeuroRT. You should extend this
|
||||
configuration in order to add your own EBML nodes in case you
|
||||
have created new EBML stream types.
|
||||
|
||||
Log level to use
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
This second settings indicates what log level will be used to
|
||||
print the EBML stream structure.
|
||||
|
||||
.. _Doc_BoxAlgorithm_EBMLStreamSpy_Examples:
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
As an example, we could connect an EBML stream spy to a sinus
|
||||
oscillator. Leave the default sinus oscillator settings to their
|
||||
default, except the sample count per buffer can be set to 8 for the
|
||||
example. Chose an appropriate log level for the EBML stream spy and
|
||||
press 'start'. You will probably notice that a lot of text is sent
|
||||
to the log manager, making the use of this box difficult in real time.
|
||||
Once again, consider it as a debugging box.
|
||||
|
||||
The output should look like this :
|
||||
|
||||
.. code::
|
||||
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy> For input Spied EBML stream 1 of type EBML stream :
|
||||
[ INF ] <Box algorithm::EBML stream spy> For chunk [id:0 (0x0)] at [time:(0x00000000, 0x00000000),(0x00000000, 0x00000000)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x002b395f, 0x108adfae)]-[name:OVTK_NodeId_Header]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00cdd0f7, 0x46b0278d)]-[name:OVTK_NodeId_Header_StreamType]-[type:uinteger]-[value:0 (0x0)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x006f5a08, 0x7796ebc5)]-[name:OVTK_NodeId_Header_StreamVersion]-[type:uinteger]-[value:0 (0x0)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x007855de, 0x3748d375)]-[name:OVTK_NodeId_Header_Signal]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00141c43, 0x0c37006b)]-[name:OVTK_NodeId_Header_Signal_Sampling]-[type:uinteger]-[value:512 (0x200)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x0072f560, 0x7ed2cbed)]-[name:OVTK_NodeId_Header_StreamedMatrix]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x003febd4, 0x2725d428)]-[name:OVTK_NodeId_Header_StreamedMatrix_DimensionCount]-[type:uinteger]-[value:2 (0x2)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x0000e3c0, 0x3a7d5141)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x001302f7, 0x36d8438a)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Size]-[type:uinteger]-[value:4 (0x4)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:Channel 0]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:Channel 1]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:Channel 2]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:Channel 3]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x0000e3c0, 0x3a7d5141)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x001302f7, 0x36d8438a)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Size]-[type:uinteger]-[value:8 (0x8)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00153e40, 0x190227e0)]-[name:OVTK_NodeId_Header_StreamedMatrix_Dimension_Label]-[type:string]-[value:]
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy> For input Spied EBML stream 1 of type EBML stream :
|
||||
[ INF ] <Box algorithm::EBML stream spy> For chunk [id:0 (0x0)] at [time:(0x00000000, 0x00000000),(0x00000000, 0x04000000)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00cf2101, 0x02375310)]-[name:OVTK_NodeId_Buffer]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00120663, 0x08fbc165)]-[name:OVTK_NodeId_Buffer_StreamedMatrix]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00b18c10, 0x427d098c)]-[name:OVTK_NodeId_Buffer_StreamedMatrix_RawBuffer]-[type:binary]-[bytes:256 (0x100)]
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy> For input Spied EBML stream 1 of type EBML stream :
|
||||
[ INF ] <Box algorithm::EBML stream spy> For chunk [id:0 (0x0)] at [time:(0x00000000, 0x04000000),(0x00000000, 0x08000000)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00cf2101, 0x02375310)]-[name:OVTK_NodeId_Buffer]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00120663, 0x08fbc165)]-[name:OVTK_NodeId_Buffer_StreamedMatrix]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00b18c10, 0x427d098c)]-[name:OVTK_NodeId_Buffer_StreamedMatrix_RawBuffer]-[type:binary]-[bytes:256 (0x100)]
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
[ INF ] <Box algorithm::EBML stream spy> For input Spied EBML stream 1 of type EBML stream :
|
||||
[ INF ] <Box algorithm::EBML stream spy> For chunk [id:0 (0x0)] at [time:(0x00000000, 0x08000000),(0x00000000, 0x0c000000)]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00cf2101, 0x02375310)]-[name:OVTK_NodeId_Buffer]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00120663, 0x08fbc165)]-[name:OVTK_NodeId_Buffer_StreamedMatrix]
|
||||
[ INF ] <Box algorithm::EBML stream spy> Opened EBML node [id:(0x00b18c10, 0x427d098c)]-[name:OVTK_NodeId_Buffer_StreamedMatrix_RawBuffer]-[type:binary]-[bytes:256 (0x100)]
|
||||
[ INF ] <Box algorithm::EBML stream spy>
|
||||
...
|
||||
|
||||
Now let's try to understand what is produced. First we notice a clear
|
||||
separation between the different chunk the box receives. In each chunk, we
|
||||
have an EBML hierarchy with the different nodes. Here we analyse a signal
|
||||
stream so we have a header followed by multiple buffers.
|
||||
|
||||
Concerning the header, we can focuse on the signal header part and
|
||||
the streamed matrix header part. In the first one, we can see that the sampling
|
||||
rate node appears as an integer with value 512 (the default sinus oscillator
|
||||
sampling frequency). The second one contains the description of the streamed
|
||||
matrix. The matrix has two dimensions (electrodes and sample count per buffer).
|
||||
The first dimension has a size of 4 (the default sinus oscillator channel count)
|
||||
and each of this channel has a label (channel 0-3). Finally, the second dimension
|
||||
has a size of 8 (the sample count per buffer you manually put in the sinus
|
||||
oscillator configuration) and the samples themselves do not have a name.
|
||||
|
||||
Now looking at the buffer, we only have the streamed matrix part (signal
|
||||
stream do not produce signal specific buffer). The buffer content can not
|
||||
be displayed in the console (it could be a huge amount of binary non human
|
||||
readable data, so it is not relevant to print it). But you have an information
|
||||
of the size of this buffer. 256 is exactly the number of channels (4) multiplied
|
||||
by the number of samples per buffer (8) multiplied by the size of a single sample
|
||||
(8 because a sample is coded on a 64 bits float).
|
||||
|
||||
When familiar with EBML and OpenViBE streams, this box is a strong tool
|
||||
to analyze what is sent from a box to another.
|
||||
|
||||
.. _Doc_BoxAlgorithm_EBMLStreamSpy_Miscellaneous:
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
|
||||
The syntax of the configuration file is simple. Each line of the file
|
||||
should contain 3 fields. The first field is the name of the EBML node
|
||||
that should be printed in the log manager (this is human readable).
|
||||
The second field is the EBML node identifier. The last field is the node
|
||||
type. Several types are supported :
|
||||
|
||||
- \e master : this means that this node does not have data attached but has
|
||||
|
||||
several children. Any non master node is a leaf, so can contain data.
|
||||
|
||||
- \e integer : this means that this node contains a signed integer value
|
||||
- \e uinteger : this means that this node contains an unsigned integer value
|
||||
- \e string : this means that this node contains an ASCII string value
|
||||
- \e float : this means that this node contains a floating point value
|
||||
- \e binary : this means that this node contains a raw buffer of elements.
|
||||
|
||||
In such case, only the size of the buffer is printed. The content of the
|
||||
buffer is not printed.
|
||||
|
||||
Any node identifier found in the stream and not present in the configuration
|
||||
file will be considered of type \e unknown and treated as if it was a \e binary
|
||||
node.
|
||||
|
||||
Following is a part of the sample configuration file to illustrate the syntax :
|
||||
|
||||
.. code::
|
||||
|
||||
...
|
||||
|
||||
OVTK_NodeId_Header_StreamedMatrix EBML::CIdentifier(0x0072F560, 0x7ED2CBED) master
|
||||
OVTK_NodeId_Header_StreamedMatrix_DimensionCount EBML::CIdentifier(0x003FEBD4, 0x2725D428) uinteger
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension EBML::CIdentifier(0x0000E3C0, 0x3A7D5141) master
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension_Size EBML::CIdentifier(0x001302F7, 0x36D8438A) uinteger
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension_Label EBML::CIdentifier(0x00153E40, 0x190227E0) string
|
||||
OVTK_NodeId_Buffer_StreamedMatrix EBML::CIdentifier(0x00120663, 0x08FBC165) master
|
||||
OVTK_NodeId_Buffer_StreamedMatrix_RawBuffer EBML::CIdentifier(0x00B18C10, 0x427D098C) binary
|
||||
|
||||
OVTK_NodeId_Header_Signal EBML::CIdentifier(0x007855DE, 0x3748D375) master
|
||||
OVTK_NodeId_Header_Signal_Sampling EBML::CIdentifier(0x00141C43, 0x0C37006B) uinteger
|
||||
|
||||
...
|
||||
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
.. _Doc_BoxAlgorithm_ExternalProcessing:
|
||||
|
||||
External Processing
|
||||
===================
|
||||
|
||||
.. container:: attribution
|
||||
|
||||
:Author:
|
||||
Alexis Placet
|
||||
:Company:
|
||||
Mensia Technologies SA
|
||||
|
||||
.. image:: images/Doc_BoxAlgorithm_ExternalProcessing.png
|
||||
|
||||
Launches an external program which can then process data. This box and the program communicate using TCP connection and a defined protocol.
|
||||
|
||||
This box allows to externalize data processing into an external program. It sends EBML data in chunks
|
||||
according to a specified protocol, the external application must respond with an EBML response following
|
||||
this same protocol.
|
||||
|
||||
A SDK for C++ and Python 3 (Python NeuroRT Box) are provided in order to simplify the development of
|
||||
external boxes.
|
||||
|
||||
This box can work in two modes, either it launches the external program itself, or it will wait for client
|
||||
connections during the initialize step.
|
||||
|
||||
.. _Doc_BoxAlgorithm_ExternalProcessing_Settings:
|
||||
|
||||
Settings
|
||||
--------
|
||||
|
||||
.. csv-table::
|
||||
:header: "Setting Name", "Type", "Default Value"
|
||||
|
||||
"Launch third party program", "Boolean", "true"
|
||||
"Executable path", "Filename", ""
|
||||
"Arguments", "String", ""
|
||||
"Port", "Integer", "0"
|
||||
"Automatic connection identifier", "Boolean", "true"
|
||||
"Custom connection identifier", "String", ""
|
||||
"Incoming connection timeout", "Integer", "10"
|
||||
"Generator", "Boolean", "false"
|
||||
|
||||
The External Processing box has several settings. The first eight parameters are reserved for the
|
||||
box. Any additional parameters will be passed to the external program.
|
||||
|
||||
Launch third party program
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
If true, the box will attempt to start the external program automatically.
|
||||
We advise to use this mode in production.
|
||||
|
||||
If this setting is false, then the box will stop
|
||||
during the initialize step and wait for the external program to connect during the time speficied by the Connection Timeout setting.
|
||||
This mode is useful during development, since it allows to run the program manually and check the console.
|
||||
|
||||
|
||||
Executable path
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Path to the executable to run. This parameter is only used if the first parameter is activated.
|
||||
|
||||
Example: OpenViBE SDK comes with two example programs, one can be found in ``${Path_Bin}/sdk-examples-communication-client-filter``
|
||||
|
||||
Example: In the case you want to run a Python script on Windows, the program you are running is python, e.g: ``C:/Python35/python.exe``
|
||||
|
||||
Arguments
|
||||
~~~~~~~~~
|
||||
|
||||
Arguments passed to the third party program, if any are necessary. This parameter is only used if the first parameter is activated.
|
||||
|
||||
This parameter will be given to the third party program as is, thus it is necessary to quote any arguments that contain spaces.
|
||||
|
||||
Example: In the case you want to run a Python script on Windows, the parameter is the absolute path to the script that you want to run, e.g.: ``C:/MyProject/myprogram.py`` or ``-m mylibrary.mymodule.mybox``.
|
||||
|
||||
Port
|
||||
~~~~
|
||||
|
||||
The TCP port that the box is listening. It must be in the range 49152-65535 or it can be 0, in which case the port will be chosen
|
||||
automatically.
|
||||
|
||||
The box acts as a Socket server and the external program as a client. If you have several External Processing boxes in the same scenario
|
||||
each has to work on a different port.
|
||||
|
||||
We advise to use port ``0`` in production.
|
||||
|
||||
An argument, with the value of the port, will be given to the third party program (after the Arguments parameter ) as: ``--port PORT``
|
||||
|
||||
This means that your external program must accept the ``--port`` parameter and use it to connect to this box.
|
||||
|
||||
Automatic connection identifier
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Whether or not to generate of a connection identifier for the connection. See the next setting for explanation.
|
||||
|
||||
Custom connection identifier
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This argument will be passed to the external program as a command line parameter: ``--connection-id CONNECTIONID`` and will be communicated to your
|
||||
program through the protocol as well. You should check that the two are matching in order to avoid a clash if two boxes would be using the same
|
||||
port.
|
||||
|
||||
We advise you to use an automatic identifier generation in production. Choose your custom connection identifier is however necessary when running
|
||||
the external program explicitly.
|
||||
|
||||
Incoming connection timeout
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A timeout, in seconds, for the incoming connection acceptance.
|
||||
|
||||
Generator
|
||||
~~~~~~~~~
|
||||
|
||||
This setting changes how often the box will process data. Each data processing requires that the box will
|
||||
wait until it has received a response from the external program. Too many of these synchronisations can
|
||||
induce a severe performance penalty.
|
||||
|
||||
If the box is a generator, then it will wait for the external program on each step. If the scenario is
|
||||
played in real-time, then the box will poll the external program at 16Hz. If the scenario is in fast-forward
|
||||
the refresh frequency of this box is 1Hz.
|
||||
|
||||
If this setting is set to false, the box will send all data it receives into the external program and wait
|
||||
until it processes it and sends it back.
|
||||
|
||||
.. _Doc_BoxAlgorithm_ExternalProcessing_Miscellaneous:
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
|
||||
Performances
|
||||
~~~~~~~~~~~~
|
||||
This box requires synchronization with the external program in order to process data correctly and in order.
|
||||
As the synchronization is a relatively slow process with regards to the duration of one update cycle (62ms) it
|
||||
is better to try to limit the number of chunks that are send between the box and the client application.
|
||||
|
||||
If you find that your scenario is too slow, try using time based epoching in front of it to make chunks of data
|
||||
larger.
|
||||
|
||||
|
||||
Development mode
|
||||
~~~~~~~~~~~~~~~~
|
||||
While developing your program, you may want to run it in Debug mode in your environment.
|
||||
|
||||
In order to run your program manually you should change the settings of the box:
|
||||
* uncheck option ``Launch Third Party Program``,
|
||||
* uncheck option ``Automatic connection identifier``,
|
||||
* change the default port, for example to ``59595``, (make sure this is the default port used by your program)
|
||||
* make sure the setting ``Incoming connection timeout`` will leave you enough time to run your program manually (default setting should be enough)
|
||||
|
||||
Then, you can first run your scenario through NeuroRT Studio, and then run your program manually.
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
.. _Doc_BoxAlgorithm_MatrixValidityChecker:
|
||||
|
||||
Matrix validity checker
|
||||
=======================
|
||||
|
||||
.. container:: attribution
|
||||
|
||||
:Author:
|
||||
Yann Renard
|
||||
:Company:
|
||||
INRIA/IRISA
|
||||
|
||||
.. image:: images/Doc_BoxAlgorithm_MatrixValidityChecker.png
|
||||
|
||||
This box is for debugging purposes and allows an author to check the validity of a streamed matrix and derived stream. This box can log a message, stop the player or interpolate data.
|
||||
|
||||
Ensures values stored in a matrix are valid, i.e. regular floating point values as opposed to NaN (not a number) or infinite.
|
||||
|
||||
Inputs
|
||||
------
|
||||
|
||||
.. csv-table::
|
||||
:header: "Input Name", "Stream Type"
|
||||
|
||||
"Stream 1", "Streamed matrix"
|
||||
|
||||
Outputs
|
||||
-------
|
||||
|
||||
.. csv-table::
|
||||
:header: "Output Name", "Stream Type"
|
||||
|
||||
"Output stream 1", "Streamed matrix"
|
||||
|
||||
.. _Doc_BoxAlgorithm_MatrixValidityChecker_Settings:
|
||||
|
||||
Settings
|
||||
--------
|
||||
|
||||
.. csv-table::
|
||||
:header: "Setting Name", "Type", "Default Value"
|
||||
|
||||
"Log level", "Log level", "Warning"
|
||||
"Action to do", "Action to do", "Log warning"
|
||||
|
||||
Log level
|
||||
~~~~~~~~~
|
||||
|
||||
Log level of messages to be printed whenever Nan or infinite values are found in input matrix.
|
||||
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
.. _Doc_BoxAlgorithm_StimulationListener:
|
||||
|
||||
Stimulation listener
|
||||
====================
|
||||
|
||||
.. container:: attribution
|
||||
|
||||
:Author:
|
||||
Yann Renard
|
||||
:Company:
|
||||
INRIA/IRISA
|
||||
|
||||
.. image:: images/Doc_BoxAlgorithm_StimulationListener.png
|
||||
|
||||
Prints each received stimulationto the log using the log level specified in the box config.
|
||||
|
||||
The stimulation listener is a debugging purpose box, with
|
||||
the same idea as the :ref:`Doc_BoxAlgorithm_EBMLStreamSpy` box
|
||||
but dedicated to stimulation streams. The idea is to dramatically
|
||||
reduce the log verbosity so the output may be followed realtime
|
||||
if necessary.
|
||||
|
||||
Inputs
|
||||
------
|
||||
|
||||
.. csv-table::
|
||||
:header: "Input Name", "Stream Type"
|
||||
|
||||
"Stimulation stream 1", "Stimulations"
|
||||
|
||||
This box can receive as many input as necessary. All the inputs
|
||||
will be of type :ref:`Doc_Streams_Stimulation` in order to
|
||||
be parsed by this the reader.
|
||||
|
||||
Stimulation stream 1
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is the default input of this box.
|
||||
|
||||
.. _Doc_BoxAlgorithm_StimulationListener_Settings:
|
||||
|
||||
Settings
|
||||
--------
|
||||
|
||||
.. csv-table::
|
||||
:header: "Setting Name", "Type", "Default Value"
|
||||
|
||||
"Log level to use", "Log level", "Information"
|
||||
|
||||
Log level to use
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
This setting indicates what log level will be used to
|
||||
print the the received stimulations.
|
||||
|
||||
.. _Doc_BoxAlgorithm_StimulationListener_Examples:
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
As an example, we could connect a clock stimulator to a
|
||||
stimulation listener. Leave the default settings of the
|
||||
clock stimulator, so it sends an \e OVTK_StimulationId_Label_00
|
||||
stimulation every second. Now chose an appropriate log level
|
||||
for the stimulation listener and press 'start'. If you're
|
||||
familiar to what :ref:`Doc_BoxAlgorithm_EBMLStreamSpy` produces,
|
||||
you may feel more confortable with what is produced here for
|
||||
stimulations.
|
||||
|
||||
The output should look like this :
|
||||
|
||||
.. code::
|
||||
|
||||
...
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 4294967296 (0x100000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 8589934592 (0x200000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 12884901888 (0x300000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 17179869184 (0x400000000) and duration 0 (0x0)
|
||||
...
|
||||
|
||||
Now let's try to understand what is produced. Each line represents
|
||||
received stimulation. The input index which received the stimulation
|
||||
is printed. Then follow the stimulation code, its date and its duration.
|
||||
The stimulation name is retrieved from the type manager when correctly
|
||||
registered. Here, you can see that an \e OVTK_StimulationId_Label_00 is
|
||||
received every second.
|
||||
|
||||
More tests could be done with another clock stimulator with different
|
||||
timings and stimulation codes. You will want to add inputs to the stimulation
|
||||
listener box in order to get proper results. For example with one more box
|
||||
sending \e OVTK_StimulationId_Label_01 every half second, the output would
|
||||
look like this :
|
||||
|
||||
.. code::
|
||||
|
||||
...
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 2147483648 (0x80000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 4294967296 (0x100000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 4294967296 (0x100000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 6442450944 (0x180000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 8589934592 (0x200000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 8589934592 (0x200000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 10737418240 (0x280000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 12884901888 (0x300000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 12884901888 (0x300000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 15032385536 (0x380000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 0 (0x0) with name Stimulation stream 1 got stimulation 33024 (0x8100)[OVTK_StimulationId_Label_00] at date 17179869184 (0x400000000) and duration 0 (0x0)
|
||||
[ INF ] <Box algorithm::Stimulation listener> For input 1 (0x1) with name Stimulation stream 2 got stimulation 33025 (0x8101)[OVTK_StimulationId_Label_01] at date 17179869184 (0x400000000) and duration 0 (0x0)
|
||||
...
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 962 B |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1010 B |
+74
@@ -0,0 +1,74 @@
|
||||
OVTK_NodeId_Acquisition_Header EBML::CIdentifier(0x00000000, 0x00004239) master
|
||||
OVTK_NodeId_Acquisition_AcquisitionInfo EBML::CIdentifier(0x00000000, 0x00004240) master
|
||||
OVTK_NodeId_Acquisition_ExperimentId EBML::CIdentifier(0x00000000, 0x00004241) uinteger
|
||||
OVTK_NodeId_Acquisition_SubjectAge EBML::CIdentifier(0x00000000, 0x00004242) uinteger
|
||||
OVTK_NodeId_Acquisition_SubjectGender EBML::CIdentifier(0x00000000, 0x00004243) uinteger
|
||||
OVTK_NodeId_Acquisition_ChannelCount EBML::CIdentifier(0x00000000, 0x00004244) uinteger
|
||||
OVTK_NodeId_Acquisition_SamplingFrequency EBML::CIdentifier(0x00000000, 0x00004245) uinteger
|
||||
OVTK_NodeId_Acquisition_ChannelNames EBML::CIdentifier(0x00000000, 0x00004246) master
|
||||
OVTK_NodeId_Acquisition_ChannelName EBML::CIdentifier(0x00000000, 0x00004247) string
|
||||
OVTK_NodeId_Acquisition_GainFactors EBML::CIdentifier(0x00000000, 0x00004248) master
|
||||
OVTK_NodeId_Acquisition_GainFactor EBML::CIdentifier(0x00000000, 0x00004249) float
|
||||
OVTK_NodeId_Acquisition_ChannelLocations EBML::CIdentifier(0x00000000, 0x00004250) master
|
||||
OVTK_NodeId_Acquisition_ChannelLocation EBML::CIdentifier(0x00000000, 0x00004251) binary(double)
|
||||
OVTK_NodeId_Acquisition_Buffer EBML::CIdentifier(0x00000000, 0x0000005A) master
|
||||
OVTK_NodeId_Acquisition_Samples EBML::CIdentifier(0x00000000, 0x0000005B) master
|
||||
OVTK_NodeId_Acquisition_SamplesPerChannelCount EBML::CIdentifier(0x00000000, 0x0000005C) uinteger
|
||||
OVTK_NodeId_Acquisition_SampleBlock EBML::CIdentifier(0x00000000, 0x0000005D) binary(float)
|
||||
OVTK_NodeId_Acquisition_Stimulations EBML::CIdentifier(0x00000000, 0x00000060) master
|
||||
OVTK_NodeId_Acquisition_StimulationsCount EBML::CIdentifier(0x00000000, 0x00000061) uinteger
|
||||
OVTK_NodeId_Acquisition_Stimulation EBML::CIdentifier(0x00000000, 0x00000062) master
|
||||
OVTK_NodeId_Acquisition_StimulationSampleIndex EBML::CIdentifier(0x00000000, 0x00000063) uinteger
|
||||
OVTK_NodeId_Acquisition_StimulationIdentifier EBML::CIdentifier(0x00000000, 0x00000064) uinteger
|
||||
|
||||
OVTK_NodeId_Header EBML::CIdentifier(0x002B395F, 0x108ADFAE) master
|
||||
OVTK_NodeId_Header_StreamType EBML::CIdentifier(0x00CDD0F7, 0x46B0278D) uinteger
|
||||
OVTK_NodeId_Header_StreamVersion EBML::CIdentifier(0x006F5A08, 0x7796EBC5) uinteger
|
||||
OVTK_NodeId_Buffer EBML::CIdentifier(0x00CF2101, 0x02375310) master
|
||||
OVTK_NodeId_End EBML::CIdentifier(0x00D9DDC3, 0x0B12873A) master
|
||||
|
||||
OVTK_NodeId_Header_StreamedMatrix EBML::CIdentifier(0x0072F560, 0x7ED2CBED) master
|
||||
OVTK_NodeId_Header_StreamedMatrix_DimensionCount EBML::CIdentifier(0x003FEBD4, 0x2725D428) uinteger
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension EBML::CIdentifier(0x0000E3C0, 0x3A7D5141) master
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension_Size EBML::CIdentifier(0x001302F7, 0x36D8438A) uinteger
|
||||
OVTK_NodeId_Header_StreamedMatrix_Dimension_Label EBML::CIdentifier(0x00153E40, 0x190227E0) string
|
||||
OVTK_NodeId_Buffer_StreamedMatrix EBML::CIdentifier(0x00120663, 0x08FBC165) master
|
||||
OVTK_NodeId_Buffer_StreamedMatrix_RawBuffer EBML::CIdentifier(0x00B18C10, 0x427D098C) binary(double)
|
||||
|
||||
OVTK_NodeId_Header_Signal EBML::CIdentifier(0x007855DE, 0x3748D375) master
|
||||
OVTK_NodeId_Header_Signal_Sampling EBML::CIdentifier(0x00141C43, 0x0C37006B) uinteger
|
||||
|
||||
OVTK_NodeId_Header_Spectrum EBML::CIdentifier(0x00CCFA4B, 0x14F37D4D) master
|
||||
OVTK_NodeId_Header_Spectrum_FrequencyBand_Deprecated EBML::CIdentifier(0x0010983C, 0x21F8BDE5) master
|
||||
OVTK_NodeId_Header_Spectrum_FrequencyBand_Start_Deprecated EBML::CIdentifier(0x00AA5654, 0x2403A2CB) float
|
||||
OVTK_NodeId_Header_Spectrum_FrequencyBand_Stop_Deprecated EBML::CIdentifier(0x00A44C82, 0x05BE50D5) float
|
||||
OVTK_NodeId_Header_Spectrum_FrequencyAbscissa EBML::CIdentifier(0x00D7287D, 0x622A2BF5) float
|
||||
OVTK_NodeId_Header_Spectrum_Sampling EBML::CIdentifier(0x006876E9, 0x1DCB0CA1) uinteger
|
||||
|
||||
OVTK_NodeId_Buffer_Stimulation EBML::CIdentifier(0x006DEABE, 0x7FC05A20) master
|
||||
OVTK_NodeId_Buffer_Stimulation_NumberOfStimulations EBML::CIdentifier(0x00BB790B, 0x2B8574D8) uinteger
|
||||
OVTK_NodeId_Buffer_Stimulation_Stimulation EBML::CIdentifier(0x0016EAC6, 0x29FBCAA1) master
|
||||
OVTK_NodeId_Buffer_Stimulation_Stimulation_ID EBML::CIdentifier(0x006FA5DB, 0x4BAC31E9) uinteger
|
||||
OVTK_NodeId_Buffer_Stimulation_Stimulation_Date EBML::CIdentifier(0x00B866D8, 0x14DA5374) uinteger
|
||||
OVTK_NodeId_Buffer_Stimulation_Stimulation_Duration EBML::CIdentifier(0x14EE055F, 0x87FBCC9C) uinteger
|
||||
OVTK_NodeId_Header_ChannelUnits EBML::CIdentifier(0x17400C76, 0x16CF14C8) master
|
||||
OVTK_NodeId_Header_ChannelUnits_Dynamic EBML::CIdentifier(0x7307023C, 0x7F754D2E) uinteger
|
||||
OVTK_NodeId_Header_ChannelLocalisation EBML::CIdentifier(0xF2CFE60B, 0xEFD63E3B) master
|
||||
OVTK_NodeId_Header_ChannelLocalisation_Dynamic EBML::CIdentifier(0x5338AF5C, 0x07C469C3) uinteger
|
||||
|
||||
OVTK_NodeId_Header_ExperimentInfo EBML::CIdentifier(0x00746BA0, 0x115AE04D) master
|
||||
OVTK_NodeId_Header_ExperimentInfo_Experiment EBML::CIdentifier(0x0011D6B7, 0x48F1AA39) master
|
||||
OVTK_NodeId_Header_ExperimentInfo_Experiment_ID EBML::CIdentifier(0x006ACD74, 0x1C960C26) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Experiment_Date EBML::CIdentifier(0x002F8FB7, 0x6DA7552D) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Subject EBML::CIdentifier(0x003EC620, 0x333E0A94) master
|
||||
OVTK_NodeId_Header_ExperimentInfo_Subject_ID EBML::CIdentifier(0x00D62974, 0x473D4AA5) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Subject_Name EBML::CIdentifier(0x0041FD0A, 0x6BCD9A99) string
|
||||
OVTK_NodeId_Header_ExperimentInfo_Subject_Age EBML::CIdentifier(0x00DF7DD9, 0x33336C51) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Subject_Gender EBML::CIdentifier(0x0069BB84, 0x3FC8E149) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Context EBML::CIdentifier(0x0018C291, 0x7985DFDD) master
|
||||
OVTK_NodeId_Header_ExperimentInfo_Context_LaboratoryID EBML::CIdentifier(0x003F11B9, 0x26D76D9C) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Context_LaboratoryName EBML::CIdentifier(0x00EB1F23, 0x51C23B83) string
|
||||
OVTK_NodeId_Header_ExperimentInfo_Context_TechnicianID EBML::CIdentifier(0x00874A7F, 0x60DC34C2) uinteger
|
||||
OVTK_NodeId_Header_ExperimentInfo_Context_TechnicianName EBML::CIdentifier(0x00C8C393, 0x31CE5B3E) string
|
||||
|
||||
DummyEnd EBML::CIdentifier(0x00000000, 0x00000000) binary
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
#include "ovpCBoxAlgorithmEBMLStreamSpy.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <fs/Files.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
|
||||
bool CBoxAlgorithmEBMLStreamSpy::initialize()
|
||||
{
|
||||
const Kernel::IBox& boxCtx = getStaticBoxContext();
|
||||
|
||||
m_reader = createReader(*this);
|
||||
m_helper = EBML::createReaderHelper();
|
||||
|
||||
bool expand;
|
||||
const CString fileName = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
|
||||
const uint64_t logLevel = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
|
||||
|
||||
if (boxCtx.getSettingCount() > 2)
|
||||
{
|
||||
expand = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);
|
||||
m_nExpandValues = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
expand = false;
|
||||
m_nExpandValues = 4;
|
||||
}
|
||||
|
||||
m_logLevel = Kernel::ELogLevel(logLevel);
|
||||
|
||||
std::ifstream file;
|
||||
FS::Files::openIFStream(file, fileName);
|
||||
while (file.good() && !file.eof())
|
||||
{
|
||||
uint32_t id1;
|
||||
uint32_t id2;
|
||||
std::string identifier1;
|
||||
std::string identifier2;
|
||||
std::string name;
|
||||
std::string type;
|
||||
|
||||
file >> name;
|
||||
file >> identifier1;
|
||||
file >> identifier2;
|
||||
file >> type;
|
||||
|
||||
sscanf(identifier1.c_str(), "EBML::CIdentifier(0x%08x", &id1);
|
||||
sscanf(identifier2.c_str(), "0x%08x)", &id2);
|
||||
|
||||
if (!expand)
|
||||
{
|
||||
if ((type == "binary(long double)") || (type == "binary(double)") || (type == "binary(float)")
|
||||
|| (type == "binary(integer8)") || (type == "binary(integer16)") || (type == "binary(integer32)")
|
||||
|| (type == "binary(integer64)") || (type == "binary(uinteger8)") || (type == "binary(uinteger16)")
|
||||
|| (type == "binary(uinteger32)") || (type == "binary(uinteger64)")) { type = "binary"; }
|
||||
}
|
||||
|
||||
// std::cout << "[" << identifier1 << "][" << identifier2 << "]" << std::endl;
|
||||
// printf("[EBML::CIdentifier(0x%08X,][0x%08X]\n", id1, id2);
|
||||
// std::cout << EBML::CIdentifier(id1, id2) << std::endl;
|
||||
|
||||
m_names[EBML::CIdentifier(id1, id2)] = name;
|
||||
m_types[EBML::CIdentifier(id1, id2)] = type;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmEBMLStreamSpy::uninitialize()
|
||||
{
|
||||
m_helper->release();
|
||||
m_helper = nullptr;
|
||||
|
||||
m_reader->release();
|
||||
m_reader = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmEBMLStreamSpy::isMasterChild(const EBML::CIdentifier& identifier)
|
||||
{
|
||||
const auto n = m_names.find(identifier);
|
||||
const auto t = m_types.find(identifier);
|
||||
if (n != m_names.end() && t != m_types.end()) { return (t->second == "master"); }
|
||||
return false;
|
||||
}
|
||||
|
||||
void CBoxAlgorithmEBMLStreamSpy::openChild(const EBML::CIdentifier& identifier)
|
||||
{
|
||||
const auto n = m_names.find(identifier);
|
||||
|
||||
getLogManager() << m_logLevel;
|
||||
|
||||
for (size_t i = 0; i <= m_nodes.size(); ++i) { getLogManager() << " "; }
|
||||
|
||||
getLogManager() << "Opened EBML node [id:" << identifier << "]-[name:" << (n != m_names.end() ? n->second : "unknown") << "]";
|
||||
|
||||
if (isMasterChild(identifier)) { getLogManager() << "\n"; }
|
||||
|
||||
m_nodes.push(identifier);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CBoxAlgorithmEBMLStreamSpy::processBinaryBlock(const void* buffer, const size_t size)
|
||||
{
|
||||
const size_t n = (size / sizeof(T));
|
||||
const T* buf = static_cast<const T*>(buffer);
|
||||
for (size_t i = 0; i < std::min(m_nExpandValues, n); ++i) { getLogManager() << (i == 0 ? "" : " ") << buf[i]; }
|
||||
if (m_nExpandValues < n) { getLogManager() << " ..."; }
|
||||
}
|
||||
|
||||
void CBoxAlgorithmEBMLStreamSpy::processChildData(const void* buffer, const size_t size)
|
||||
{
|
||||
const auto t = m_types.find(m_nodes.top());
|
||||
|
||||
if (t != m_types.end())
|
||||
{
|
||||
if (t->second == "uinteger") { getLogManager() << "-[type:" << t->second << "]-[value:" << m_helper->getUInt(buffer, size) << "]"; }
|
||||
else if (t->second == "integer") { getLogManager() << "-[type:" << t->second << "]-[value:" << m_helper->getInt(buffer, size) << "]"; }
|
||||
else if (t->second == "float") { getLogManager() << "-[type:" << t->second << "]-[value:" << m_helper->getDouble(buffer, size) << "]"; }
|
||||
else if (t->second == "string") { getLogManager() << "-[type:" << t->second << "]-[value:" << m_helper->getStr(buffer, size) << "]"; }
|
||||
else if (t->second == "binary") { getLogManager() << "-[type:" << t->second << "]-[bytes:" << size << "]"; }
|
||||
else if (t->second == "binary(double)")
|
||||
{
|
||||
getLogManager() << "-[type:" << t->second << "]-[values:";
|
||||
processBinaryBlock<double>(buffer, size);
|
||||
getLogManager() << "]";
|
||||
}
|
||||
else if (t->second == "binary(float)")
|
||||
{
|
||||
getLogManager() << "-[type:" << t->second << "]-[values:";
|
||||
processBinaryBlock<float>(buffer, size);
|
||||
getLogManager() << "]";
|
||||
}
|
||||
else if (t->second == "binary(integer8)")
|
||||
{
|
||||
getLogManager() << "-[type:" << t->second << "]-[values:";
|
||||
processBinaryBlock<int8_t>(buffer, size);
|
||||
getLogManager() << "]";
|
||||
}
|
||||
else if (t->second == "binary(integer16)")
|
||||
{
|
||||
getLogManager() << "-[type:" << t->second << "]-[values:";
|
||||
processBinaryBlock<int16_t>(buffer, size);
|
||||
getLogManager() << "]";
|
||||
}
|
||||
else if (t->second == "binary(integer32)")
|
||||
{
|
||||
getLogManager() << "-[type:" << t->second << "]-[values:";
|
||||
processBinaryBlock<int>(buffer, size);
|
||||
getLogManager() << "]";
|
||||
}
|
||||
else if (t->second == "binary(integer64)")
|
||||
{
|
||||
getLogManager() << "-[type:" << t->second << "]-[values:";
|
||||
processBinaryBlock<int64_t>(buffer, size);
|
||||
getLogManager() << "]";
|
||||
}
|
||||
else if (t->second == "binary(uinteger8)")
|
||||
{
|
||||
getLogManager() << "-[type:" << t->second << "]-[values:";
|
||||
processBinaryBlock<uint8_t>(buffer, size);
|
||||
getLogManager() << "]";
|
||||
}
|
||||
else if (t->second == "binary(uinteger16)")
|
||||
{
|
||||
getLogManager() << "-[type:" << t->second << "]-[values:";
|
||||
processBinaryBlock<uint16_t>(buffer, size);
|
||||
getLogManager() << "]";
|
||||
}
|
||||
else if (t->second == "binary(uinteger32)")
|
||||
{
|
||||
getLogManager() << "-[type:" << t->second << "]-[values:";
|
||||
processBinaryBlock<uint32_t>(buffer, size);
|
||||
getLogManager() << "]";
|
||||
}
|
||||
else if (t->second == "binary(uinteger64)")
|
||||
{
|
||||
getLogManager() << "-[type:" << t->second << "]-[values:";
|
||||
processBinaryBlock<uint64_t>(buffer, size);
|
||||
getLogManager() << "]";
|
||||
}
|
||||
else { getLogManager() << "-[type:unknown]-[bytes:" << size << "]"; }
|
||||
}
|
||||
getLogManager() << "\n";
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmEBMLStreamSpy::processInput(const size_t /*index*/)
|
||||
{
|
||||
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmEBMLStreamSpy::process()
|
||||
{
|
||||
Kernel::IBoxIO& boxCtx = getDynamicBoxContext();
|
||||
const Kernel::IBox& staticBoxCtx = getStaticBoxContext();
|
||||
|
||||
uint64_t tStart = 0;
|
||||
uint64_t tEnd = 0;
|
||||
size_t size = 0;
|
||||
const uint8_t* buffer = nullptr;
|
||||
|
||||
getLogManager() << m_logLevel << "\n";
|
||||
|
||||
for (size_t i = 0; i < staticBoxCtx.getInputCount(); ++i)
|
||||
{
|
||||
if (boxCtx.getInputChunkCount(i))
|
||||
{
|
||||
CString inputName;
|
||||
staticBoxCtx.getInputName(i, inputName);
|
||||
|
||||
CIdentifier inputType;
|
||||
staticBoxCtx.getInputType(i, inputType);
|
||||
|
||||
getLogManager() << m_logLevel << "For input " << inputName << " of type " << getTypeManager().getTypeName(inputType) << " :\n";
|
||||
|
||||
for (size_t j = 0; j < boxCtx.getInputChunkCount(i); ++j)
|
||||
{
|
||||
boxCtx.getInputChunk(i, j, tStart, tEnd, size, buffer);
|
||||
boxCtx.markInputAsDeprecated(i, j);
|
||||
|
||||
getLogManager() << m_logLevel << "For chunk [id:" << j << "] at [time:" << CIdentifier(tStart) << "," << CIdentifier(tEnd)
|
||||
<< " / " << CTime(tStart) << "," << CTime(tEnd) << "]\n";
|
||||
|
||||
m_reader->processData(buffer, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getLogManager() << m_logLevel << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ovp_defines.h"
|
||||
|
||||
#include <toolkit/ovtk_all.h>
|
||||
#include <ebml/IReader.h>
|
||||
#include <ebml/IReaderHelper.h>
|
||||
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
|
||||
class CBoxAlgorithmEBMLStreamSpy final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>, virtual public EBML::IReaderCallback
|
||||
{
|
||||
public:
|
||||
|
||||
CBoxAlgorithmEBMLStreamSpy() { }
|
||||
void release() override { delete this; }
|
||||
bool initialize() override;
|
||||
bool uninitialize() override;
|
||||
bool isMasterChild(const EBML::CIdentifier& identifier) override;
|
||||
void openChild(const EBML::CIdentifier& identifier) override;
|
||||
void processChildData(const void* buffer, const size_t size) override;
|
||||
void closeChild() override { m_nodes.pop(); }
|
||||
bool processInput(const size_t index) override;
|
||||
bool process() override;
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_EBMLStreamSpy)
|
||||
|
||||
protected:
|
||||
|
||||
template <class T>
|
||||
void processBinaryBlock(const void* buffer, size_t size);
|
||||
|
||||
std::stack<EBML::CIdentifier> m_nodes;
|
||||
std::map<EBML::CIdentifier, std::string> m_names;
|
||||
std::map<EBML::CIdentifier, std::string> m_types;
|
||||
size_t m_nExpandValues = 0;
|
||||
Kernel::ELogLevel m_logLevel = Kernel::ELogLevel::LogLevel_None;
|
||||
EBML::IReader* m_reader = nullptr;
|
||||
EBML::IReaderHelper* m_helper = nullptr;
|
||||
};
|
||||
|
||||
class CBoxAlgorithmEBMLStreamSpyListener final : public Toolkit::TBoxListener<IBoxListener>
|
||||
{
|
||||
public:
|
||||
|
||||
bool check(Kernel::IBox& box) const
|
||||
{
|
||||
for (size_t i = 0; i < box.getInputCount(); ++i)
|
||||
{
|
||||
box.setInputName(i, ("Spied EBML stream " + std::to_string(i + 1)).c_str());
|
||||
box.setInputType(i, OV_TypeId_EBMLStream);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onInputRemoved(Kernel::IBox& box, const size_t /*index*/) override { return this->check(box); }
|
||||
bool onInputAdded(Kernel::IBox& box, const size_t /*index*/) override { return this->check(box); }
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
|
||||
};
|
||||
|
||||
class CBoxAlgorithmEBMLStreamSpyDesc final : public IBoxAlgorithmDesc
|
||||
{
|
||||
public:
|
||||
void release() override { }
|
||||
CString getName() const override { return "EBML stream spy"; }
|
||||
CString getAuthorName() const override { return "Yann Renard"; }
|
||||
CString getAuthorCompanyName() const override { return "INRIA/IRISA"; }
|
||||
CString getShortDescription() const override { return "EBML stream tree viewer"; }
|
||||
|
||||
CString getDetailedDescription() const override { return "This sample EBML stream analyzer prints the EBML tree structure to the console"; }
|
||||
|
||||
CString getCategory() const override { return "Tools"; }
|
||||
CString getVersion() const override { return "1.0"; }
|
||||
CString getSoftwareComponent() const override { return "openvibe-sdk"; }
|
||||
CString getAddedSoftwareVersion() const override { return "0.0.0"; }
|
||||
CString getUpdatedSoftwareVersion() const override { return "0.0.0"; }
|
||||
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_EBMLStreamSpy; }
|
||||
IPluginObject* create() override { return new CBoxAlgorithmEBMLStreamSpy(); }
|
||||
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmEBMLStreamSpyListener; }
|
||||
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
|
||||
|
||||
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
|
||||
{
|
||||
prototype.addInput("Spied EBML stream 1", OV_TypeId_EBMLStream);
|
||||
prototype.addSetting("EBML nodes description", OV_TypeId_Filename, "${Path_Data}/plugins/tools/config-ebml-stream-spy.txt");
|
||||
prototype.addSetting("Log level to use", OV_TypeId_LogLevel, "Information");
|
||||
prototype.addSetting("Expand binary blocks", OV_TypeId_Boolean, "false");
|
||||
prototype.addSetting("Number of values in expanded blocks", OV_TypeId_Integer, "4");
|
||||
prototype.addFlag(Kernel::BoxFlag_CanAddInput);
|
||||
return true;
|
||||
}
|
||||
|
||||
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_EBMLStreamSpyDesc)
|
||||
};
|
||||
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+609
@@ -0,0 +1,609 @@
|
||||
#include "ovpCBoxAlgorithmExternalProcessing.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <stdlib.h>
|
||||
#include <random>
|
||||
#include <thread>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef TARGET_OS_Windows
|
||||
#include <process.h>
|
||||
#include <Windows.h>
|
||||
#include <ctime>
|
||||
#else
|
||||
#include <spawn.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
extern char **environ;
|
||||
#endif
|
||||
|
||||
#include <system/ovCTime.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
|
||||
static Kernel::ELogLevel convertLogLevel(const Communication::ELogLevel level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case Communication::LogLevel_Info: return Kernel::LogLevel_Info;
|
||||
case Communication::LogLevel_Warning: return Kernel::LogLevel_Warning;
|
||||
case Communication::LogLevel_Error: return Kernel::LogLevel_Error;
|
||||
case Communication::LogLevel_Fatal: return Kernel::LogLevel_Fatal;
|
||||
case Communication::LogLevel_Max:
|
||||
case Communication::LogLevel_Unknown:
|
||||
default: return Kernel::LogLevel_Info;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t CBoxAlgorithmExternalProcessing::getClockFrequency()
|
||||
{
|
||||
if (m_isGenerator)
|
||||
{
|
||||
// We slow down the generator type boxes by default, in order to limit syncing
|
||||
// In fast forward we limit the syncing even more by setting the frequency to 1Hz
|
||||
if (this->getPlayerContext().getStatus() == Kernel::EPlayerStatus::Forward) { return 1LL << 32; }
|
||||
return 16LL << 32;
|
||||
}
|
||||
return 128LL << 32;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmExternalProcessing::initialize()
|
||||
{
|
||||
m_port = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3);
|
||||
|
||||
// Check that the port is not in the system range
|
||||
OV_ERROR_UNLESS_KRF((m_port >= 49152 && m_port <= 65535) || (m_port == 0),
|
||||
"Port [" << m_port << "] is invalid. It must be either 0 or a number in the range 49152-65535.", Kernel::ErrorType::BadConfig);
|
||||
|
||||
// Settings
|
||||
const Kernel::IBox& staticboxCtx = this->getStaticBoxContext();
|
||||
|
||||
for (size_t i = 8; i < staticboxCtx.getSettingCount(); ++i)
|
||||
{
|
||||
CString name;
|
||||
staticboxCtx.getSettingName(i, name);
|
||||
|
||||
CIdentifier type;
|
||||
staticboxCtx.getSettingType(i, type);
|
||||
|
||||
const CString value = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), i);
|
||||
|
||||
OV_FATAL_UNLESS_K(m_messaging.addParameter(i, type.id(), name.toASCIIString(), value.toASCIIString()),
|
||||
"Failed to add a parameter: " << i, Kernel::ErrorType::Internal);
|
||||
}
|
||||
|
||||
// Inputs
|
||||
for (size_t i = 0; i < staticboxCtx.getInputCount(); ++i)
|
||||
{
|
||||
CIdentifier type;
|
||||
staticboxCtx.getInputType(i, type);
|
||||
|
||||
if (type == OV_TypeId_Stimulations) { m_decoders[i].initialize(*this, i); }
|
||||
|
||||
CString name;
|
||||
staticboxCtx.getInputName(i, name);
|
||||
|
||||
OV_FATAL_UNLESS_K(m_messaging.addInput(i, type.id(), name.toASCIIString()),
|
||||
"Failed to add an input: " << i, Kernel::ErrorType::Internal);
|
||||
}
|
||||
|
||||
// Outputs
|
||||
for (size_t i = 0; i < staticboxCtx.getOutputCount(); ++i)
|
||||
{
|
||||
CIdentifier type;
|
||||
staticboxCtx.getOutputType(i, type);
|
||||
|
||||
CString name;
|
||||
staticboxCtx.getOutputName(i, name);
|
||||
|
||||
if (!m_messaging.addOutput(i, type.id(), name.toASCIIString()))
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Error << "Failed to add an output: " << i << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const bool mustGenerateConnectionID = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 4);
|
||||
|
||||
if (mustGenerateConnectionID) { m_connectionID = generateConnectionID(32); }
|
||||
else
|
||||
{
|
||||
const CString connectionID = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 5);
|
||||
m_connectionID = connectionID.toASCIIString();
|
||||
}
|
||||
|
||||
OV_ERROR_UNLESS_KRF(m_messaging.listen(m_port),
|
||||
"Could not listen to TCP port: " << m_port << ". This port may be already used by another service. Please try another one.",
|
||||
Kernel::ErrorType::BadNetworkConnection);
|
||||
|
||||
if (m_port == 0)
|
||||
{
|
||||
m_messaging.getSocketPort(m_port);
|
||||
this->getLogManager() << Kernel::LogLevel_Info << "Box is now listening on TCP port [" << m_port << "].\n";
|
||||
}
|
||||
|
||||
m_shouldLaunchProgram = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
|
||||
|
||||
if (m_shouldLaunchProgram)
|
||||
{
|
||||
const CString programPath = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
|
||||
const CString arguments = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);
|
||||
|
||||
if (!launchThirdPartyProgram(programPath.toASCIIString(), arguments.toASCIIString()))
|
||||
{
|
||||
// Error message in the function
|
||||
return false;
|
||||
}
|
||||
|
||||
this->getLogManager() << Kernel::LogLevel_Info << "Third party program [" << programPath.toASCIIString() << "] started.\n";
|
||||
}
|
||||
|
||||
const auto startTime = System::Time::zgetTime();
|
||||
|
||||
bool clientConnected = false;
|
||||
m_hasReceivedEndMessage = false;
|
||||
|
||||
m_acceptTimeout = CTime(double(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 6))).time();
|
||||
m_isGenerator = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 7);
|
||||
|
||||
while (System::Time::zgetTime() - startTime < m_acceptTimeout)
|
||||
{
|
||||
if (m_messaging.accept())
|
||||
{
|
||||
clientConnected = true;
|
||||
this->getLogManager() << Kernel::LogLevel_Info << "Client connected to the server.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
const Communication::MessagingServer::ELibraryError error = m_messaging.getLastError();
|
||||
if (error == Communication::MessagingServer::ELibraryError::BadAuthenticationReceived)
|
||||
{
|
||||
OV_WARNING_K("A client sent a bad authentication.");
|
||||
break;
|
||||
}
|
||||
if (error == Communication::MessagingServer::ELibraryError::NoAuthenticationReceived) { OV_WARNING_K("The client has not sent authentication."); }
|
||||
}
|
||||
|
||||
OV_ERROR_UNLESS_KRF(clientConnected, "No client connected before the timeout.", Kernel::ErrorType::Internal);
|
||||
|
||||
|
||||
// Now synchronize once with the client so it can perform its initialize before
|
||||
// the processing starts
|
||||
m_messaging.pushSync();
|
||||
|
||||
|
||||
while (m_messaging.isConnected() && !m_messaging.waitForSyncMessage())
|
||||
{
|
||||
if (!m_messaging.waitForSyncMessage()) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); }
|
||||
}
|
||||
|
||||
m_syncTimeout = CTime(0.0625).time();
|
||||
m_lastSyncTime = System::Time::zgetTime();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmExternalProcessing::uninitialize()
|
||||
{
|
||||
for (auto& decoder : m_decoders) { decoder.second.uninitialize(); }
|
||||
|
||||
if (!m_hasReceivedEndMessage)
|
||||
{
|
||||
const bool result = m_messaging.close();
|
||||
|
||||
#ifdef TARGET_OS_Windows
|
||||
if (m_shouldLaunchProgram && m_extProcessId > 0)
|
||||
{
|
||||
DWORD exitCode;
|
||||
|
||||
// Wait for external process to stop by himself, terminate it if necessary
|
||||
const auto startTime = System::Time::zgetTime();
|
||||
while (System::Time::zgetTime() - startTime < m_acceptTimeout)
|
||||
{
|
||||
GetExitCodeProcess(HANDLE(m_extProcessId), &exitCode);
|
||||
|
||||
if (exitCode != STILL_ACTIVE) { break; }
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
|
||||
if (exitCode == STILL_ACTIVE)
|
||||
{
|
||||
OV_ERROR_UNLESS_KRF(TerminateProcess(HANDLE(m_extProcessId), EXIT_FAILURE), "Failed to kill third party program.",
|
||||
Kernel::ErrorType::Unknown);
|
||||
}
|
||||
else if (exitCode != 0) { OV_WARNING_K("Third party program [" << m_extProcessId << "] has terminated with exit code [" << int(exitCode) << "]"); }
|
||||
}
|
||||
#else
|
||||
if (m_shouldLaunchProgram && m_extProcessId != 0)
|
||||
{
|
||||
int status;
|
||||
pid_t pid = waitpid(m_extProcessId, &status, WNOHANG);
|
||||
|
||||
// Wait for external process to stop by himself, terminate it after 10s
|
||||
auto startTime = System::Time::zgetTime();
|
||||
while (pid == 0 && System::Time::zgetTime() - startTime < m_acceptTimeout)
|
||||
{
|
||||
// Check if the program has hung itself
|
||||
pid = waitpid(m_extProcessId, &status, WNOHANG);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
if (pid != 0)
|
||||
{
|
||||
if (WIFEXITED(status)) { OV_WARNING_K("Third party program [" << m_extProcessId << "] has terminated with exit code [" << WEXITSTATUS(status) << "]"); }
|
||||
else if (WIFSIGNALED(status)) { OV_WARNING_K("Third party program [" << m_extProcessId << "] killed by signal [" << WTERMSIG(status) << "]"); }
|
||||
}
|
||||
else
|
||||
{
|
||||
kill(m_extProcessId, SIGTERM);
|
||||
waitpid(m_extProcessId, &status, 0);
|
||||
this->getLogManager() << Kernel::LogLevel_Info << "Third party program [" << m_extProcessId << "] exited with status [" << WEXITSTATUS(status) << "]\n";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmExternalProcessing::processClock(Kernel::CMessageClock& /*msg*/) { return this->getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess(); }
|
||||
|
||||
bool CBoxAlgorithmExternalProcessing::processInput(const size_t /*index*/)
|
||||
{
|
||||
this->getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmExternalProcessing::process()
|
||||
{
|
||||
if (m_messaging.isInErrorState())
|
||||
{
|
||||
const std::string errorString = Communication::MessagingServer::getErrorString(m_messaging.getLastError());
|
||||
OV_ERROR_KRF("Error state connection: " << errorString << ".\n This may be due to a broken client connection.",
|
||||
Kernel::ErrorType::BadNetworkConnection);
|
||||
}
|
||||
|
||||
if (m_hasReceivedEndMessage == false && m_messaging.isEndReceived() == true)
|
||||
{
|
||||
this->getLogManager() << Kernel::LogLevel_Info << "The third party program has ended the communication.\n";
|
||||
m_messaging.close();
|
||||
m_hasReceivedEndMessage = true;
|
||||
}
|
||||
|
||||
OV_ERROR_UNLESS_KRF(m_messaging.pushTime(this->getPlayerContext().getCurrentTime()), "Failed to push Time.", Kernel::ErrorType::BadNetworkConnection);
|
||||
|
||||
const Kernel::IBox& staticboxCtx = this->getStaticBoxContext();
|
||||
Kernel::IBoxIO& boxCtx = this->getDynamicBoxContext();
|
||||
|
||||
// Send input EBML to the client
|
||||
|
||||
bool hasSentDataToClient = false;
|
||||
|
||||
for (size_t i = 0; i < staticboxCtx.getInputCount(); ++i)
|
||||
{
|
||||
auto maybeStimulationDecoder = m_decoders.find(i);
|
||||
for (size_t j = 0; j < boxCtx.getInputChunkCount(i); ++j)
|
||||
{
|
||||
if (!m_hasReceivedEndMessage)
|
||||
{
|
||||
uint64_t startTime = 0;
|
||||
uint64_t endTime = 0;
|
||||
size_t chunkSize = 0;
|
||||
const uint8_t* chunkBuffer = nullptr;
|
||||
|
||||
OV_FATAL_UNLESS_K(boxCtx.getInputChunk(i, j, startTime, endTime, chunkSize, chunkBuffer),
|
||||
"Failed to get input chunk [" << i << "][" << j << "]", Kernel::ErrorType::Internal);
|
||||
|
||||
std::shared_ptr<std::vector<uint8_t>> ebml(new std::vector<uint8_t>(chunkBuffer, chunkBuffer + chunkSize));
|
||||
|
||||
// We only encode stimulation stream chunks if they contain stimulations
|
||||
if (maybeStimulationDecoder != m_decoders.end())
|
||||
{
|
||||
maybeStimulationDecoder->second.decode(j, false); // The input will be marked as deprecated later
|
||||
|
||||
// Cache empty chunks, we will send them when a stimulation or a signal chunk arrives
|
||||
if (maybeStimulationDecoder->second.getOutputStimulationSet()->getStimulationCount() == 0)
|
||||
{
|
||||
m_packetHistory.emplace(startTime, endTime, i, ebml);
|
||||
OV_FATAL_UNLESS_K(boxCtx.markInputAsDeprecated(i, j), "Failed to mark input as deprecated", Kernel::ErrorType::Internal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Empty the history before to send useful data
|
||||
while (!m_packetHistory.empty())
|
||||
{
|
||||
OV_ERROR_UNLESS_KRF(m_messaging.pushEBML(m_packetHistory.front().index, m_packetHistory.front().startTime, m_packetHistory.front().endTime,
|
||||
m_packetHistory.front().EBML), "Failed to push EBML.", Kernel::ErrorType::BadNetworkConnection);
|
||||
|
||||
m_packetHistory.pop();
|
||||
}
|
||||
|
||||
// Push the last EBML
|
||||
OV_ERROR_UNLESS_KRF(m_messaging.pushEBML(i, startTime, endTime, ebml), "Failed to push EBML.", Kernel::ErrorType::BadNetworkConnection);
|
||||
hasSentDataToClient = true;
|
||||
}
|
||||
|
||||
OV_FATAL_UNLESS_K(boxCtx.markInputAsDeprecated(i, j), "Failed to mark input as deprecated", Kernel::ErrorType::Internal);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasSentDataToClient || m_isGenerator || System::Time::zgetTime() - m_lastSyncTime > m_syncTimeout)
|
||||
{
|
||||
m_lastSyncTime = System::Time::zgetTime();
|
||||
// Here, we send a sync message to tell to the client that we have no more data to send.
|
||||
// Generators do not have input data, so the box never has to send data to the external program
|
||||
// and thus needs to perform syncing on each tick.
|
||||
|
||||
OV_ERROR_UNLESS_KRF(m_messaging.pushSync(), "Failed to push sync message.", Kernel::ErrorType::BadNetworkConnection);
|
||||
|
||||
if (!m_hasReceivedEndMessage)
|
||||
{
|
||||
this->log();
|
||||
|
||||
uint64_t packetId;
|
||||
size_t index;
|
||||
uint64_t startTime;
|
||||
uint64_t endTime;
|
||||
std::shared_ptr<const std::vector<uint8_t>> ebml;
|
||||
|
||||
bool receivedSync = false;
|
||||
while (!receivedSync && !m_hasReceivedEndMessage && !m_messaging.isInErrorState() && m_messaging.isConnected())
|
||||
{
|
||||
receivedSync = m_messaging.waitForSyncMessage();
|
||||
while (m_messaging.popEBML(packetId, index, startTime, endTime, ebml))
|
||||
{
|
||||
OV_ERROR_UNLESS_KRF(boxCtx.appendOutputChunkData(index, ebml->data(), ebml->size()),
|
||||
"Failed to append output chunk data.", Kernel::ErrorType::Internal);
|
||||
|
||||
OV_ERROR_UNLESS_KRF(boxCtx.markOutputAsReadyToSend(index, startTime, endTime),
|
||||
"Failed to mark output as ready to send.", Kernel::ErrorType::Internal);
|
||||
}
|
||||
if (!receivedSync) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string CBoxAlgorithmExternalProcessing::generateConnectionID(const size_t size)
|
||||
{
|
||||
std::default_random_engine generator{ std::random_device()() };
|
||||
std::uniform_int_distribution<int> uni(0, 34);
|
||||
|
||||
std::string connectionID;
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
const char c = char(uni(generator));
|
||||
connectionID.push_back((c < 26) ? ('A' + c) : '1' + (c - 26));
|
||||
}
|
||||
|
||||
return connectionID;
|
||||
}
|
||||
|
||||
static std::vector<std::string> splitCommandLine(const std::string& cmdLine)
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
std::string arg;
|
||||
bool escape = false;
|
||||
enum { Idle, Arg, QuotedArg } state = Idle;
|
||||
|
||||
for (const char c : cmdLine)
|
||||
{
|
||||
if (!escape && c == '\\')
|
||||
{
|
||||
escape = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case Idle:
|
||||
if (!escape && c == '"')
|
||||
{
|
||||
state = QuotedArg;
|
||||
#if defined TARGET_OS_Windows
|
||||
arg += c;
|
||||
#endif
|
||||
}
|
||||
else if (escape || c != ' ')
|
||||
{
|
||||
arg += c;
|
||||
state = Arg;
|
||||
}
|
||||
break;
|
||||
|
||||
case Arg:
|
||||
if (!escape && c == '"')
|
||||
{
|
||||
state = QuotedArg;
|
||||
#if defined TARGET_OS_Windows
|
||||
arg += c;
|
||||
#endif
|
||||
}
|
||||
else if (escape || c != ' ') { arg += c; }
|
||||
else
|
||||
{
|
||||
list.push_back(arg);
|
||||
arg.clear();
|
||||
state = Idle;
|
||||
}
|
||||
break;
|
||||
|
||||
case QuotedArg:
|
||||
if (!escape && c == '"')
|
||||
{
|
||||
state = arg.empty() ? Idle : Arg;
|
||||
#if defined TARGET_OS_Windows
|
||||
arg += c;
|
||||
#endif
|
||||
}
|
||||
else { arg += c; }
|
||||
break;
|
||||
}
|
||||
|
||||
escape = false;
|
||||
}
|
||||
|
||||
if (!arg.empty()) { list.push_back(arg); }
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
char* strToChar(const std::string& s)
|
||||
{
|
||||
char* c = new char[s.size() + 1];
|
||||
std::copy(s.begin(), s.end(), c);
|
||||
return c;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmExternalProcessing::launchThirdPartyProgram(const std::string& programPath, const std::string& arguments)
|
||||
{
|
||||
m_extProcessId = 0;
|
||||
|
||||
const std::vector<std::string> argumentsVector = splitCommandLine(arguments);
|
||||
|
||||
std::vector<std::string> programArguments = { programPath, "--connection-id", m_connectionID, "--port", std::to_string(m_port) };
|
||||
programArguments.insert(programArguments.begin() + 1, argumentsVector.cbegin(), argumentsVector.cend()); // Add the arguments after the program path.
|
||||
std::vector<char*> argv;
|
||||
|
||||
std::transform(programArguments.begin(), programArguments.end(), std::back_inserter(argv), strToChar);
|
||||
|
||||
argv.push_back(nullptr);
|
||||
|
||||
#ifdef TARGET_OS_Windows
|
||||
// _spawnp on Windows has a special case for empty program
|
||||
int status;
|
||||
if (programPath.empty())
|
||||
{
|
||||
status = -1;
|
||||
_set_errno(ENOENT);
|
||||
}
|
||||
else { status = int(_spawnvp(_P_NOWAIT, programPath.c_str(), argv.data())); }
|
||||
m_extProcessId = status;
|
||||
// _P_DETACH,
|
||||
#else
|
||||
posix_spawn_file_actions_t fileAction;
|
||||
int res = posix_spawn_file_actions_init(&fileAction);
|
||||
OV_ERROR_UNLESS_KRF(res==0, "File action could not be initialized. Got error [" << res << "]", Kernel::ErrorType::BadCall);
|
||||
res = posix_spawn_file_actions_addclose(&fileAction, STDOUT_FILENO);
|
||||
OV_ERROR_UNLESS_KRF(res==0, "File action 'close' could not be added. Got error [" << res << "]", Kernel::ErrorType::BadCall);
|
||||
|
||||
this->getLogManager() << Kernel::LogLevel_Info << "Run third party program [" << programPath << "] with arguments [" << arguments << "].\n";
|
||||
int status = posix_spawnp(&m_extProcessId, programPath.c_str(), &fileAction, nullptr, argv.data(), environ);
|
||||
|
||||
#ifdef TARGET_OS_Linux
|
||||
// On linux the glibc is bugged and posix_spawnp does not actually work as specified
|
||||
// we have to check if the program did not exit immediately with a 127 error code
|
||||
// for this we need to wait a bit because it could be that the process has not yet launched
|
||||
|
||||
// wait until the process exists or if it has failed
|
||||
|
||||
bool processExists = false;
|
||||
bool processHasFailed = false;
|
||||
while (!processExists && !processHasFailed)
|
||||
{
|
||||
System::Time::sleep(10);
|
||||
processExists = (kill(m_extProcessId, 0) == 0);
|
||||
|
||||
int childStatus;
|
||||
pid_t pid = waitpid(m_extProcessId, &childStatus, WNOHANG);
|
||||
|
||||
if (pid != 0)
|
||||
{
|
||||
// The process is dead
|
||||
if (WIFEXITED(childStatus))
|
||||
{
|
||||
// If the exit status is 0 this means that maybe we will actually succeed in launching the program
|
||||
if (WEXITSTATUS(childStatus) != 0)
|
||||
{
|
||||
m_extProcessId = 0;
|
||||
status = WEXITSTATUS(childStatus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OV_WARNING_K("The third party process died");
|
||||
m_extProcessId = 0;
|
||||
status = 1;
|
||||
}
|
||||
processHasFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < argv.size() - 1; ++i) { delete[] argv[i]; }
|
||||
|
||||
#if defined TARGET_OS_Linux || defined TARGET_OS_MacOS
|
||||
if (status != 0)
|
||||
{
|
||||
const std::string errorMessage = "Failed to launch the program [" + programPath + "]: ";
|
||||
m_extProcessId = 0;
|
||||
OV_ERROR_KRF( errorMessage.c_str() << "[" << status << "]", Kernel::ErrorType::BadResourceCreation);
|
||||
}
|
||||
#else
|
||||
if (status == -1)
|
||||
{
|
||||
std::string errorMessage = "Failed to launch the program [" + programPath + "]:";
|
||||
|
||||
switch (errno)
|
||||
{
|
||||
case E2BIG:
|
||||
errorMessage += "Argument list exceeds 1024 bytes.\n";
|
||||
break;
|
||||
|
||||
case EINVAL:
|
||||
errorMessage += "Mode argument is invalid.\n";
|
||||
break;
|
||||
|
||||
case ENOENT:
|
||||
errorMessage += "File or path is not found.\n";
|
||||
break;
|
||||
|
||||
case ENOEXEC:
|
||||
errorMessage += "Specified file is not executable or has invalid executable-file format.\n";
|
||||
break;
|
||||
|
||||
case ENOMEM:
|
||||
errorMessage += "Not enough memory is available to execute the new process.\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
errorMessage += "Unknown error.\n";
|
||||
break;
|
||||
}
|
||||
|
||||
OV_ERROR_KRF(errorMessage.c_str(), Kernel::ErrorType::BadResourceCreation);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBoxAlgorithmExternalProcessing::log()
|
||||
{
|
||||
Communication::ELogLevel logLevel;
|
||||
std::string logMessage;
|
||||
uint64_t packetId;
|
||||
|
||||
while (m_messaging.popLog(packetId, logLevel, logMessage))
|
||||
{
|
||||
this->getLogManager() << convertLogLevel(logLevel) << "From third party program: " << logMessage << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ovp_defines.h"
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
#include <communication/ovCMessagingServer.h>
|
||||
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
class CBoxAlgorithmExternalProcessing final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
|
||||
{
|
||||
public:
|
||||
CBoxAlgorithmExternalProcessing() : m_acceptTimeout(10ULL << 32) {}
|
||||
void release() override { delete this; }
|
||||
uint64_t getClockFrequency() override;
|
||||
bool initialize() override;
|
||||
bool uninitialize() override;
|
||||
bool processClock(Kernel::CMessageClock& msg) override;
|
||||
bool processInput(const size_t index) override;
|
||||
bool process() override;
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_ExternalProcessing)
|
||||
|
||||
private:
|
||||
|
||||
struct SPacket
|
||||
{
|
||||
uint64_t startTime;
|
||||
uint64_t endTime;
|
||||
size_t index;
|
||||
std::shared_ptr<std::vector<uint8_t>> EBML;
|
||||
|
||||
SPacket(const uint64_t startTime, const uint64_t endTime, const size_t index, const std::shared_ptr<std::vector<uint8_t>>& ebml)
|
||||
: startTime(startTime), endTime(endTime), index(index), EBML(ebml) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief generate a connection identifier.
|
||||
*
|
||||
* \param size Size of the connection identifier.
|
||||
*
|
||||
* \return A string composed of size characters in the A-Z,0-9 range
|
||||
*/
|
||||
static std::string generateConnectionID(const size_t size);
|
||||
|
||||
/**
|
||||
* \brief Launch a third party program
|
||||
*
|
||||
* \param programPath Executable path
|
||||
* \param arguments Arguments to pass to the program
|
||||
*
|
||||
* \retval true
|
||||
* \retval false
|
||||
*/
|
||||
bool launchThirdPartyProgram(const std::string& programPath, const std::string& arguments);
|
||||
|
||||
/**
|
||||
* \brief Log in NeuroRT log from third party program
|
||||
*/
|
||||
void log();
|
||||
|
||||
Communication::MessagingServer m_messaging;
|
||||
size_t m_port = 0;
|
||||
std::string m_connectionID;
|
||||
std::string m_programPath;
|
||||
bool m_isGenerator = false;
|
||||
|
||||
int m_extProcessId = 0;
|
||||
|
||||
uint64_t m_acceptTimeout = 0;
|
||||
bool m_shouldLaunchProgram = false;
|
||||
bool m_hasReceivedEndMessage = false;
|
||||
// Synchronization timeout, and save time of last synchronization
|
||||
uint64_t m_syncTimeout = 0;
|
||||
uint64_t m_lastSyncTime = 0;
|
||||
|
||||
std::map<uint64_t, Toolkit::TStimulationDecoder<CBoxAlgorithmExternalProcessing>> m_decoders;
|
||||
std::queue<SPacket> m_packetHistory;
|
||||
};
|
||||
|
||||
class CBoxAlgorithmExternalProcessingListener final : public Toolkit::TBoxListener<IBoxListener>
|
||||
{
|
||||
public:
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
|
||||
};
|
||||
|
||||
class CBoxAlgorithmExternalProcessingDesc final : public IBoxAlgorithmDesc
|
||||
{
|
||||
public:
|
||||
void release() override {}
|
||||
CString getName() const override { return "External Processing"; }
|
||||
CString getAuthorName() const override { return "Alexis Placet"; }
|
||||
CString getAuthorCompanyName() const override { return "Mensia Technologies SA"; }
|
||||
CString getShortDescription() const override { return "This box can communicate via TCP with an other program."; }
|
||||
|
||||
CString getDetailedDescription() const override
|
||||
{
|
||||
return "Launches an external program which can then processes data. This box and the program communicate using TCP connection and a defined protocol.";
|
||||
}
|
||||
|
||||
CString getCategory() const override { return "Scripting"; }
|
||||
CString getVersion() const override { return "1.0"; }
|
||||
CString getSoftwareComponent() const override { return "openvibe-sdk"; }
|
||||
CString getAddedSoftwareVersion() const override { return "1.0.0"; }
|
||||
CString getUpdatedSoftwareVersion() const override { return "1.0.0"; }
|
||||
CString getStockItemName() const override { return "gtk-edit"; }
|
||||
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_ExternalProcessing; }
|
||||
IPluginObject* create() override { return new CBoxAlgorithmExternalProcessing; }
|
||||
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmExternalProcessingListener; }
|
||||
void releaseBoxListener(IBoxListener* boxListener) const override { delete boxListener; }
|
||||
|
||||
bool getBoxPrototype(Kernel::IBoxProto& boxAlgorithmPrototype) const override
|
||||
{
|
||||
boxAlgorithmPrototype.addSetting("Launch third party program", OV_TypeId_Boolean, "true"); // 0
|
||||
boxAlgorithmPrototype.addSetting("Executable path", OV_TypeId_Filename, ""); // 1
|
||||
boxAlgorithmPrototype.addSetting("Arguments", OV_TypeId_String, ""); // 2
|
||||
boxAlgorithmPrototype.addSetting("Port", OV_TypeId_Integer, "0"); // 3
|
||||
boxAlgorithmPrototype.addSetting("Automatic connection identifier", OV_TypeId_Boolean, "true"); // 4
|
||||
boxAlgorithmPrototype.addSetting("Custom connection identifier", OV_TypeId_String, ""); // 5
|
||||
boxAlgorithmPrototype.addSetting("Incoming connection timeout", OV_TypeId_Integer, "10"); // 6
|
||||
boxAlgorithmPrototype.addSetting("Generator", OV_TypeId_Boolean, "false"); // 7
|
||||
|
||||
boxAlgorithmPrototype.addFlag(Kernel::BoxFlag_CanAddInput);
|
||||
boxAlgorithmPrototype.addFlag(Kernel::BoxFlag_CanModifyInput);
|
||||
boxAlgorithmPrototype.addFlag(Kernel::BoxFlag_CanAddOutput);
|
||||
boxAlgorithmPrototype.addFlag(Kernel::BoxFlag_CanModifyOutput);
|
||||
boxAlgorithmPrototype.addFlag(Kernel::BoxFlag_CanAddSetting);
|
||||
boxAlgorithmPrototype.addFlag(Kernel::BoxFlag_CanModifySetting);
|
||||
return true;
|
||||
}
|
||||
|
||||
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_ExternalProcessingDesc)
|
||||
};
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
#include "ovpCBoxAlgorithmMatrixValidityChecker.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
|
||||
bool CBoxAlgorithmMatrixValidityChecker::initialize()
|
||||
{
|
||||
const Kernel::IBox& boxCtx = this->getStaticBoxContext();
|
||||
|
||||
uint64_t logLevel = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
|
||||
m_logLevel = Kernel::ELogLevel(logLevel);
|
||||
m_validityCheckerType = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
|
||||
if (boxCtx.getSettingCount() == 1
|
||||
) { m_validityCheckerType = OVP_TypeId_ValidityCheckerType_LogWarning.id(); } // note that for boxes with one setting, we fallback to the old behavior
|
||||
|
||||
OV_ERROR_UNLESS_KRF(boxCtx.getSettingCount() <= 1 || boxCtx.getInputCount() == boxCtx.getOutputCount(),
|
||||
"Invalid input count [" << boxCtx.getInputCount() << "] (expected same value as output count [" << boxCtx.getOutputCount() <<
|
||||
"])",
|
||||
Kernel::ErrorType::BadConfig);
|
||||
|
||||
m_decoders.resize(boxCtx.getInputCount());
|
||||
m_encoders.resize(boxCtx.getInputCount());
|
||||
for (size_t i = 0; i < boxCtx.getInputCount(); ++i)
|
||||
{
|
||||
m_decoders[i].initialize(*this, i);
|
||||
m_encoders[i].initialize(*this, i);
|
||||
m_encoders[i].getInputMatrix().setReferenceTarget(m_decoders[i].getOutputMatrix());
|
||||
}
|
||||
|
||||
m_lastValidSamples.clear();
|
||||
m_lastValidSamples.resize(boxCtx.getInputCount());
|
||||
m_nTotalInterpolatedSample.clear();
|
||||
m_nTotalInterpolatedSample.resize(boxCtx.getInputCount());
|
||||
m_nTotalInterpolatedChunk.clear();
|
||||
m_nTotalInterpolatedChunk.resize(boxCtx.getInputCount());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmMatrixValidityChecker::uninitialize()
|
||||
{
|
||||
const size_t nInput = this->getStaticBoxContext().getInputCount();
|
||||
for (size_t i = 0; i < nInput; ++i)
|
||||
{
|
||||
m_decoders[i].uninitialize();
|
||||
m_encoders[i].uninitialize();
|
||||
}
|
||||
m_decoders.clear();
|
||||
m_encoders.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmMatrixValidityChecker::processInput(const size_t /*index*/)
|
||||
{
|
||||
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmMatrixValidityChecker::process()
|
||||
{
|
||||
Kernel::IBoxIO& boxCtx = this->getDynamicBoxContext();
|
||||
const size_t nInput = this->getStaticBoxContext().getInputCount();
|
||||
const size_t nSetting = this->getStaticBoxContext().getSettingCount();
|
||||
|
||||
for (size_t i = 0; i < nInput; ++i)
|
||||
{
|
||||
for (size_t j = 0; j < boxCtx.getInputChunkCount(i); ++j)
|
||||
{
|
||||
m_decoders[i].decode(j);
|
||||
CMatrix* matrix = m_decoders[i].getOutputMatrix();
|
||||
|
||||
if (m_decoders[i].isHeaderReceived())
|
||||
{
|
||||
if (nSetting > 1) { m_encoders[i].encodeHeader(); }
|
||||
|
||||
if (m_validityCheckerType == OVP_TypeId_ValidityCheckerType_Interpolate.id())
|
||||
{
|
||||
m_nTotalInterpolatedSample[i] = 0;
|
||||
m_nTotalInterpolatedChunk[i] = 0;
|
||||
// for each channel, save of the last valid sample
|
||||
m_lastValidSamples[i].resize(matrix->getDimensionSize(0));
|
||||
}
|
||||
}
|
||||
if (m_decoders[i].isBufferReceived())
|
||||
{
|
||||
// log warning
|
||||
if (m_validityCheckerType == OVP_TypeId_ValidityCheckerType_LogWarning.id())
|
||||
{
|
||||
if (!matrix->isBufferValid())
|
||||
{
|
||||
getLogManager() << m_logLevel << "Matrix on input " << i << " either contains NAN or Infinity between " <<
|
||||
CTime(boxCtx.getInputChunkStartTime(i, j)) << " and " << CTime(boxCtx.getInputChunkEndTime(i, j)) << ".\n";
|
||||
}
|
||||
}
|
||||
// stop player
|
||||
else if (m_validityCheckerType == OVP_TypeId_ValidityCheckerType_StopPlayer.id())
|
||||
{
|
||||
if (!matrix->isBufferValid())
|
||||
{
|
||||
this->getPlayerContext().stop();
|
||||
OV_ERROR_KRF(
|
||||
"Invalid matrix content on input [" << i << "]: either contains NAN or Infinity between [" << CTime(boxCtx.
|
||||
getInputChunkStartTime(i, j)) << "] and [" << CTime(boxCtx.getInputChunkEndTime(i, j)) << "]",
|
||||
Kernel::ErrorType::BadInput);
|
||||
}
|
||||
}
|
||||
// interpolate
|
||||
else if (m_validityCheckerType == OVP_TypeId_ValidityCheckerType_Interpolate.id())
|
||||
{
|
||||
const size_t nChannel = matrix->getDimensionSize(0);
|
||||
const size_t nSample = matrix->getDimensionSize(1);
|
||||
double* buffer = matrix->getBuffer();
|
||||
size_t nInterpolatedSample = 0;
|
||||
|
||||
for (size_t k = 0; k < nChannel; ++k)
|
||||
{
|
||||
for (size_t l = 0; l < nSample; ++l)
|
||||
{
|
||||
if (std::isnan(buffer[l + k * nSample]) || std::isinf(buffer[l + k * nSample]))
|
||||
{
|
||||
// interpolation : order 0 (easiest for online interpolation)
|
||||
buffer[l + k * nSample] = m_lastValidSamples[i][k];
|
||||
nInterpolatedSample++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// save of the last valid sample of channel k
|
||||
m_lastValidSamples[i][k] = buffer[l + k * nSample];
|
||||
}
|
||||
}
|
||||
}
|
||||
m_nTotalInterpolatedSample[i] += nInterpolatedSample;
|
||||
|
||||
// log management
|
||||
if (nInterpolatedSample > 0 && m_nTotalInterpolatedSample[i] == nInterpolatedSample) // beginning of interpolation
|
||||
{
|
||||
getLogManager() << m_logLevel << "Matrix on input " << i << " either contains NAN or Infinity from " << CTime(
|
||||
boxCtx.getInputChunkStartTime(i, j)) << ": interpolation is enable.\n";
|
||||
}
|
||||
if (nInterpolatedSample > 0) // update of ChunkCount during interpolation
|
||||
{
|
||||
m_nTotalInterpolatedChunk[i]++;
|
||||
}
|
||||
if (nInterpolatedSample == 0 && m_nTotalInterpolatedSample[i] > 0) // end of interpolation
|
||||
{
|
||||
getLogManager() << m_logLevel << "Matrix on input " << i << " contained " << 100.0 * m_nTotalInterpolatedSample[i] / (
|
||||
m_nTotalInterpolatedChunk[i] * nSample * nChannel) << " % of NAN or Infinity. Interpolation disable from " << CTime(
|
||||
boxCtx.getInputChunkStartTime(i, j)) << ".\n";
|
||||
m_nTotalInterpolatedSample[i] = 0; // reset
|
||||
m_nTotalInterpolatedChunk[i] = 0;
|
||||
}
|
||||
}
|
||||
else { OV_WARNING_K("Invalid action type [" << m_validityCheckerType << "]"); }
|
||||
|
||||
if (nSetting > 1) { m_encoders[i].encodeBuffer(); }
|
||||
}
|
||||
if (m_decoders[i].isEndReceived()) { if (nSetting > 1) { m_encoders[i].encodeEnd(); } }
|
||||
if (nSetting > 1) { boxCtx.markOutputAsReadyToSend(i, boxCtx.getInputChunkStartTime(i, j), boxCtx.getInputChunkEndTime(i, j)); }
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ovp_defines.h"
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
class CBoxAlgorithmMatrixValidityChecker 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>, OVP_ClassId_BoxAlgorithm_MatrixValidityChecker)
|
||||
|
||||
protected:
|
||||
|
||||
std::vector<Toolkit::TStreamedMatrixDecoder<CBoxAlgorithmMatrixValidityChecker>> m_decoders;
|
||||
std::vector<Toolkit::TStreamedMatrixEncoder<CBoxAlgorithmMatrixValidityChecker>> m_encoders;
|
||||
Kernel::ELogLevel m_logLevel = Kernel::ELogLevel::LogLevel_None;
|
||||
uint64_t m_validityCheckerType = 0;
|
||||
|
||||
std::vector<size_t> m_nTotalInterpolatedSample;
|
||||
std::vector<size_t> m_nTotalInterpolatedChunk;
|
||||
std::vector<std::vector<double>> m_lastValidSamples;
|
||||
};
|
||||
|
||||
class CBoxAlgorithmMatrixValidityCheckerListener final : public Toolkit::TBoxListener<IBoxListener>
|
||||
{
|
||||
public:
|
||||
|
||||
bool check(Kernel::IBox& box) const
|
||||
{
|
||||
for (size_t i = 0; i < box.getInputCount(); ++i)
|
||||
{
|
||||
box.setInputName(i, ("Stream " + std::to_string(i + 1)).c_str());
|
||||
box.setInputType(i, OV_TypeId_StreamedMatrix);
|
||||
}
|
||||
for (size_t i = 0; i < box.getOutputCount(); ++i)
|
||||
{
|
||||
box.setOutputName(i, ("Output stream " + std::to_string(i + 1)).c_str());
|
||||
box.setInputType(i, OV_TypeId_StreamedMatrix);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onInputAdded(Kernel::IBox& box, const size_t index) override
|
||||
{
|
||||
box.setInputType(index, OV_TypeId_StreamedMatrix);
|
||||
if (box.getSettingCount() > 1) { box.addOutput("", OV_TypeId_StreamedMatrix); }
|
||||
this->check(box);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onInputRemoved(Kernel::IBox& box, const size_t index) override
|
||||
{
|
||||
box.removeOutput(index);
|
||||
this->check(box);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onOutputAdded(Kernel::IBox& box, const size_t index) override
|
||||
{
|
||||
box.setOutputType(index, OV_TypeId_StreamedMatrix);
|
||||
box.addInput("", OV_TypeId_StreamedMatrix);
|
||||
this->check(box);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onOutputRemoved(Kernel::IBox& box, const size_t index) override
|
||||
{
|
||||
box.removeInput(index);
|
||||
this->check(box);
|
||||
return true;
|
||||
}
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
|
||||
};
|
||||
|
||||
class CBoxAlgorithmMatrixValidityCheckerDesc final : virtual public IBoxAlgorithmDesc
|
||||
{
|
||||
public:
|
||||
void release() override { }
|
||||
CString getName() const override { return "Matrix validity checker"; }
|
||||
CString getAuthorName() const override { return "Yann Renard"; }
|
||||
CString getAuthorCompanyName() const override { return "INRIA/IRISA"; }
|
||||
|
||||
CString getShortDescription() const override { return "Checks if a matrix contains \"not a number\" or \"infinity\" elements"; }
|
||||
|
||||
CString getDetailedDescription() const override
|
||||
{
|
||||
return
|
||||
"This box is for debugging purposes and allows an author to check the validity of a streamed matrix and derived stream. This box can log a message, stop the player or interpolate data.";
|
||||
}
|
||||
|
||||
CString getCategory() const override { return "Tools"; }
|
||||
CString getVersion() const override { return "1.0"; }
|
||||
CString getSoftwareComponent() const override { return "openvibe-sdk"; }
|
||||
CString getAddedSoftwareVersion() const override { return "0.0.0"; }
|
||||
CString getUpdatedSoftwareVersion() const override { return "0.0.0"; }
|
||||
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_MatrixValidityChecker; }
|
||||
IPluginObject* create() override { return new CBoxAlgorithmMatrixValidityChecker; }
|
||||
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmMatrixValidityCheckerListener; }
|
||||
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
|
||||
|
||||
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
|
||||
{
|
||||
prototype.addInput("Stream 1", OV_TypeId_StreamedMatrix);
|
||||
prototype.addOutput("Output stream 1", OV_TypeId_StreamedMatrix);
|
||||
prototype.addSetting("Log level", OV_TypeId_LogLevel, "Warning");
|
||||
prototype.addSetting("Action to do", OVP_TypeId_ValidityCheckerType, OVP_TypeId_ValidityCheckerType_LogWarning.toString());
|
||||
prototype.addFlag(Kernel::BoxFlag_CanAddInput);
|
||||
prototype.addFlag(Kernel::BoxFlag_CanAddOutput);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_MatrixValidityCheckerDesc)
|
||||
};
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
#include "ovpCBoxAlgorithmStimulationListener.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
|
||||
bool CBoxAlgorithmStimulationListener::initialize()
|
||||
{
|
||||
const size_t nInput = this->getStaticBoxContext().getInputCount();
|
||||
for (size_t i = 0; i < nInput; ++i) { m_stimulationDecoders.push_back(new Toolkit::TStimulationDecoder<CBoxAlgorithmStimulationListener>(*this, i)); }
|
||||
|
||||
m_logLevel = Kernel::ELogLevel(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmStimulationListener::uninitialize()
|
||||
{
|
||||
const size_t nInput = this->getStaticBoxContext().getInputCount();
|
||||
for (size_t i = 0; i < nInput; ++i)
|
||||
{
|
||||
m_stimulationDecoders[i]->uninitialize();
|
||||
delete m_stimulationDecoders[i];
|
||||
}
|
||||
m_stimulationDecoders.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmStimulationListener::processInput(const size_t /*index*/)
|
||||
{
|
||||
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxAlgorithmStimulationListener::process()
|
||||
{
|
||||
const Kernel::IBox& staticboxCtx = this->getStaticBoxContext();
|
||||
Kernel::IBoxIO& boxCtx = this->getDynamicBoxContext();
|
||||
const size_t nInput = this->getStaticBoxContext().getInputCount();
|
||||
|
||||
for (size_t i = 0; i < nInput; ++i)
|
||||
{
|
||||
for (size_t j = 0; j < boxCtx.getInputChunkCount(i); ++j)
|
||||
{
|
||||
m_stimulationDecoders[i]->decode(j);
|
||||
if (m_stimulationDecoders[i]->isHeaderReceived()) { }
|
||||
if (m_stimulationDecoders[i]->isBufferReceived())
|
||||
{
|
||||
const IStimulationSet* stimSet = m_stimulationDecoders[i]->getOutputStimulationSet();
|
||||
|
||||
CString inputName;
|
||||
staticboxCtx.getInputName(i, inputName);
|
||||
for (size_t k = 0; k < stimSet->getStimulationCount(); ++k)
|
||||
{
|
||||
this->getLogManager() << m_logLevel
|
||||
<< "For input " << i << " with name " << inputName
|
||||
<< " got stimulation " << stimSet->getStimulationIdentifier(k)
|
||||
<< "[" << getTypeManager().getEnumerationEntryNameFromValue(OV_TypeId_Stimulation, stimSet->getStimulationIdentifier(k)) << "]"
|
||||
<< " at date " << CTime(stimSet->getStimulationDate(k))
|
||||
<< " and duration " << CTime(stimSet->getStimulationDuration(k)) << "\n";
|
||||
|
||||
OV_WARNING_UNLESS_K(
|
||||
stimSet->getStimulationDate(k) >= boxCtx.getInputChunkStartTime(i, j)
|
||||
&& stimSet->getStimulationDate(k) <= boxCtx.getInputChunkEndTime(i, j),
|
||||
"Invalid out of range date [" << CTime(stimSet->getStimulationDate(k)) << "] (expected value between ["
|
||||
<< CTime(boxCtx.getInputChunkStartTime(i, j)) << "] and [" << CTime(boxCtx.getInputChunkEndTime(i, j)) << "])");
|
||||
}
|
||||
}
|
||||
if (m_stimulationDecoders[i]->isEndReceived()) { }
|
||||
boxCtx.markInputAsDeprecated(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ovp_defines.h"
|
||||
#include <openvibe/ov_all.h>
|
||||
#include <toolkit/ovtk_all.h>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
|
||||
class CBoxAlgorithmStimulationListener 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>, OVP_ClassId_BoxAlgorithm_StimulationListener)
|
||||
|
||||
protected:
|
||||
|
||||
Kernel::ELogLevel m_logLevel = Kernel::LogLevel_None;
|
||||
std::vector<Toolkit::TStimulationDecoder<CBoxAlgorithmStimulationListener>*> m_stimulationDecoders;
|
||||
};
|
||||
|
||||
class CBoxAlgorithmStimulationListenerListener final : public Toolkit::TBoxListener<IBoxListener>
|
||||
{
|
||||
public:
|
||||
|
||||
bool check(Kernel::IBox& box) const
|
||||
{
|
||||
for (size_t i = 0; i < box.getInputCount(); ++i)
|
||||
{
|
||||
box.setInputName(i, ("Stimulation stream " + std::to_string(i + 1)).c_str());
|
||||
box.setInputType(i, OV_TypeId_Stimulations);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onInputRemoved(Kernel::IBox& box, const size_t /*index*/) override { return this->check(box); }
|
||||
bool onInputAdded(Kernel::IBox& box, const size_t /*index*/) override { return this->check(box); }
|
||||
|
||||
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
|
||||
};
|
||||
|
||||
class CBoxAlgorithmStimulationListenerDesc final : virtual public IBoxAlgorithmDesc
|
||||
{
|
||||
public:
|
||||
void release() override { }
|
||||
CString getName() const override { return "Stimulation listener"; }
|
||||
CString getAuthorName() const override { return "Yann Renard"; }
|
||||
CString getAuthorCompanyName() const override { return "INRIA/IRISA"; }
|
||||
CString getShortDescription() const override { return "Prints stimulation codes in the log manager"; }
|
||||
|
||||
CString getDetailedDescription() const override { return "Prints each received stimulationto the log using the log level specified in the box config."; }
|
||||
|
||||
CString getCategory() const override { return "Tools"; }
|
||||
CString getVersion() const override { return "1.0"; }
|
||||
CString getSoftwareComponent() const override { return "openvibe-sdk"; }
|
||||
CString getAddedSoftwareVersion() const override { return "0.0.0"; }
|
||||
CString getUpdatedSoftwareVersion() const override { return "0.0.0"; }
|
||||
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_StimulationListener; }
|
||||
IPluginObject* create() override { return new CBoxAlgorithmStimulationListener; }
|
||||
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmStimulationListenerListener; }
|
||||
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
|
||||
|
||||
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
|
||||
{
|
||||
prototype.addInput("Stimulation stream 1", OV_TypeId_Stimulations);
|
||||
prototype.addSetting("Log level to use", OV_TypeId_LogLevel, "Information");
|
||||
prototype.addFlag(Kernel::BoxFlag_CanAddInput);
|
||||
return true;
|
||||
}
|
||||
|
||||
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_StimulationListenerDesc)
|
||||
};
|
||||
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
// Boxes
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
#define OVP_ClassId_BoxAlgorithm_EBMLStreamSpy OpenViBE::CIdentifier(0x0ED76695, 0x01A69CC3)
|
||||
#define OVP_ClassId_BoxAlgorithm_EBMLStreamSpyDesc OpenViBE::CIdentifier(0x354A6864, 0x06BC570C)
|
||||
#define OVP_ClassId_BoxAlgorithm_ExternalProcessing OpenViBE::CIdentifier(0x15422959, 0x16304449)
|
||||
#define OVP_ClassId_BoxAlgorithm_ExternalProcessingDesc OpenViBE::CIdentifier(0x63386942, 0x61D42502)
|
||||
#define OVP_ClassId_BoxAlgorithm_MatrixValidityChecker OpenViBE::CIdentifier(0x60210579, 0x6F7519B6)
|
||||
#define OVP_ClassId_BoxAlgorithm_MatrixValidityCheckerDesc OpenViBE::CIdentifier(0x6AFC2671, 0x1D8C493C)
|
||||
#define OVP_ClassId_BoxAlgorithm_StimulationListener OpenViBE::CIdentifier(0x65731E1D, 0x47DE5276)
|
||||
#define OVP_ClassId_BoxAlgorithm_StimulationListenerDesc OpenViBE::CIdentifier(0x0EC013FD, 0x5DD23E44)
|
||||
|
||||
// Global defines
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
#ifdef TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
|
||||
#include "ovp_global_defines.h"
|
||||
#endif // TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
|
||||
|
||||
#define OVP_TypeId_ValidityCheckerType OpenViBE::CIdentifier(0x32EA493A, 0x11E56D82)
|
||||
#define OVP_TypeId_ValidityCheckerType_LogWarning OpenViBE::CIdentifier(0x747A0F84, 0x1097253A)
|
||||
#define OVP_TypeId_ValidityCheckerType_StopPlayer OpenViBE::CIdentifier(0x4EC06D50, 0x5B131CE2)
|
||||
#define OVP_TypeId_ValidityCheckerType_Interpolate OpenViBE::CIdentifier(0x1DE96E02, 0x53767550)
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "ovp_defines.h"
|
||||
|
||||
#include "box-algorithms/ovpCBoxAlgorithmEBMLStreamSpy.h"
|
||||
#include "box-algorithms/ovpCBoxAlgorithmStimulationListener.h"
|
||||
#include "box-algorithms/ovpCBoxAlgorithmMatrixValidityChecker.h"
|
||||
#include "box-algorithms/ovpCBoxAlgorithmExternalProcessing.h"
|
||||
|
||||
namespace OpenViBE {
|
||||
namespace Plugins {
|
||||
namespace Tools {
|
||||
|
||||
OVP_Declare_Begin()
|
||||
// ValidityCheckerType: this type registration enables the choice between different action to do on an invalid stream
|
||||
context.getTypeManager().registerEnumerationType(OVP_TypeId_ValidityCheckerType, "Action to do");
|
||||
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_ValidityCheckerType, "Log warning", OVP_TypeId_ValidityCheckerType_LogWarning.id());
|
||||
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_ValidityCheckerType, "Stop player", OVP_TypeId_ValidityCheckerType_StopPlayer.id());
|
||||
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_ValidityCheckerType, "Interpolate", OVP_TypeId_ValidityCheckerType_Interpolate.id());
|
||||
|
||||
OVP_Declare_New(CBoxAlgorithmStimulationListenerDesc);
|
||||
OVP_Declare_New(CBoxAlgorithmEBMLStreamSpyDesc);
|
||||
OVP_Declare_New(CBoxAlgorithmMatrixValidityCheckerDesc);
|
||||
OVP_Declare_New(CBoxAlgorithmExternalProcessingDesc);
|
||||
OVP_Declare_End()
|
||||
|
||||
} // namespace Tools
|
||||
} // namespace Plugins
|
||||
} // namespace OpenViBE
|
||||
@@ -0,0 +1,5 @@
|
||||
Time:1x1,End Time,Time signal:,Event Id,Event Date,Event Duration
|
||||
0.0000000000,1.0000000000,-1.#IND000000,,,
|
||||
1.0000000000,2.0000000000,-1.#IND000000,,,
|
||||
2.0000000000,3.0000000000,-1.#INF000000,,,
|
||||
3.0000000000,4.0000000000,0.0000000000,,,
|
||||
|
+421
@@ -0,0 +1,421 @@
|
||||
<OpenViBE-Scenario>
|
||||
<FormatVersion>2</FormatVersion>
|
||||
<Creator>OpenViBE Designer</Creator>
|
||||
<CreatorVersion>2.2.0</CreatorVersion>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<Identifier>(0x460057cc, 0xfaa7362d)</Identifier>
|
||||
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
|
||||
<Name>Test Name</Name>
|
||||
<DefaultValue>matrix-validity</DefaultValue>
|
||||
<Value>matrix-validity</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Inputs></Inputs>
|
||||
<Outputs></Outputs>
|
||||
<Boxes>
|
||||
<Box>
|
||||
<Identifier>(0x000003fa, 0x00002132)</Identifier>
|
||||
<Name>Matrix validity checker</Name>
|
||||
<AlgorithmClassIdentifier>(0x60210579, 0x6f7519b6)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
|
||||
<Name>Stream 1</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Outputs>
|
||||
<Output>
|
||||
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
|
||||
<Name>Output stream 1</Name>
|
||||
</Output>
|
||||
</Outputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0xa88b3667, 0x0871638c)</TypeIdentifier>
|
||||
<Name>Log level</Name>
|
||||
<DefaultValue>Warning</DefaultValue>
|
||||
<Value>Warning</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x32ea493a, 0x11e56d82)</TypeIdentifier>
|
||||
<Name>Action to do</Name>
|
||||
<DefaultValue>Log warning</DefaultValue>
|
||||
<Value>Log warning</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>368</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>960</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0xfa1061e7, 0x341aafb9)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x00000d10, 0x00007eaa)</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>1</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>256</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>960</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>(0x00003e6a, 0x00004b24)</Identifier>
|
||||
<Name>CSV File Writer</Name>
|
||||
<AlgorithmClassIdentifier>(0x428375e8, 0x325f2db9)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
|
||||
<Name>Input stream</Name>
|
||||
</Input>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Stimulations stream</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
|
||||
<Name>Filename</Name>
|
||||
<DefaultValue>record-[$core{date}-$core{time}].csv</DefaultValue>
|
||||
<Value>${Player_ScenarioDirectory}/$var{Test Name}-output.csv</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
|
||||
<Name>Precision</Name>
|
||||
<DefaultValue>10</DefaultValue>
|
||||
<Value>10</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Append data</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
|
||||
<Name>Only last matrix</Name>
|
||||
<DefaultValue>false</DefaultValue>
|
||||
<Value>false</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>432</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>960</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0xee4b6d30, 0x788aed29)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
|
||||
<Value></Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>4</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
<Box>
|
||||
<Identifier>(0x00004679, 0x000071fa)</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</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>1104</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>(0x00004e4d, 0x000039e9)</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>log(x-2)</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>304</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>960</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>(0x000058a3, 0x00004604)</Identifier>
|
||||
<Name>Player Controller</Name>
|
||||
<AlgorithmClassIdentifier>(0x5f426dce, 0x08456e13)</AlgorithmClassIdentifier>
|
||||
<Inputs>
|
||||
<Input>
|
||||
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
|
||||
<Name>Stimulations</Name>
|
||||
</Input>
|
||||
</Inputs>
|
||||
<Settings>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
|
||||
<Name>Stimulation name</Name>
|
||||
<DefaultValue>OVTK_StimulationId_Label_00</DefaultValue>
|
||||
<Value>OVTK_StimulationId_Label_00</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
<Setting>
|
||||
<TypeIdentifier>(0xcc14d8d6, 0xf27ecb73)</TypeIdentifier>
|
||||
<Name>Action to perform</Name>
|
||||
<DefaultValue>Pause</DefaultValue>
|
||||
<Value>Stop</Value>
|
||||
<Modifiability>false</Modifiability>
|
||||
</Setting>
|
||||
</Settings>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
|
||||
<Value>432</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
|
||||
<Value>1104</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
|
||||
<Value>(0x568d148e, 0x650792b3)</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
|
||||
<Value>2</Value>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
|
||||
<Value>1</Value>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Box>
|
||||
</Boxes>
|
||||
<Links>
|
||||
<Link>
|
||||
<Identifier>(0x00000c57, 0x00001eb3)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00004e4d, 0x000039e9)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x000003fa, 0x00002132)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x0000337a, 0x0000449a)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00000d10, 0x00007eaa)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x00004e4d, 0x000039e9)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x0000651e, 0x000040fc)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x000003fa, 0x00002132)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x00003e6a, 0x00004b24)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
<Link>
|
||||
<Identifier>(0x00007567, 0x00000d11)</Identifier>
|
||||
<Source>
|
||||
<BoxIdentifier>(0x00004679, 0x000071fa)</BoxIdentifier>
|
||||
<BoxOutputIndex>0</BoxOutputIndex>
|
||||
</Source>
|
||||
<Target>
|
||||
<BoxIdentifier>(0x000058a3, 0x00004604)</BoxIdentifier>
|
||||
<BoxInputIndex>0</BoxInputIndex>
|
||||
</Target>
|
||||
</Link>
|
||||
</Links>
|
||||
<Comments></Comments>
|
||||
<Metadata>
|
||||
<Entry>
|
||||
<Identifier>(0x00003b78, 0x00006392)</Identifier>
|
||||
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
|
||||
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":320,"identifier":"(0x000011d8, 0x00001e90)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":480},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00004896, 0x00003e2f)","index":0,"name":"Default tab","parentIdentifier":"(0x000011d8, 0x00001e90)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x000015cd, 0x00006b70)","index":0,"name":"Empty","parentIdentifier":"(0x00004896, 0x00003e2f)","type":0}]</Data>
|
||||
</Entry>
|
||||
</Metadata>
|
||||
</OpenViBE-Scenario>
|
||||
Reference in New Issue
Block a user