This commit is contained in:
2021-10-14 13:47:35 +02:00
commit 6625a8dfaa
4026 changed files with 844291 additions and 0 deletions
@@ -0,0 +1,50 @@
PROJECT(openvibe-plugins-signal-processing)
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
SET(PROJECT_VERSION ${OV_GLOBAL_VERSION_STRING})
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.hpp src/*.inl)
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRC_FILES}
"../../../contrib/packages/wavelet2d/wavelet2s.cpp"
"../../../contrib/packages/wavelet2d/wavelet2s.h")
target_include_directories(${PROJECT_NAME}
PRIVATE
src
src/algorithms/connectivity
src/algorithms/basic)
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
FOLDER ${PLUGINS_FOLDER}
COMPILE_FLAGS "-DOVP_Exports -DOVP_Shared")
INCLUDE_DIRECTORIES("../../../contrib/packages/wavelet2d")
ADD_DEFINITIONS(-D_USE_MATH_DEFINES)
# ---------------------------------
INCLUDE("FindOpenViBE")
INCLUDE("FindOpenViBECommon")
INCLUDE("FindOpenViBEToolkit")
INCLUDE("FindOpenViBEModuleEBML")
INCLUDE("FindThirdPartyBoost")
INCLUDE("FindThirdPartyEigen")
INCLUDE("FindThirdPartyFFTW3") # used by the wavelet library
INCLUDE("FindThirdPartyITPP") # note that itpp gives the fftw3 on Win
IF(OV_COMPILE_TESTS)
ADD_SUBDIRECTORY("test")
ENDIF(OV_COMPILE_TESTS)
# -----------------------------
# Install files
# -----------------------------
INSTALL(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${DIST_BINDIR}
LIBRARY DESTINATION ${DIST_LIBDIR}
ARCHIVE DESTINATION ${DIST_LIBDIR})
INSTALL(DIRECTORY signals/ DESTINATION ${DIST_DATADIR}/openvibe/scenarios/signals)
INSTALL(DIRECTORY box-tutorials/ DESTINATION ${DIST_DATADIR}/openvibe/scenarios/box-tutorials)
@@ -0,0 +1,600 @@
<OpenViBE-Scenario>
<FormatVersion>1</FormatVersion>
<Creator>openvibe</Creator>
<CreatorVersion>2.0</CreatorVersion>
<Boxes>
<Box>
<Identifier>(0x00000503, 0x00001d65)</Identifier>
<Name>1;4</Name>
<AlgorithmClassIdentifier>(0x361722e8, 0x311574e8)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Channel List</Name>
<DefaultValue>:</DefaultValue>
<Value>1;4</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x3bcf9e67, 0x0c23994d)</TypeIdentifier>
<Name>Action</Name>
<DefaultValue>Select</DefaultValue>
<Value>Select</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x666f25e9, 0x3e5738d6)</TypeIdentifier>
<Name>Channel Matching Method</Name>
<DefaultValue>Smart</DefaultValue>
<Value>Smart</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>160.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>336.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x277826e1, 0xa30a3bd0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>106</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00000ba1, 0x00004ae1)</Identifier>
<Name>Before</Name>
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Data</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel Units</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
<Name>Display Mode</Name>
<DefaultValue>Scan</DefaultValue>
<Value>Scan</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
<Name>Auto vertical scale</Name>
<DefaultValue>Per channel</DefaultValue>
<Value>Per channel</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Scale refresh interval (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Scale</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Offset</Name>
<DefaultValue>0</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Time Scale</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Horizontal ruler</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Vertical ruler</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Multiview</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>160.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>224.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>88</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>9</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000576e, 0x00000a4e)</Identifier>
<Name>Sinus oscillator</Name>
<AlgorithmClassIdentifier>(0x7e33bdb8, 0x68194a4a)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Generated signal</Name>
</Output>
</Outputs>
<Settings>
<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 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>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x0b214ed8, 0x1f9ad83a)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>121</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00ac4ab1)</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00006298, 0x000025dc)</Identifier>
<Name>After</Name>
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Data</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel Units</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
<Name>Display Mode</Name>
<DefaultValue>Scan</DefaultValue>
<Value>Scan</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
<Name>Auto vertical scale</Name>
<DefaultValue>Per channel</DefaultValue>
<Value>Per channel</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Scale refresh interval (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Scale</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Offset</Name>
<DefaultValue>0</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Time Scale</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Horizontal ruler</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Vertical ruler</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Multiview</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>256.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>88</Value>
</Attribute>
<Attribute>
<Identifier>(0xc67a01dc, 0x28ce06c1)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>9</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x00000924, 0x00001d39)</Identifier>
<Source>
<BoxIdentifier>(0x0000576e, 0x00000a4e)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00000ba1, 0x00004ae1)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>130</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>209</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00003d0f, 0x000056cd)</Identifier>
<Source>
<BoxIdentifier>(0x00000503, 0x00001d65)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00006298, 0x000025dc)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>192</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>226</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>289</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00007953, 0x00007c5f)</Identifier>
<Source>
<BoxIdentifier>(0x0000576e, 0x00000a4e)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00000503, 0x00001d65)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>130</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>336</Value>
</Attribute>
</Attributes>
</Link>
</Links>
<Comments>
<Comment>
<Identifier>(0x00002f95, 0x0000072c)</Identifier>
<Text>You can browse each box' documentation by selecting the box and pressing &lt;b&gt;F1&lt;/b&gt;</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>464</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>352</Value>
</Attribute>
</Attributes>
</Comment>
<Comment>
<Identifier>(0x0000479b, 0x00005f64)</Identifier>
<Text>Finally, the right &lt;i&gt;Signal Display&lt;/i&gt; box
displays the 2 selected channels</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>576</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>272</Value>
</Attribute>
</Attributes>
</Comment>
<Comment>
<Identifier>(0x000047d8, 0x00000b37)</Identifier>
<Text>The &lt;i&gt;&lt;b&gt;Channel Selector&lt;/b&gt;&lt;/i&gt; box takes only
the &lt;b&gt;first&lt;/b&gt; and &lt;b&gt;fourth&lt;/b&gt; channels
&lt;small&gt;(channel names are 0 indexed)&lt;/small&gt;</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>576</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>192</Value>
</Attribute>
</Attributes>
</Comment>
<Comment>
<Identifier>(0x00004fd2, 0x00003b1e)</Identifier>
<Text>Those 4 channels are displayed with the left
&lt;i&gt;Signal Display&lt;/i&gt; box</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>576</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>112</Value>
</Attribute>
</Attributes>
</Comment>
<Comment>
<Identifier>(0x000057a6, 0x00006a3d)</Identifier>
<Text>The &lt;i&gt;Sinus Oscillator&lt;/i&gt; box generates
a 4 channels sinusoidal signal</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>576</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>32</Value>
</Attribute>
</Attributes>
</Comment>
</Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":678,"identifier":"(0x0000037f, 0x000006dc)","index":0,"name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":794},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00003ddc, 0x00006202)","index":0,"name":"Default tab","parentIdentifier":"(0x0000037f, 0x000006dc)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":2,"dividerPosition":314,"identifier":"(0x000019f0, 0x0000358d)","index":0,"maxDividerPosition":633,"name":"Vertical split","parentIdentifier":"(0x00003ddc, 0x00006202)","type":4},{"boxIdentifier":"(0x00000ba1, 0x00004ae1)","childCount":0,"identifier":"(0x0000654d, 0x000076f4)","index":0,"parentIdentifier":"(0x000019f0, 0x0000358d)","type":3},{"boxIdentifier":"(0x00006298, 0x000025dc)","childCount":0,"identifier":"(0x00000303, 0x00002727)","index":1,"parentIdentifier":"(0x000019f0, 0x0000358d)","type":3}]</Data>
</Entry>
</Metadata>
<Attributes>
<Attribute>
<Identifier>(0x790d75b8, 0x3bb90c33)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x8c1fc55b, 0x7b433dc2)</Identifier>
<Value>1.0</Value>
</Attribute>
<Attribute>
<Identifier>(0x9f5c4075, 0x4a0d3666)</Identifier>
<Value>Channel Selector tutorial</Value>
</Attribute>
<Attribute>
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
<Value>Inria</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>
@@ -0,0 +1,509 @@
<OpenViBE-Scenario>
<FormatVersion>1</FormatVersion>
<Creator>openvibe</Creator>
<CreatorVersion>2.0</CreatorVersion>
<Boxes>
<Box>
<Identifier>(0x0000376d, 0x000001ee)</Identifier>
<Name>Signal display</Name>
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Data</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel Units</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
<Name>Display Mode</Name>
<DefaultValue>Scan</DefaultValue>
<Value>Scan</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
<Name>Auto vertical scale</Name>
<DefaultValue>Per channel</DefaultValue>
<Value>Per channel</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Scale refresh interval (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Scale</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Offset</Name>
<DefaultValue>0</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Time Scale</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Horizontal ruler</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Vertical ruler</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Multiview</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>336.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>113</Value>
</Attribute>
<Attribute>
<Identifier>(0xc67a01dc, 0x28ce06c1)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>9</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x5bdd9691, 0x130584b9)</Identifier>
<Name>Crop</Name>
<AlgorithmClassIdentifier>(0x7f1a3002, 0x358117ba)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input matrix</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output matrix</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0xd0643f9e, 0x8e35fe0a)</TypeIdentifier>
<Name>Crop method</Name>
<DefaultValue>Min</DefaultValue>
<Value>Min/Max</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Min crop value</Name>
<DefaultValue>-1</DefaultValue>
<Value>-3.000000</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Max crop value</Name>
<DefaultValue>1</DefaultValue>
<Value>3.000000</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>224</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>320</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x1b151919, 0x63b9f9c9)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>67</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x005c9c00)</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x5e2124c7, 0x1bda2228)</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>4 * cos(X)</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>112</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>320</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>(0xad100179, 0xa3c984ab)</Identifier>
<Value>95</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>(0x791a5334, 0x05cb62a2)</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>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>320</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x9e5ca01e, 0x30a4d8c3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>94</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00903800)</Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x00002232, 0x000023c9)</Identifier>
<Source>
<BoxIdentifier>(0x5bdd9691, 0x130584b9)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0000376d, 0x000001ee)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>249</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>320</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>312</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>289</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x39ec49f3, 0x56c136ff)</Identifier>
<Source>
<BoxIdentifier>(0x791a5334, 0x05cb62a2)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x5e2124c7, 0x1bda2228)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>320</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>88</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>320</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x3f52384e, 0x2c2082d2)</Identifier>
<Source>
<BoxIdentifier>(0x5e2124c7, 0x1bda2228)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x5bdd9691, 0x130584b9)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>137</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>320</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>200</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>320</Value>
</Attribute>
</Attributes>
</Link>
</Links>
<Comments>
<Comment>
<Identifier>(0x071dad5e, 0x17b33a03)</Identifier>
<Text>The &lt;i&gt;Time Signal&lt;/i&gt; box generates
a 1 channel linear signal (&lt;i&gt;f(t)=t&lt;/i&gt;)</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>576</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>48</Value>
</Attribute>
</Attributes>
</Comment>
<Comment>
<Identifier>(0x0f97f08c, 0x14474c97)</Identifier>
<Text>The &lt;i&gt;Simple DSP&lt;/i&gt; box applies a simple
function to each sample. This function is
&lt;i&gt;4 * cos(X)&lt;/i&gt; so the output signal is a
sinusoid in the [-4 +4] range.</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>576</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>128</Value>
</Attribute>
</Attributes>
</Comment>
<Comment>
<Identifier>(0x612a81a4, 0x68d7e635)</Identifier>
<Text>You can browse each box' documentation by selecting the box and pressing &lt;b&gt;F1&lt;/b&gt;</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>480</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>400</Value>
</Attribute>
</Attributes>
</Comment>
<Comment>
<Identifier>(0x698cfa37, 0x232575e8)</Identifier>
<Text>The &lt;i&gt;&lt;b&gt;Crop&lt;/b&gt;&lt;/i&gt; box cuts the signal
to a minimum of &lt;b&gt;-3&lt;/b&gt; and a maximum of
&lt;b&gt;+3&lt;/b&gt;. If the signal gets lower to the minimum
or higher to the maximum, the sample value is simply
replaced by the actual minimum or the actual maximum.</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>576</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>240</Value>
</Attribute>
</Attributes>
</Comment>
<Comment>
<Identifier>(0x7278a690, 0x0b27f24e)</Identifier>
<Text>Finally, the &lt;i&gt;Signal Display&lt;/i&gt; box
displays the result.</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>576</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>336</Value>
</Attribute>
</Attributes>
</Comment>
</Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0x0000376d, 0x000001ee)","childCount":0,"identifier":"(0x0000688d, 0x00006cbf)","index":0,"parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":1,"identifier":"(0x1aaf4e4d, 0x2e459ad4)","index":0,"name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":1},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x7293e89a, 0x29495377)","index":0,"name":"Default tab","parentIdentifier":"(0x1aaf4e4d, 0x2e459ad4)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x2b68cb14, 0x3a1b7595)","index":0,"name":"Empty","parentIdentifier":"(0x7293e89a, 0x29495377)","type":0}]</Data>
</Entry>
</Metadata>
</OpenViBE-Scenario>
@@ -0,0 +1,17 @@
4 4 32
0.190954
0.0934296
-0.018267
0.43378
0.0588937
0.28019
-0.0240636
0.308092
0.699474
-0.0584318
-0.0255184
0.189858
0.224142
0.139218
-0.0306152
0.215256
@@ -0,0 +1,916 @@
<OpenViBE-Scenario>
<FormatVersion>2</FormatVersion>
<Creator>OpenViBE Designer</Creator>
<CreatorVersion>2.1.0</CreatorVersion>
<Settings></Settings>
<Inputs></Inputs>
<Outputs></Outputs>
<Boxes>
<Box>
<Identifier>(0x000018a8, 0x00007deb)</Identifier>
<Name>Keyboard stimulator</Name>
<AlgorithmClassIdentifier>(0x00d317b9, 0x6324c3ff)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Outgoing Stimulations</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue>${Path_Data}/plugins/stimulation/simple-keyboard-to-stimulations.txt</DefaultValue>
<Value>${Path_Data}/plugins/stimulation/simple-keyboard-to-stimulations.txt</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>192</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>208</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x9b5dd008, 0x475a2ecd)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x027a6071)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00001ac2, 0x00007b76)</Identifier>
<Name>GDF file reader</Name>
<AlgorithmClassIdentifier>(0x3eeb1264, 0x4edfbd9a)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x403488e7, 0x565d70b6)</TypeIdentifier>
<Name>Experiment information</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EEG stream</Name>
</Output>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue></DefaultValue>
<Value>${Path_Data}/scenarios/signals/eog-artifact.gdf</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Samples per buffer</Name>
<DefaultValue>32</DefaultValue>
<Value>32</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Subtract physical minimum</Name>
<DefaultValue>False</DefaultValue>
<Value>False</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>-48</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>385</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x78b8b69d, 0x27afe678)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x016d098c)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00001ccf, 0x00002414)</Identifier>
<Name>EOG</Name>
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Data</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel Units</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
<Name>Display Mode</Name>
<DefaultValue>Scan</DefaultValue>
<Value>Scan</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
<Name>Auto vertical scale</Name>
<DefaultValue>Per channel</DefaultValue>
<Value>Per channel</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Scale refresh interval (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Scale</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Offset</Name>
<DefaultValue>0</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Time Scale</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Horizontal ruler</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Vertical ruler</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Multiview</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>448</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>224</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>9</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00003b19, 0x00002e65)</Identifier>
<Name>EOG</Name>
<AlgorithmClassIdentifier>(0x361722e8, 0x311574e8)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Channel List</Name>
<DefaultValue>:</DefaultValue>
<Value>1:4</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x3bcf9e67, 0x0c23994d)</TypeIdentifier>
<Name>Action</Name>
<DefaultValue>Select</DefaultValue>
<Value>Select</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x666f25e9, 0x3e5738d6)</TypeIdentifier>
<Name>Channel Matching Method</Name>
<DefaultValue>Smart</DefaultValue>
<Value>Smart</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>128</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>448</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x277826e1, 0xa30a3bd0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x001ceae3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000416e, 0x00001e7e)</Identifier>
<Name>EOG_Denoising_Calibration</Name>
<AlgorithmClassIdentifier>(0xe8dfe002, 0x70389932)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EEG</Name>
</Input>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EOG</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Train-completed Flag</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename b Matrix</Name>
<DefaultValue>b-Matrix-EEG.cfg</DefaultValue>
<Value>${Player_ScenarioDirectory}/b-Matrix-EEG.cfg</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Train Trigger</Name>
<DefaultValue>OVTK_GDF_End_Of_Session</DefaultValue>
<Value>OVTK_GDF_End_Of_Session</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>289</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>384</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xefef60c9, 0xe53f77fc)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x02afc5fc)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</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>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000041f0, 0x00007465)</Identifier>
<Name>EEG</Name>
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Data</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel Units</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
<Name>Display Mode</Name>
<DefaultValue>Scan</DefaultValue>
<Value>Scan</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
<Name>Auto vertical scale</Name>
<DefaultValue>Per channel</DefaultValue>
<Value>Per channel</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Scale refresh interval (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Scale</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Offset</Name>
<DefaultValue>0</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Time Scale</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Horizontal ruler</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Vertical ruler</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Multiview</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>448</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>96</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>9</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000489a, 0x0000011d)</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_TrainCompleted</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>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>352</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x568d148e, 0x650792b3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00f1bfbf)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00006eb3, 0x00003bc9)</Identifier>
<Name>Temporal filter</Name>
<AlgorithmClassIdentifier>(0xb4f9d042, 0x9d79f2e5)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Filtered signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x2f2c606c, 0x8512ed68)</TypeIdentifier>
<Name>Filter method</Name>
<DefaultValue>Butterworth</DefaultValue>
<Value>Butterworth</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0xfa20178e, 0x4cba62e9)</TypeIdentifier>
<Name>Filter type</Name>
<DefaultValue>Band pass</DefaultValue>
<Value>Band pass</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Filter order</Name>
<DefaultValue>4</DefaultValue>
<Value>4</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Low cut frequency (Hz)</Name>
<DefaultValue>29</DefaultValue>
<Value>2</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>High cut frequency (Hz)</Name>
<DefaultValue>40</DefaultValue>
<Value>40</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Pass band ripple (dB)</Name>
<DefaultValue>0.5</DefaultValue>
<Value>0.5</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>32</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>384</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x27a4ceec, 0x876d6384)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x01129423)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>6</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000071e4, 0x00006ad6)</Identifier>
<Name>EEG</Name>
<AlgorithmClassIdentifier>(0x361722e8, 0x311574e8)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Channel List</Name>
<DefaultValue>:</DefaultValue>
<Value>1:4</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x3bcf9e67, 0x0c23994d)</TypeIdentifier>
<Name>Action</Name>
<DefaultValue>Select</DefaultValue>
<Value>Reject</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x666f25e9, 0x3e5738d6)</TypeIdentifier>
<Name>Channel Matching Method</Name>
<DefaultValue>Smart</DefaultValue>
<Value>Smart</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>128</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>320</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x277826e1, 0xa30a3bd0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00269e1b)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x000022d8, 0x00002198)</Identifier>
<Source>
<BoxIdentifier>(0x00003b19, 0x00002e65)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0000416e, 0x00001e7e)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00002618, 0x00005d65)</Identifier>
<Source>
<BoxIdentifier>(0x000071e4, 0x00006ad6)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000041f0, 0x00007465)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x000026a2, 0x00001e65)</Identifier>
<Source>
<BoxIdentifier>(0x00006eb3, 0x00003bc9)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00003b19, 0x00002e65)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00002eaa, 0x00005a2b)</Identifier>
<Source>
<BoxIdentifier>(0x00001ac2, 0x00007b76)</BoxIdentifier>
<BoxOutputIndex>1</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00006eb3, 0x00003bc9)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x000039a0, 0x000077bd)</Identifier>
<Source>
<BoxIdentifier>(0x000018a8, 0x00007deb)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0000416e, 0x00001e7e)</BoxIdentifier>
<BoxInputIndex>2</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x000049ef, 0x000056c3)</Identifier>
<Source>
<BoxIdentifier>(0x00003b19, 0x00002e65)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00001ccf, 0x00002414)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00005978, 0x0000666f)</Identifier>
<Source>
<BoxIdentifier>(0x00006eb3, 0x00003bc9)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000071e4, 0x00006ad6)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x0000785e, 0x0000764c)</Identifier>
<Source>
<BoxIdentifier>(0x0000416e, 0x00001e7e)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0000489a, 0x0000011d)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00007c20, 0x00000003)</Identifier>
<Source>
<BoxIdentifier>(0x000071e4, 0x00006ad6)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0000416e, 0x00001e7e)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
</Links>
<Comments>
<Comment>
<Identifier>(0x00001b37, 0x000073e5)</Identifier>
<Text>This scenario estimates a denoising regressor
following the work of Schlögl and al., 2007.
Here, &lt;b&gt;&lt;i&gt;EOG Denoising Calibration&lt;/i&gt;&lt;/b&gt; estimates
the model using a more contaminated signal in the EOG
input and the rest (EEG signal) in the EEG input.
Press 'a' to in &lt;b&gt;&lt;i&gt;Keyboard Stimulator&lt;/i&gt;&lt;/b&gt; to start the
model estimation. Press 'u' to stop. The model is
output after the whole input has been processed.
After the model has been estimated, it can be
used with the 'eog-run.xml' scenario.
</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>720.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>160.000000</Value>
</Attribute>
</Attributes>
</Comment>
</Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0x000041f0, 0x00007465)","childCount":0,"identifier":"(0x0000218f, 0x00003d69)","parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":320,"identifier":"(0x0000299d, 0x00003e7a)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":475},{"boxIdentifier":"(0x000018a8, 0x00007deb)","childCount":0,"identifier":"(0x000047a3, 0x0000671a)","parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0x00001ccf, 0x00002414)","childCount":0,"identifier":"(0x00005019, 0x00007d87)","parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x000011ab, 0x00002e7d)","index":0,"name":"Default tab","parentIdentifier":"(0x0000299d, 0x00003e7a)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x0000031e, 0x000026a1)","index":0,"name":"Empty","parentIdentifier":"(0x000011ab, 0x00002e7d)","type":0}]</Data>
</Entry>
</Metadata>
<Attributes>
<Attribute>
<Identifier>(0x790d75b8, 0x3bb90c33)</Identifier>
<Value>Joao-Pedro Berti-Ligabo</Value>
</Attribute>
<Attribute>
<Identifier>(0x8c1fc55b, 0x7b433dc2)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x9f5c4075, 0x4a0d3666)</Identifier>
<Value>EOG: Run</Value>
</Attribute>
<Attribute>
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
<Value>Inria</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>
@@ -0,0 +1,960 @@
<OpenViBE-Scenario>
<FormatVersion>1</FormatVersion>
<Creator>openvibe</Creator>
<CreatorVersion>2.0</CreatorVersion>
<Boxes>
<Box>
<Identifier>(0x00003b19, 0x00002e65)</Identifier>
<Name>EOG</Name>
<AlgorithmClassIdentifier>(0x361722e8, 0x311574e8)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Channel List</Name>
<DefaultValue>:</DefaultValue>
<Value>1:4</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x3bcf9e67, 0x0c23994d)</TypeIdentifier>
<Name>Action</Name>
<DefaultValue>Select</DefaultValue>
<Value>Select</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x666f25e9, 0x3e5738d6)</TypeIdentifier>
<Name>Channel Matching Method</Name>
<DefaultValue>Smart</DefaultValue>
<Value>Smart</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>192.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>464.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x277826e1, 0xa30a3bd0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>106</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x001ceae3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00004d05, 0x00007de5)</Identifier>
<Name>After</Name>
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Data</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel Units</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
<Name>Display Mode</Name>
<DefaultValue>Scan</DefaultValue>
<Value>Scan</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
<Name>Auto vertical scale</Name>
<DefaultValue>Per channel</DefaultValue>
<Value>Per channel</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Scale refresh interval (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Scale</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Offset</Name>
<DefaultValue>0</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Time Scale</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Horizontal ruler</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Vertical ruler</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Multiview</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>432.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>416.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>88</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00221c5f)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc67a01dc, 0x28ce06c1)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>9</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000053ed, 0x0000612d)</Identifier>
<Name>EOG Denoising</Name>
<AlgorithmClassIdentifier>(0xc223ff12, 0x069a987e)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EEG</Name>
</Input>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EOG</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EEG_Corrected</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename b Matrix</Name>
<DefaultValue>b-Matrix-EEG.txt</DefaultValue>
<Value>${Player_ScenarioDirectory}/b-Matrix-EEG.cfg</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>288.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>416.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xc15f2638, 0x928d2db0)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>119</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x002fcaa5)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</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>2</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00005e30, 0x0000017a)</Identifier>
<Name>GDF file reader</Name>
<AlgorithmClassIdentifier>(0x3eeb1264, 0x4edfbd9a)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x403488e7, 0x565d70b6)</TypeIdentifier>
<Name>Experiment information</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EEG stream</Name>
</Output>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue></DefaultValue>
<Value>${Path_Data}/scenarios/signals/eog-artifact.gdf</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Samples per buffer</Name>
<DefaultValue>32</DefaultValue>
<Value>32</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Subtract physical minimum</Name>
<DefaultValue>False</DefaultValue>
<Value>False</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>32.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>400.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x78b8b69d, 0x27afe678)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>123</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00315309)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000069dc, 0x00007101)</Identifier>
<Name>Temporal filter</Name>
<AlgorithmClassIdentifier>(0xb4f9d042, 0x9d79f2e5)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Filtered signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x2f2c606c, 0x8512ed68)</TypeIdentifier>
<Name>Filter method</Name>
<DefaultValue>Butterworth</DefaultValue>
<Value>Butterworth</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0xfa20178e, 0x4cba62e9)</TypeIdentifier>
<Name>Filter type</Name>
<DefaultValue>Band pass</DefaultValue>
<Value>Band pass</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Filter order</Name>
<DefaultValue>4</DefaultValue>
<Value>4</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Low cut frequency (Hz)</Name>
<DefaultValue>29</DefaultValue>
<Value>2</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>High cut frequency (Hz)</Name>
<DefaultValue>40</DefaultValue>
<Value>40</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Pass band ripple (dB)</Name>
<DefaultValue>0.5</DefaultValue>
<Value>0.5</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>96</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x27a4ceec, 0x876d6384)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>119</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x003e921f)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>6</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000071e4, 0x00006ad6)</Identifier>
<Name>EEG</Name>
<AlgorithmClassIdentifier>(0x361722e8, 0x311574e8)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Channel List</Name>
<DefaultValue>:</DefaultValue>
<Value>1:4</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x3bcf9e67, 0x0c23994d)</TypeIdentifier>
<Name>Action</Name>
<DefaultValue>Select</DefaultValue>
<Value>Reject</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x666f25e9, 0x3e5738d6)</TypeIdentifier>
<Name>Channel Matching Method</Name>
<DefaultValue>Smart</DefaultValue>
<Value>Smart</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>192.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>336.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x277826e1, 0xa30a3bd0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>106</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00269e1b)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000721d, 0x00006b03)</Identifier>
<Name>Before</Name>
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Data</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel Units</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
<Name>Display Mode</Name>
<DefaultValue>Scan</DefaultValue>
<Value>Scan</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
<Name>Auto vertical scale</Name>
<DefaultValue>Per channel</DefaultValue>
<Value>Per channel</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Scale refresh interval (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Scale</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Offset</Name>
<DefaultValue>0</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Time Scale</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Horizontal ruler</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Vertical ruler</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Multiview</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>432.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>272.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>88</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00240e2e)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>9</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x00000568, 0x00001560)</Identifier>
<Source>
<BoxIdentifier>(0x000071e4, 0x00006ad6)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0000721d, 0x00006b03)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>224</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>402</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>257</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00000730, 0x0000533a)</Identifier>
<Source>
<BoxIdentifier>(0x00005e30, 0x0000017a)</BoxIdentifier>
<BoxOutputIndex>1</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000069dc, 0x00007101)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>79</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>400</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x0000150f, 0x00005c52)</Identifier>
<Source>
<BoxIdentifier>(0x000053ed, 0x0000612d)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00004d05, 0x00007de5)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>313</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>416</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>402</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>401</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x000018c1, 0x00002528)</Identifier>
<Source>
<BoxIdentifier>(0x000069dc, 0x00007101)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00003b19, 0x00002e65)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>115</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>162</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>464</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00003155, 0x00006d63)</Identifier>
<Source>
<BoxIdentifier>(0x00003b19, 0x00002e65)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000053ed, 0x0000612d)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>224</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>464</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>264</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>423</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00003ea1, 0x0000322f)</Identifier>
<Source>
<BoxIdentifier>(0x000069dc, 0x00007101)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000071e4, 0x00006ad6)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>115</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>162</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>336</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x0000515e, 0x00004b1e)</Identifier>
<Source>
<BoxIdentifier>(0x000071e4, 0x00006ad6)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000053ed, 0x0000612d)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>224</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>264</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>408</Value>
</Attribute>
</Attributes>
</Link>
</Links>
<Comments>
<Comment>
<Identifier>(0x00007d4d, 0x00006501)</Identifier>
<Text>This scenario performs denoising following
the work of Schl&#246;gl and al., 2007.
The model should be first calibrated using
the 'eog-calibration.xml' scenario.
&lt;b&gt;&lt;i&gt;EOG Denoising&lt;/i&gt;&lt;/b&gt; box uses the estimated model
and attempts to clean the EEG input of artifacts.
</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>720.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>224.000000</Value>
</Attribute>
</Attributes>
</Comment>
</Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":320,"identifier":"(0x00006444, 0x00003b19)","index":0,"name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":467},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x0000408e, 0x00005287)","index":0,"name":"Default tab","parentIdentifier":"(0x00006444, 0x00003b19)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":2,"dividerPosition":135,"identifier":"(0x00004ee6, 0x00007589)","index":0,"maxDividerPosition":275,"name":"Vertical split","parentIdentifier":"(0x0000408e, 0x00005287)","type":4},{"boxIdentifier":"(0x0000721d, 0x00006b03)","childCount":0,"identifier":"(0x00004fca, 0x000005fa)","index":0,"parentIdentifier":"(0x00004ee6, 0x00007589)","type":3},{"boxIdentifier":"(0x00004d05, 0x00007de5)","childCount":0,"identifier":"(0x00005ad7, 0x00000e3a)","index":1,"parentIdentifier":"(0x00004ee6, 0x00007589)","type":3}]</Data>
</Entry>
</Metadata>
<Attributes>
<Attribute>
<Identifier>(0x790d75b8, 0x3bb90c33)</Identifier>
<Value>Joao-Pedro Berti-Ligabo</Value>
</Attribute>
<Attribute>
<Identifier>(0x8c1fc55b, 0x7b433dc2)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x9f5c4075, 0x4a0d3666)</Identifier>
<Value>EOG: Calibration</Value>
</Attribute>
<Attribute>
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
<Value>Inria</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>
@@ -0,0 +1,50 @@
g_sent = false
g_numTrials = 10
function initialize(box)
dofile(box:get_config("${Path_Data}") .. "/plugins/stimulation/lua-stimulator-stim-codes.lua")
-- make sure we get equal number of both trials
g_numTrials = 2 * box:get_setting(2)
g_sent = false;
end
function uninitialize(box)
end
function process(box)
while box:keep_processing() and g_sent == false do
box:send_stimulation(1, OVTK_StimulationId_ExperimentStart, 0, 0)
current_time = 5
for i = 1 , g_numTrials do
if i % 2 == 0 then
box:send_stimulation(1, OVTK_GDF_Left, current_time+0, 0)
else
box:send_stimulation(1, OVTK_GDF_Right, current_time+0, 0)
end
box:send_stimulation(1, OVTK_StimulationId_Label_01, current_time+1, 0)
box:send_stimulation(1, OVTK_StimulationId_Label_00, current_time+2, 0)
box:send_stimulation(1, OVTK_StimulationId_Label_01, current_time+3, 0)
box:send_stimulation(1, OVTK_StimulationId_Label_00, current_time+4, 0)
box:send_stimulation(1, OVTK_StimulationId_RestStart, current_time+5, 0)
current_time = current_time + 10
end
box:send_stimulation(1, OVTK_StimulationId_ExperimentStop, current_time, 0)
box:send_stimulation(1, OVTK_StimulationId_EndOfFile, current_time+2, 0)
g_sent = true
box:sleep()
end
end
Binary file not shown.

After

Width:  |  Height:  |  Size: 558 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 939 B

@@ -0,0 +1,81 @@
/**
* \page BoxAlgorithm_AutoRegressiveCoefficients AR Features
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_AutoRegressiveCoefficients_Description|
*The AR features box calculate the coefficients using Burg's method [1] to compute the AutoRegressive (AR) model of an input signal.
The AR model is a representation that describes a time varying process by its own previous values.
The definition used is :
\image html ARBurg_Formula.png
<!-- "Formula of the AR model is x(t)=\sum_{i=1}^N a(i)x(t-i)+e(t)" -->
Where \e a(i) are the autoregressive coefficients or parameters of the model, \e x(t) is the input signal, \e x(t-i) its previous values, \e N is the order (length) of the model and \e epsilon(t) is the residue, assumed to be Gaussian white noise.
For more informations about AR model :
https://en.wikipedia.org/wiki/Autoregressive_model
http://paulbourke.net/miscellaneous/ar/
The model order (see [2]) needs to be specified in the settings of the box.
[1] Burg, J.P. (1967) "Maximum Entropy Spectral Analysis", Proceedings of the 37th Meeting of the Society of Exploration Geophysicists, Oklahoma City, Oklahoma
[2] D.J. Krusienski, D.J. MacFarland, J.R. Wolpaw. An evaluation of autoregressive spectral estimation model order for brain-computer interface application. Proceedings of the 28th IEEE EMBS Annual International Conference, New York City, USA, Aug 30-Sept 3, 2006
* |OVP_DocEnd_BoxAlgorithm_AutoRegressiveCoefficients_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_AutoRegressiveCoefficients_Inputs|
* |OVP_DocEnd_BoxAlgorithm_AutoRegressiveCoefficients_Inputs|
* |OVP_DocBegin_BoxAlgorithm_AutoRegressiveCoefficients_Input1|
The input signal
* |OVP_DocEnd_BoxAlgorithm_AutoRegressiveCoefficients_Input1|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_AutoRegressiveCoefficients_Outputs|
* |OVP_DocEnd_BoxAlgorithm_AutoRegressiveCoefficients_Outputs|
* |OVP_DocBegin_BoxAlgorithm_AutoRegressiveCoefficients_Output1|
The AR coefficients stored in a Feature vector
* |OVP_DocEnd_BoxAlgorithm_AutoRegressiveCoefficients_Output1|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_AutoRegressiveCoefficients_Settings|
* |OVP_DocEnd_BoxAlgorithm_AutoRegressiveCoefficients_Settings|
* |OVP_DocBegin_BoxAlgorithm_AutoRegressiveCoefficients_Setting1|
Specify the order, thus the number of coefficients calculated
* |OVP_DocEnd_BoxAlgorithm_AutoRegressiveCoefficients_Setting1|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_AutoRegressiveCoefficients_Examples|
* |OVP_DocEnd_BoxAlgorithm_AutoRegressiveCoefficients_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_AutoRegressiveCoefficients_Miscellaneous|
The output feature vector contains the coefficients for each channel : the first [order+1] elements are the coefficients of the first channel, etc.
* |OVP_DocEnd_BoxAlgorithm_AutoRegressiveCoefficients_Miscellaneous|
*/
@@ -0,0 +1,93 @@
/**
* \page BoxAlgorithm_ConnectivityMeasure Connectivity Measure
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Description|
This box measure connectivity between all channels of a signal using several method. For now, Coherence, Magnitude Squared Coherence, Imaginary part of Coherence, and absolute value of the Imaginary part are available.
They are defined in [1].
The coherence definitions used are :
\f[ Coherence = \frac{\left| S_{xy} \right|}{sqrt{(P_{xx}.P_{yy})} } \f]
\f[ Magnitude Squared Coherence = \frac{\left| S_{xy} \right|^2}{(P_{xx}.P_{yy})} \f]
\f[ Imaginary Coherence = \frac{Im(S_{xy})}{sqrt{(P_{xx}.P_{yy})} } \f]
\f[ Absolute Value Of Imaginary Coherence = \frac{\left| Im(S_{xy}) \right|}{sqrt{(P_{xx}.P_{yy})} } \f]
With \e \f$ S_{xy} \f$ the cross-spectral density between two signal channels, and \e \f$ P_{xx} \f$ and \e \f$ P_{yy} \f$ the Power Spectral Densities of the two channels.
The spectral densities are estimated via Welch's method [2]
[1] Nolte & al (2004) "Identifying true brain interaction from EEG data using the imaginary part of coherency", Clinical Neurophysiology Volume 115, Issue 10, October 2004
[2] Welch, P.D. (1967) "The Use of Fast Fourier Transform for the Estimation of Power Spectra: A Method Based on Time Averaging Over Short, Modified Periodograms", IEEE Transactions on Audio Electroacoustics, AU-15, 70–73
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Inputs|
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Inputs|
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Input1|
The input signal on which connectivity between channels will be measured.
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Input1|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Outputs|
The output of the box is the connectivity Matrix
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Outputs|
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Output1|
The connectivity matrix is a 3D Matrix of size \e frequency_taps \e x \e nb_channels \e x \e nb_channels
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Output1|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Settings|
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Settings|
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Setting1|
Choice of the algorithm to measure the connectivity (Magnitude Squared Coherence, Imaginary Coherence).
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Setting1|
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Setting2|
The windowing method to apply. Available options are Hamming, Hanning and Welch.
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Setting2|
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Setting3|
The length of the window in seconds for the windowing method.
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Setting3|
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Setting4|
The percentage of overlap of the windowing method
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Setting4|
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Setting5|
The length of signal to receive (in seconds) before processing the connectivity on it.
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Setting5|
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Setting6|
The percentage of signal overlap to process the connectivity on.
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Setting6|
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Setting7|
The amount of frequency taps for the connectivity measure.
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Setting7|
* |OVP_DocBegin_BoxAlgorithm_ConnectivityMeasure_Setting8|
Option to remove DC component from signal.
* |OVP_DocEnd_BoxAlgorithm_ConnectivityMeasure_Setting8|
@@ -0,0 +1,79 @@
/**
* \page BoxAlgorithm_DiscreteWaveletTransform DiscreteWaveletTransform
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Description|
* This box calculates the discrete wavelet transform using the following library:
http://wavelet2d.sourceforge.net/
There are differents options for the wavelet's choice like Haar,Daubechie, Biorthogonal, Coiflets, Symlets.
The user must pay attention in the samples quantity sent to the box because it has to be higher than 2^J
where J is the decomposition levels.
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Inputs|
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Inputs|
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Input1|
Signal to be decomposed.
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Input1|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Outputs|
There are at least 3 outputs and there is always the 'Info' output which is necessary to be connected to the
'Info' signal in the inverse discrete wavelets transform.
The decompositions start with the less detailed level (low frequencies) (A) and go until the highest detailed level (high frequencies) (D1)
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Outputs|
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Output1|
Info signal (needed to export samples length)
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Output1|
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Output2|
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Output2|
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Output3|
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Output3|
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Output4|
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Output4|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Settings|
You can choose the level of decomposition and the wavelet type
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Settings|
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Setting1|
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Setting1|
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Setting2|
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Setting2|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Examples|
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_DiscreteWaveletTransform_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_DiscreteWaveletTransform_Miscellaneous|
*/
@@ -0,0 +1,69 @@
/**
* \page BoxAlgorithm_EOGDenoising EOG Denoising
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoising_Description|
* This box uses a denoising matrix 'b' calculated previously through the EOG_Denoising_Calibration for removing the EOG effects on EEG. The principle is based on regression analysis (see article 'A fully automated correction method of EOG artifacts in EEG recordings) where a matrix 'b' is estimated being:b = <'Nt N>-¹<'N S> with N being the noise (EOG electrodes) and S the source (EEG electrodes).
The signal output is the EEG_Corrected (free of EOG noise):O=S-b*N (EEG_Corrected = EEG - b*EOG)
* |OVP_DocEnd_BoxAlgorithm_EOGDenoising_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoising_Inputs|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoising_Inputs|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoising_Input1|
* Make sure to select the same quantity of EEG channels as specified in your 'b' parameter matrix
* |OVP_DocEnd_BoxAlgorithm_EOGDenoising_Input1|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoising_Input2|
* Make sure to select the same quantity of EOG channels as specified in your 'b' parameter matrix
* |OVP_DocEnd_BoxAlgorithm_EOGDenoising_Input2|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoising_Outputs|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoising_Outputs|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoising_Output1|
* The output has the same structure as the EEG input
* |OVP_DocEnd_BoxAlgorithm_EOGDenoising_Output1|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoising_Settings|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoising_Settings|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoising_Setting1|
* Make sure to select the right file containing your 'b' matrix with the right coefficients
* |OVP_DocEnd_BoxAlgorithm_EOGDenoising_Setting1|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoising_Examples|
* You can apply these boxes in a set with a high density of blinking eyes and see the results before and after.
* |OVP_DocEnd_BoxAlgorithm_EOGDenoising_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoising_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoising_Miscellaneous|
*/
@@ -0,0 +1,77 @@
/**
* \page BoxAlgorithm_EOGDenoisingCalibration EOG_Denoising_Calibration
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Description|
This box calculates a denoising matrix 'b' for removing the EOG effects on EEG. The principle is based on regression analysis (see article 'A fully automated correction method of EOG artifacts in EEG recordings' - Schlogl2007) where a matrix 'b' is estimated being: b = <'Nt N>-¹<'N S> with N being the noise (EOG electrodes) and S the source (EEG electrodes).
This box reads necessarily from a file where the subject does lots of blinks. User will set a starting and an ending point at this file then the program will calculates the b matrix after reading throughout the file.
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Inputs|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Inputs|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Input1|
* Make sure to select the desirable EEG channels
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Input1|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Input2|
* Make sure to select the desirable EOG channels
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Input2|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Input3|
* Connect this stimulation to the keyboard_controller.
* Press 'a' for set the starting point and 'u' for set the ending point
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Input3|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Outputs|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Outputs|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Output1|
Connect this stimulation to the Player Controller to stop the scenario when b matrix is calculated
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Output1|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Settings|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Settings|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Setting1|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Setting1|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Setting2|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Setting2|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Setting3|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Setting3|
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Setting4|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Setting4|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Examples|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EOGDenoisingCalibration_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_EOGDenoisingCalibration_Miscellaneous|
*/
@@ -0,0 +1,96 @@
/**
* \page BoxAlgorithm_ERSPAverage ERSP Average
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_ERSPAverage_Description|
The ERSP Average box is intended to be used for computing
Event-Related Spectral Perturbation (ERSP) plots. These plots
show, starting from a stimulus onset, how the power spectrum
develops over time on the average across the trials. This is not
straightforwardly achievable with the other averaging boxes,
as the OpenViBE Spectrum stream does not have a time dimension:
a spectrum chunk is a matrix [frequency X channel], whereas to compute
the average evolution of a spectra over time, we would need a
tensor [frequency X channel X time] per trial and then average
these across the trials.
To achieve the average, the ERSP Average box collects individual
spectra, and computes the average when requested. In more detail,
assume you have EEG data for trial t. Using other boxes, you can
segment this trial to k spectral power estimates s1,s2,...,sk.
Now what the ERSP average does is to average these estimates
across the trials, and returns E[s1], E[s2], ..., E[sk], which
you can then plot as the average evolution of the spectrum
after the stimulus onset.
* |OVP_DocEnd_BoxAlgorithm_ERSPAverage_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_ERSPAverage_Inputs|
* |OVP_DocEnd_BoxAlgorithm_ERSPAverage_Inputs|
* |OVP_DocBegin_BoxAlgorithm_ERSPAverage_Input1|
The spectrum stream to average
* |OVP_DocEnd_BoxAlgorithm_ERSPAverage_Input1|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_ERSPAverage_Outputs|
* |OVP_DocEnd_BoxAlgorithm_ERSPAverage_Outputs|
* |OVP_DocBegin_BoxAlgorithm_ERSPAverage_Output1|
A sequence of chunks encoding the evolution of the spectra after stimulus onset.
* |OVP_DocEnd_BoxAlgorithm_ERSPAverage_Output1|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_ERSPAverage_Settings|
* |OVP_DocEnd_BoxAlgorithm_ERSPAverage_Settings|
* |OVP_DocBegin_BoxAlgorithm_ERSPAverage_Setting1|
The stimulation to identify the trial start (stimulus onset).
* |OVP_DocEnd_BoxAlgorithm_ERSPAverage_Setting1|
* |OVP_DocBegin_BoxAlgorithm_ERSPAverage_Setting2|
The stimulation to trigger the computation of the average.
* |OVP_DocEnd_BoxAlgorithm_ERSPAverage_Setting2|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_ERSPAverage_Examples|
See the box tutorial ersp-average.mxs bundled with OpenViBE.
* |OVP_DocEnd_BoxAlgorithm_ERSPAverage_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_ERSPAverage_Miscellaneous|
The box does not return anything until the computation trigger is received. After that, its output is set to start from time 0. Upon computation, its buffers and counters will be automatically cleared.
* |OVP_DocEnd_BoxAlgorithm_ERSPAverage_Miscellaneous|
*/
@@ -0,0 +1,186 @@
/**
* \page BoxAlgorithm_EpochVariance Epoch variance
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Description|
* This box is an extension of the Epoch Average box. It offers several methods of averaging for epoched streams but also outputs variance and confidence bounds.
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Inputs|
* The input type of this box can be changed. Its type must be derived of
* type \ref Doc_Streams_StreamedMatrix in order to be parsed by the input
* reader. If the author changes the input type, the output type will
* be changed the same way.
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Inputs|
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Input1|
* This input receives the input streamed matrix to average.
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Input1|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Outputs|
* The output type of this box can be changed. Its type must be derived of
* type \ref Doc_Streams_StreamedMatrix in order for the writer to format
* the output chunks. If the author changes the output type, the input
* type will be changed the same way.
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Outputs|
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Output1|
* This output sends the averaged streamed matrix. Averaging method is done
* according to the box settings.
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Output1|
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Output2|
* This output sends the variance of the input. Averaging method is done
* according to the box settings.
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Output2|
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Output3|
* This output sends the confidence bounds of the input. Averaging method is done
* according to the box settings.
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Output3|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Settings|
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Settings|
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Setting1|
* This setting gives the method to use in order to average the input
* matrices. It can be of two types :
* - <em>Moving average</em> : in this case, the averaging is done at
* every input reception on the last few buffers, starting as soon
* as enough input has been received.
* - <em>Moving average (Immediate)</em> : in this case, the averaging is done at
* every input reception on the last few buffers, starting immediately. When
* the number of received buffer is lower than the wished number of epochs, the
* average is computed on this very few number of input buffers.
* - <em>Epoch block average</em> : in this case, the averaging
* is done on a number of epochs (see next setting). Once this exact
* number of input is received, the average is computed and output.
* - <em>Cumulative average</em> : in this case, the averaging
* is done on an infinite number of epochs starting from the first
* received buffer to the last received buffer. This can be \b very
* memory consuming !
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Setting1|
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Setting2|
* This setting tells the box how much buffer it should use in order to
* compute the average.
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Setting2|
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Setting3|
* Significance Level for the confidence bound computation.
* The higher it is, the tighter the confidence interval will be.
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Setting3|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Examples|
* Let's study two cases. First, suppose you have such box with
* <em>Epoch block average</em> set and <em>four</em> epochs.
* The input stream is as follows :
\verbatim
+----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+
| I1 | | I2 | | I3 | | I4 | | I5 | | I6 | | I7 | | I8 | | I9 | ...
+----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+
\endverbatim
* The output stream will look like this :
\verbatim
+----+ +----+
| O1 | | O2 | ...
+----+ +----+
\endverbatim
* where \c O1 is the average of \c I1, \c I2, \c I3 and \c I4 and
* where \c O2 is the average of \c I5, \c I6, \c I7 and \c I8.
*
* Now consider the case where you configured this box with
* <em>Moving average</em> and <em>four</em> epochs. Given the
* same input stream :
\verbatim
+----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+
| I1 | | I2 | | I3 | | I4 | | I5 | | I6 | | I7 | | I8 | | I9 | ...
+----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+
\endverbatim
* The output stream will look like this :
\verbatim
+----+ +----+ +----+ +----+ +----+ +----+
| O1 | | O2 | | O3 | | O4 | | O5 | | O6 | ...
+----+ +----+ +----+ +----+ +----+ +----+
\endverbatim
* where :
* - \c O1 is the average of \c I1, \c I2, \c I3 and \c I4
* - \c O2 is the average of \c I2, \c I3, \c I4 and \c I5
* - \c O3 is the average of \c I3, \c I4, \c I5 and \c I6
* - \c O4 is the average of \c I4, \c I5, \c I6 and \c I7
* - etc...
*
* Again consider the case where you configured this box with
* <em>Moving average (Immediate)</em> and <em>four</em> epochs. Given the
* same input stream :
\verbatim
+----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+
| I1 | | I2 | | I3 | | I4 | | I5 | | I6 | | I7 | | I8 | | I9 | ...
+----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+
\endverbatim
* The output stream will look like this :
\verbatim
+----+ +----+ +----+ +----+ +----+ +----+
| O1 | | O2 | | O3 | | O4 | | O5 | | O6 | ...
+----+ +----+ +----+ +----+ +----+ +----+
\endverbatim
* where :
* - \c O1 is exactly \c I1
* - \c O2 is the average of \c I1 and \c I2
* - \c O3 is the average of \c I1, \c I2 and \c I3
* - \c O4 is the average of \c I1, \c I2, \c I3 and \c I4
* - \c O5 is the average of \c I2, \c I3, \c I4 and \c I5
* - \c O6 is the average of \c I3, \c I4, \c I5 and \c I6
* - etc...
*
* Finally consider the case where you configured this box with
* <em>Cumulative average</em> and <em>four</em> epochs. Given the
* same input stream :
\verbatim
+----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+
| I1 | | I2 | | I3 | | I4 | | I5 | | I6 | | I7 | | I8 | | I9 | ...
+----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+ +----+
\endverbatim
* The output stream will look like this :
\verbatim
+----+ +----+ +----+ +----+ +----+ +----+
| O1 | | O2 | | O3 | | O4 | | O5 | | O6 | ...
+----+ +----+ +----+ +----+ +----+ +----+
\endverbatim
* where :
* - \c O1 is exactly \c I1
* - \c O2 is the average of \c I1 and \c I2
* - \c O3 is the average of \c I1, \c I2 and \c I3
* - \c O4 is the average of \c I1, \c I2, \c I3 and \c I4
* - \c O5 is the average of \c I1, \c I2, \c I3, \c I4, and \c I5
* - \c O6 is the average of \c I1, \c I2, \c I3, \c I4, \c I5, and \c I6
* - etc...
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_EpochVariance_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_EpochVariance_Miscellaneous|
*/
@@ -0,0 +1,71 @@
/**
* \page BoxAlgorithm_HilbertTransform Hilbert Transform
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_HilbertTransform_Description|
This box computes the envelope and the instantaneous phase by performing the Discrete-Time Analytic signal [1] using Hilbert transform (see http://en.wikipedia.org/wiki/Analytic_signal).
The definition of analytic signal :
\image html AnalyticRepresentation.png
<!-- "Formula of the Analytic signal is x_a(t)=x(t)+i*H(x)(t)"-->
With \e x(t) the input signal, \e H(x) its Hilbert transform and \e i the imaginary unit.
For more informations on Hilbert transform and EEG see also : http://www.scholarpedia.org/article/Hilbert_transform_for_brain_waves
[1] Marple, S.L., "Computing the discrete-time analytic signal via FFT," IEEE Transactions on Signal Processing, Vol. 47, No.9 (September 1999), pp.2600-2603.
* |OVP_DocEnd_BoxAlgorithm_HilbertTransform_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_HilbertTransform_Inputs|
* |OVP_DocEnd_BoxAlgorithm_HilbertTransform_Inputs|
* |OVP_DocBegin_BoxAlgorithm_HilbertTransform_Input1|
The input signal
* |OVP_DocEnd_BoxAlgorithm_HilbertTransform_Input1|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_HilbertTransform_Outputs|
* |OVP_DocEnd_BoxAlgorithm_HilbertTransform_Outputs|
* |OVP_DocBegin_BoxAlgorithm_HilbertTransform_Output1|
Return the Hilbert transform (imaginary part of the analytic signal) of the input
* |OVP_DocEnd_BoxAlgorithm_HilbertTransform_Output1|
* |OVP_DocBegin_BoxAlgorithm_HilbertTransform_Output2|
Return the envelope signal of the input
* |OVP_DocEnd_BoxAlgorithm_HilbertTransform_Output2|
* |OVP_DocBegin_BoxAlgorithm_HilbertTransform_Output3|
Return instantaneous phase of the input
* |OVP_DocEnd_BoxAlgorithm_HilbertTransform_Output3|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_HilbertTransform_Examples|
<!--TO DO : Add some examples and screenshots of the results-->
* |OVP_DocEnd_BoxAlgorithm_HilbertTransform_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_HilbertTransform_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_HilbertTransform_Miscellaneous|
*/
@@ -0,0 +1,67 @@
/**
* \page BoxAlgorithm_InverseDWT Inverse DWT
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Description|
See Discrete Wavelet Transform box for more informations
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Inputs|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Inputs|
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Input1|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Input1|
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Input2|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Input2|
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Input3|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Input3|
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Input4|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Input4|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Outputs|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Outputs|
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Output1|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Output1|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Settings|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Settings|
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Setting1|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Setting1|
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Setting2|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Setting2|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Examples|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_InverseDWT_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_InverseDWT_Miscellaneous|
*/
@@ -0,0 +1,51 @@
/**
* \page BoxAlgorithm_Matrix3DTo2D 3D to 2D Matrix conversion
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_Matrix3DTo2D_Description|
This box extracts a 2D matrix from a 3D matrix by removing a dimension and selecting a 2D matrix at the desired index
of the removed dimension.
* |OVP_DocEnd_BoxAlgorithm_Matrix3DTo2D_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_Matrix3DTo2D_Inputs|
* |OVP_DocEnd_BoxAlgorithm_Matrix3DTo2D_Inputs|
* |OVP_DocBegin_BoxAlgorithm_Matrix3DTo2D_Input1|
3D Matrix from which a 2D matrix ( a "slice") will be extracted.
* |OVP_DocEnd_BoxAlgorithm_Matrix3DTo2D_Input1|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_Matrix3DTo2D_Outputs|
* |OVP_DocEnd_BoxAlgorithm_Matrix3DTo2D_Outputs|
* |OVP_DocBegin_BoxAlgorithm_Matrix3DTo2D_Output1|
The 2D matrix extrated from the input Matrix
* |OVP_DocEnd_BoxAlgorithm_Matrix3DTo2D_Output1|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_Matrix3DTo2D_Settings|
* |OVP_DocEnd_BoxAlgorithm_Matrix3DTo2D_Settings|
* |OVP_DocBegin_BoxAlgorithm_Matrix3DTo2D_Setting1|
The dimension to remove from the 3D Matrix. Possible values are ranging in [ 0 - 2 ].
* |OVP_DocEnd_BoxAlgorithm_Matrix3DTo2D_Setting1|
* |OVP_DocBegin_BoxAlgorithm_Matrix3DTo2D_Setting2|
The index from the removed dimension at which to extract the 2 Matrix (the "slice").
* |OVP_DocEnd_BoxAlgorithm_Matrix3DTo2D_Setting2|
* |OVP_DocBegin_BoxAlgorithm_Matrix3DTo2D_Setting3|
* |OVP_DocEnd_BoxAlgorithm_Matrix3DTo2D_Setting3|
@@ -0,0 +1,88 @@
/**
* \page BoxAlgorithm_QuadraticForm Quadratic Form
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_QuadraticForm_Description|
a square matrix A (which can be seen as a spatial filter) is applied to the input signals m (a vector). Then the transpose m^T of the input signals is multiplied to the resulting vector. In other words the output o is such as: o = m^T * A * m.
* |OVP_DocEnd_BoxAlgorithm_QuadraticForm_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_QuadraticForm_Inputs|
* |OVP_DocEnd_BoxAlgorithm_QuadraticForm_Inputs|
* |OVP_DocBegin_BoxAlgorithm_QuadraticForm_Input1|
The input signal to be used in the computation of the quadratic form
* |OVP_DocEnd_BoxAlgorithm_QuadraticForm_Input1|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_QuadraticForm_Outputs|
* |OVP_DocEnd_BoxAlgorithm_QuadraticForm_Outputs|
* |OVP_DocBegin_BoxAlgorithm_QuadraticForm_Output1|
the results of the computation of the quadratic form, perform with the input signals and the matrix defined in the settings
* |OVP_DocEnd_BoxAlgorithm_QuadraticForm_Output1|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_QuadraticForm_Settings|
* |OVP_DocEnd_BoxAlgorithm_QuadraticForm_Settings|
* |OVP_DocBegin_BoxAlgorithm_QuadraticForm_Setting1|
The values of the matrix coefficients. These values are entered as a single line of values,
which line should correspond to the concatenation of each matrix row.
For instance the setting "1 2 3 4" corresponds to the matrix:
[1 2]
[3 4]
* |OVP_DocEnd_BoxAlgorithm_QuadraticForm_Setting1|
* |OVP_DocBegin_BoxAlgorithm_QuadraticForm_Setting2|
The number of rows/columns of the matrix (the number of rows is equal to the number of columns as the matrix is square.
For the matrix given as example above, this setting should be equal to "2".
* |OVP_DocEnd_BoxAlgorithm_QuadraticForm_Setting2|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_QuadraticForm_Examples|
* |OVP_DocEnd_BoxAlgorithm_QuadraticForm_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_QuadraticForm_Miscellaneous|
this box could typically be used to compute the current density in a given brain region,
for instance using the inverse solution sLORETA. In such a case the matrix using as parameter should be a
matrix obtained thanks to this sLORETA inverse solution.
see the following paper for details:
Congedo M. (2006), Subspace Projection Filters for Real-Time Brain Electromagnetic Imaging, IEEE Transactions on Biomedical Engineering, 53(8), 1624-34
* |OVP_DocEnd_BoxAlgorithm_QuadraticForm_Miscellaneous|
*/
@@ -0,0 +1,72 @@
/**
* \page BoxAlgorithm_SignalDifferential_Integral Signal Differential/Integral
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_SignalDifferential_Integral_Description|
This box can be used to calculate signal differential or integral of any order.
* |OVP_DocEnd_BoxAlgorithm_SignalDifferential_Integral_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_SignalDifferential_Integral_Inputs|
* |OVP_DocEnd_BoxAlgorithm_SignalDifferential_Integral_Inputs|
* |OVP_DocBegin_BoxAlgorithm_SignalDifferential_Integral_Input1|
The signal to be derivated/integrated
* |OVP_DocEnd_BoxAlgorithm_SignalDifferential_Integral_Input1|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_SignalDifferential_Integral_Outputs|
* |OVP_DocEnd_BoxAlgorithm_SignalDifferential_Integral_Outputs|
* |OVP_DocBegin_BoxAlgorithm_SignalDifferential_Integral_Output1|
Resulting derivated/integrated signal
* |OVP_DocEnd_BoxAlgorithm_SignalDifferential_Integral_Output1|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_SignalDifferential_Integral_Settings|
* |OVP_DocEnd_BoxAlgorithm_SignalDifferential_Integral_Settings|
* |OVP_DocBegin_BoxAlgorithm_SignalDifferential_Integral_Setting1|
Function to be used, either a derivation or an integral
* |OVP_DocEnd_BoxAlgorithm_SignalDifferential_Integral_Setting1|
* |OVP_DocBegin_BoxAlgorithm_SignalDifferential_Integral_Setting2|
The function order.
* |OVP_DocEnd_BoxAlgorithm_SignalDifferential_Integral_Setting2|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_SignalDifferential_Integral_Examples|
* |OVP_DocEnd_BoxAlgorithm_SignalDifferential_Integral_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_SignalDifferential_Integral_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_SignalDifferential_Integral_Miscellaneous|
*/
@@ -0,0 +1,68 @@
/**
* \page BoxAlgorithm_StreamSynchronization Stream Synchronization
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_StreamSynchronization_Description|
This box enables you to synchronize inputs from multiple acquisition devices connected together with a hardware tagging system. Each acquisition device must translate the hardware tag into a stimulation, let's call it 'start' stimulation. The synchronisation box outputs signal only after 'start' stimulation has been received, and the time is shifted so that first data is at time 0. Plug each device on its own synchronisation box, so that the signals have the same 'start' time after these boxes.
* |OVP_DocEnd_BoxAlgorithm_StreamSynchronization_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_StreamSynchronization_Inputs|
* |OVP_DocEnd_BoxAlgorithm_StreamSynchronization_Inputs|
* |OVP_DocBegin_BoxAlgorithm_StreamSynchronization_Input1|
The signal from the acquisition device to be synchronized.
* |OVP_DocEnd_BoxAlgorithm_StreamSynchronization_Input1|
* |OVP_DocBegin_BoxAlgorithm_StreamSynchronization_Input2|
The stimulations from the acquisition device. The 'start' stimulation, marking the beginning of the experiment, should appear in this input.
* |OVP_DocEnd_BoxAlgorithm_StreamSynchronization_Input2|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_StreamSynchronization_Outputs|
* |OVP_DocEnd_BoxAlgorithm_StreamSynchronization_Outputs|
* |OVP_DocBegin_BoxAlgorithm_StreamSynchronization_Output1|
Time shifted signal.
* |OVP_DocEnd_BoxAlgorithm_StreamSynchronization_Output1|
* |OVP_DocBegin_BoxAlgorithm_StreamSynchronization_Output2|
Time shifted stimulations.
* |OVP_DocEnd_BoxAlgorithm_StreamSynchronization_Output2|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_StreamSynchronization_Settings|
* |OVP_DocEnd_BoxAlgorithm_StreamSynchronization_Settings|
* |OVP_DocBegin_BoxAlgorithm_StreamSynchronization_Setting1|
The ID of the stimulation which marks the beginning of the acquisition.
* |OVP_DocEnd_BoxAlgorithm_StreamSynchronization_Setting1|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_StreamSynchronization_Examples|
This box is useful if you want to use two acquisition devices at the same time. The best way to synchronize the two devices is by a physical link, this should be handled by the hardware. When experiment starts, a trigger is sent to both device through this physical link, and each device driver translate this trigger into a stimulation. As the devices received the trigger at the same time, this stimulation will have the same dating in the OpenViBE acquisition server. Finally the output of each acquisition device should pass through the synchronization box, which will re-date the signal as if it started at the moment of the reception of the stimulation.
* |OVP_DocEnd_BoxAlgorithm_StreamSynchronization_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_StreamSynchronization_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_StreamSynchronization_Miscellaneous|
*/
@@ -0,0 +1,92 @@
/**
* \page BoxAlgorithm_XDAWNTrainerDeprecated xDAWN Spatial Filter Trainer
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_XDAWNTrainerDeprecated_Description|
* This box can be used in order to compute a spatial filter in order to enhance the
* detection of evoked response potentials. In order to compute such filter, this box
* needs to receive the whole contain of a session on the first hand, and a succession
* of evoked response potentials on the other hand. It then computes the averaged evoked
* response potential computes the spatial filter that makes this averaged potential
* appear in the whole signal. This can be used e.g. for better P300 signal detection.
*
* It is important to consider the fact that this box will have best results for a
* reasonably big number of input channels, possibly all over the scalp (areas where
* the evoked response potential can not be seen will be naturally used as references
* to reduce noise). The spatial filter results in space reduction to only keep significant
* channels for later detection. Consider using at least 4 times more input channels than
* the number of output channels you want. For example, reducing 16 electrodes to 3 channels
* for P300 detection is OK.
*
* For more details about xDAWN, see <a href="https://www.gipsa-lab.grenoble-inp.fr/~bertrand.rivet/references/Rivet2009a.pdf">Rivet et al. 2009</a>
* or in case this links disappears, <a href="http://www.ncbi.nlm.nih.gov/pubmed/19174332">this website</a>.
* |OVP_DocEnd_BoxAlgorithm_XDAWNTrainerDeprecated_Description|
__________________________________________________________________
Inputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_XDAWNTrainerDeprecated_Inputs|
* |OVP_DocEnd_BoxAlgorithm_XDAWNTrainerDeprecated_Inputs|
* |OVP_DocBegin_BoxAlgorithm_XDAWNTrainerDeprecated_Input1|
* This input receives the experiment stimulations. As soon as the "train"
* stimulation is received, the spatial filter is computed.
* |OVP_DocEnd_BoxAlgorithm_XDAWNTrainerDeprecated_Input1|
* |OVP_DocBegin_BoxAlgorithm_XDAWNTrainerDeprecated_Input2|
* This input should receive the whole signal of the session.
* |OVP_DocEnd_BoxAlgorithm_XDAWNTrainerDeprecated_Input2|
* |OVP_DocBegin_BoxAlgorithm_XDAWNTrainerDeprecated_Input3|
* This input should receive the multiple evoked response potentials.
* |OVP_DocEnd_BoxAlgorithm_XDAWNTrainerDeprecated_Input3|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_CSPSpatialFilterTrainer_Outputs|
* |OVP_DocEnd_BoxAlgorithm_CSPSpatialFilterTrainer_Outputs|
* |OVP_DocBegin_BoxAlgorithm_CSPSpatialFilterTrainer_Output1|
The xDAWN Trainer outputs the stimulation <b>OVTK_StimulationId_TrainCompleted</b> when the training process was successful. No output is produced if the process failed.
* |OVP_DocEnd_BoxAlgorithm_CSPSpatialFilterTrainer_Output1|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_XDAWNTrainerDeprecated_Settings|
* |OVP_DocEnd_BoxAlgorithm_XDAWNTrainerDeprecated_Settings|
* |OVP_DocBegin_BoxAlgorithm_XDAWNTrainerDeprecated_Setting1|
* This setting contains the stimulation to use to trigger the training process.
* |OVP_DocEnd_BoxAlgorithm_XDAWNTrainerDeprecated_Setting1|
* |OVP_DocBegin_BoxAlgorithm_XDAWNTrainerDeprecated_Setting2|
* This setting tells the box what configuration file to generate. This configuration file can
* be used to set the correct values of a \ref Doc_BoxAlgorithm_SpatialFilter box.
* |OVP_DocEnd_BoxAlgorithm_XDAWNTrainerDeprecated_Setting2|
* |OVP_DocBegin_BoxAlgorithm_XDAWNTrainerDeprecated_Setting3|
* This setting tells how many dimension should be kept out of the spatial filter.
* |OVP_DocEnd_BoxAlgorithm_XDAWNTrainerDeprecated_Setting3|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_XDAWNTrainerDeprecated_Examples|
* |OVP_DocEnd_BoxAlgorithm_XDAWNTrainerDeprecated_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_XDAWNTrainerDeprecated_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_XDAWNTrainerDeprecated_Miscellaneous|
*/
Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

@@ -0,0 +1,143 @@
#if defined(TARGET_HAS_ThirdPartyEIGEN)
#include "ovpCAlgorithmARBurgMethod.h"
#include <iostream>
#include <sstream>
#include <Eigen/Dense>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CAlgorithmARBurgMethod::initialize()
{
ip_pMatrix.initialize(this->getInputParameter(OVP_Algorithm_ARBurgMethod_InputParameterId_Matrix));
op_pMatrix.initialize(this->getOutputParameter(OVP_Algorithm_ARBurgMethod_OutputParameterId_Matrix));
ip_Order.initialize(this->getInputParameter(OVP_Algorithm_ARBurgMethod_InputParameterId_UInteger));
return true;
}
bool CAlgorithmARBurgMethod::uninitialize()
{
op_pMatrix.uninitialize();
ip_pMatrix.uninitialize();
ip_Order.uninitialize();
return true;
}
bool CAlgorithmARBurgMethod::process()
{
m_order = size_t(ip_Order);
const size_t nChannel = ip_pMatrix->getDimensionSize(0);
const size_t samplesPerChannel = ip_pMatrix->getDimensionSize(1);
CMatrix* iMatrix = ip_pMatrix;
CMatrix* oMatrix = op_pMatrix;
if (this->isInputTriggerActive(OVP_Algorithm_ARBurgMethod_InputTriggerId_Initialize))
{
if (iMatrix->getDimensionCount() != 2)
{
this->getLogManager() << Kernel::LogLevel_Error << "The input matrix must have 2 dimensions";
return false;
}
if (iMatrix->getDimensionSize(1) < 2 * m_order)
{
this->getLogManager() << Kernel::LogLevel_Error << "The input vector must be greater than twice the order";
return false;
}
// Setting size of output
oMatrix->resize(nChannel, m_order + 1); // The number of coefficients per channel is equal to the order + 1
for (size_t i = 0; i < nChannel; ++i)
{
const std::string label = "Channel " + std::to_string(i + 1);
oMatrix->setDimensionLabel(0, i, label);
}
for (size_t i = 0; i < (m_order + 1); ++i)
{
const std::string label = "ARCoeff " + std::to_string(i + 1);
oMatrix->setDimensionLabel(1, i, label);
}
}
if (this->isInputTriggerActive(OVP_Algorithm_ARBurgMethod_InputTriggerId_Process))
{
// Compute the coefficients for each channel
for (size_t j = 0; j < nChannel; ++j)
{
// Initialization of all needed vectors
m_errForwardPrediction = Eigen::RowVectorXd::Zero(samplesPerChannel); // Error Forward prediction
m_errBackwardPrediction = Eigen::RowVectorXd::Zero(samplesPerChannel); //Error Backward prediction
m_errForward = Eigen::RowVectorXd::Zero(samplesPerChannel); // Error Forward
m_errBackward = Eigen::RowVectorXd::Zero(samplesPerChannel); // Error Backward
m_arCoefs = Eigen::RowVectorXd::Zero(m_order + 1); // Vector containing the AR coefficients for each channel, it will be our output vector
m_error = Eigen::RowVectorXd::Zero(m_order + 1); // Total error
m_k = 0.0;
m_arCoefs(0) = 1.0;
Eigen::VectorXd arReversed;
arReversed = Eigen::VectorXd::Zero(m_order + 1);
// Retrieving input datas
for (size_t i = 0; i < samplesPerChannel; ++i)
{
m_errForward(i) = iMatrix->getBuffer()[i + j * (samplesPerChannel)]; // Error Forward is the input matrix at first
m_errBackward(i) = iMatrix->getBuffer()[i + j * (samplesPerChannel)]; //Error Backward is the input matrix at first
m_error(0) += (iMatrix->getBuffer()[i + j * (samplesPerChannel)] * iMatrix->getBuffer()[i + j * (samplesPerChannel)]) / samplesPerChannel;
}
// we iterate over the order
for (size_t n = 1; n <= m_order; ++n)
{
const size_t length = samplesPerChannel - n;
m_errForwardPrediction.resize(length);
m_errBackwardPrediction.resize(length);
m_errForwardPrediction = m_errForward.tail(length);
m_errBackwardPrediction = m_errBackward.head(length);
const double num = -2.0 * m_errBackwardPrediction.dot(m_errForwardPrediction);
const double den = (m_errForwardPrediction.dot(m_errForwardPrediction)) + (m_errBackwardPrediction.dot(m_errBackwardPrediction));
m_k = num / den;
// Update errors forward and backward vectors
m_errForward = m_errForwardPrediction + m_k * m_errBackwardPrediction;
m_errBackward = m_errBackwardPrediction + m_k * m_errForwardPrediction;
// Compute the AR coefficients
for (size_t i = 1; i <= n; ++i) { arReversed(i) = m_arCoefs(n - i); }
m_arCoefs = m_arCoefs + m_k * arReversed;
// Update Total Error
m_error(n) = (1 - m_k * m_k) * m_error(n - 1);
}
for (size_t i = 0; i <= m_order; ++i) { oMatrix->getBuffer()[i + j * (m_order + 1)] = m_arCoefs(i); }
}
this->activateOutputTrigger(OVP_Algorithm_ARBurgMethod_OutputTriggerId_ProcessDone, true);
}
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif // TARGET_HAS_ThirdPartyEIGEN
@@ -0,0 +1,84 @@
# pragma once
#if defined(TARGET_HAS_ThirdPartyEIGEN)
#include "../../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <Eigen/Dense>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
class CAlgorithmARBurgMethod final : public Toolkit::TAlgorithm<IAlgorithm>
{
public:
void release() override { delete this; }
bool initialize() override;
bool uninitialize() override;
bool process() override;
_IsDerivedFromClass_Final_(Toolkit::TAlgorithm<IAlgorithm>, OVP_ClassId_Algorithm_ARBurgMethod)
protected:
Kernel::TParameterHandler<CMatrix*> ip_pMatrix; // input matrix
Kernel::TParameterHandler<CMatrix*> op_pMatrix; // output matrix
Kernel::TParameterHandler<uint64_t> ip_Order;
private:
Eigen::VectorXd m_errForward; // Error Forward
Eigen::VectorXd m_errBackward; //Error Backward
Eigen::VectorXd m_arCoefs; // AutoRegressive Coefficents
Eigen::VectorXd m_errForwardPrediction; // Error Forward prediction
Eigen::VectorXd m_errBackwardPrediction; //Error Backward prediction
Eigen::VectorXd m_error; // Total error vector
double m_k = 0;
size_t m_order = 0;
};
class CAlgorithmARBurgMethodDesc final : public IAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("AR Burg's Method algorithm"); }
CString getAuthorName() const override { return CString("Alison Cellard"); }
CString getAuthorCompanyName() const override { return CString("INRIA"); }
CString getShortDescription() const override { return CString("Extract AR coefficient using Burg's Method"); }
CString getDetailedDescription() const override { return CString(""); }
CString getCategory() const override { return CString("Signal Processing"); }
CString getVersion() const override { return CString("1.0"); }
virtual CString getStockItemName() const { return CString("gtk-execute"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_Algorithm_ARBurgMethod; }
IPluginObject* create() override { return new CAlgorithmARBurgMethod; }
bool getAlgorithmPrototype(Kernel::IAlgorithmProto& prototype) const override
{
prototype.addInputParameter(OVP_Algorithm_ARBurgMethod_InputParameterId_Matrix, "Vector", Kernel::ParameterType_Matrix);
prototype.addOutputParameter(OVP_Algorithm_ARBurgMethod_OutputParameterId_Matrix, "Coefficents Vector", Kernel::ParameterType_Matrix);
prototype.addInputParameter(OVP_Algorithm_ARBurgMethod_InputParameterId_UInteger, "Order", Kernel::ParameterType_UInteger);
prototype.addInputTrigger(OVP_Algorithm_ARBurgMethod_InputTriggerId_Initialize, "Initialize");
prototype.addInputTrigger(OVP_Algorithm_ARBurgMethod_InputTriggerId_Process, "Process");
prototype.addOutputTrigger(OVP_Algorithm_ARBurgMethod_OutputTriggerId_ProcessDone, "Process done");
return true;
}
_IsDerivedFromClass_Final_(IAlgorithmDesc, OVP_ClassId_Algorithm_ARBurgMethodDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif // TARGET_HAS_ThirdPartyEIGEN
@@ -0,0 +1,147 @@
#if defined(TARGET_HAS_ThirdPartyEIGEN)
#include "ovpCHilbertTransform.h"
#include <complex>
#include <Eigen/Dense>
#include <unsupported/Eigen/FFT>
bool HilbertTransform::transform(const Eigen::VectorXcd& in, Eigen::VectorXcd& out)
{
const size_t nSamples = in.size();
// Resize our buffers if input size has changed
if (size_t(m_signalFourier.size()) != nSamples)
{
m_signalFourier = Eigen::VectorXcd::Zero(nSamples);
m_hilbert = Eigen::VectorXcd::Zero(nSamples);
//Initialization of vector h used to compute analytic signal
m_hilbert(0) = 1.0;
if (nSamples % 2 == 0)
{
m_hilbert(nSamples / 2) = 1.0;
m_hilbert.segment(1, (nSamples / 2) - 1).setOnes();
m_hilbert.segment(1, (nSamples / 2) - 1) *= 2.0;
m_hilbert.tail((nSamples / 2) + 1).setZero();
}
else
{
m_hilbert((nSamples + 1) / 2) = 1.0;
m_hilbert.segment(1, (nSamples / 2)).setOnes();
m_hilbert.segment(1, (nSamples / 2)) *= 2.0;
m_hilbert.tail(((nSamples + 1) / 2) + 1).setZero();
}
}
// Always resize output for safety
out.resize(nSamples);
//Fast Fourier Transform of input signal
m_fft.fwd(m_signalFourier, in);
//Apply Hilbert transform by element-wise multiplying fft vector by h
m_signalFourier = m_signalFourier.cwiseProduct(m_hilbert);
//Inverse Fast Fourier transform
m_fft.inv(out, m_signalFourier); // m_vecXcdSignalBuffer is now the analytical signal of the initial input signal
return true;
}
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CAlgorithmHilbertTransform::initialize()
{
ip_matrix.initialize(this->getInputParameter(OVP_Algorithm_HilbertTransform_InputParameterId_Matrix));
op_hilbertMatrix.initialize(this->getOutputParameter(OVP_Algorithm_HilbertTransform_OutputParameterId_HilbertMatrix));
op_envelopeMatrix.initialize(this->getOutputParameter(OVP_Algorithm_HilbertTransform_OutputParameterId_EnvelopeMatrix));
op_phaseMatrix.initialize(this->getOutputParameter(OVP_Algorithm_HilbertTransform_OutputParameterId_PhaseMatrix));
return true;
}
bool CAlgorithmHilbertTransform::uninitialize()
{
op_hilbertMatrix.uninitialize();
op_envelopeMatrix.uninitialize();
op_phaseMatrix.uninitialize();
ip_matrix.uninitialize();
return true;
}
bool CAlgorithmHilbertTransform::process()
{
const size_t nChannel = ip_matrix->getDimensionSize(0);
const size_t samplesPerChannel = ip_matrix->getDimensionSize(1);
CMatrix* matrix = ip_matrix;
CMatrix* hilbert = op_hilbertMatrix;
CMatrix* envelope = op_envelopeMatrix;
CMatrix* phase = op_phaseMatrix;
if (this->isInputTriggerActive(OVP_Algorithm_HilbertTransform_InputTriggerId_Initialize)) //Check if the input is correct
{
if (matrix->getDimensionCount() != 2)
{
this->getLogManager() << Kernel::LogLevel_Error << "The input matrix must have 2 dimensions, here the dimension is " << matrix->getDimensionCount()
<< "\n";
return false;
}
if (matrix->getDimensionSize(1) < 2)
{
this->getLogManager() << Kernel::LogLevel_Error << "Can't compute Hilbert transform on data length " << matrix->getDimensionSize(1) << "\n";
return false;
}
//Setting size of outputs
hilbert->resize(nChannel, samplesPerChannel);
envelope->resize(nChannel, samplesPerChannel);
phase->resize(nChannel, samplesPerChannel);
for (size_t i = 0; i < nChannel; ++i)
{
hilbert->setDimensionLabel(0, i, matrix->getDimensionLabel(0, i));
envelope->setDimensionLabel(0, i, matrix->getDimensionLabel(0, i));
phase->setDimensionLabel(0, i, matrix->getDimensionLabel(0, i));
}
}
if (this->isInputTriggerActive(OVP_Algorithm_HilbertTransform_InputTriggerId_Process))
{
//Compute Hilbert transform for each channel separately
for (size_t c = 0; c < nChannel; ++c)
{
// We cannot do a simple ptr assignment here as we need to convert real input to a complex vector
Eigen::VectorXcd vecXcdSingleChannel = Eigen::VectorXcd::Zero(samplesPerChannel);
const double* buffer = &matrix->getBuffer()[c * samplesPerChannel];
for (size_t samples = 0; samples < samplesPerChannel; ++samples)
{
vecXcdSingleChannel(samples) = buffer[samples];
vecXcdSingleChannel(samples).imag(0.0);
}
Eigen::VectorXcd vecXcdSingleChannelTransformed;
m_hilbert.transform(vecXcdSingleChannel, vecXcdSingleChannelTransformed);
//Compute envelope and phase and pass them to the corresponding outputs
for (size_t s = 0; s < samplesPerChannel; ++s)
{
hilbert->getBuffer()[s + c * samplesPerChannel] = vecXcdSingleChannelTransformed(s).imag();
envelope->getBuffer()[s + c * samplesPerChannel] = abs(vecXcdSingleChannelTransformed(s));
phase->getBuffer()[s + c * samplesPerChannel] = arg(vecXcdSingleChannelTransformed(s));
}
}
}
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif //TARGET_HAS_ThirdPartyEIGEN
@@ -0,0 +1,93 @@
#pragma once
#if defined(TARGET_HAS_ThirdPartyEIGEN)
#include "../../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <Eigen/Dense>
#include <unsupported/Eigen/FFT>
// This class could be in its own file
class HilbertTransform
{
public:
bool transform(const Eigen::VectorXcd& in, Eigen::VectorXcd& out);
private:
Eigen::VectorXcd m_signalFourier; // Fourier Transform of the input signal
Eigen::VectorXcd m_hilbert; // Vector h used to apply Hilbert transform
Eigen::FFT<double, Eigen::internal::kissfft_impl<double>> m_fft; // Instance of the fft transform
};
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
class CAlgorithmHilbertTransform final : public Toolkit::TAlgorithm<IAlgorithm>
{
public:
void release() override { delete this; }
bool initialize() override;
bool uninitialize() override;
bool process() override;
_IsDerivedFromClass_Final_(Toolkit::TAlgorithm<IAlgorithm>, OVP_ClassId_Algorithm_HilbertTransform)
protected:
Kernel::TParameterHandler<CMatrix*> ip_matrix; //input matrix
Kernel::TParameterHandler<CMatrix*> op_hilbertMatrix; //output matrix 1 : Hilbert transform of the signal
Kernel::TParameterHandler<CMatrix*> op_envelopeMatrix; //output matrix 2 : Envelope of the signal
Kernel::TParameterHandler<CMatrix*> op_phaseMatrix; //output matrix 3 : Phase of the signal
HilbertTransform m_hilbert; // Instance of the Hilbert transform doing the actual computation
};
class CAlgorithmHilbertTransformDesc final : public IAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Hilbert Transform"); }
CString getAuthorName() const override { return CString("Alison Cellard"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("Computes the Hilbert transform of a signal"); }
CString getDetailedDescription() const override
{
return CString("Give the analytic signal ua(t) = u(t) + iH(u(t)) of the input signal u(t) using Hilbert transform");
}
CString getCategory() const override { return CString("Signal processing/Basic"); }
CString getVersion() const override { return CString("0.2"); }
virtual CString getStockItemName() const { return CString("gtk-execute"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_Algorithm_HilbertTransform; }
IPluginObject* create() override { return new CAlgorithmHilbertTransform; }
bool getAlgorithmPrototype(Kernel::IAlgorithmProto& prototype) const override
{
prototype.addInputParameter(OVP_Algorithm_HilbertTransform_InputParameterId_Matrix, "Matrix", Kernel::ParameterType_Matrix);
prototype.addOutputParameter(OVP_Algorithm_HilbertTransform_OutputParameterId_HilbertMatrix, "Hilbert Matrix", Kernel::ParameterType_Matrix);
prototype.addOutputParameter(OVP_Algorithm_HilbertTransform_OutputParameterId_EnvelopeMatrix, "Envelope Matrix", Kernel::ParameterType_Matrix);
prototype.addOutputParameter(OVP_Algorithm_HilbertTransform_OutputParameterId_PhaseMatrix, "Phase Matrix", Kernel::ParameterType_Matrix);
prototype.addInputTrigger(OVP_Algorithm_HilbertTransform_InputTriggerId_Initialize, "Initialize");
prototype.addInputTrigger(OVP_Algorithm_HilbertTransform_InputTriggerId_Process, "Process");
prototype.addOutputTrigger(OVP_Algorithm_HilbertTransform_OutputTriggerId_ProcessDone, "Process done");
return true;
}
_IsDerivedFromClass_Final_(IAlgorithmDesc, OVP_ClassId_Algorithm_HilbertTransformDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif //TARGET_HAS_ThirdPartyEIGEN
@@ -0,0 +1,230 @@
#if defined(TARGET_HAS_ThirdPartyITPP)
#include "ovpCMatrixVariance.h"
#include <cmath>
// the boost version used at the moment of writing this caused 4800 by internal call to "int _isnan" in a bool-returning function.
#if defined(WIN32)
#pragma warning (disable : 4800)
#endif
#include <boost/math/distributions/students_t.hpp>
#include <itpp/base/vec.h>
#include <itpp/base/math/elem_math.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CMatrixVariance::initialize()
{
ip_averagingMethod.initialize(getInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_AveragingMethod));
ip_matrixCount.initialize(getInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_MatrixCount));
ip_significanceLevel.initialize(getInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_SignificanceLevel));
ip_matrix.initialize(getInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_Matrix));
op_averagedMatrix.initialize(getOutputParameter(OVP_Algorithm_MatrixVariance_OutputParameterId_AveragedMatrix));
op_varianceMatrix.initialize(getOutputParameter(OVP_Algorithm_MatrixVariance_OutputParameterId_Variance));
op_confidenceBound.initialize(getOutputParameter(OVP_Algorithm_MatrixVariance_OutputParameterId_ConfidenceBound));
return true;
}
bool CMatrixVariance::uninitialize()
{
for (auto it = m_history.begin(); it != m_history.end(); ++it) { delete *it; }
m_history.clear();
op_averagedMatrix.uninitialize();
op_varianceMatrix.uninitialize();
op_confidenceBound.uninitialize();
ip_matrix.uninitialize();
ip_matrixCount.uninitialize();
ip_averagingMethod.uninitialize();
ip_significanceLevel.uninitialize();
return true;
}
// ________________________________________________________________________________________________________________
//
bool CMatrixVariance::process()
{
CMatrix* iMatrix = ip_matrix;
//CMatrix* oMatrix=op_pAveragedMatrix;
bool shouldPerformAverage = false;
if (this->isInputTriggerActive(OVP_Algorithm_MatrixVariance_InputTriggerId_Reset))
{
m_mean.set_size(int(ip_matrix->getBufferElementCount()));
m_mean.zeros();
m_m.set_size(int(ip_matrix->getBufferElementCount()));
m_m.zeros();
m_variance.set_size(int(ip_matrix->getBufferElementCount()));
m_variance.zeros();
m_inputCounter = 0;
for (auto it = m_history.begin(); it != m_history.end(); ++it) { delete *it; }
m_history.clear();
op_averagedMatrix->copyDescription(*iMatrix);
op_varianceMatrix->copyDescription(*iMatrix);
op_confidenceBound->copyDescription(*iMatrix);
}
if (this->isInputTriggerActive(OVP_Algorithm_MatrixVariance_InputTriggerId_FeedMatrix))
{
const int nElement = int(iMatrix->getBufferElementCount());
if (ip_averagingMethod == size_t(EEpochAverageMethod::Moving))
{
//CMatrix* swapMatrix= nullptr;
if (m_history.size() >= ip_matrixCount)
{
delete m_history.front();
m_history.pop_front();
}
/*else
{
swapMatrix=new CMatrix();
swapMatrix->copyDescription(*iMatrix);
}*/
//swapMatrix->copyContent(*iMatrix);
itpp::Vec<double>* matrices = new itpp::Vec<double>(iMatrix->getBuffer(), nElement);
m_history.push_back(matrices);
shouldPerformAverage = (m_history.size() == ip_matrixCount);
}
else if (ip_averagingMethod == size_t(EEpochAverageMethod::MovingImmediate))
{
//CMatrix* swapMatrix= nullptr;
if (m_history.size() >= ip_matrixCount)
{
delete m_history.front();
m_history.pop_front();
}
/*else
{
swapMatrix=new CMatrix();
swapMatrix->copyDescription(*iMatrix);
}*/
//swapMatrix->copyContent(*iMatrix);
itpp::Vec<double>* matrices = new itpp::Vec<double>(iMatrix->getBuffer(), nElement);
m_history.push_back(matrices);
shouldPerformAverage = (!m_history.empty());
}
else if (ip_averagingMethod == size_t(EEpochAverageMethod::Block))
{
//CMatrix* swapMatrix=new CMatrix();
if (m_history.size() >= ip_matrixCount)
{
for (auto it = m_history.begin(); it != m_history.end(); ++it) { delete *it; }
m_history.clear();
}
//swapMatrix->copy(*iMatrix);
itpp::Vec<double>* matrices = new itpp::Vec<double>(iMatrix->getBuffer(), nElement);
m_history.push_back(matrices);
shouldPerformAverage = (m_history.size() == ip_matrixCount);
}
else if (ip_averagingMethod == size_t(EEpochAverageMethod::Cumulative))
{
if (!m_history.empty())
{
//std::cout << "size of history " << m_history.size() << "\n";
delete m_history.front();
m_history.pop_front();
}
//else { std::cout << "history empty \n"; }
//CMatrix* swapMatrix=new CMatrix();
//swapMatrix->copy(*iMatrix);
itpp::Vec<double>* matrices = new itpp::Vec<double>(iMatrix->getBuffer(), nElement);
m_history.push_back(matrices);
shouldPerformAverage = (!m_history.empty());
}
else { shouldPerformAverage = false; }
}
if (shouldPerformAverage)
{
if (!m_history.empty())
{
boost::math::students_t_distribution<double> distrib(2);
if (ip_averagingMethod == size_t(EEpochAverageMethod::Cumulative))
{
//incremental estimation of mean and variance
for (auto it = m_history.begin(); it != m_history.end(); ++it)
{
m_inputCounter++;
itpp::Vec<double> buffer = **it;
itpp::Vec<double> delta = buffer - m_mean;
m_mean += delta / double(m_inputCounter);
m_m += elem_mult(delta, (buffer - m_mean));
if (m_inputCounter > 1) { m_variance = m_m / double(m_inputCounter - 1); }
}
distrib = boost::math::students_t_distribution<double>(m_inputCounter <= 1 ? 1 : m_inputCounter - 1);
//CMatrix swapMatrix();
//getLogManager() << Kernel::LogLevel_Info << "Variance first element " << m_Variance[0] << ", last element " << m_Variance[iMatrix->getBufferElementCount()-1] << "\n";
memcpy(op_averagedMatrix->getBuffer(), m_mean._data(), iMatrix->getBufferElementCount() * sizeof(double));
memcpy(op_varianceMatrix->getBuffer(), m_variance._data(), iMatrix->getBufferElementCount() * sizeof(double));
}
else
{
distrib = boost::math::students_t_distribution<double>(double(ip_matrixCount) - 1);
op_varianceMatrix->resetBuffer();
op_averagedMatrix->resetBuffer();
const size_t count = op_averagedMatrix->getBufferElementCount();
const double scale = 1. / m_history.size();
for (auto& h : m_history)
{
//batch computation of mean
itpp::Vec<double> buffer = *h;
double* averageBuffer = op_averagedMatrix->getBuffer();
for (int i = 0; i < int(count); ++i)
{
*averageBuffer += buffer[i] * scale;
averageBuffer++;
}
//batch computation of variance
averageBuffer = op_averagedMatrix->getBuffer();
double* matrixVarianceBuffer = op_varianceMatrix->getBuffer();
for (int i = 0; i < int(count); ++i)
{
*matrixVarianceBuffer += (buffer[i] - *(averageBuffer + i)) * (buffer[i] - *(averageBuffer + i)) / (m_history.size() - 1.0F);
matrixVarianceBuffer++;
}
}
m_variance = itpp::Vec<double>(op_averagedMatrix->getBuffer(), int(count));
}
//computing confidence bounds
const double q = double(quantile(complement(distrib, ip_significanceLevel / 2.0)));
getLogManager() << Kernel::LogLevel_Debug << "Quantile at " << ip_significanceLevel << " is " << q << "\n";
itpp::Vec<double> bound;
if (ip_averagingMethod == size_t(EEpochAverageMethod::Cumulative)) { bound = (q / sqrt(double(m_inputCounter))) * itpp::sqrt(m_variance); }
else { bound = (q / double(ip_matrixCount)) * itpp::sqrt(m_variance); }
memcpy(op_confidenceBound->getBuffer(), bound._data(), iMatrix->getBufferElementCount() * sizeof(double));
}
this->activateOutputTrigger(OVP_Algorithm_MatrixVariance_OutputTriggerId_AveragePerformed, true);
}
return true;
}
#endif
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,90 @@
#pragma once
#if defined(TARGET_HAS_ThirdPartyITPP)
#include "../../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <itpp/base/vec.h>
#include <deque>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
class CMatrixVariance final : public Toolkit::TAlgorithm<IAlgorithm>
{
public:
void release() override { delete this; }
bool initialize() override;
bool uninitialize() override;
bool process() override;
_IsDerivedFromClass_Final_(Toolkit::TAlgorithm<IAlgorithm>, OVP_ClassId_Algorithm_MatrixVariance)
protected:
Kernel::TParameterHandler<uint64_t> ip_averagingMethod;
Kernel::TParameterHandler<uint64_t> ip_matrixCount;
Kernel::TParameterHandler<double> ip_significanceLevel;
Kernel::TParameterHandler<CMatrix*> ip_matrix;
Kernel::TParameterHandler<CMatrix*> op_averagedMatrix;
Kernel::TParameterHandler<CMatrix*> op_varianceMatrix;
Kernel::TParameterHandler<CMatrix*> op_confidenceBound;
std::deque<itpp::Vec<double>*> m_history;
itpp::Vec<double> m_mean;
itpp::Vec<double> m_m;
itpp::Vec<double> m_variance;
size_t m_inputCounter = 0;
};
class CMatrixVarianceDesc final : public IAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Matrix variance"); }
CString getAuthorName() const override { return CString("Dieter Devlaminck"); }
CString getAuthorCompanyName() const override { return CString("INRIA"); }
CString getShortDescription() const override { return CString(""); }
CString getDetailedDescription() const override { return CString(""); }
CString getCategory() const override { return CString("Signal processing/Basic"); }
CString getVersion() const override { return CString("1.0"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_Algorithm_MatrixVariance; }
IPluginObject* create() override { return new CMatrixVariance(); }
bool getAlgorithmPrototype(Kernel::IAlgorithmProto& prototype) const override
{
prototype.addInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_Matrix, "Matrix", Kernel::ParameterType_Matrix);
prototype.addInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_MatrixCount, "Matrix count", Kernel::ParameterType_UInteger);
prototype.addInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_SignificanceLevel, "Significance Level", Kernel::ParameterType_UInteger);
prototype.addInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_AveragingMethod, "Averaging Method", Kernel::ParameterType_UInteger);
prototype.addOutputParameter(OVP_Algorithm_MatrixVariance_OutputParameterId_AveragedMatrix, "Averaged matrix", Kernel::ParameterType_Matrix);
prototype.addOutputParameter(OVP_Algorithm_MatrixVariance_OutputParameterId_Variance, "Matrix variance", Kernel::ParameterType_Matrix);
prototype.addOutputParameter(OVP_Algorithm_MatrixVariance_OutputParameterId_ConfidenceBound, "Confidence bound", Kernel::ParameterType_Matrix);
prototype.addInputTrigger(OVP_Algorithm_MatrixVariance_InputTriggerId_Reset, "Reset");
prototype.addInputTrigger(OVP_Algorithm_MatrixVariance_InputTriggerId_FeedMatrix, "Feed matrix");
prototype.addInputTrigger(OVP_Algorithm_MatrixVariance_InputTriggerId_ForceAverage, "Force average");
prototype.addOutputTrigger(OVP_Algorithm_MatrixVariance_OutputTriggerId_AveragePerformed, "Average performed");
return true;
}
_IsDerivedFromClass_Final_(IAlgorithmDesc, OVP_ClassId_Algorithm_MatrixVarianceDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif
@@ -0,0 +1,92 @@
///-------------------------------------------------------------------------------------------------
///
/// \file windowFunctions.cpp
/// \brief Implementation of Windowing functions
/// \author Alison Cellard
/// \version 1.0
/// \date 13/11/2013
///
/// \copyright (C) 2021 INRIA
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as published
/// by the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program. If not, see <https://www.gnu.org/licenses/>.
///-------------------------------------------------------------------------------------------------
#if defined(TARGET_HAS_ThirdPartyEIGEN)
#include "windowFunctions.hpp"
#include <iostream>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
namespace WindowFunctions {
bool bartlett(Eigen::VectorXd& window, const size_t size)
{
for (size_t i = 0; i < size; ++i)
{
if (i <= (size - 1) / 2)
{
window(i) = 2. * i / (size - 1);
}
else if (i < size) {
window(i) = 2. * ((size - 1) - i) / (size - 1);
}
}
return true;
}
bool hamming(Eigen::VectorXd& window, const size_t size)
{
for (size_t i = 0; i < size; ++i)
{
window(i) = 0.54 - 0.46 * cos(2. * M_PI * i / (size - 1));
}
return true;
}
bool hann(Eigen::VectorXd& window, const size_t size)
{
for (size_t i = 0; i < size; ++i)
{
window(i) = 0.5 - 0.5 * cos(2. * M_PI * i / (size - 1));
}
return true;
}
bool parzen(Eigen::VectorXd& window, const size_t size)
{
for (size_t i = 0; i < size; ++i)
{
window(i) = 1. - pow((i - (size - 1.) / 2.) / ((size + 1.) / 2.), 2);
}
return true;
}
bool welch(Eigen::VectorXd& window, const size_t size)
{
for (size_t i = 0; i < size; ++i)
{
window(i) = 1.0 - fabs((i - (size - 1.0) / 2.0) / ((size + 1.0) / 2.0));
}
return true;
}
} //namespace WindowFunctions
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif //TARGET_HAS_ThirdPartyEIGEN
@@ -0,0 +1,77 @@
///-------------------------------------------------------------------------------------------------
///
/// \file windowFunctions.hpp
/// \brief Windowing functions and helpers for Connectivity Measure
/// \author Alison Cellard
/// \version 1.0
/// \date 13/11/2013
///
/// \copyright (C) 2021 INRIA
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as published
/// by the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program. If not, see <https://www.gnu.org/licenses/>.
///-------------------------------------------------------------------------------------------------
#pragma once
#if defined(TARGET_HAS_ThirdPartyEIGEN)
#include <openvibe/ov_all.h>
#include <Eigen/Dense>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
namespace WindowFunctions {
///
/// \brief Generate Bartlett window
/// \param windowBuffer The buffer in which the window is stored
/// \param size The size of the window
/// \return True
bool bartlett(Eigen::VectorXd& window, const size_t size);
///
/// \brief Generate Hamming window
/// \param windowBuffer The buffer in which the window is stored
/// \param size The size of the window
/// \return True
bool hamming(Eigen::VectorXd& window, const size_t size);
///
/// \brief Generate Hann window
/// \param windowBuffer The buffer in which the window is stored
/// \param size The size of the window
/// \return True
bool hann(Eigen::VectorXd& window, const size_t size);
///
/// \brief Generate Parzen window
/// \param windowBuffer The buffer in which the window is stored
/// \param size The size of the window
/// \return True
bool parzen(Eigen::VectorXd& window, const size_t size);
///
/// \brief Generate Welch window
/// \param windowBuffer The buffer in which the window is stored
/// \param size The size of the window
/// \return True
bool welch(Eigen::VectorXd& window, const size_t size);
} // namespace WindowFunctions
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif //TARGET_HAS_ThirdPartyEIGEN
@@ -0,0 +1,289 @@
///-------------------------------------------------------------------------------------------------
///
/// \file connectivityMeasureMetrics.cpp
/// \brief All connectivity metrics.
/// \author Arthur Desbois (Inria).
/// \version 1.0
/// \date 30/10/2020
///
/// \copyright (C) 2020 INRIA
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as published
/// by the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program. If not, see <https://www.gnu.org/licenses/>.
///-------------------------------------------------------------------------------------------------
#include <cmath>
#include <complex>
#include <iostream>
#include <Eigen/Dense>
#include <unsupported/Eigen/FFT>
#include "connectivityMeasure.hpp"
#include <openvibe/ov_all.h>
#include <windowFunctions.hpp>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
//************************************************************************
//******* Connectivity measurements & associated helper functions ********
//************************************************************************
bool ConnectivityMeasure::initialize(const EConnectMetric metric,
EConnectWindowMethod windowMethod,
int windowLength,
int windowOverlap,
size_t nbChannels,
size_t fftSize,
bool dcRemoval)
{
m_metric = metric;
m_windowMethod = windowMethod;
m_windowLength = windowLength; // size of one welch window (samples)
m_windowOverlap = windowOverlap; // overlap btw windows (%)
m_windowOverlapSamples = std::floor(double(m_windowLength * windowOverlap) / 100.0);
m_nbChannels = nbChannels;
m_fftSize = fftSize;
m_dcRemoval = dcRemoval;
m_window = Eigen::VectorXd::Zero(m_windowLength);
switch (m_windowMethod)
{
case EConnectWindowMethod::Hamming:
WindowFunctions::hamming(m_window, m_windowLength);
break;
case EConnectWindowMethod::Hann:
WindowFunctions::hann(m_window, m_windowLength);
break;
case EConnectWindowMethod::Welch:
WindowFunctions::welch(m_window, m_windowLength);
break;
}
// window normalization constant
m_u = 0;
for (size_t i = 0; i < size_t(m_window.size()); ++i)
{
m_u += std::pow(m_window(i), 2);
}
// Instantiate the big spectra & x-spectra arrays
m_dft.resize(m_nbChannels); // vector of channels x fftsize
m_psd.resize(m_nbChannels); // vector of channels x fftsize
m_cpsd.resize(m_nbChannels); // matrix of channels x channels x fftsize
for (size_t chan = 0; chan < m_nbChannels; chan++)
{
m_cpsd[chan].resize(m_nbChannels);
}
return true;
}
bool ConnectivityMeasure::process(const std::vector <Eigen::VectorXd>& samples,
std::vector <Eigen::MatrixXd>& connectivityMatrix)
{
// Windowing
size_t windowShift = m_window.size() - m_windowOverlapSamples;
size_t nbWindows = std::floor(double(samples[0].size() - windowShift) / double(windowShift));
// Remove the DC component of each channel
std::vector <Eigen::VectorXd> mySamples;
if (m_dcRemoval)
{
for (size_t chan = 0; chan < m_nbChannels; chan++)
{
Eigen::VectorXd temp = samples[chan] - Eigen::VectorXd::Ones(samples[chan].size()) * samples[chan].mean();
mySamples.push_back(temp);
}
} else
{
mySamples = samples;
}
// TODO : don't recompute the whole set of DFTs, because connectivity measures overlap !
// Periodigrams (DFTs)
for (size_t chan = 0; chan < m_nbChannels; chan++)
{
periodogram(mySamples[chan], m_dft[chan], nbWindows);
}
// PSDs
for (size_t chan = 0; chan < m_nbChannels; chan++)
{
powerSpectralDensity(m_dft[chan], m_psd[chan], nbWindows);
}
// Cross-SPECTRA
for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++)
{
for (size_t chan2 = chan1; chan2 < m_nbChannels; chan2++)
{
crossSpectralDensity(m_dft[chan1], m_dft[chan2], m_cpsd[chan1][chan2], nbWindows);
}
}
// Use PSDs & x-spectra to compute the connectivity matrix
switch (m_metric)
{
case EConnectMetric::Coherence:
return coherence(connectivityMatrix);
case EConnectMetric::MagnitudeSquaredCoherence:
return magnitudeSquaredCoherence(connectivityMatrix);
case EConnectMetric::ImaginaryCoherence:
return imaginaryCoherence(connectivityMatrix);
case EConnectMetric::AbsImaginaryCoherence:
return absImaginaryCoherence(connectivityMatrix);
default:
return coherence(connectivityMatrix);
}
}
bool ConnectivityMeasure::periodogram(const Eigen::VectorXd& input,
Eigen::MatrixXcd& periodograms,
const size_t& nSegments)
{
periodograms = Eigen::MatrixXcd::Zero(m_fftSize, nSegments);
// Cut input vector into segments, and apply window to each segment
for (size_t k = 0; k < nSegments; ++k)
{
Eigen::VectorXd segment = Eigen::VectorXd::Zero(m_fftSize);
for (size_t i = 0; i < size_t(m_windowLength); ++i)
{
segment(i) = input(i + k * m_windowOverlapSamples) * m_window(i);
}
Eigen::VectorXcd dft = Eigen::VectorXcd::Zero(m_fftSize);
m_fft.fwd(dft, segment, m_fftSize);
periodograms.col(k) = dft;
}
return true;
}
bool ConnectivityMeasure::powerSpectralDensity(const Eigen::MatrixXcd& dft,
Eigen::VectorXd& output,
const size_t& nSegments)
{
// output(i) will be the power for the band i across segments (time) as summed from the periodogram
output = Eigen::VectorXd::Zero(m_fftSize);
for (size_t k = 0; k < nSegments; ++k)
{
output += dft.col(k).cwiseAbs2();
}
double factor = double(nSegments) * m_u;
output /= factor;
return true;
}
bool ConnectivityMeasure::crossSpectralDensity(const Eigen::MatrixXcd& dft1,
const Eigen::MatrixXcd& dft2,
Eigen::VectorXcd& output,
const size_t& nSegments)
{
output = Eigen::VectorXcd::Zero(m_fftSize);
for (size_t k = 0; k < nSegments; ++k)
{
output += dft2.col(k).cwiseProduct(dft1.col(k).conjugate());
}
double factor = double(nSegments) * m_u;
output /= factor;
return true;
}
bool ConnectivityMeasure::coherence(std::vector <Eigen::MatrixXd>& connectivityMatrix)
{
for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++)
{
connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_psd[0].size());
for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++)
{
connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1][chan2].cwiseAbs2().cwiseQuotient(
m_psd[chan1].cwiseProduct(m_psd[chan2])).cwiseSqrt();
connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
}
}
return true;
}
bool ConnectivityMeasure::magnitudeSquaredCoherence(std::vector <Eigen::MatrixXd>& connectivityMatrix)
{
for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++)
{
connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_psd[0].size());
for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++)
{
connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1][chan2].cwiseAbs2().cwiseQuotient( m_psd[chan1].cwiseProduct(m_psd[chan2]) );
connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
}
}
return true;
}
bool ConnectivityMeasure::imaginaryCoherence(std::vector <Eigen::MatrixXd>& connectivityMatrix)
{
for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++)
{
connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_psd[0].size());
for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++)
{
connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1][chan2].imag().cwiseQuotient(
m_psd[chan1].cwiseProduct(m_psd[chan2]).cwiseSqrt());
connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
}
}
return true;
}
bool ConnectivityMeasure::absImaginaryCoherence(std::vector <Eigen::MatrixXd>& connectivityMatrix)
{
for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++)
{
connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_psd[0].size());
for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++)
{
connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1][chan2].imag().cwiseAbs().cwiseQuotient(
m_psd[chan1].cwiseProduct(m_psd[chan2]).cwiseSqrt());
connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
}
}
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,263 @@
///-------------------------------------------------------------------------------------------------
///
/// \file connectivityMeasureMetrics.hpp
/// \brief All connectivity metrics.
/// \author Arthur Desbois (Inria).
/// \version 1.0
/// \date 30/10/2020
///
/// \copyright (C) 2020 INRIA
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as published
/// by the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program. If not, see <https://www.gnu.org/licenses/>.
///-------------------------------------------------------------------------------------------------
#pragma once
#include <string>
#include <Eigen/Dense>
#include <unsupported/Eigen/FFT>
#include <openvibe/ov_all.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
/// \brief Enumeration of metrics.
enum class EConnectMetric
{
Coherence,
MagnitudeSquaredCoherence,
ImaginaryCoherence,
AbsImaginaryCoherence
};
/// \brief Convert Metrics to string.
/// \param metric The metric.
/// \return The metric as human readable string
inline std::string toString(const EConnectMetric metric)
{
switch (metric)
{
case EConnectMetric::Coherence:
return "Coherence";
case EConnectMetric::MagnitudeSquaredCoherence:
return "MagnitudeSquaredCoherence";
case EConnectMetric::ImaginaryCoherence:
return "ImaginaryCoherence";
case EConnectMetric::AbsImaginaryCoherence:
return "AbsImaginaryCoherence";
}
}
/// \brief Convert string to Metric.
/// \param metric The metric as a string
/// \return \ref EConnectMetric
inline EConnectMetric StringToMetric(const std::string& metric)
{
if (metric == "Coherence")
{ return EConnectMetric::Coherence; }
if (metric == "MagnitudeSquaredCoherence")
{ return EConnectMetric::MagnitudeSquaredCoherence; }
if (metric == "ImaginaryCoherence")
{ return EConnectMetric::ImaginaryCoherence; }
if (metric == "AbsImaginaryCoherence")
{ return EConnectMetric::AbsImaginaryCoherence; }
return EConnectMetric::Coherence; // default
}
/// \brief Enumeration of windowing methods
enum class EConnectWindowMethod
{
Hamming,
Hann,
Welch
};
/// \brief Convert Window method to string.
/// \param metric The metric.
/// \return the window method as human readable string
inline std::string toString(const EConnectWindowMethod winMethod)
{
switch (winMethod)
{
case EConnectWindowMethod::Hamming:
return "Hamming";
case EConnectWindowMethod::Hann:
return "Hann";
case EConnectWindowMethod::Welch:
return "Welch";
}
}
class ConnectivityMeasure
{
public:
ConnectivityMeasure()
{};
~ConnectivityMeasure()
{};
bool initialize(const EConnectMetric metric,
EConnectWindowMethod windowMethod,
int windowLength, int windowOverlap,
size_t nbChannels, size_t fftSize,
bool dcRemoval);
/// \brief Select the function to call for the connectivity measurement.
/// \param samples The input data set \f$x\f$. With \f$ nChan \f$ channels and \f$ nSamp \f$ samples per channel
/// \param connectivityMatrix The connectivity matrix
/// \param metric The chosen metric
/// \param windowsMethod The windowing method
/// \param windowLength The length of one window of processing (eg for Welch)
/// \param windowOverlap The overlap btw windows
/// \param connectLength The length of one connectivity measurement window
/// \param connectOverlap The overlap btw connectivity windows
bool process(const std::vector <Eigen::VectorXd>& samples,
std::vector <Eigen::MatrixXd>& connectivityMatrix);
private:
/// \brief Calculation of the Coherence
/// \f$ Pxx = PSD of x \f$ // \f$ Pyy = PSD of y \f$ // \f$ Sxy = cross spectral density of x and y \f$
/// \f$ MSC = \frac{\left| Sxy \right|}{sqrt{(Pxx.Pyy)} } \f$
///
/// The connectivity matrix is symmetrical, so we only need to compute its top part
/// and discard the diagonal (no need to compute connectivity of a single channel...)
/// eg [0 1 2 3] :
/// [ 01 02 03]
/// [ 12 13]
/// [ 23]
/// [ ]
/// \param connectivityMatrix The connectivity matrix as a vector of 2D Matrices of size nbChannels x (nbChannles x frequency_taps)
/// \return True if it succeeds, false if it fails.
/// \todo don't recompute the whole table, because connectivity measures overlap !
bool coherence(std::vector <Eigen::MatrixXd>& connectivityMatrix);
/// \brief Calculation of the Magnitude Squared Coherence
/// \f$ Pxx = PSD of x \f$ // \f$ Pyy = PSD of y \f$ // \f$ Sxy = cross spectral density of x and y \f$
/// \f$ MSC = \frac{\left| Sxy \right|^2}{(Pxx.Pyy)} \f$
///
/// The connectivity matrix is symmetrical, so we only need to compute its top part
/// and discard the diagonal (no need to compute connectivity of a single channel...)
/// eg [0 1 2 3] :
/// [ 01 02 03]
/// [ 12 13]
/// [ 23]
/// [ ]
/// \param connectivityMatrix The connectivity matrix as a vector of 2D Matrices of size nbChannels x (nbChannles x frequency_taps)
/// \return True if it succeeds, false if it fails.
/// \todo don't recompute the whole table, because connectivity measures overlap !
bool magnitudeSquaredCoherence(std::vector <Eigen::MatrixXd>& connectivityMatrix);
/// \brief Calculation of the Imaginary part of the coherence
/// \f$ Pxx = PSD of x \f$ // \f$ Pyy = PSD of y \f$ // \f$ Sxy = cross spectral density of x and y \f$
/// \f$ ImC = \frac{Im(Sxy)}{sqrt{Pxx.Pyy} } \f$
/// The connectivity matrix is symmetrical, so we only need to compute
/// its top part, and discard the diagonal (no need to compute connectivity of a single channel...)
/// eg [0 1 2 3] :
/// [ 01 02 03]
/// [ 12 13]
/// [ 23]
/// [ ]
/// \param connectivityMatrix The connectivity matrix as a vector of 2D Matrices of size nbChannels x (nbChannles x frequency_taps)
/// \return True if it succeeds, false if it fails.
/// \todo don't recompute the whole table, because connectivity measures overlap !
bool imaginaryCoherence(std::vector <Eigen::MatrixXd>& connectivityMatrix);
/// \brief Calculation of the absolute value of the Imaginary part of the coherence
/// \f$ Pxx = PSD of x \f$ // \f$ Pyy = PSD of y \f$ // \f$ Sxy = cross spectral density of x and y \f$
/// \f$ ImC = \frac{\left| Im(Sxy) \right|}{sqrt{Pxx.Pyy} } \f$
/// The connectivity matrix is symmetrical, so we only need to compute
/// its top part, and discard the diagonal (no need to compute connectivity of a single channel...)
/// eg [0 1 2 3] :
/// [ 01 02 03]
/// [ 12 13]
/// [ 23]
/// [ ]
/// \param connectivityMatrix The connectivity matrix as a vector of 2D Matrices of size nbChannels x (nbChannles x frequency_taps)
/// \return True if it succeeds, false if it fails.
/// \todo don't recompute the whole table, because connectivity measures overlap !
bool absImaginaryCoherence(std::vector <Eigen::MatrixXd>& connectivityMatrix);
///
/// \brief Generates periodigram of signal
/// \param input The signal
/// \param periodograms The generated periodigram
/// \param nSegments
/// \return True on succes, false otherwise
bool periodogram(const Eigen::VectorXd& input,
Eigen::MatrixXcd& periodograms,
const size_t& nSegments);
///
/// \brief Computes the spectral density of a spectrum
/// \param dft The discrete fourier transform
/// \param output The generated spectral density
/// \param nSegments
/// \return True on success, false otherwise
bool powerSpectralDensity(const Eigen::MatrixXcd& dft,
Eigen::VectorXd& output,
const size_t& nSegments);
///
/// \brief Computes cross spectral density of 2 spectra
/// Only computes the top diagonal of the CPSD matrix
/// eg [0 1 2 3] :
/// [00 01 02 03]
/// [ 11 12 13]
/// [ 22 23]
/// [ 33]
/// \param dft1 The first discrete fourier transform
/// \param dft2 The second discrete fourier transform
/// \param output The generated cross spectral density matrix
/// \param nSegments
/// \return True on success, false otherwise
///
/// \todo : don't compute only the top part, because some connectivity measurements are not symmetrical ?
bool crossSpectralDensity(const Eigen::MatrixXcd& dft1,
const Eigen::MatrixXcd& dft2,
Eigen::VectorXcd& output,
const size_t& nSegments);
// Parameters / Members
Eigen::FFT<double, Eigen::internal::kissfft_impl<double>> m_fft; // Instance of the fft transform
EConnectMetric m_metric = EConnectMetric::Coherence;
EConnectWindowMethod m_windowMethod = EConnectWindowMethod::Hann;
Eigen::VectorXd m_window; // Window used for Welch method
double m_u = 0; // Window normalization factor
std::vector <Eigen::MatrixXcd> m_dft; // Discrete Fourier Transform
std::vector <Eigen::VectorXd> m_psd; // Power Spectral Density
std::vector <std::vector<Eigen::VectorXcd>> m_cpsd; // Cross Power Spectral Density
int m_windowLength = 128; // size of one Welch window (samples)
int m_windowOverlap = 50; // overlap btw windows (%)
int m_windowOverlapSamples = 64;
int m_nbWindows = 8;
size_t m_fftSize = 256;
size_t m_nbChannels = 1;
bool m_dcRemoval = false;
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,168 @@
///-------------------------------------------------------------------------------------------------
///
/// \file CBoxAlgorithmMatrix3dTo2d.cpp
/// \brief Implementation of the box Matrix3dTo2d
/// \author Arthur DESBOIS (INRIA).
/// \version 0.0.1.
/// \date Fri Feb 12 15:13:00 2021.
///
/// \copyright (C) 2021 INRIA
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as published
/// by the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program. If not, see <https://www.gnu.org/licenses/>.
///-------------------------------------------------------------------------------------------------
#include "CBoxAlgorithmMatrix3dTo2d.hpp"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmMatrix3dTo2d::initialize()
{
m_matrixDecoder.initialize(*this, 0);
m_matrixEncoder.initialize(*this, 0);
m_iMatrix = m_matrixDecoder.getOutputMatrix();
m_oMatrix = m_matrixEncoder.getInputMatrix();
m_dimensionToRemove = int(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0));
m_removedDimensionIdx = int(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1));
OV_ERROR_UNLESS_KRF(m_dimensionToRemove == 0 || m_dimensionToRemove == 1 || m_dimensionToRemove == 2, "Invalid dimension number", Kernel::ErrorType::BadInput);
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmMatrix3dTo2d::uninitialize()
{
m_matrixDecoder.uninitialize();
m_matrixEncoder.uninitialize();
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmMatrix3dTo2d::processInput(const size_t index)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmMatrix3dTo2d::process()
{
const Kernel::IBox& staticBoxContext=this->getStaticBoxContext();
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
m_matrixDecoder.decode(i);
if(m_matrixDecoder.isHeaderReceived())
{
OV_ERROR_UNLESS_KRF(m_iMatrix->getDimensionCount() == 3, "Input matrix should have 3 dimensions", Kernel::ErrorType::BadInput);
m_dim0Size = m_iMatrix->getDimensionSize(0);
m_dim1Size = m_iMatrix->getDimensionSize(1);
m_dim2Size = m_iMatrix->getDimensionSize(2);
switch(m_dimensionToRemove) {
case 0:
OV_ERROR_UNLESS_KRF(m_dim0Size > m_removedDimensionIdx, "Idx in removed dimension over dimension size", Kernel::ErrorType::BadInput);
MatrixInit(*m_oMatrix, m_dim1Size, m_dim2Size);
break;
case 1:
OV_ERROR_UNLESS_KRF(m_dim1Size > m_removedDimensionIdx, "Idx in removed dimension over dimension size", Kernel::ErrorType::BadInput);
MatrixInit(*m_oMatrix, m_dim0Size, m_dim2Size);
break;
case 2:
OV_ERROR_UNLESS_KRF(m_dim2Size > m_removedDimensionIdx, "Idx in removed dimension over dimension size", Kernel::ErrorType::BadInput);
MatrixInit(*m_oMatrix, m_dim0Size, m_dim1Size);
break;
}
m_matrixEncoder.encodeHeader();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if(m_matrixDecoder.isBufferReceived())
{
RemoveDimension(*m_iMatrix, *m_oMatrix);
this->getLogManager() << Kernel::LogLevel_Debug<< "Received matrix with dimensions " << m_iMatrix->getDimensionSize(0) << " x " << m_iMatrix->getDimensionSize(1) << " x " << m_iMatrix->getDimensionSize(2) << "\n";
this->getLogManager() << Kernel::LogLevel_Debug << "Output matrix has dimensions " << m_oMatrix->getDimensionSize(0) << " x " << m_oMatrix->getDimensionSize(1) << "\n";
m_matrixEncoder.encodeBuffer();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if(m_matrixDecoder.isEndReceived())
{
m_matrixEncoder.encodeEnd();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
}
return true;
}
bool CBoxAlgorithmMatrix3dTo2d::MatrixInit(IMatrix& out, const size_t dim0, const size_t dim1)
{
out.setDimensionCount(2);
out.setDimensionSize(0, dim0);
out.setDimensionSize(1, dim1);
return true;
}
bool CBoxAlgorithmMatrix3dTo2d::RemoveDimension(const IMatrix& in, IMatrix& out)
{
size_t idxOutBuffer = 0;
const double* inBuffer = in.getBuffer();
double* outBuffer = out.getBuffer();
switch(m_dimensionToRemove) {
case 0:
for(size_t idx1 = 0; idx1 < m_dim1Size; idx1++) {
for(size_t idx2 = 0; idx2 < m_dim2Size; idx2++) {
outBuffer[idxOutBuffer++] = inBuffer[m_removedDimensionIdx*m_dim1Size*m_dim2Size + idx1*m_dim2Size + idx2];
}
}
break;
case 1:
for(size_t idx0 = 0; idx0 < m_dim0Size; idx0++) {
for(size_t idx2 = 0; idx2 < m_dim2Size; idx2++) {
outBuffer[idxOutBuffer++] = inBuffer[idx0*m_dim1Size*m_dim2Size + m_removedDimensionIdx*m_dim2Size + idx2];
}
}
break;
case 2:
for(size_t idx0 = 0; idx0 < m_dim0Size; idx0++) {
for(size_t idx1 = 0; idx1 < m_dim1Size; idx1++) {
outBuffer[idxOutBuffer++] = inBuffer[idx0*m_dim1Size*m_dim2Size + idx1*m_dim2Size + m_removedDimensionIdx];
}
}
break;
}
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,114 @@
///-------------------------------------------------------------------------------------------------
///
/// \file CBoxAlgorithmMatrix3dTo2d.hpp
/// \brief Classes of the box Matrix3dTo2d
/// \author Arthur DESBOIS (INRIA).
/// \version 0.0.1.
/// \date Fri Feb 12 15:13:00 2021.
///
/// \copyright (C) 2021 INRIA
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as published
/// by the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program. If not, see <https://www.gnu.org/licenses/>.
///-------------------------------------------------------------------------------------------------
#pragma once
#include "ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
/// \brief The class CBoxAlgorithmMatrix3dTo2d describes the box Matrix 3D to 2D.
class CBoxAlgorithmMatrix3dTo2d 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_Matrix3dTo2d)
protected:
// Codecs
Toolkit::TStreamedMatrixDecoder <CBoxAlgorithmMatrix3dTo2d> m_matrixDecoder;
Toolkit::TStreamedMatrixEncoder <CBoxAlgorithmMatrix3dTo2d> m_matrixEncoder;
// Matrices
CMatrix* m_iMatrix = nullptr;
CMatrix* m_oMatrix = nullptr;
// Parameters
int m_dimensionToRemove;
int m_removedDimensionIdx;
size_t m_dim0Size;
size_t m_dim1Size;
size_t m_dim2Size;
private:
bool MatrixInit(CMatrix& m, const size_t dim0, const size_t dim1);
bool RemoveDimension(const CMatrix& in, CMatrix& out);
};
/// \brief Descriptor of the box Matrix 3D to 2D.
class CBoxAlgorithmMatrix3dTo2dDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override
{}
CString getName() const override { return CString("Matrix 3D to 2D"); }
CString getAuthorName() const override { return CString("Arthur Desbois"); }
CString getAuthorCompanyName() const override { return CString("INRIA"); }
CString getShortDescription() const override { return CString("Convert 3D matrices to 2D"); }
CString getDetailedDescription() const override { return CString("Convert 3 dimensional matrices to 2D matrices, by selecting a dimension to remove"); }
CString getCategory() const override { return CString("Signal processing/Basic"); }
CString getVersion() const override { return CString("0.0.1"); }
CString getStockItemName() const override { return CString(""); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_Matrix3dTo2d; }
IPluginObject* create() override { return new CBoxAlgorithmMatrix3dTo2d; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("input", OV_TypeId_StreamedMatrix);
prototype.addOutput("output", OV_TypeId_StreamedMatrix);
prototype.addSetting("Dimension to remove", OV_TypeId_Integer, "");
prototype.addSetting("Index in removed dimension", OV_TypeId_Integer, "");
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_Matrix3dTo2dDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,125 @@
#if defined(TARGET_HAS_ThirdPartyEIGEN)
#include "ovpCBoxAlgorithmARCoefficients.h"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmARCoefficients::initialize()
{
// Signal stream decoder
m_decoder.initialize(*this, 0);
m_method = &this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_ClassId_Algorithm_ARBurgMethod));
m_method->initialize();
ip_matrix.initialize(m_method->getInputParameter(OVP_Algorithm_ARBurgMethod_InputParameterId_Matrix));
op_matrix.initialize(m_method->getOutputParameter(OVP_Algorithm_ARBurgMethod_OutputParameterId_Matrix));
ip_order.initialize(m_method->getInputParameter(OVP_Algorithm_ARBurgMethod_InputParameterId_UInteger));
ip_order = uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0));
// Feature vector stream encoder
m_encoder.initialize(*this, 0);
// The AR Burg's Method algorithm will take the matrix coming from the signal decoder:
ip_matrix.setReferenceTarget(m_decoder.getOutputMatrix());
// The feature vector encoder will take the matrix from the AR Burg's Method algorithm:
m_encoder.getInputMatrix().setReferenceTarget(op_matrix);
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmARCoefficients::uninitialize()
{
m_decoder.uninitialize();
ip_matrix.uninitialize();
ip_order.uninitialize();
op_matrix.uninitialize();
m_method->uninitialize();
this->getAlgorithmManager().releaseAlgorithm(*m_method);
m_encoder.uninitialize();
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmARCoefficients::processInput(const size_t /*index*/)
{
// ready to process !
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmARCoefficients::process()
{
// the dynamic box context describes the current state of the box inputs and outputs (i.e. the chunks)
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
// we decode the input signal chunks
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
m_decoder.decode(i);
if (m_decoder.isHeaderReceived())
{
// Header received
m_method->process(OVP_Algorithm_ARBurgMethod_InputTriggerId_Initialize);
// Make sure the algo initialization was successful
if (!m_method->process(OVP_Algorithm_ARBurgMethod_InputTriggerId_Initialize))
{
this->getLogManager() << Kernel::LogLevel_Error << "Initialization was unsuccessful\n";
return false;
}
// Pass the header to the next boxes, by encoding a header on the output 0:
m_encoder.encodeHeader();
// send the output chunk containing the header. The dates are the same as the input chunk:
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_decoder.isBufferReceived())
{
// we process the signal matrix with our algorithm
m_method->process(OVP_Algorithm_ARBurgMethod_InputTriggerId_Process);
// If the process is done successfully, we can encode the buffer
if (m_method->isOutputTriggerActive(OVP_Algorithm_ARBurgMethod_OutputTriggerId_ProcessDone))
{
// Encode the output buffer :
m_encoder.encodeBuffer();
// and send it to the next boxes :
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
}
if (m_decoder.isEndReceived())
{
// End of stream received. This happens only once when pressing "stop". Just pass it to the next boxes so they receive the message :
m_encoder.encodeEnd();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
}
return true;
}
#endif // #if defined(TARGET_HAS_ThirdPartyEIGEN)
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,100 @@
#pragma once
#if defined(TARGET_HAS_ThirdPartyEIGEN)
//You may have to change this path to match your folder organisation
#include "../../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
/**
* \class CBoxAlgorithmARCoefficients
* \author Alison Cellard (Inria)
* \date Wed Nov 28 10:40:52 2012
* \brief The class CBoxAlgorithmARCoefficients describes the box AR Features.
*
*/
class CBoxAlgorithmARCoefficients final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
void release() override { delete this; }
bool initialize() override;
bool uninitialize() override;
// Process callbacks on new input received
bool processInput(const size_t index) override;
bool process() override;
// As we do with any class in openvibe, we use the macro below
// to associate this box to an unique identifier.
// The inheritance information is also made available,
// as we provide the superclass Toolkit::TBoxAlgorithm < IBoxAlgorithm >
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_ARCoefficients)
protected:
// Signal stream decoder
Toolkit::TSignalDecoder<CBoxAlgorithmARCoefficients> m_decoder;
// Feature vector stream encoder
Toolkit::TStreamedMatrixEncoder<CBoxAlgorithmARCoefficients> m_encoder;
Kernel::IAlgorithmProxy* m_method = nullptr;
Kernel::TParameterHandler<CMatrix*> ip_matrix;
Kernel::TParameterHandler<CMatrix*> op_matrix;
Kernel::TParameterHandler<uint64_t> ip_order;
};
/**
* \class CBoxAlgorithmARCoefficientsDesc
* \author Alison Cellard (Inria)
* \date Wed Nov 28 10:40:52 2012
* \brief Descriptor of the box AR Features.
*
*/
class CBoxAlgorithmARCoefficientsDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("AutoRegressive Coefficients"); }
CString getAuthorName() const override { return CString("Alison Cellard"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("Estimates autoregressive (AR) coefficients from a set of signals"); }
CString getDetailedDescription() const override { return CString("Estimates autoregressive (AR) linear model coefficients using Burg's method"); }
CString getCategory() const override { return CString("Signal processing/Basic"); }
CString getVersion() const override { return CString("1.0"); }
CString getStockItemName() const override { return CString("gtk-convert"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_ARCoefficients; }
IPluginObject* create() override { return new CBoxAlgorithmARCoefficients; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("EEG Signal",OV_TypeId_Signal);
prototype.addOutput("AR Features",OV_TypeId_StreamedMatrix);
prototype.addSetting("Order",OV_TypeId_Integer, "1");
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_ARCoefficientsDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif // TARGET_HAS_ThirdPartyEIGEN
@@ -0,0 +1,141 @@
#include "ovpCBoxAlgorithmDifferentialIntegral.h"
#include <iostream>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmDifferentialIntegral::initialize()
{
// Signal stream decoder
m_decoder.initialize(*this, 0);
// Signal stream encoder
m_encoder.initialize(*this, 0);
// If you need to, you can manually set the reference targets to link the codecs input and output. To do so, you can use :
m_encoder.getInputMatrix().setReferenceTarget(m_decoder.getOutputMatrix());
m_encoder.getInputSamplingRate().setReferenceTarget(m_decoder.getOutputSamplingRate());
m_operation = EDifferentialIntegralOperation(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0)));
m_filterOrder = uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1));
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmDifferentialIntegral::uninitialize()
{
m_decoder.uninitialize();
m_encoder.uninitialize();
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmDifferentialIntegral::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
/*******************************************************************************/
double CBoxAlgorithmDifferentialIntegral::operation(const double a, const double b) const
{
if (m_operation == EDifferentialIntegralOperation::Differential) { return a - b; }
if (m_operation == EDifferentialIntegralOperation::Integral) { return a + b; }
return 0;
}
bool CBoxAlgorithmDifferentialIntegral::process()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
//iterate over all chunk on input 0
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
// decode the chunk i on input 0
m_decoder.decode(i);
if (m_decoder.isHeaderReceived())
{
// initialize the past data array
CMatrix* matrix = m_decoder.getOutputMatrix(); // the StreamedMatrix of samples.
// initialize all of the tables according to the number of channels
m_pastData = new double*[matrix->getDimensionSize(0)];
m_tmpData = new double*[matrix->getDimensionSize(0)];
m_stabilized = new bool[matrix->getDimensionSize(0)];
m_step = new size_t[matrix->getDimensionSize(0)];
for (size_t k = 0; k < matrix->getDimensionSize(0); ++k)
{
m_stabilized[k] = false;
m_step[k] = 0;
m_pastData[k] = new double[m_filterOrder];
m_tmpData[k] = new double[m_filterOrder];
m_tmpData[k][0] = 0;
}
// Encode the output header
m_encoder.encodeHeader();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_decoder.isBufferReceived())
{
CMatrix* matrix = m_decoder.getOutputMatrix(); // the StreamedMatrix of samples.
const size_t nChannel = matrix->getDimensionSize(0);
const size_t samplesPerChannel = matrix->getDimensionSize(1);
// ... do some process on the matrix ...
double* buffer = matrix->getBuffer();
for (size_t c = 0; c < nChannel; ++c)
{
for (size_t s = 0; s < samplesPerChannel; ++s)
{
// save the results of the previous step in a temporary array
for (size_t step = 0; step < m_step[c]; ++step) { m_tmpData[c][step] = m_pastData[c][step]; }
// save the current sample as f^0(x)
m_pastData[c][0] = buffer[s + c * samplesPerChannel];
// save all of the f^n(x)
for (size_t step = 1; step < m_step[c]; ++step) { m_pastData[c][step] = operation(m_pastData[c][step - 1], m_tmpData[c][step - 1]); }
// if the filter is not yet stabilized we increase the step and use 0 as a return value
if (!m_stabilized[c])
{
if (m_step[c] == m_filterOrder) { m_stabilized[c] = true; }
else { m_step[c]++; }
buffer[s + c * samplesPerChannel] = 0;
}
// otherwise use f^order(x)
else { buffer[s + c * samplesPerChannel] = operation(m_pastData[c][m_filterOrder - 1], m_tmpData[c][m_filterOrder - 1]); }
}
}
// Encode the output buffer
m_encoder.encodeBuffer();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_decoder.isEndReceived())
{
// End of stream received. This happens only once when pressing "stop". Just pass it to the next boxes so they receive the message :
m_encoder.encodeEnd();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
}
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,100 @@
#pragma once
//You may have to change this path to match your folder organisation
#include "../../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
// The unique identifiers for the box and its descriptor.
// Identifier are randomly chosen by the skeleton-generator.
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
/**
* \class CBoxAlgorithmDifferentialIntegral
* \author Jozef Legeny (INRIA)
* \date Thu Oct 27 15:24:05 2011
* \brief The class CBoxAlgorithmDifferentialIntegral describes the box DifferentialIntegral.
*
*/
class CBoxAlgorithmDifferentialIntegral 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_DifferentialIntegral)
protected:
Toolkit::TSignalDecoder<CBoxAlgorithmDifferentialIntegral> m_decoder;
Toolkit::TSignalEncoder<CBoxAlgorithmDifferentialIntegral> m_encoder;
private:
double operation(const double a, const double b) const;
EDifferentialIntegralOperation m_operation = EDifferentialIntegralOperation::Differential;
uint64_t m_filterOrder = 0;
/// Holds the differentials/integrals of all orders from the previous step
double** m_pastData = nullptr;
double** m_tmpData = nullptr;
/// Is true when the filter is stabilized
bool* m_stabilized = nullptr;
/// Counts the samples up to the filter order, used to stabilize the filter
size_t* m_step = nullptr;
};
/**
* \class CBoxAlgorithmDifferentialIntegralDesc
* \author Jozef Legeny (INRIA)
* \date Thu Oct 27 15:24:05 2011
* \brief Descriptor of the box DifferentialIntegral.
*
*/
class CBoxAlgorithmDifferentialIntegralDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Signal Differential/Integral"); }
CString getAuthorName() const override { return CString("Jozef Legeny"); }
CString getAuthorCompanyName() const override { return CString("INRIA"); }
CString getShortDescription() const override { return CString("Calculates a differential or an integral of a signal"); }
CString getDetailedDescription() const override { return CString("Calculates a differential or an integral of a signal."); }
CString getCategory() const override { return CString("Signal processing/Basic"); }
CString getVersion() const override { return CString("1.0"); }
CString getStockItemName() const override { return CString("gtk-execute"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_DifferentialIntegral; }
IPluginObject* create() override { return new CBoxAlgorithmDifferentialIntegral; }
/*
virtual IBoxListener* createBoxListener() const { return new CBoxAlgorithmDifferentialIntegralListener; }
virtual void releaseBoxListener(IBoxListener* listener) const { delete listener; }
*/
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Input Signal",OV_TypeId_Signal);
prototype.addOutput("Output Signal",OV_TypeId_Signal);
prototype.addSetting("Operation", OVP_TypeId_DifferentialIntegralOperation, "Differential");
prototype.addSetting("Order", OV_TypeId_Integer, "1");
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_DifferentialIntegralDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,143 @@
#include "ovpCBoxAlgorithmERSPAverage.h"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmERSPAverage::initialize()
{
m_epochingStim = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_computeStim = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_decoderSpectrum.initialize(*this, 0);
m_decoderStimulations.initialize(*this, 1);
m_encoder.initialize(*this, 0);
return true;
}
bool CBoxAlgorithmERSPAverage::uninitialize()
{
m_encoder.uninitialize();
m_decoderSpectrum.uninitialize();
m_decoderStimulations.uninitialize();
for (auto& v : m_cachedSpectra) { for (auto m : v) { delete m; } }
m_cachedSpectra.clear();
return true;
}
bool CBoxAlgorithmERSPAverage::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmERSPAverage::process()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
for (size_t i = 0; i < boxContext.getInputChunkCount(1); ++i)
{
m_decoderStimulations.decode(i);
if (m_decoderStimulations.isBufferReceived())
{
const auto stims = m_decoderStimulations.getOutputStimulationSet();
for (size_t j = 0; j < stims->getStimulationCount(); ++j)
{
if (stims->getStimulationIdentifier(j) == m_epochingStim)
{
m_currentChunk = 0;
m_numTrials++;
}
if (stims->getStimulationIdentifier(j) == m_computeStim) { computeAndSend(); }
}
}
}
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
m_decoderSpectrum.decode(i);
if (m_decoderSpectrum.isHeaderReceived())
{
const uint64_t samplingRate = m_decoderSpectrum.getOutputSamplingRate();
m_encoder.getInputSamplingRate() = samplingRate;
m_encoder.getInputFrequencyAbscissa()->copy(*m_decoderSpectrum.getOutputFrequencyAbscissa());
m_encoder.getInputMatrix()->copyDescription(*m_decoderSpectrum.getOutputMatrix());
m_encoder.encodeHeader();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_decoderSpectrum.isBufferReceived())
{
const CMatrix* input = m_decoderSpectrum.getOutputMatrix();
appendChunk(*input, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_decoderSpectrum.isEndReceived())
{
m_encoder.encodeEnd();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
}
return true;
}
bool CBoxAlgorithmERSPAverage::appendChunk(const CMatrix& chunk, const uint64_t startTime, const uint64_t endTime)
{
if (m_cachedSpectra.size() <= m_currentChunk)
{
m_cachedSpectra.resize(m_currentChunk + 1);
m_timestamps.resize(m_currentChunk + 1);
}
CMatrix* matrixCopy = new CMatrix();
matrixCopy->copy(chunk);
m_cachedSpectra[m_currentChunk].push_back(matrixCopy);
m_timestamps[m_currentChunk].start = startTime;
m_timestamps[m_currentChunk].end = endTime;
m_currentChunk++;
return true;
}
bool CBoxAlgorithmERSPAverage::computeAndSend()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
double* outptr = m_encoder.getInputMatrix()->getBuffer();
this->getLogManager() << Kernel::LogLevel_Info << "Counted " << m_numTrials << " trials and " << m_cachedSpectra.size() << " spectra per trial.\n";
for (size_t i = 0; i < m_cachedSpectra.size(); ++i)
{
// Compute average for each slice
const double divider = 1.0 / m_cachedSpectra[i].size();
m_encoder.getInputMatrix()->resetBuffer();
for (auto mat : m_cachedSpectra[i])
{
const double* inptr = mat->getBuffer();
for (size_t p = 0; p < mat->getBufferElementCount(); ++p) { outptr[p] += divider * inptr[p]; }
delete mat;
}
m_encoder.encodeBuffer();
boxContext.markOutputAsReadyToSend(0, m_timestamps[i].start - m_timestamps[0].start, m_timestamps[i].end - m_timestamps[0].start);
}
m_numTrials = 0;
m_currentChunk = 0;
m_cachedSpectra.clear();
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,92 @@
#pragma once
#include "../../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
class CBoxAlgorithmERSPAverage 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_ERSPAverage)
protected:
bool appendChunk(const CMatrix& chunk, uint64_t startTime, uint64_t endTime);
bool computeAndSend();
Toolkit::TSpectrumDecoder<CBoxAlgorithmERSPAverage> m_decoderSpectrum;
Toolkit::TStimulationDecoder<CBoxAlgorithmERSPAverage> m_decoderStimulations;
Toolkit::TSpectrumEncoder<CBoxAlgorithmERSPAverage> m_encoder;
struct STimestamp
{
uint64_t start, end;
};
std::vector<std::vector<CMatrix*>> m_cachedSpectra;
std::vector<STimestamp> m_timestamps;
size_t m_currentChunk = 0;
size_t m_numTrials = 0;
uint64_t m_epochingStim = 0;
uint64_t m_computeStim = 0;
};
class CBoxAlgorithmERSPAverageDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("ERSP Average"); }
CString getAuthorName() const override { return CString("Jussi T. Lindgren"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override
{
return CString("Averages a sequence of spectra per trial across multiple trials. The result is a sequence starting from t=0.");
}
CString getDetailedDescription() const override
{
return CString(
"Example: Given an input sequence [t,s1,s2,t,s3,s4] for two trials with s* the spectra and t a stimulation denoting the trial start, the box returns 1/2*(s1+s3), 1/2*(s2+s4).");
}
CString getCategory() const override { return CString("Signal processing/Basic"); }
CString getVersion() const override { return CString("0.1"); }
CString getStockItemName() const override { return CString("gtk-sort-ascending"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_ERSPAverage; }
IPluginObject* create() override { return new CBoxAlgorithmERSPAverage; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Input spectra", OV_TypeId_Spectrum);
prototype.addInput("Control stream", OV_TypeId_Stimulations);
prototype.addOutput("Output spectra", OV_TypeId_Spectrum);
prototype.addSetting("Trial start marker", OV_TypeId_Stimulation, "OVTK_GDF_Start_Of_Trial", false);
prototype.addSetting("Computation trigger", OV_TypeId_Stimulation, "OVTK_StimulationId_ExperimentStop", false);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_ERSPAverageDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,195 @@
#include "ovpCBoxAlgorithmEpochVariance.h"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CEpochVariance::initialize()
{
CIdentifier inputTypeID;
getStaticBoxContext().getInputType(0, inputTypeID);
if (inputTypeID == OV_TypeId_StreamedMatrix)
{
m_decoder = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StreamedMatrixDecoder));
m_encoder = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StreamedMatrixEncoder));
m_encoderForVariance = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StreamedMatrixEncoder));
m_encoderForConfidenceBound = &getAlgorithmManager().
getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StreamedMatrixEncoder));
}
else if (inputTypeID == OV_TypeId_FeatureVector)
{
m_decoder = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_FeatureVectorDecoder));
m_encoder = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_FeatureVectorEncoder));
m_encoderForVariance = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_FeatureVectorEncoder));
m_encoderForConfidenceBound = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_FeatureVectorEncoder));
}
else if (inputTypeID == OV_TypeId_Signal)
{
m_decoder = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SignalDecoder));
m_encoder = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SignalEncoder));
m_encoderForVariance = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SignalEncoder));
m_encoderForConfidenceBound = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SignalEncoder));
}
else if (inputTypeID == OV_TypeId_Spectrum)
{
m_decoder = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SpectrumDecoder));
m_encoder = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SpectrumEncoder));
m_encoderForVariance = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SpectrumDecoder));
m_encoderForConfidenceBound = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SpectrumDecoder));
}
else { return false; }
m_decoder->initialize();
m_encoder->initialize();
m_encoderForVariance->initialize();
m_encoderForConfidenceBound->initialize();
m_matrixVariance = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_ClassId_Algorithm_MatrixVariance));
m_matrixVariance->initialize();
if (inputTypeID == OV_TypeId_StreamedMatrix) { }
else if (inputTypeID == OV_TypeId_FeatureVector) { }
else if (inputTypeID == OV_TypeId_Signal)
{
m_encoder->getInputParameter(OVP_GD_Algorithm_SignalEncoder_InputParameterId_Sampling)->setReferenceTarget(
m_decoder->getOutputParameter(OVP_GD_Algorithm_SignalDecoder_OutputParameterId_Sampling));
m_encoderForVariance->getInputParameter(OVP_GD_Algorithm_SignalEncoder_InputParameterId_Sampling)->setReferenceTarget(
m_decoder->getOutputParameter(OVP_GD_Algorithm_SignalDecoder_OutputParameterId_Sampling));
m_encoderForConfidenceBound->getInputParameter(OVP_GD_Algorithm_SignalEncoder_InputParameterId_Sampling)->setReferenceTarget(
m_decoder->getOutputParameter(OVP_GD_Algorithm_SignalDecoder_OutputParameterId_Sampling));
}
else if (inputTypeID == OV_TypeId_Spectrum)
{
m_encoder->getInputParameter(OVP_GD_Algorithm_SpectrumEncoder_InputParameterId_FrequencyAbscissa)->setReferenceTarget(
m_decoder->getOutputParameter(OVP_GD_Algorithm_SpectrumDecoder_OutputParameterId_FrequencyAbscissa));
m_encoderForVariance->getInputParameter(OVP_GD_Algorithm_SpectrumEncoder_InputParameterId_FrequencyAbscissa)->setReferenceTarget(
m_decoder->getOutputParameter(OVP_GD_Algorithm_SpectrumDecoder_OutputParameterId_FrequencyAbscissa));
m_encoderForConfidenceBound->getInputParameter(OVP_GD_Algorithm_SpectrumEncoder_InputParameterId_FrequencyAbscissa)->setReferenceTarget(
m_decoder->
getOutputParameter(OVP_GD_Algorithm_SpectrumDecoder_OutputParameterId_FrequencyAbscissa));
m_encoder->getInputParameter(OVP_GD_Algorithm_SpectrumEncoder_InputParameterId_Sampling)->setReferenceTarget(
m_decoder->getOutputParameter(OVP_GD_Algorithm_SpectrumDecoder_OutputParameterId_Sampling));
m_encoderForVariance->getInputParameter(OVP_GD_Algorithm_SpectrumEncoder_InputParameterId_Sampling)->setReferenceTarget(
m_decoder->getOutputParameter(OVP_GD_Algorithm_SpectrumDecoder_OutputParameterId_Sampling));
m_encoderForConfidenceBound->getInputParameter(OVP_GD_Algorithm_SpectrumEncoder_InputParameterId_Sampling)->setReferenceTarget(
m_decoder->getOutputParameter(OVP_GD_Algorithm_SpectrumDecoder_OutputParameterId_Sampling));
}
ip_averagingMethod.initialize(m_matrixVariance->getInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_AveragingMethod));
ip_matrixCount.initialize(m_matrixVariance->getInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_MatrixCount));
ip_SignificanceLevel.initialize(m_matrixVariance->getInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_SignificanceLevel));
ip_averagingMethod = uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0));
ip_matrixCount = uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1));
ip_SignificanceLevel = double(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2));
m_matrixVariance->getInputParameter(OVP_Algorithm_MatrixVariance_InputParameterId_Matrix)->setReferenceTarget(
m_decoder->getOutputParameter(OVP_GD_Algorithm_StreamedMatrixDecoder_OutputParameterId_Matrix));
m_encoder->getInputParameter(OVP_GD_Algorithm_StreamedMatrixEncoder_InputParameterId_Matrix)->setReferenceTarget(
m_matrixVariance->getOutputParameter(OVP_Algorithm_MatrixVariance_OutputParameterId_AveragedMatrix));
m_encoderForVariance->getInputParameter(OVP_GD_Algorithm_StreamedMatrixEncoder_InputParameterId_Matrix)->setReferenceTarget(
m_matrixVariance->getOutputParameter(OVP_Algorithm_MatrixVariance_OutputParameterId_Variance));
m_encoderForConfidenceBound->getInputParameter(OVP_GD_Algorithm_StreamedMatrixEncoder_InputParameterId_Matrix)->setReferenceTarget(
m_matrixVariance->getOutputParameter(OVP_Algorithm_MatrixVariance_OutputParameterId_ConfidenceBound));
if (ip_matrixCount <= 0)
{
getLogManager() << Kernel::LogLevel_Error << "You should provide a positive number of epochs better than " << ip_matrixCount << "\n";
return false;
}
return true;
}
bool CEpochVariance::uninitialize()
{
ip_averagingMethod.uninitialize();
ip_matrixCount.uninitialize();
m_matrixVariance->uninitialize();
m_encoder->uninitialize();
m_encoderForVariance->uninitialize();
m_encoderForConfidenceBound->uninitialize();
m_decoder->uninitialize();
getAlgorithmManager().releaseAlgorithm(*m_matrixVariance);
getAlgorithmManager().releaseAlgorithm(*m_encoder);
getAlgorithmManager().releaseAlgorithm(*m_encoderForVariance);
getAlgorithmManager().releaseAlgorithm(*m_encoderForConfidenceBound);
getAlgorithmManager().releaseAlgorithm(*m_decoder);
return true;
}
bool CEpochVariance::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CEpochVariance::process()
{
Kernel::IBoxIO& boxContext = getDynamicBoxContext();
const size_t nInput = getStaticBoxContext().getInputCount();
for (size_t i = 0; i < nInput; ++i)
{
for (size_t j = 0; j < boxContext.getInputChunkCount(i); ++j)
{
Kernel::TParameterHandler<const IMemoryBuffer*> bufferHandle(
m_decoder->getInputParameter(OVP_GD_Algorithm_StreamedMatrixDecoder_InputParameterId_MemoryBufferToDecode));
Kernel::TParameterHandler<IMemoryBuffer*> obufferHandle(
m_encoder->getOutputParameter(OVP_GD_Algorithm_StreamedMatrixEncoder_OutputParameterId_EncodedMemoryBuffer));
Kernel::TParameterHandler<IMemoryBuffer*> obufferHandleForVariance(
m_encoderForVariance->getOutputParameter(OVP_GD_Algorithm_StreamedMatrixEncoder_OutputParameterId_EncodedMemoryBuffer));
Kernel::TParameterHandler<IMemoryBuffer*> bufferHandleForConfidenceBound(
m_encoderForConfidenceBound->getOutputParameter(OVP_GD_Algorithm_StreamedMatrixEncoder_OutputParameterId_EncodedMemoryBuffer));
bufferHandle = boxContext.getInputChunk(i, j);
obufferHandle = boxContext.getOutputChunk(0);
obufferHandleForVariance = boxContext.getOutputChunk(1);
bufferHandleForConfidenceBound = boxContext.getOutputChunk(2);
m_decoder->process();
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_StreamedMatrixDecoder_OutputTriggerId_ReceivedHeader))
{
m_matrixVariance->process(OVP_Algorithm_MatrixVariance_InputTriggerId_Reset);
m_encoder->process(OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeHeader);
m_encoderForVariance->process(OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeHeader);
m_encoderForConfidenceBound->process(OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeHeader);
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(i, j), boxContext.getInputChunkEndTime(i, j));
boxContext.markOutputAsReadyToSend(1, boxContext.getInputChunkStartTime(i, j), boxContext.getInputChunkEndTime(i, j));
boxContext.markOutputAsReadyToSend(2, boxContext.getInputChunkStartTime(i, j), boxContext.getInputChunkEndTime(i, j));
}
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_StreamedMatrixDecoder_OutputTriggerId_ReceivedBuffer))
{
m_matrixVariance->process(OVP_Algorithm_MatrixVariance_InputTriggerId_FeedMatrix);
if (m_matrixVariance->isOutputTriggerActive(OVP_Algorithm_MatrixVariance_OutputTriggerId_AveragePerformed))
{
m_encoder->process(OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeBuffer);
m_encoderForVariance->process(OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeBuffer);
m_encoderForConfidenceBound->process(OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeBuffer);
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(i, j), boxContext.getInputChunkEndTime(i, j));
boxContext.markOutputAsReadyToSend(1, boxContext.getInputChunkStartTime(i, j), boxContext.getInputChunkEndTime(i, j));
boxContext.markOutputAsReadyToSend(2, boxContext.getInputChunkStartTime(i, j), boxContext.getInputChunkEndTime(i, j));
}
}
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_StreamedMatrixDecoder_OutputTriggerId_ReceivedEnd))
{
m_encoder->process(OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeEnd);
m_encoderForVariance->process(OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeEnd);
m_encoderForConfidenceBound->process(OVP_GD_Algorithm_StreamedMatrixEncoder_InputTriggerId_EncodeEnd);
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(i, j), boxContext.getInputChunkEndTime(i, j));
boxContext.markOutputAsReadyToSend(1, boxContext.getInputChunkStartTime(i, j), boxContext.getInputChunkEndTime(i, j));
boxContext.markOutputAsReadyToSend(2, boxContext.getInputChunkStartTime(i, j), boxContext.getInputChunkEndTime(i, j));
}
boxContext.markInputAsDeprecated(i, j);
}
}
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,95 @@
#pragma once
#include "../../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
class CEpochVariance final : 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_EpochVariance)
protected:
Kernel::IAlgorithmProxy* m_decoder = nullptr;
Kernel::IAlgorithmProxy* m_encoder = nullptr;
Kernel::IAlgorithmProxy* m_encoderForVariance = nullptr;
Kernel::IAlgorithmProxy* m_encoderForConfidenceBound = nullptr;
Kernel::IAlgorithmProxy* m_matrixVariance = nullptr;
Kernel::TParameterHandler<uint64_t> ip_matrixCount;
Kernel::TParameterHandler<uint64_t> ip_averagingMethod;
Kernel::TParameterHandler<double> ip_SignificanceLevel;
};
class CEpochVarianceListener final : public Toolkit::TBoxListener<IBoxListener>
{
public:
bool onInputTypeChanged(Kernel::IBox& box, const size_t index) override
{
CIdentifier typeID = CIdentifier::undefined();
box.getInputType(index, typeID);
for (size_t i = 0; i < box.getOutputCount(); ++i) { box.setOutputType(i, typeID); }
return true;
}
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
};
class CEpochVarianceDesc final : public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Epoch variance"); }
CString getAuthorName() const override { return CString("Dieter Devlaminck"); }
CString getAuthorCompanyName() const override { return CString("INRIA"); }
CString getShortDescription() const override { return CString("Computes variance of each sample over several epochs"); }
CString getDetailedDescription() const override { return CString(""); }
CString getCategory() const override { return CString("Signal processing/Basic"); }
CString getVersion() const override { return CString("1.0"); }
CString getStockItemName() const override { return CString("gtk-missing-image"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_EpochVariance; }
IPluginObject* create() override { return new CEpochVariance(); }
IBoxListener* createBoxListener() const override { return new CEpochVarianceListener; }
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Input epochs", OV_TypeId_StreamedMatrix);
prototype.addOutput("Averaged epochs", OV_TypeId_StreamedMatrix);
prototype.addOutput("Variance of epochs", OV_TypeId_StreamedMatrix);
prototype.addOutput("Confidence bounds", OV_TypeId_StreamedMatrix);
prototype.addSetting("Averaging type", OVP_TypeId_EpochAverageMethod, "Moving epoch average");
prototype.addSetting("Epoch count", OV_TypeId_Integer, "4");
prototype.addSetting("Significance level", OV_TypeId_Float, "0.01");
prototype.addFlag(Kernel::BoxFlag_CanModifyInput);
prototype.addInputSupport(OV_TypeId_StreamedMatrix);
prototype.addInputSupport(OV_TypeId_FeatureVector);
prototype.addInputSupport(OV_TypeId_Signal);
prototype.addInputSupport(OV_TypeId_Spectrum);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_EpochVarianceDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,125 @@
#include "ovpCBoxAlgorithmHilbert.h"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmHilbert::initialize()
{
// Signal stream decoder
m_decoder.initialize(*this, 0);
// Signal stream encoder
m_algo1Encoder.initialize(*this, 0);
m_algo2Encoder.initialize(*this, 1);
m_algo3Encoder.initialize(*this, 2);
m_hilbertAlgo = &this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_ClassId_Algorithm_HilbertTransform));
m_hilbertAlgo->initialize();
ip_signalMatrix.initialize(m_hilbertAlgo->getInputParameter(OVP_Algorithm_HilbertTransform_InputParameterId_Matrix));
op_hilbertMatrix.initialize(m_hilbertAlgo->getOutputParameter(OVP_Algorithm_HilbertTransform_OutputParameterId_HilbertMatrix));
op_envelopeMatrix.initialize(m_hilbertAlgo->getOutputParameter(OVP_Algorithm_HilbertTransform_OutputParameterId_EnvelopeMatrix));
op_phaseMatrix.initialize(m_hilbertAlgo->getOutputParameter(OVP_Algorithm_HilbertTransform_OutputParameterId_PhaseMatrix));
ip_signalMatrix.setReferenceTarget(m_decoder.getOutputMatrix());
m_algo1Encoder.getInputSamplingRate().setReferenceTarget(m_decoder.getOutputSamplingRate());
m_algo2Encoder.getInputSamplingRate().setReferenceTarget(m_decoder.getOutputSamplingRate());
m_algo3Encoder.getInputSamplingRate().setReferenceTarget(m_decoder.getOutputSamplingRate());
m_algo1Encoder.getInputMatrix().setReferenceTarget(op_hilbertMatrix);
m_algo2Encoder.getInputMatrix().setReferenceTarget(op_envelopeMatrix);
m_algo3Encoder.getInputMatrix().setReferenceTarget(op_phaseMatrix);
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmHilbert::uninitialize()
{
m_decoder.uninitialize();
m_algo1Encoder.uninitialize();
m_algo2Encoder.uninitialize();
m_algo3Encoder.uninitialize();
ip_signalMatrix.uninitialize();
op_hilbertMatrix.uninitialize();
op_envelopeMatrix.uninitialize();
op_phaseMatrix.uninitialize();
m_hilbertAlgo->uninitialize();
this->getAlgorithmManager().releaseAlgorithm(*m_hilbertAlgo);
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmHilbert::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmHilbert::process()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
//iterate over all chunk on input 0
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
// decode the chunk i on input 0
m_decoder.decode(i);
// the decoder may have decoded 3 different parts : the header, a buffer or the end of stream.
if (m_decoder.isHeaderReceived())
{
// Header received
m_hilbertAlgo->process(OVP_Algorithm_HilbertTransform_InputTriggerId_Initialize);
// Pass the header to the next boxes, by encoding a header on the output 0:
m_algo1Encoder.encodeHeader();
m_algo2Encoder.encodeHeader();
m_algo3Encoder.encodeHeader();
// send the output chunk containing the header. The dates are the same as the input chunk:
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
boxContext.markOutputAsReadyToSend(1, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
boxContext.markOutputAsReadyToSend(2, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_decoder.isBufferReceived())
{
m_hilbertAlgo->process(OVP_Algorithm_HilbertTransform_InputTriggerId_Process);
// Encode the output buffer :
m_algo1Encoder.encodeBuffer();
m_algo2Encoder.encodeBuffer();
m_algo3Encoder.encodeBuffer();
// and send it to the next boxes :
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
boxContext.markOutputAsReadyToSend(1, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
boxContext.markOutputAsReadyToSend(2, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_decoder.isEndReceived())
{
// End of stream received. This happens only once when pressing "stop". Just pass it to the next boxes so they receive the message :
m_algo1Encoder.encodeEnd();
m_algo2Encoder.encodeEnd();
m_algo3Encoder.encodeEnd();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
boxContext.markOutputAsReadyToSend(1, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
boxContext.markOutputAsReadyToSend(2, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
// The current input chunk has been processed, and automaticcaly discarded.
// you don't need to call "boxContext.markInputAsDeprecated(0, i);"
}
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,102 @@
#pragma once
#include "../../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
/**
* \class CBoxAlgorithmHilbert
* \author Alison Cellard (Inria)
* \date Thu Jun 6 13:47:53 2013
* \brief The class CBoxAlgorithmHilbert describes the box Phase and Envelope.
*
*/
class CBoxAlgorithmHilbert 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;
// As we do with any class in openvibe, we use the macro below
// to associate this box to an unique identifier.
// The inheritance information is also made available,
// as we provide the superclass Toolkit::TBoxAlgorithm < IBoxAlgorithm >
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_Hilbert)
protected:
// Signal stream decoder
Toolkit::TSignalDecoder<CBoxAlgorithmHilbert> m_decoder;
// Signal stream encoder
Toolkit::TSignalEncoder<CBoxAlgorithmHilbert> m_algo1Encoder;
Toolkit::TSignalEncoder<CBoxAlgorithmHilbert> m_algo2Encoder;
Toolkit::TSignalEncoder<CBoxAlgorithmHilbert> m_algo3Encoder;
Kernel::IAlgorithmProxy* m_hilbertAlgo = nullptr;
Kernel::TParameterHandler<CMatrix*> ip_signalMatrix;
Kernel::TParameterHandler<CMatrix*> op_hilbertMatrix;
Kernel::TParameterHandler<CMatrix*> op_envelopeMatrix;
Kernel::TParameterHandler<CMatrix*> op_phaseMatrix;
};
/**
* \class CBoxAlgorithmHilbertDesc
* \author Alison Cellard (Inria)
* \date Thu Jun 6 13:47:53 2013
* \brief Descriptor of the box Phase and Envelope.
*
*/
class CBoxAlgorithmHilbertDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Hilbert Transform"); }
CString getAuthorName() const override { return CString("Alison Cellard"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("Hilbert transform, Phase and Envelope from discrete-time analytic signal using Hilbert"); }
CString getDetailedDescription() const override
{
return CString("Return Hilbert transform, phase and envelope of the input signal using analytic signal computation");
}
CString getCategory() const override { return CString("Signal processing/Basic"); }
CString getVersion() const override { return CString("1"); }
CString getStockItemName() const override { return CString("gtk-new"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_Hilbert; }
IPluginObject* create() override { return new CBoxAlgorithmHilbert; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Input Signal",OV_TypeId_Signal);
prototype.addOutput("Hilbert Transform", OV_TypeId_Signal);
prototype.addOutput("Envelope",OV_TypeId_Signal);
prototype.addOutput("Phase",OV_TypeId_Signal);
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_HilbertDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,183 @@
#if defined TARGET_HAS_ThirdPartyITPP
//#define __OpenViBEPlugins_BoxAlgorithm_IFFTbox_CPP__
// to get ifft:
#include <itpp/itsignal.h>
#include "ovpCBoxAlgorithmIFFTbox.h"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmIFFTbox::initialize()
{
m_decoder[0].initialize(*this, 0); // Spectrum stream real part decoder
m_decoder[1].initialize(*this, 1); // Spectrum stream imaginary part decoder
m_encoder.initialize(*this, 0); // Signal stream encoder
m_nSample = 0;
m_headerSent = false;
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmIFFTbox::uninitialize()
{
m_decoder[0].uninitialize();
m_decoder[1].uninitialize();
m_encoder.uninitialize();
return true;
}
bool CBoxAlgorithmIFFTbox::processInput(const size_t /*index*/)
{
IDynamicBoxContext& boxContext = this->getDynamicBoxContext();
const size_t nInput = this->getStaticBoxContext().getInputCount();
if (boxContext.getInputChunkCount(0) == 0) { return true; }
const uint64_t start = boxContext.getInputChunkStartTime(0, 0);
const uint64_t end = boxContext.getInputChunkEndTime(0, 0);
for (size_t i = 1; i < nInput; ++i)
{
if (boxContext.getInputChunkCount(i) == 0) { return true; }
if (start != boxContext.getInputChunkStartTime(i, 0) || end != boxContext.getInputChunkEndTime(i, 0))
{
OV_WARNING_K("Chunk dates mismatch, check stream structure or parameters");
return false;
}
}
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmIFFTbox::process()
{
// the dynamic box context describes the current state of the box inputs and outputs (i.e. the chunks)
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
const size_t nInput = this->getStaticBoxContext().getInputCount();
size_t nHeader = 0;
size_t nBuffer = 0;
size_t nEnd = 0;
for (size_t i = 0; i < nInput; ++i)
{
m_decoder[i].decode(0);
if (m_decoder[i].isHeaderReceived())
{
//detect if header of other input is already received
if (0 == nHeader)
{
// Header received. This happens only once when pressing "play". For example with a StreamedMatrix input, you now know the dimension count, sizes, and labels of the matrix
// ... maybe do some process ...
m_channelsNumber = m_decoder[i].getOutputMatrix()->getDimensionSize(0);
m_nSample = m_decoder[i].getOutputMatrix()->getDimensionSize(1);
OV_ERROR_UNLESS_KRF(m_channelsNumber > 0 && m_nSample > 0, "Both dims of the input matrix must have positive size",
Kernel::ErrorType::BadProcessing);
m_nSample = (m_nSample - 1) * 2;
if (m_nSample == 0) { m_nSample = 1; }
}
else
{
OV_ERROR_UNLESS_KRF(
m_decoder[0].getOutputMatrix()->isDescriptionEqual(*m_decoder[i].getOutputMatrix(), false),
"The matrix components of the two streams have different properties, check stream structures or parameters",
Kernel::ErrorType::BadProcessing);
OV_ERROR_UNLESS_KRF(
m_decoder[0].getOutputFrequencyAbscissa()->isDescriptionEqual(*m_decoder[i].getOutputFrequencyAbscissa(), false),
"The frequencies abscissas descriptors of the two streams have different properties, check stream structures or parameters",
Kernel::ErrorType::BadProcessing);
OV_ERROR_UNLESS_KRF(
m_decoder[0].getOutputMatrix()->getDimensionSize(1) == m_decoder[i].getOutputFrequencyAbscissa()->getDimensionSize(0),
"Frequencies abscissas count " << m_decoder[i].getOutputFrequencyAbscissa()->getDimensionSize(0) <<
" does not match the corresponding matrix chunk size " << m_decoder[0].getOutputMatrix()->getDimensionSize(1) <<
", check stream structures or parameters", Kernel::ErrorType::BadProcessing);
OV_ERROR_UNLESS_KRF(m_decoder[0].getOutputSamplingRate(), "Sampling rate must be positive, check stream structures or parameters",
Kernel::ErrorType::BadProcessing);
OV_ERROR_UNLESS_KRF(m_decoder[0].getOutputSamplingRate() == m_decoder[i].getOutputSamplingRate(),
"Sampling rates don't match (" << m_decoder[0].getOutputSamplingRate() << " != " << m_decoder[i].getOutputSamplingRate() <<
"), please check stream structures or parameters", Kernel::ErrorType::BadProcessing);
}
nHeader++;
}
if (m_decoder[i].isBufferReceived()) { nBuffer++; }
if (m_decoder[i].isEndReceived()) { nEnd++; }
}
if ((nHeader && nHeader != nInput) || (nBuffer && nBuffer != nInput) || (nEnd && nEnd != nInput))
{
OV_WARNING_K("Stream structure mismatch");
return false;
}
if (nBuffer)
{
OV_ERROR_UNLESS_KRF(m_nSample, "Received buffer before header, shouldn't happen\n", Kernel::ErrorType::BadProcessing);
if (!m_headerSent)
{
m_signalBuffer.set_size(int(m_nSample));
m_frequencyBuffer.set_size(int(m_nSample));
m_encoder.getInputSamplingRate() = m_decoder[0].getOutputSamplingRate();
m_encoder.getInputMatrix()->resize(m_channelsNumber, m_nSample);
for (size_t channel = 0; channel < m_channelsNumber; ++channel)
{
m_encoder.getInputMatrix()->setDimensionLabel(
0, channel, m_decoder[0].getOutputMatrix()->getDimensionLabel(0, channel));
}
// Pass the header to the next boxes, by encoding a header on the output 0:
m_encoder.encodeHeader();
// send the output chunk containing the header. The dates are the same as the input chunk:
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, 0), boxContext.getInputChunkEndTime(0, 0));
m_headerSent = true;
}
const double* bufferInput0 = m_decoder[0].getOutputMatrix()->getBuffer();
const double* bufferInput1 = m_decoder[1].getOutputMatrix()->getBuffer();
for (size_t channel = 0; channel < m_channelsNumber; ++channel)
{
for (size_t j = 0; j < m_nSample; ++j)
{
m_frequencyBuffer[j].real(bufferInput0[int(channel * m_nSample + j)]);
m_frequencyBuffer[j].imag(bufferInput1[int(channel * m_nSample + j)]);
}
m_signalBuffer = ifft_real(m_frequencyBuffer);
double* bufferOutput = m_encoder.getInputMatrix()->getBuffer();
for (size_t j = 0; j < m_nSample; ++j) { bufferOutput[int(channel * m_nSample + j)] = m_signalBuffer[j]; }
}
m_encoder.encodeBuffer();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, 0), boxContext.getInputChunkEndTime(0, 0));
}
if (nEnd)
{
// End of stream received. This happens only once when pressing "stop". Just pass it to the next boxes so they receive the message :
m_encoder.encodeEnd();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, 0), boxContext.getInputChunkEndTime(0, 0));
}
return true;
}
#endif //TARGET_HAS_ThirdPartyITPP
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,94 @@
#pragma once
#if defined TARGET_HAS_ThirdPartyITPP
//You may have to change this path to match your folder organisation
#include "../../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <complex>
#include <itpp/itbase.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
/**
* \class CBoxAlgorithmIFFTbox
* \author Guillermo Andrade B. (INRIA)
* \date Fri Jan 20 15:35:05 2012
* \brief The class CBoxAlgorithmIFFTbox describes the box IFFT box.
*
*/
class CBoxAlgorithmIFFTbox 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_IFFTbox)
protected:
// Codec algorithms specified in the skeleton-generator:
Toolkit::TSpectrumDecoder<CBoxAlgorithmIFFTbox> m_decoder[2];
Toolkit::TSignalEncoder<CBoxAlgorithmIFFTbox> m_encoder;
private:
itpp::Vec<std::complex<double>> m_frequencyBuffer;
itpp::Vec<double> m_signalBuffer;
size_t m_nSample = 0;
size_t m_channelsNumber = 0;
bool m_headerSent = false;
};
/**
* \class CBoxAlgorithmIFFTboxDesc
* \author Guillermo Andrade B. (INRIA)
* \date Fri Jan 20 15:35:05 2012
* \brief Descriptor of the box IFFT box.
*
*/
class CBoxAlgorithmIFFTboxDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("IFFT"); }
CString getAuthorName() const override { return CString("Guillermo Andrade B."); }
CString getAuthorCompanyName() const override { return CString("INRIA"); }
CString getShortDescription() const override { return CString("Compute Inverse Fast Fourier Transformation"); }
CString getDetailedDescription() const override { return CString("Compute Inverse Fast Fourier Transformation (depends on ITPP/fftw)"); }
CString getCategory() const override { return CString("Signal processing/Spectral Analysis"); }
CString getVersion() const override { return CString("0.2"); }
CString getStockItemName() const override { return CString("gtk-execute"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_IFFTbox; }
IPluginObject* create() override { return new CBoxAlgorithmIFFTbox; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("real part",OV_TypeId_Spectrum);
prototype.addInput("imaginary part",OV_TypeId_Spectrum);
prototype.addOutput("Signal output",OV_TypeId_Signal);
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_IFFTboxDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif //TARGET_HAS_ThirdPartyITPP
@@ -0,0 +1,111 @@
#include "ovpCBoxAlgorithmMatrixTranspose.h"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmMatrixTranspose::initialize()
{
m_decoder.initialize(*this, 0);
m_encoder.initialize(*this, 0);
return true;
}
bool CBoxAlgorithmMatrixTranspose::uninitialize()
{
m_encoder.uninitialize();
m_decoder.uninitialize();
return true;
}
bool CBoxAlgorithmMatrixTranspose::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmMatrixTranspose::process()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
m_decoder.decode(i);
if (m_decoder.isHeaderReceived())
{
const size_t nDim = m_decoder.getOutputMatrix()->getDimensionCount();
const CMatrix* input = m_decoder.getOutputMatrix();
CMatrix* output = m_encoder.getInputMatrix();
if (nDim == 1)
{
this->getLogManager() << Kernel::LogLevel_Trace << "Upgrading your 1 dimensional matrix to 2 dimensions, [" << input->getDimensionSize(0) <<
"x 1]\n";
output->resize(input->getDimensionSize(0), 1);
for (size_t j = 0; j < input->getDimensionSize(0); ++j) { output->setDimensionLabel(0, j, input->getDimensionLabel(0, j)); }
output->setDimensionLabel(1, 0, "Dimension 0");
}
else if (nDim == 2)
{
output->resize(input->getDimensionSize(1), input->getDimensionSize(0));
for (size_t j = 0; j < output->getDimensionSize(0); ++j) { output->setDimensionLabel(0, j, input->getDimensionLabel(1, j)); }
for (size_t j = 0; j < output->getDimensionSize(1); ++j) { output->setDimensionLabel(1, j, input->getDimensionLabel(0, j)); }
}
else
{
this->getLogManager() << Kernel::LogLevel_Error << "Only 1 and 2 dimensional matrices supported\n";
return false;
}
this->getLogManager() << Kernel::LogLevel_Trace << "Output matrix will be [" << output->getDimensionSize(0) << "x" << output->getDimensionSize(1) << "]\n";
m_encoder.encodeHeader();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_decoder.isBufferReceived())
{
const CMatrix* input = m_decoder.getOutputMatrix();
CMatrix* output = m_encoder.getInputMatrix();
if (input->getDimensionCount() == 1)
{
const double* iBuffer = input->getBuffer();
double* oBuffer = output->getBuffer();
for (size_t j = 0; j < input->getBufferElementCount(); ++j) { oBuffer[j] = iBuffer[j]; }
}
else
{
// 2 dim
const size_t nRows = input->getDimensionSize(0);
const size_t nCols = input->getDimensionSize(1);
const double* iBuffer = input->getBuffer();
double* oBuffer = output->getBuffer();
for (size_t j = 0; j < nRows; ++j) { for (size_t k = 0; k < nCols; ++k) { oBuffer[k * nRows + j] = iBuffer[j * nCols + k]; } }
}
m_encoder.encodeBuffer();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_decoder.isEndReceived())
{
m_encoder.encodeEnd();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
}
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,65 @@
#pragma once
#include "../../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
class CBoxAlgorithmMatrixTranspose 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_MatrixTranspose)
protected:
Toolkit::TStreamedMatrixDecoder<CBoxAlgorithmMatrixTranspose> m_decoder;
Toolkit::TStreamedMatrixEncoder<CBoxAlgorithmMatrixTranspose> m_encoder;
};
class CBoxAlgorithmMatrixTransposeDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Matrix Transpose"); }
CString getAuthorName() const override { return CString("Jussi T. Lindgren"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("Transposes each matrix of the input stream"); }
CString getDetailedDescription() const override
{
return CString("Only works for 1 and 2 dimensional matrices. One-dimensional matrixes will be upgraded to two dimensions: [N x 1]");
}
CString getCategory() const override { return CString("Signal processing/Basic"); }
CString getVersion() const override { return CString("1.0"); }
CString getStockItemName() const override { return CString("gtk-sort-ascending"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_MatrixTranspose; }
IPluginObject* create() override { return new CBoxAlgorithmMatrixTranspose; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Input matrix", OV_TypeId_StreamedMatrix);
prototype.addOutput("Output matrix", OV_TypeId_StreamedMatrix);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_MatrixTransposeDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,23 @@
#include "ovpCBoxAlgorithmNull.h"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmNull::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmNull::process()
{
Kernel::IBoxIO* boxContext = getBoxAlgorithmContext()->getDynamicBoxContext();
const size_t nInput = getBoxAlgorithmContext()->getStaticBoxContext()->getInputCount();
for (size_t i = 0; i < nInput; ++i) { for (size_t j = 0; j < boxContext->getInputChunkCount(i); ++j) { boxContext->markInputAsDeprecated(i, j); } }
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,59 @@
#pragma once
#include <toolkit/ovtk_all.h>
#define OVP_ClassId_BoxAlgorithm_Null OpenViBE::CIdentifier(0x601118A8, 0x14BF700F)
#define OVP_ClassId_BoxAlgorithm_NullDesc OpenViBE::CIdentifier(0x6BD21A21, 0x0A5E685A)
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
class CBoxAlgorithmNull final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
void release() override { delete this; }
bool processInput(const size_t index) override;
bool process() override;
_IsDerivedFromClass_Final_(IBoxAlgorithm, OVP_ClassId_BoxAlgorithm_Null)
};
class CBoxAlgorithmNullDesc final : public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Null"); }
CString getAuthorName() const override { return CString("Jussi T. Lindgren"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("Consumes input and produces nothing. It can be used to show scenario design intent."); }
CString getDetailedDescription() const override
{
return CString("Directing to Null instead of leaving a box output unconnected may add a tiny overhead.");
}
CString getCategory() const override { return CString("Signal processing/Basic"); }
CString getVersion() const override { return CString("1.0"); }
CString getSoftwareComponent() const override { return CString("openvibe-extras"); }
CString getAddedSoftwareVersion() const override { return CString("0.0.0"); }
CString getUpdatedSoftwareVersion() const override { return CString("0.0.0"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_Null; }
IPluginObject* create() override { return new CBoxAlgorithmNull(); }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Input stream", OV_TypeId_EBMLStream);
prototype.addFlag(Kernel::BoxFlag_CanAddInput);
prototype.addFlag(Kernel::BoxFlag_CanModifyInput);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_NullDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,247 @@
///-------------------------------------------------------------------------------------------------
///
/// \file CBoxAlgorithmConnectivityMeasure.cpp
/// \brief Implementation of the Box Connectivity Measure.
/// \author Arthur DESBOIS (INRIA).
/// \version 0.0.1.
/// \date Fri Oct 30 16:18:49 2020.
///
/// \copyright (C) 2020 INRIA
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as published
/// by the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program. If not, see <https://www.gnu.org/licenses/>.
///-------------------------------------------------------------------------------------------------
#include "CBoxAlgorithmConnectivityMeasure.hpp"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmConnectivityMeasure::initialize()
{
m_signalDecoder.initialize(*this, 0);
m_matrixEncoder.initialize(*this, 0);
m_iMatrix = m_signalDecoder.getOutputMatrix();
m_oMatrix = m_matrixEncoder.getInputMatrix();
// Settings
m_metric = EConnectMetric(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0)));
m_windowMethod = EConnectWindowMethod(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1)));
m_windowLengthSeconds = double(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2));
m_windowOverlap = int(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3));
m_connectLengthSeconds = double(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 4));
m_connectOverlap = int(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 5));
m_fftSize = int(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 6));
m_dcRemoval = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 7);
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmConnectivityMeasure::uninitialize()
{
m_signalDecoder.uninitialize();
m_matrixEncoder.uninitialize();
return true;
}
bool CBoxAlgorithmConnectivityMeasure::processInput(const size_t)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmConnectivityMeasure::process()
{
// the static box context describes the box inputs, outputs, settings structures
const Kernel::IBox& staticBoxContext = this->getStaticBoxContext();
// the dynamic box context describes the current state of the box inputs and outputs (i.e. the chunks)
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
//iterate over all chunk on input 0
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
m_signalDecoder.decode(i);
const uint64_t tStart = boxContext.getInputChunkStartTime(0, i); // Time Code Chunk Start
const uint64_t tEnd = boxContext.getInputChunkEndTime(0, i); // Time Code Chunk End
if (m_signalDecoder.isHeaderReceived())
{
// Header received. This happens only once when pressing "play".
CMatrix* matrix = m_signalDecoder.getOutputMatrix(); // the StreamedMatrix of samples.
uint64_t sampRate = m_signalDecoder.getOutputSamplingRate(); // the sampling rate of the signal
m_windowLength = std::floor((float) sampRate * m_windowLengthSeconds);
m_connectLength = std::floor((float) sampRate * m_connectLengthSeconds);
m_connectOverlapSamples = int(std::floor(double(m_connectLength) * double(m_connectOverlap) / 100.0));
m_windowOverlapSamples = int(std::floor(double(m_windowLength) * double(m_windowOverlap) / 100.0));
m_nbChannels = matrix->getDimensionSize(0);
const auto sampPerChan = matrix->getDimensionSize(1);
this->getLogManager() << Kernel::LogLevel_Debug << "HEADER : nChannels " << m_nbChannels << ", " << sampPerChan
<< " samples, sampling rate " << sampRate << "\n";
this->getLogManager() << Kernel::LogLevel_Debug << "Connectivity segments overlap percent/samples : "
<< m_connectOverlap << " " << m_connectOverlapSamples << "\n";
this->getLogManager() << Kernel::LogLevel_Debug << "Welch Windows overlap percent/samples : " << m_windowOverlap
<< " " << m_windowOverlapSamples << "\n";
// Vectors buffers init
m_vectorXdBuffer.resize(m_nbChannels);
m_signalChannelBuffers.resize(m_nbChannels);
this->getLogManager() << Kernel::LogLevel_Debug << "m_signalChannelBuffers.size() " << m_signalChannelBuffers.size()
<< "\n";
// Connectivity algo class inits
connectivityMeasure.initialize(m_metric, m_windowMethod, m_windowLength, m_windowOverlap, m_nbChannels,
m_fftSize, m_dcRemoval);
matrix3DInit(*m_oMatrix, m_fftSize, m_nbChannels, m_nbChannels); // nbFreqs x nbChan x nbChan
m_matrixEncoder.encodeHeader(); // Pass the header to the next boxes
} else if (m_signalDecoder.isBufferReceived())
{
CMatrix* matrix = m_signalDecoder.getOutputMatrix(); // the StreamedMatrix of samples.
uint64_t sampRate = m_signalDecoder.getOutputSamplingRate(); // the sampling rate of the signal
const auto sampPerChan = matrix->getDimensionSize(1);
// Accumulate buffers here and send a whole chunk to the connectivity algorithm
const double* buffer = matrix->getBuffer();
size_t idx = 0;
std::vector<double> temp;
for (size_t row = 0; row < m_nbChannels; ++row)
{
for (size_t col = 0; col < sampPerChan; ++col)
{ // parse all columns in the buffer
temp.push_back(buffer[idx++]);
}
m_signalChannelBuffers[row].insert(m_signalChannelBuffers[row].end(), temp.begin(), temp.end());
temp.clear();
}
this->getLogManager() << Kernel::LogLevel_Debug << "BUFFER : " << sampPerChan << " samples per " << m_nbChannels
<< " channels, sampling rate " << sampRate << " // Signal buffers size : "
<< m_signalChannelBuffers[0].size() << "\n";
// If enough data was accumulated, process it.
if (m_signalChannelBuffers[0].size() >= m_connectLength)
{
this->getLogManager() << Kernel::LogLevel_Debug << "Signal buffers : FULL (" << m_signalChannelBuffers[0].size()
<< ")\n";
// Convert to Eigen container for easier use in algo
for (size_t aa = 0; aa < m_nbChannels; ++aa)
{
m_vectorXdBuffer[aa] = Eigen::VectorXd::Map(m_signalChannelBuffers[aa].data(),
m_signalChannelBuffers[aa].size());
}
// Connectivity chunk overlap for next processing loop: Keep the overlapping part in the vectors, discard the rest
for (size_t aa = 0; aa < m_nbChannels; ++aa)
{
m_signalChannelBuffers[aa].erase(m_signalChannelBuffers[aa].begin(),
m_signalChannelBuffers[aa].begin() +
(m_connectLength - m_connectOverlapSamples));
}
// 3D Matrix init, vector of size (chan) of Matrices (chan x fftsize)
std::vector <Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>> connectivityMatrix(m_nbChannels,
Eigen::MatrixXd(
m_nbChannels,
m_fftSize));
OV_ERROR_UNLESS_KRF(connectivityMeasure.process(m_vectorXdBuffer, connectivityMatrix),
"Connectivity measurement error", Kernel::ErrorType::BadProcessing);
this->getLogManager() << Kernel::LogLevel_Debug << "Exited connectivityMeasure.process() : connect size "
<< connectivityMatrix.size() << " x " << connectivityMatrix[0].rows() << " x "
<< connectivityMatrix[0].cols() << "\n";
// Convert output matrix (nchan x nchan x fftsize) to matrix (fftsize x nchan x nchan)
matrix3DConvert(connectivityMatrix, *m_oMatrix);
m_matrixEncoder.encodeBuffer();
}
} else if (m_signalDecoder.isEndReceived())
{
m_matrixEncoder.encodeEnd();
}
boxContext.markOutputAsReadyToSend(0, tStart, tEnd);
}
return true;
}
void CBoxAlgorithmConnectivityMeasure::matrix3DInit(CMatrix& m, const size_t dim0, const size_t dim1, const size_t dim2)
{
m.setDimensionCount(3);
m.setDimensionSize(0, dim0);
m.setDimensionSize(1, dim1);
m.setDimensionSize(2, dim2);
}
bool CBoxAlgorithmConnectivityMeasure::matrix3DConvert(const std::vector <Eigen::MatrixXd>& in, CMatrix& out)
{
if (in.size() == 0 || in[0].rows() == 0 || in[0].cols() == 0)
{ return false; }
const size_t nChan0 = in.size(), nChan1 = in[0].rows(), fftSize = in[0].cols();
if (out.getDimensionCount() != 3
|| out.getDimensionSize(0) != fftSize
|| out.getDimensionSize(1) != nChan1
|| out.getDimensionSize(2) != nChan0)
{
out.setDimensionCount(3);
out.setDimensionSize(0, fftSize);
out.setDimensionSize(1, nChan1);
out.setDimensionSize(2, nChan0);
}
size_t idx = 0;
double* buffer = out.getBuffer();
for (size_t fftIdx = 0; fftIdx < fftSize; ++fftIdx)
{
for (size_t chan1 = 0; chan1 < nChan1; ++chan1)
{
for (size_t chan0 = 0; chan0 < nChan0; ++chan0)
{
buffer[idx++] = in[chan0](chan1, fftIdx);
}
}
}
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,160 @@
///-------------------------------------------------------------------------------------------------
///
/// \file CBoxAlgorithmConnectivityMeasure.hpp
/// \brief Classes of the Box Connectivity Measure.
/// \author Arthur DESBOIS (INRIA).
/// \version 0.0.1.
/// \date Fri Oct 30 16:18:49 2020.
///
/// \copyright (C) 2020 INRIA
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License as published
/// by the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program. If not, see <https://www.gnu.org/licenses/>.
///-------------------------------------------------------------------------------------------------
#pragma once
#include <Eigen/Dense>
#include "ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include "connectivityMeasure.hpp"
#define OV_AttributeId_Box_FlagIsUnstable OpenViBE::CIdentifier(0x666FFFFF, 0x666FFFFF)
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
///
/// \brief The class CBoxAlgorithmConnectivityMeasure describes the box Connectivity Measure.
///
class CBoxAlgorithmConnectivityMeasure 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_ConnectivityMeasure)
protected:
// Algo class instance
ConnectivityMeasure connectivityMeasure;
// Codecs
Toolkit::TSignalDecoder <CBoxAlgorithmConnectivityMeasure> m_signalDecoder;
Toolkit::TStreamedMatrixEncoder <CBoxAlgorithmConnectivityMeasure> m_matrixEncoder; // Output Matrix Codec
// Matrices
CMatrix* m_iMatrix = nullptr; // Input Matrix pointer
CMatrix* m_oMatrix = nullptr; // Output Matrix pointer
std::vector <Eigen::VectorXd> m_vectorXdBuffer; // Vector buffer, for connectivity segments
std::vector <std::vector<double>> m_signalChannelBuffers;
Eigen::VectorXd m_window;
// Settings
EConnectMetric m_metric = EConnectMetric::Coherence;
EConnectWindowMethod m_windowMethod = EConnectWindowMethod::Hann;
float m_windowLengthSeconds = 0.25f; // size of one windowing (sec)
float m_connectLengthSeconds = 0.5f; // size of one full connectivity estimation occurrence (sec)
int m_windowLength = 128; // size of one windowing (samples)
int m_windowOverlap = 50; // overlap btw windows (%)
int m_connectLength = 256; // size of one full connectivity estimation occurrence (samples)
int m_connectOverlap = 50; // overlap btw connectivity measurements (%)
int m_fftSize = 128; // FFT size (and nb of freq taps at the output)
int m_nbChannels = 0;
int m_connectOverlapSamples = 128;
int m_windowOverlapSamples = 64;
bool m_dcRemoval = false;
private:
///
/// \brief Conversion from a vector of 2D Matrices into OpenViBE's CMatrix of 3 dimensions
/// \param in std:vector<Eigen::Matrix> (vect of nChan x Matrices (nChan x fftsize)
/// \param out CMatrix of 3 dimensions (fftsize x nchan x nchan)
/// \return True if the conversion was successful, false otherwise
bool matrix3DConvert(const std::vector <Eigen::MatrixXd>& in, CMatrix& out);
///
/// \brief Initialises 3 dimensions matrix with the provided dimensions
/// \param m The matrix to initialise
/// \param dim1 dimension 1
/// \param dim2 dimension 2
/// \param dim3 dimension 3
void matrix3DInit(CMatrix& m, const size_t dim1, const size_t dim2, const size_t dim3);
};
///
/// \brief Descriptor of the box Connectivity Measure.
///
class CBoxAlgorithmConnectivityMeasureDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override {}
CString getName() const override { return CString("Connectivity Measure"); }
CString getAuthorName() const override { return CString("Arthur DESBOIS"); }
CString getAuthorCompanyName() const override { return CString("INRIA"); }
CString getShortDescription() const override { return CString("Connectivity Measure"); }
CString getDetailedDescription() const override { return CString("Measure connectivity between pairs of channel"); }
CString getCategory() const override { return CString("Signal processing/Connectivity"); }
CString getVersion() const override { return CString("0.0.1"); }
CString getStockItemName() const override { return CString(""); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_ConnectivityMeasure; }
IPluginObject* create() override { return new CBoxAlgorithmConnectivityMeasure; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Input signal", OV_TypeId_Signal);
prototype.addOutput("Connectivity Matrix", OV_TypeId_StreamedMatrix);
prototype.addSetting("Metric", OVP_TypeId_Connectivity_Metric,
toString(EConnectMetric::Coherence).c_str());
prototype.addSetting("Welch Window method", OV_TypeId_ConnectivityMeasure_WindowMethod, "Hann");
prototype.addSetting("Welch Window Length (in sec)", OV_TypeId_Float, "0.25"); // s
prototype.addSetting("Welch Window Overlap (in %)", OV_TypeId_Integer, "50"); // percent
prototype.addSetting("Connectivity Measure Length (in sec)", OV_TypeId_Float, "0.5"); //s
prototype.addSetting("Connectivity Measure Overlap (in %)", OV_TypeId_Integer, "50"); // percent
prototype.addSetting("FFT size (frequency taps)", OV_TypeId_Integer, "128");
prototype.addSetting("DC removal", OV_TypeId_Boolean, "false");
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_ConnectivityMeasureDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,379 @@
#if defined TARGET_HAS_ThirdPartyITPP
#include "ovpCBoxAlgorithmXDAWNSpatialFilterTrainer.h"
#include <complex>
#include <sstream>
#include <cstdio>
#include <vector>
#include <map>
#include <itpp/base/algebra/inv.h>
#include <itpp/stat/misc_stat.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
// Taken from http://techlogbook.wordpress.com/2009/08/12/adding-generalized-eigenvalue-functions-to-it
// http://techlogbook.wordpress.com/2009/08/12/calling-lapack-functions-from-c-codes
// http://sourceforge.net/projects/itpp/forums/forum/115656/topic/3363490?message=7557038
//
// http://icl.cs.utk.edu/projectsfiles/f2j/javadoc/org/netlib/lapack/DSYGV.html
// http://www.lassp.cornell.edu/sethna/GeneDynamics/NetworkCodeDocumentation/lapack_8h.html#a17
namespace {
extern "C" {
// This symbol comes from LAPACK
/*
void zggev_(char *jobvl, char *jobvr, int *n, std::complex<double> *a,
int *lda, std::complex<double> *b, int *ldb, std::complex<double> *alpha,
std::complex<double> *beta, std::complex<double> *vl,
int *ldvl, std::complex<double> *vr, int *ldvr,
std::complex<double> *work, int *lwork, double *rwork, int *info);
*/
int dsygv_(int* itype, char* jobz, char* uplo, int* n, double* a, int* lda, double* b, int* ldb, double* w, double* work, int* lwork, int* info);
}
} // namespace
namespace itppext {
bool eig(const itpp::mat& A, const itpp::mat& B, itpp::vec& d, itpp::mat& V)
{
it_assert_debug(A.rows() == A.cols(), "eig: Matrix A is not square");
it_assert_debug(B.rows() == B.cols(), "eig: Matrix B is not square");
it_assert_debug(A.rows() == B.cols(), "eig: Matrix A and B don't have the same size");
const int worksize = 4 * A.rows(); // This may be chosen better!
itpp::mat lA(A);
itpp::mat lB(B);
itpp::vec lW(A.rows());
itpp::vec lWork(worksize);
lW.zeros();
lWork.zeros();
int itype = 1; // 1: Ax=lBx 2: ABx=lx 3: BAx=lx
char jobz = 'V', uplo = 'U';
int n = lA.rows();
double* a = lA._data();
int lda = n;
double* b = lB._data();
int ldb = n;
double* w = lW._data();
int lwork = worksize;
double* work = lWork._data();
int info = 0;
dsygv_(&itype, &jobz, &uplo, &n, a, &lda, b, &ldb, w, work, &lwork, &info);
d = lW;
V = lA;
return (info == 0);
}
itpp::mat convert(const CMatrix& matrix)
{
itpp::mat res(matrix.getDimensionSize(1), matrix.getDimensionSize(0));
memcpy(res._data(), matrix.getBuffer(), matrix.getBufferElementCount() * sizeof(double));
return res.transpose();
}
} // namespace itppext
bool CBoxAlgorithmXDAWNSpatialFilterTrainer::initialize()
{
m_stimulationDecoder.initialize(*this, 0);
m_signalDecoder.initialize(*this, 1);
m_evokedPotentialDecoder.initialize(*this, 2);
m_encoder.initialize(*this, 0);
m_stimID = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_spatialFilterConfigurationFilename = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_filterDim = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);
m_saveAsBoxConfig = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3);
return true;
}
bool CBoxAlgorithmXDAWNSpatialFilterTrainer::uninitialize()
{
m_evokedPotentialDecoder.uninitialize();
m_signalDecoder.uninitialize();
m_stimulationDecoder.uninitialize();
m_encoder.uninitialize();
return true;
}
bool CBoxAlgorithmXDAWNSpatialFilterTrainer::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
namespace {
typedef struct
{
uint64_t startTime;
uint64_t endTime;
CMatrix* matrix;
} chunk_t;
}
bool CBoxAlgorithmXDAWNSpatialFilterTrainer::process()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
bool shouldTrain = false;
uint64_t date = 0, chunkStartTime = 0, chunkEndTime = 0;
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
m_stimulationDecoder.decode(i);
if (m_stimulationDecoder.isHeaderReceived())
{
m_encoder.encodeHeader();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_stimulationDecoder.isBufferReceived())
{
IStimulationSet* stimSet = m_stimulationDecoder.getOutputStimulationSet();
// See if there is a training stimulation. If several, accept the first one.
for (size_t j = 0; j < stimSet->getStimulationCount(); ++j)
{
if (stimSet->getStimulationIdentifier(j) == m_stimID)
{
date = stimSet->getStimulationDate(j); // date of the last matching stimulus in the set
chunkStartTime = boxContext.getInputChunkStartTime(0, i);
chunkEndTime = boxContext.getInputChunkEndTime(0, i);
shouldTrain = true;
break;
}
}
}
if (m_stimulationDecoder.isEndReceived())
{
m_encoder.encodeEnd();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
boxContext.markInputAsDeprecated(0, i);
}
if (shouldTrain)
{
this->getLogManager() << Kernel::LogLevel_Info << "Received train stimulation - be patient\n";
this->getLogManager() << Kernel::LogLevel_Trace << "Decoding signal chunks ...\n";
bool isContinuous = true;
uint64_t end = 0;
std::vector<chunk_t> chunks;
for (size_t i = 0; i < boxContext.getInputChunkCount(1); ++i)
{
m_signalDecoder.decode(i);
if (m_signalDecoder.isHeaderReceived())
{
// Don't care about the header
}
if (m_signalDecoder.isBufferReceived())
{
const CMatrix* matrix = m_signalDecoder.getOutputMatrix();
chunk_t chunk;
chunk.startTime = boxContext.getInputChunkStartTime(1, i);
chunk.endTime = boxContext.getInputChunkEndTime(1, i);
chunk.matrix = new CMatrix;
chunk.matrix->copy(*matrix);
chunks.push_back(chunk);
if (chunk.startTime != end)
{
this->getLogManager() << Kernel::LogLevel_Error << "Chunk " << i << " start time != last chunk end time [" << chunk.startTime << " vs "
<< end << "]\n";
isContinuous = false;
break;
}
end = chunk.endTime;
}
if (m_signalDecoder.isEndReceived()) { }
boxContext.markInputAsDeprecated(1, i);
}
if (!isContinuous)
{
// @fixme mem leak
this->getLogManager() << Kernel::LogLevel_Error << "Input signal is not continuous... Can't continue\n";
return false;
}
this->getLogManager() << Kernel::LogLevel_Trace << "Decoding evoked response potential chunks ...\n";
std::vector<chunk_t> evokedPotential;
for (size_t i = 0; i < boxContext.getInputChunkCount(2); ++i)
{
m_evokedPotentialDecoder.decode(i);
if (m_evokedPotentialDecoder.isHeaderReceived())
{
// Don't care about the header
}
if (m_evokedPotentialDecoder.isBufferReceived())
{
const CMatrix* matrix = m_evokedPotentialDecoder.getOutputMatrix();
chunk_t chunk;
chunk.startTime = boxContext.getInputChunkStartTime(2, i);
chunk.endTime = boxContext.getInputChunkEndTime(2, i);
chunk.matrix = new CMatrix;
chunk.matrix->copy(*matrix);
evokedPotential.push_back(chunk);
}
if (m_evokedPotentialDecoder.isEndReceived()) { }
boxContext.markInputAsDeprecated(2, i);
}
if (evokedPotential.empty())
{
// @fixme mem leak
this->getLogManager() << Kernel::LogLevel_Error << "No evoked potentials received... Can't continue\n";
return false;
}
this->getLogManager() << Kernel::LogLevel_Trace << "Averaging evoked response potential...\n";
auto it = evokedPotential.begin();
CMatrix averagedERPMatrixOV;
averagedERPMatrixOV.copy(*it->matrix);
for (++it; it != evokedPotential.end(); ++it)
{
const double* potentialBuffer = it->matrix->getBuffer();
double* buffer = averagedERPMatrixOV.getBuffer();
for (size_t j = 0; j < averagedERPMatrixOV.getBufferElementCount(); ++j) { *(buffer++) += *(potentialBuffer++); }
}
double* buffer = averagedERPMatrixOV.getBuffer();
for (size_t j = 0; j < averagedERPMatrixOV.getBufferElementCount(); ++j) { (*buffer++) /= evokedPotential.size(); }
// WARNING - OpenViBE matrices are transposed ITPP matrices !
this->getLogManager() << Kernel::LogLevel_Trace << "Converting OpenViBE matrices to IT++ matrices...\n";
const size_t nChunk = chunks.size();
const size_t nChannel = chunks.begin()->matrix->getDimensionSize(0);
const size_t nSamplePerChunk = chunks.begin()->matrix->getDimensionSize(1);
const size_t nSamplePerErp = averagedERPMatrixOV.getDimensionSize(1);
itpp::mat matrix(nChannel, nChunk * nSamplePerChunk);
it = chunks.begin();
for (size_t i = 0; it != chunks.end(); ++it, ++i)
{
const itpp::mat m = itppext::convert(*it->matrix);
matrix.set_submatrix(0, int(i) * nSamplePerChunk, m);
}
itpp::mat averagedERPMatrix(nChannel, nSamplePerErp);
averagedERPMatrix = itppext::convert(averagedERPMatrixOV);
itpp::mat dMatrix(nChunk * nSamplePerChunk, nSamplePerErp);
dMatrix.clear();
for (it = evokedPotential.begin(); it != evokedPotential.end(); ++it)
{
// Compute index of the sample corresponding to the start of the ERP
const uint64_t erpStartTime = it->startTime;
const size_t erpStartIndex = size_t(CTime(erpStartTime).toSampleCount(m_signalDecoder.getOutputSamplingRate()));
for (size_t k = 0; k < nSamplePerErp; ++k) { dMatrix(erpStartIndex + k, k) = 1; }
}
const itpp::mat A = (averagedERPMatrix * inv(dMatrix.transpose() * dMatrix) * averagedERPMatrix.transpose()) * double(evokedPotential.size())
/ double(nSamplePerChunk * nChunk);
std::stringstream s4;
s4 << "A :\n" << A << "\n";
this->getLogManager() << Kernel::LogLevel_Debug << s4.str() << "\n";
const itpp::mat B = (matrix * matrix.transpose()) / double(nSamplePerChunk * nChunk);
std::stringstream s5;
s5 << "B :\n" << B << "\n";
this->getLogManager() << Kernel::LogLevel_Debug << s5.str() << "\n";
// Free resources
for (auto& c : chunks) { delete c.matrix; }
chunks.clear();
for (auto& ep : evokedPotential) { delete ep.matrix; }
evokedPotential.clear();
this->getLogManager() << Kernel::LogLevel_Trace << "Computing generalized eigen vector decomposition...\n";
itpp::mat eigenVector;
itpp::vec eigenValue;
if (itppext::eig(A, B, eigenValue, eigenVector))
{
std::map<double, itpp::vec> eigenVectors;
for (size_t i = 0; i < nChannel; ++i)
{
itpp::vec v = eigenVector.get_col(i);
eigenVectors[eigenValue[i]] = v / norm(v);
}
size_t cnt = 0;
//We need to compute the size of the first dimension before setting the matrix
const size_t dimension1Size = eigenVectors.size() < m_filterDim ? eigenVectors.size() : m_filterDim;
CMatrix outputVectors;
outputVectors.resize(dimension1Size, nChannel);
auto itR = eigenVectors.rbegin();
for (size_t i = 0; i < dimension1Size; ++itR, i++) { for (size_t j = 0; j < nChannel; ++j) { outputVectors.getBuffer()[cnt++] = itR->second[j]; } }
if (m_saveAsBoxConfig)
{
FILE* file = fopen(m_spatialFilterConfigurationFilename.toASCIIString(), "wb");
if (!file)
{
this->getLogManager() << Kernel::LogLevel_Error << "The file [" << m_spatialFilterConfigurationFilename
<< "] could not be opened for writing...";
return false;
}
fprintf(file, "<OpenViBE-SettingsOverride>\n");
fprintf(file, "\t<SettingValue>");
for (size_t i = 0; i < outputVectors.getBufferElementCount(); ++i) { fprintf(file, "%e ", outputVectors.getBuffer()[i]); }
fprintf(file, "</SettingValue>\n");
fprintf(file, "\t<SettingValue>%zu</SettingValue>\n", m_filterDim);
fprintf(file, "\t<SettingValue>%zu</SettingValue>\n", nChannel);
fprintf(file, "\t<SettingValue></SettingValue>\n");
fprintf(file, "</OpenViBE-SettingsOverride>\n");
fclose(file);
}
else
{
if (!Toolkit::Matrix::saveToTextFile(outputVectors, m_spatialFilterConfigurationFilename))
{
this->getLogManager() << Kernel::LogLevel_Error << "Unable to save to [" << m_spatialFilterConfigurationFilename << "\n";
return false;
}
}
this->getLogManager() << Kernel::LogLevel_Info << "Training finished... Eigen values are ";
itR = eigenVectors.rbegin();
for (size_t i = 0; itR != eigenVectors.rend() && i < m_filterDim; ++itR, i++) { this->getLogManager() << " | " << double(itR->first); }
this->getLogManager() << "\n";
}
else
{
this->getLogManager() << Kernel::LogLevel_Error << "Generalized eigen vector decomposition failed...\n";
return false;
}
this->getLogManager() << Kernel::LogLevel_Info << "xDAWN Spatial filter trained successfully.\n";
m_encoder.getInputStimulationSet()->clear();
m_encoder.getInputStimulationSet()->appendStimulation(OVTK_StimulationId_TrainCompleted, date, 0);
m_encoder.encodeBuffer();
boxContext.markOutputAsReadyToSend(0, chunkStartTime, chunkEndTime);
}
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif // TARGET_HAS_ThirdPartyITPP
@@ -0,0 +1,85 @@
#pragma once
#if defined TARGET_HAS_ThirdPartyITPP
#include "../../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
class CBoxAlgorithmXDAWNSpatialFilterTrainer final : 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_XDAWNSpatialFilterTrainer)
protected:
Toolkit::TStimulationDecoder<CBoxAlgorithmXDAWNSpatialFilterTrainer> m_stimulationDecoder;
Toolkit::TSignalDecoder<CBoxAlgorithmXDAWNSpatialFilterTrainer> m_signalDecoder;
Toolkit::TSignalDecoder<CBoxAlgorithmXDAWNSpatialFilterTrainer> m_evokedPotentialDecoder;
Toolkit::TStimulationEncoder<CBoxAlgorithmXDAWNSpatialFilterTrainer> m_encoder;
uint64_t m_stimID = 0;
CString m_spatialFilterConfigurationFilename;
size_t m_filterDim = 0;
bool m_saveAsBoxConfig = false;
};
class CBoxAlgorithmXDAWNSpatialFilterTrainerDesc final : public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("xDAWN Trainer (Deprecated)"); }
CString getAuthorName() const override { return CString("Yann Renard"); }
CString getAuthorCompanyName() const override { return CString("INRIA"); }
CString getShortDescription() const override
{
return CString(
"Computes spatial filter coeffcients in order to get better evoked potential classification (typically used for P300 detection)");
}
CString getDetailedDescription() const override { return CString(""); }
CString getCategory() const override { return CString("Signal processing/Filtering"); }
CString getVersion() const override { return CString("1.0"); }
CString getStockItemName() const override { return CString("gtk-missing-image"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_XDAWNSpatialFilterTrainer; }
IPluginObject* create() override { return new CBoxAlgorithmXDAWNSpatialFilterTrainer; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Stimulations", OV_TypeId_Stimulations);
prototype.addInput("Session signal", OV_TypeId_Signal);
prototype.addInput("Evoked potential epochs", OV_TypeId_Signal);
prototype.addOutput("Train-completed Flag", OV_TypeId_Stimulations);
prototype.addSetting("Train stimulation", OV_TypeId_Stimulation, "OVTK_StimulationId_Train");
prototype.addSetting("Spatial filter configuration", OV_TypeId_Filename, "");
prototype.addSetting("Filter dimension", OV_TypeId_Integer, "4");
prototype.addSetting("Save as box config", OV_TypeId_Boolean, "true");
// prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
prototype.addFlag(Kernel::BoxFlag_IsDeprecated);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_XDAWNSpatialFilterTrainerDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif // TARGET_HAS_ThirdPartyITPP
@@ -0,0 +1,216 @@
#if defined(TARGET_HAS_ThirdPartyFFTW3) // fftw3 required by wavelet2s
#include "ovpCBoxAlgorithmDiscreteWaveletTransform.h"
#include <cstdlib>
#include <vector>
#include <map>
#include <math.h>
#include <fstream>
#include <string>
#include "../../../contrib/packages/wavelet2d/wavelet2s.h"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmDiscreteWaveletTransform::initialize()
{
const size_t nOutput = this->getStaticBoxContext().getOutputCount();
m_decoder.initialize(*this, 0); // Signal stream decoder
m_encoder.initialize(*this, 0); // Signal stream encoder
m_waveletType = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_decompositionLevel = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
for (size_t o = 0; o < nOutput - 1; ++o) { m_encoders.push_back(new Toolkit::TSignalEncoder<CBoxAlgorithmDiscreteWaveletTransform>(*this, o + 1)); }
m_infolength = 0;
return true;
}
bool CBoxAlgorithmDiscreteWaveletTransform::uninitialize()
{
m_decoder.uninitialize();
m_encoder.uninitialize();
for (auto& elem : m_encoders)
{
elem->uninitialize();
delete elem;
}
m_encoders.clear();
return true;
}
bool CBoxAlgorithmDiscreteWaveletTransform::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmDiscreteWaveletTransform::process()
{
// the dynamic box context describes the current state of the box inputs and outputs (i.e. the chunks)
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
const int j = std::atoi(m_decompositionLevel);
const std::string nm(m_waveletType.toASCIIString());
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
//Decode input signal
m_decoder.decode(i);
// Construct header when we receive one
if (m_decoder.isHeaderReceived())
{
const size_t nChannels0 = m_decoder.getOutputMatrix()->getDimensionSize(0);
const size_t nSamples0 = m_decoder.getOutputMatrix()->getDimensionSize(1);
if (nSamples0 <= std::pow(2.0, j + 1))
{
this->getLogManager() << Kernel::LogLevel_Error << "Number of samples [" << nSamples0 << "] is smaller or equal than 2^{J+1} == ["
<< std::pow(2.0, j + 1) << "]\n";
this->getLogManager() << Kernel::LogLevel_Error << "Verify quantity of samples and number of decomposition levels" << "\n";
this->getLogManager() << Kernel::LogLevel_Error <<
"You can introduce a Time based epoching to have more samples per chunk or reduce the decomposition levels" << "\n";
return false;
}
//sig will be resized to the number of channels and the total number of samples (Channels x Samples)
m_sig.resize(nChannels0);
for (size_t c = 0; c < nChannels0; ++c) { m_sig[c].resize(nSamples0); }
//Do one dummy transform to get the m_flag and m_length filled. Since all channels & blocks have the same chunk size in OV, once is enough.
std::vector<double> flag; //flag is an auxiliar vector (see wavelet2d library)
std::vector<size_t> length; //length contains the length of each decomposition level. last entry is the length of the original signal.
std::vector<double> dwtOutput; //dwt_output is the vector containing the decomposition levels
dwt(m_sig[0], j, nm, dwtOutput, flag, length);
// Set info stream dimension
m_infolength = (length.size() + flag.size() + 2);
m_encoder.getInputMatrix()->resize(nChannels0, m_infolength);
// Set decomposition stream dimensions
for (size_t e = 0; e < m_encoders.size(); ++e) { m_encoders[e]->getInputMatrix()->resize(nChannels0, length[e]); }
// Set decomposition stream channel names
for (size_t c = 0; c < nChannels0; c++)
{
for (auto& encoder : m_encoders) { encoder->getInputMatrix()->setDimensionLabel(0, c, m_decoder.getOutputMatrix()->getDimensionLabel(0, c)); }
}
// Info stream header
m_encoder.getInputSamplingRate().setReferenceTarget(m_decoder.getOutputSamplingRate());
m_encoder.encodeHeader();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
// Decomposition stream headers
for (size_t e = 0; e < m_encoders.size(); ++e)
{
const double sampling = double(m_decoder.getOutputSamplingRate()) / std::pow(2.0, int(e));
m_encoders[e]->getInputSamplingRate() = uint64_t(std::floor(sampling));
m_encoders[e]->encodeHeader();
boxContext.markOutputAsReadyToSend(e + 1, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
}
if (m_decoder.isBufferReceived())
{
const CMatrix* matrix = m_decoder.getOutputMatrix();
const double* buffer0 = matrix->getBuffer();
const size_t nChannels0 = matrix->getDimensionSize(0);
const size_t nSamples0 = matrix->getDimensionSize(1);
//sig will store the samples of the different channels
for (size_t c = 0; c < nChannels0; ++c) //Number of EEG channels
{
for (size_t s = 0; s < nSamples0; ++s) //Number of Samples per Chunk
{
m_sig[c][s] = (buffer0[s + c * nSamples0]);
}
}
// Due to how wavelet2s works, we'll have to have the output variables empty before each call.
std::vector<std::vector<double>> flag;
std::vector<std::vector<size_t>> length;
std::vector<std::vector<double>> dwtOutput;
flag.resize(nChannels0);
length.resize(nChannels0);
dwtOutput.resize(nChannels0);
//Calculation of wavelets coefficients for each channel.
for (size_t c = 0; c < nChannels0; ++c) { dwt(m_sig[c], j, nm, dwtOutput[c], flag[c], length[c]); }
//Transmission of some information (flag and legth) to the inverse dwt box
//@fixme since the data dimensions do not change runtime, it should be sufficient to send this only once
for (size_t c = 0; c < nChannels0; ++c)
{
size_t f = 0;
m_encoder.getInputMatrix()->getBuffer()[f + c * m_infolength] = double(length[c].size());
for (size_t l = 0; l < length[c].size(); ++l)
{
m_encoder.getInputMatrix()->getBuffer()[l + 1 + c * m_infolength] = double(length[c][l]);
f = l;
}
m_encoder.getInputMatrix()->getBuffer()[f + 2 + c * m_infolength] = double(flag[c].size());
for (size_t l = 0; l < flag[c].size(); ++l) { m_encoder.getInputMatrix()->getBuffer()[f + 3 + l + c * m_infolength] = flag[c][l]; }
}
//Decode the dwt coefficients of each decomposition level to separate channels
for (size_t c = 0; c < nChannels0; ++c)
{
for (size_t e = 0, vectorPos = 0; e < m_encoders.size(); ++e)
{
CMatrix* oMatrix = m_encoders[e]->getInputMatrix();
double* oBuffer = oMatrix->getBuffer();
// loop levels
for (size_t l = 0; l < size_t(length[c][e]); ++l) { oBuffer[l + c * length[c][e]] = dwtOutput[c][l + vectorPos]; }
vectorPos = vectorPos + length[c][e];
}
}
m_encoder.encodeBuffer();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
for (size_t e = 0; e < m_encoders.size(); ++e)
{
m_encoders[e]->encodeBuffer();
boxContext.markOutputAsReadyToSend(e + 1, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
}
if (m_decoder.isEndReceived())
{
m_encoder.encodeEnd();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
for (size_t e = 0; e < m_encoders.size(); ++e)
{
m_encoders[e]->encodeEnd();
boxContext.markOutputAsReadyToSend(e + 1, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
}
}
return true;
}
#endif
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,141 @@
#pragma once
#if defined(TARGET_HAS_ThirdPartyFFTW3) // required by wavelet2s
//You may have to change this path to match your folder organisation
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <iostream>
#include <string>
#include <sstream>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
/**
* \class CBoxAlgorithmDiscreteWaveletTransform
* \author Joao-Pedro Berti-Ligabo / Inria
* \date Wed Jul 16 15:05:16 2014
* \brief The class CBoxAlgorithmDiscreteWaveletTransform describes the box DiscreteWaveletTransform.
*
*/
class CBoxAlgorithmDiscreteWaveletTransform 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_DiscreteWaveletTransform)
protected:
// Codec algorithms specified in the skeleton-generator:
// Signal stream decoder
Toolkit::TSignalDecoder<CBoxAlgorithmDiscreteWaveletTransform> m_decoder;
Toolkit::TSignalEncoder<CBoxAlgorithmDiscreteWaveletTransform> m_encoder;
std::vector<Toolkit::TSignalEncoder<CBoxAlgorithmDiscreteWaveletTransform>*> m_encoders;
CString m_waveletType;
CString m_decompositionLevel;
size_t m_infolength = 0;
std::vector<std::vector<double>> m_sig;
};
// The box listener can be used to call specific callbacks whenever the box structure changes : input added, name changed, etc.
// Please uncomment below the callbacks you want to use.
class CBoxAlgorithmDiscreteWaveletTransformListener final : public Toolkit::TBoxListener<IBoxListener>
{
public:
bool onSettingValueChanged(Kernel::IBox& box, const size_t index) override
{
if (index == 0) { return true; }
if (index == 1)
{
const size_t nOutputs = box.getOutputCount();
CString str;
box.getSettingValue(1, str);
const size_t nDecompositionLevels = atoi(str);
if (nOutputs != nDecompositionLevels + 2)
{
for (size_t i = 0; i < nOutputs; ++i) { box.removeOutput(nOutputs - i - 1); }
box.addOutput("Info",OV_TypeId_Signal);
box.addOutput("A",OV_TypeId_Signal);
for (size_t i = nDecompositionLevels; i > 0; i--) { box.addOutput(("D" + std::to_string(i)).c_str(),OV_TypeId_Signal); }
}
}
return true;
}
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
};
/**
* \class CBoxAlgorithmDiscreteWaveletTransformDesc
* \author Joao-Pedro Berti-Ligabo / Inria
* \date Wed Jul 16 15:05:16 2014
* \brief Descriptor of the box DiscreteWaveletTransform.
*
*/
class CBoxAlgorithmDiscreteWaveletTransformDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Discrete Wavelet Transform"); }
CString getAuthorName() const override { return CString("Joao-Pedro Berti-Ligabo"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("Calculate DiscreteWaveletTransform"); }
CString getDetailedDescription() const override { return CString("Calculate DiscreteWaveletTransform using different types of wavelets"); }
CString getCategory() const override { return CString("Signal processing/Wavelets"); }
CString getVersion() const override { return CString("1.0"); }
CString getStockItemName() const override { return CString("gnome-fs-regular.png"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_DiscreteWaveletTransform; }
IPluginObject* create() override { return new CBoxAlgorithmDiscreteWaveletTransform; }
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmDiscreteWaveletTransformListener; }
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Signal",OV_TypeId_Signal);
prototype.addOutput("Info",OV_TypeId_Signal);
prototype.addOutput("A",OV_TypeId_Signal);
prototype.addOutput("D2",OV_TypeId_Signal);
prototype.addOutput("D1",OV_TypeId_Signal);
prototype.addSetting("Wavelet type",OVP_TypeId_WaveletType, "");
prototype.addSetting("Wavelet decomposition levels",OVP_TypeId_WaveletLevel, "");
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_DiscreteWaveletTransformDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif
@@ -0,0 +1,172 @@
#if defined(TARGET_HAS_ThirdPartyEIGEN)
#include "ovpCBoxAlgorithmEOG_Denoising.h"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmEOG_Denoising::initialize()
{
// Signal stream decoder
m_algo0SignalDecoder.initialize(*this, 0);
m_algo1SignalDecoder.initialize(*this, 1);
m_algo2SignalEncoder.getInputSamplingRate().setReferenceTarget(m_algo0SignalDecoder.getOutputSamplingRate());
m_filename = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_fBMatrixFile.open(m_filename.toASCIIString(), std::ios::in);
if (m_fBMatrixFile.fail())
{
this->getLogManager() << Kernel::LogLevel_Error << "Failed to open [" << m_filename << "] for reading\n";
return false;
}
m_fBMatrixFile >> m_nChannels0;
m_fBMatrixFile >> m_nChannels1;
m_fBMatrixFile >> m_nSamples0;
if (m_fBMatrixFile.fail())
{
this->getLogManager() << Kernel::LogLevel_Error << "Not able to successfully read dims from [" << m_filename << "]\n";
m_fBMatrixFile.close();
return false;
}
m_nSamples1 = m_nSamples0;
m_noiseCoeff.resize(m_nChannels0, m_nChannels1); //Noise Coefficients Matrix (Dim: Channels EEG x Channels EOG)
m_noiseCoeff.setZero(m_nChannels0, m_nChannels1);
for (size_t i = 0; i < m_nChannels0; ++i) //Number of channels
{
for (size_t j = 0; j < m_nChannels1; ++j) { m_fBMatrixFile >> m_noiseCoeff(i, j); } //Number of Samples per Chunk
}
if (m_fBMatrixFile.fail())
{
this->getLogManager() << Kernel::LogLevel_Error << "Not able to successfully read coefficients from [" << m_filename << "]\n";
m_fBMatrixFile.close();
return false;
}
m_fBMatrixFile.close();
// Signal stream encoder
m_algo2SignalEncoder.initialize(*this, 0);
return true;
}
bool CBoxAlgorithmEOG_Denoising::uninitialize()
{
m_algo0SignalDecoder.uninitialize();
m_algo1SignalDecoder.uninitialize();
m_algo2SignalEncoder.uninitialize();
return true;
}
bool CBoxAlgorithmEOG_Denoising::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmEOG_Denoising::process()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
Eigen::MatrixXd data0(m_nChannels0, m_nSamples0); //EEG data
Eigen::MatrixXd data1(m_nChannels1, m_nSamples1); //EOG data
Eigen::MatrixXd eegC(m_nChannels0, m_nSamples0); //Corrected Matrix
if (boxContext.getInputChunkCount(0) != 0)
{
for (size_t i = 0; i < boxContext.getInputChunkCount(1); ++i) //Don't know why getinputchunkcount(1)
{
// Signal EEG
// decode the chunk ii on input 0
m_algo0SignalDecoder.decode(i);
CMatrix* matrix0 = m_algo0SignalDecoder.getOutputMatrix();
double* buffer0 = matrix0->getBuffer();
for (size_t c = 0; c < m_nChannels0; ++c) //Number of channels
{
for (size_t s = 0; s < m_nSamples0; ++s) { data0(c, s) = buffer0[s + c * m_nSamples0]; } //Number of Samples per Chunk
}
//Signal EOG
m_algo1SignalDecoder.decode(i);
CMatrix* matrix1 = m_algo1SignalDecoder.getOutputMatrix();
double* buffer1 = matrix1->getBuffer();
for (size_t c = 0; c < m_nChannels1; ++c) //Number of channels
{
for (size_t s = 0; s < m_nSamples1; ++s) { data1(c, s) = buffer1[s + c * m_nSamples1]; } //Number of Samples per Chunk
}
//Set the output (corrected EEG) to the same structure as the EEG input
m_algo2SignalEncoder.getInputMatrix()->resize(m_nChannels0, m_nSamples0);
for (size_t c = 0; c < m_nChannels0; c++)
{
m_algo2SignalEncoder.getInputMatrix()->setDimensionLabel(0, c, m_algo0SignalDecoder.getOutputMatrix()->getDimensionLabel(0, c));
}
//Remove the noise
eegC = data0 - (m_noiseCoeff * data1);
for (size_t c = 0; c < m_nChannels0; ++c) //Number of EEG channels
{
for (size_t s = 0; s < m_nSamples0; ++s) //Number of Samples per Chunk
{
m_algo2SignalEncoder.getInputMatrix()->getBuffer()[s + c * m_nSamples0] = eegC(c, s);
}
}
m_algo2SignalEncoder.getInputSamplingRate().setReferenceTarget(m_algo1SignalDecoder.getOutputSamplingRate());
if (m_algo1SignalDecoder.isHeaderReceived())
{
m_algo2SignalEncoder.encodeHeader();
// send the output chunk containing the header. The dates are the same as the input chunk:
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_algo1SignalDecoder.isBufferReceived())
{
// Encode the output buffer :
m_algo2SignalEncoder.encodeBuffer();
// and send it to the next boxes :
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
if (m_algo1SignalDecoder.isEndReceived())
{
// End of stream received. This happens only once when pressing "stop". Just pass it to the next boxes so they receive the message :
m_algo2SignalEncoder.encodeEnd();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
}
}
return true;
}
#endif
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,125 @@
#pragma once
#if defined(TARGET_HAS_ThirdPartyEIGEN)
//You may have to change this path to match your folder organisation
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <fstream>
// Verify Eigen Path
#include <Eigen/Dense>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
/**
* \class CBoxAlgorithmEOG_Denoising
* \author Joao-Pedro Berti-Ligabo / Inria
* \date Tue May 20 15:33:22 2014
* \brief The class CBoxAlgorithmEOG_Denoising describes the box Test.
*
*/
class CBoxAlgorithmEOG_Denoising final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
void release() override { delete this; }
bool initialize() override;
bool uninitialize() override;
//Here is the different process callbacks possible
// - On clock ticks :
//virtual bool processClock(Kernel::CMessageClock& msg);
// - On new input received (the most common behaviour for signal processing) :
bool processInput(const size_t index) override;
// If you want to use processClock, you must provide the clock frequency.
//virtual uint64_t getClockFrequency();
bool process() override;
// As we do with any class in openvibe, we use the macro below
// to associate this box to an unique identifier.
// The inheritance information is also made available,
// as we provide the superclass Toolkit::TBoxAlgorithm < IBoxAlgorithm >
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_EOG_Denoising)
protected:
// Codec algorithms specified in the skeleton-generator:
// Signal stream decoder
Toolkit::TSignalDecoder<CBoxAlgorithmEOG_Denoising> m_algo0SignalDecoder;
Toolkit::TSignalDecoder<CBoxAlgorithmEOG_Denoising> m_algo1SignalDecoder;
// Kernel::IAlgorithmProxy* m_matrixRegressionAlgorithm;
// Kernel::TParameterHandler < CMatrix* > ip_pMatrixRegressionAlgorithm_Matrix0;
// Kernel::TParameterHandler < CMatrix* > ip_pMatrixRegressionAlgorithm_Matrix1;
// Kernel::TParameterHandler < CMatrix* > op_pMatrixRegressionAlgorithm_Matrix;
// Kernel::TParameterHandler < CString > par_Filename;
// Signal stream encoder
Toolkit::TSignalEncoder<CBoxAlgorithmEOG_Denoising> m_algo2SignalEncoder;
CString m_filename;
std::ifstream m_fBMatrixFile;
Eigen::MatrixXd m_noiseCoeff;
size_t m_nChannels0 = 0;
size_t m_nChannels1 = 0;
size_t m_nSamples0 = 0;
size_t m_nSamples1 = 0;
};
/**
* \class CBoxAlgorithmEOG_DenoisingDesc
* \author Joao-Pedro Berti-Ligabo / Inria
* \date Tue May 20 15:33:22 2014
* \brief Descriptor of the box Test.
*
*/
class CBoxAlgorithmEOG_DenoisingDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("EOG Denoising"); }
CString getAuthorName() const override { return CString("Joao-Pedro Berti-Ligabo"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("EOG Denoising using Regression Analysis"); }
CString getDetailedDescription() const override { return CString("Algorithm implementation as suggested in Schlogl's article of 2007"); }
CString getCategory() const override { return CString("Signal processing/Denoising"); }
CString getVersion() const override { return CString("023"); }
CString getStockItemName() const override { return CString("gnome-fs-regular.png"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_EOG_Denoising; }
IPluginObject* create() override { return new CBoxAlgorithmEOG_Denoising; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("EEG",OV_TypeId_Signal);
prototype.addInput("EOG",OV_TypeId_Signal);
prototype.addOutput("EEG_Corrected",OV_TypeId_Signal);
prototype.addSetting("Filename b Matrix", OV_TypeId_Filename, "b-Matrix-EEG.txt");
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_EOG_DenoisingDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif
@@ -0,0 +1,386 @@
#if defined(TARGET_HAS_ThirdPartyEIGEN)
#include "ovpCBoxAlgorithmEOG_Denoising_Calibration.h"
#include <Eigen/Dense>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmEOG_Denoising_Calibration::initialize()
{
m_algo0SignalDecoder.initialize(*this, 0);
m_algo1SignalDecoder.initialize(*this, 1);
m_algo2StimulationDecoder.initialize(*this, 2);
m_stimulationEncoder.initialize(*this, 0);
m_calibrationFilename = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_stimID = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_startTime = 0;
m_endTime = 0;
m_nChunks = 0;
m_chunksVerify = -1;
m_endProcess = false;
m_time = 0;
m_startTimeChunks = 0;
m_endTimeChunks = 0;
// Random id for tmp token, clash possible if multiple boxes run in parallel (but unlikely)
const CString randomToken = CIdentifier::random().toString();
m_eegTempFilename = this->getConfigurationManager().expand("${Path_Tmp}/denoising_") + randomToken + "_EEG_tmp.dat";
m_eogTempFilename = this->getConfigurationManager().expand("${Path_Tmp}/denoising_") + randomToken + "_EOG_tmp.dat";
m_eegFile.open(m_eegTempFilename, std::ios::out | std::ios::in | std::ios::trunc);
if (m_eegFile.fail())
{
this->getLogManager() << Kernel::LogLevel_Error << "Opening [" << m_eegTempFilename << "] for r/w failed\n";
return false;
}
m_eogFile.open(m_eogTempFilename, std::ios::out | std::ios::in | std::ios::trunc);
if (m_eogFile.fail())
{
this->getLogManager() << Kernel::LogLevel_Error << "Opening [" << m_eogTempFilename << "] for r/w failed\n";
return false;
}
m_matrixFile.open(m_calibrationFilename.toASCIIString(), std::ios::out | std::ios::trunc);
if (m_matrixFile.fail())
{
this->getLogManager() << Kernel::LogLevel_Error << "Opening [" << m_calibrationFilename << "] for writing failed\n";
return false;
}
return true;
}
bool CBoxAlgorithmEOG_Denoising_Calibration::uninitialize()
{
m_algo0SignalDecoder.uninitialize();
m_algo1SignalDecoder.uninitialize();
m_algo2StimulationDecoder.uninitialize();
m_stimulationEncoder.uninitialize();
// Clean up temporary files
if (m_eegFile.is_open()) { m_eegFile.close(); }
if (m_eegTempFilename != CString("")) { std::remove(m_eegTempFilename); }
if (m_eogFile.is_open()) { m_eogFile.close(); }
if (m_eogTempFilename != CString("")) { std::remove(m_eogTempFilename); }
if (m_matrixFile.is_open()) { m_matrixFile.close(); }
return true;
}
bool CBoxAlgorithmEOG_Denoising_Calibration::processClock(Kernel::CMessageClock& /*msg*/)
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
if (m_nChunks != m_chunksVerify && m_endProcess == false)
{
m_chunksVerify = m_nChunks;
if (m_time == m_startTime) { m_startTimeChunks = m_nChunks; }
if (m_time == m_endTime) { m_endTimeChunks = m_nChunks; }
}
else if (m_nChunks == m_chunksVerify && m_endProcess == false)
{
if ((m_startTime >= m_endTime) || (m_endTime >= m_time))
{
this->getLogManager() << Kernel::LogLevel_Warning << "Verify time interval of sampling" << "\n";
this->getLogManager() << Kernel::LogLevel_Warning << "Total time of your sample: " << m_time << "\n";
this->getLogManager() << Kernel::LogLevel_Warning << "b Matrix was NOT successfully calculated" << "\n";
m_stimulationEncoder.getInputStimulationSet()->clear();
m_stimulationEncoder.getInputStimulationSet()->appendStimulation(OVTK_StimulationId_TrainCompleted, 0, 0);
m_stimulationEncoder.encodeBuffer();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, 0), boxContext.getInputChunkEndTime(0, 0));
//this->getLogManager() << Kernel::LogLevel_Warning << "You can stop this scenario " <<"\n";
m_chunksVerify = -1;
m_endProcess = true;
}
else
{
this->getLogManager() << Kernel::LogLevel_Info << "End of data gathering...calculating b matrix" << "\n";
m_eegFile.close();
m_eogFile.close();
m_eegFile.open(m_eegTempFilename, std::ios::in | std::ios::app);
if (m_eegFile.fail())
{
this->getLogManager() << Kernel::LogLevel_Error << "Opening [" << m_eegTempFilename << "] for reading failed\n";
return false;
}
m_eogFile.open(m_eogTempFilename, std::ios::in | std::ios::app);
if (m_eogFile.fail())
{
this->getLogManager() << Kernel::LogLevel_Error << "Opening [" << m_eogTempFilename << "] for reading failed\n";
return false;
}
//Process to extract the Matrix B
double aux;
Eigen::MatrixXd data0(m_nChannels0, m_nSamples0 * m_nChunks); //EEG data
Eigen::MatrixXd data1(m_nChannels1, m_nSamples1 * m_nChunks); //EOG data
for (size_t k = 0; k < m_nChunks; ++k)
{
for (size_t i = 0; i < m_nChannels0; ++i) //Number of channels
{
for (size_t j = 0; j < m_nSamples0; ++j) //Number of Samples per Chunk
{
m_eegFile >> aux;
data0(i, j + k * m_nSamples0) = aux;
}
}
}
for (size_t k = 0; k < m_nChunks; ++k)
{
for (size_t i = 0; i < m_nChannels1; ++i) //Number of channels
{
for (size_t j = 0; j < m_nSamples1; ++j) //Number of Samples per Chunk
{
m_eogFile >> aux;
data1(i, j + k * m_nSamples1) = aux;
}
}
}
// We will eliminate the firsts and lasts chunks of each channel
Eigen::MatrixXd data0N(m_nChannels0, m_nSamples0 * m_nChunks); //EEG data
Eigen::MatrixXd data1N(m_nChannels1, m_nSamples1 * m_nChunks); //EOG data
size_t validChunks = m_endTimeChunks - m_startTimeChunks;
size_t iblockeeg = 0;
size_t jblockeeg = m_startTimeChunks * m_nSamples0 - 1;
size_t pblockeeg = m_nChannels0;
size_t qblockeeg = m_nSamples0 * (validChunks);
size_t iblockeog = 0;
size_t jblockeog = m_startTimeChunks * m_nSamples1 - 1;
size_t pblockeog = m_nChannels1;
size_t qblockeog = m_nSamples1 * (validChunks);
data0N = data0.block(iblockeeg, jblockeeg, pblockeeg, qblockeeg);
data1N = data1.block(iblockeog, jblockeog, pblockeog, qblockeog);
double nVal = 0;
double min = 1e-6;
double max = 1e6;
Eigen::VectorXd meanRowEEG(m_nChannels0);
Eigen::VectorXd meanRowEog(m_nChannels1);
meanRowEEG.setZero(m_nChannels0, 1);
meanRowEog.setZero(m_nChannels1, 1);
for (size_t i = 0; i < m_nChannels0; ++i) //Number of channels
{
nVal = 0;
for (size_t j = 0; j < m_nSamples0 * validChunks; ++j) //Number of Samples per Chunk
{
if ((data0N(i, j) > -max && data0N(i, j) < -min) || (data0N(i, j) > min && data0N(i, j) < max))
{
//Valid Interval
meanRowEEG(i) = meanRowEEG(i) + data0N(i, j);
nVal = nVal + 1;
}
}
if (nVal != 0) { meanRowEEG(i) = meanRowEEG(i) / nVal; }
else { meanRowEEG(i) = 0; }
}
for (size_t i = 0; i < m_nChannels1; ++i) //Number of channels
{
nVal = 0;
for (size_t j = 0; j < m_nSamples1 * validChunks; ++j) //Number of Samples per Chunk
{
if ((data1N(i, j) > -max && data1N(i, j) < -min) || (data1N(i, j) > min && data1N(i, j) < max))
{
//Valid Interval
meanRowEog(i) = meanRowEog(i) + data1N(i, j);
nVal = nVal + 1;
}
}
if (nVal != 0) { meanRowEog(i) = meanRowEog(i) / nVal; }
else { meanRowEog(i) = 0; }
}
// The values which are not valid (very large or very small) will be set to the mean value
// So these values will not influence to the covariance calcul because the covariance is centered (value - mean)
for (size_t i = 0; i < m_nChannels0; ++i) //Number of channels
{
for (size_t j = 0; j < m_nSamples0 * validChunks; ++j) //Number of total samples
{
if ((data0N(i, j) > -max && data0N(i, j) < -min) || (data0N(i, j) > min && data0N(i, j) < max))
{
//Valid Interval
data0N(i, j) = data0N(i, j) - meanRowEEG(i);
}
else { data0N(i, j) = 0; } //Invalid
}
}
for (size_t i = 0; i < m_nChannels1; ++i) //Number of channels
{
for (size_t j = 0; j < m_nSamples1 * validChunks; ++j) //Number of total samples
{
if ((data1N(i, j) > -max && data1N(i, j) < -min) || (data1N(i, j) > min && data1N(i, j) < max))
{
//Valid Interval
data1N(i, j) = data1N(i, j) - meanRowEog(i);
}
else { data1N(i, j) = 0; } //Invalid
}
}
//Now we need to calculate the matrix b (which tells us the correct weights to be stored in b matrix)
Eigen::MatrixXd noiseCoeff(m_nChannels0, m_nChannels1); //Noise Coefficients Matrix (Dim: Channels EEG x Channels EOG)
Eigen::MatrixXd covEog(m_nChannels1, m_nChannels1);
Eigen::MatrixXd covEogInv(m_nChannels1, m_nChannels1);
Eigen::MatrixXd covEegAndEog(m_nChannels0, m_nChannels1);
covEog = (data1N * data1N.transpose());
covEogInv = covEog.inverse();
covEegAndEog = data0N * (data1N.transpose());
noiseCoeff = covEegAndEog * covEogInv;
// Save Matrix b to the file specified in the parameters
m_matrixFile << m_nChannels0 << " " << m_nChannels1 << " " << m_nSamples0 << "\n";
for (size_t i = 0; i < m_nChannels0; ++i) //Number of channels EEG
{
for (size_t j = 0; j < m_nChannels1; ++j) { m_matrixFile << noiseCoeff(i, j) << "\n"; } //Number of channels EOG
}
m_eegFile.close();
m_eogFile.close();
m_matrixFile.close();
m_chunksVerify = -1;
m_endProcess = true;
this->getLogManager() << Kernel::LogLevel_Info << "b Matrix was successfully calculated" << "\n";
this->getLogManager() << Kernel::LogLevel_Info << "Wrote the matrix to [" << m_calibrationFilename << "]\n";
//this->getLogManager() << Kernel::LogLevel_Warning << "You can stop this scenario " <<"\n";
m_stimulationEncoder.getInputStimulationSet()->clear();
m_stimulationEncoder.getInputStimulationSet()->appendStimulation(OVTK_StimulationId_TrainCompleted, 0, 0);
m_stimulationEncoder.encodeBuffer();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, 0), boxContext.getInputChunkEndTime(0, 0));
}
}
m_time++;
return true;
}
bool CBoxAlgorithmEOG_Denoising_Calibration::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmEOG_Denoising_Calibration::process()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
if (m_endProcess)
{
// We have done our stuff and have sent out a stimuli that we're done. However, if we're called again, we just do nothing,
// but do not return false (==error) as this state is normal after training.
return true;
}
// Signal EEG
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
m_algo0SignalDecoder.decode(i);
m_nChannels0 = m_algo0SignalDecoder.getOutputMatrix()->getDimensionSize(0);
m_nSamples0 = m_algo0SignalDecoder.getOutputMatrix()->getDimensionSize(1);
CMatrix* matrix0 = m_algo0SignalDecoder.getOutputMatrix();
double* buffer0 = matrix0->getBuffer();
for (size_t j = 0; j < matrix0->getBufferElementCount(); ++j) { m_eegFile << buffer0[j] << "\n"; }
}
//Signal EOG
for (size_t i = 0; i < boxContext.getInputChunkCount(1); ++i)
{
m_algo1SignalDecoder.decode(i);
m_nChannels1 = m_algo1SignalDecoder.getOutputMatrix()->getDimensionSize(0);
m_nSamples1 = m_algo1SignalDecoder.getOutputMatrix()->getDimensionSize(1);
CMatrix* matrix1 = m_algo1SignalDecoder.getOutputMatrix();
double* buffer1 = matrix1->getBuffer();
for (size_t j = 0; j < matrix1->getBufferElementCount(); ++j) { m_eogFile << buffer1[j] << "\n"; }
m_nChunks++;
}
for (size_t chunk = 0; chunk < boxContext.getInputChunkCount(2); ++chunk)
{
m_algo2StimulationDecoder.decode(chunk);
for (size_t j = 0; j < m_algo2StimulationDecoder.getOutputStimulationSet()->getStimulationCount(); ++j)
{
if (m_algo2StimulationDecoder.getOutputStimulationSet()->getStimulationIdentifier(j) == 33025)
{
m_startTime = m_time;
this->getLogManager() << Kernel::LogLevel_Info << "Start time: " << m_startTime << "\n";
}
if (m_algo2StimulationDecoder.getOutputStimulationSet()->getStimulationIdentifier(j) == 33031)
{
m_endTime = m_time;
this->getLogManager() << Kernel::LogLevel_Info << "End time: " << m_endTime << "\n";
}
// m_trainDate = m_algo2StimulationDecoder.getOutputStimulationSet()->getStimulationDate(m_algo2StimulationDecoder.getOutputStimulationSet()->getStimulationCount());
m_trainDate = m_algo2StimulationDecoder.getOutputStimulationSet()->getStimulationDate(j);
}
}
return true;
}
#endif
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,142 @@
#pragma once
#if defined(TARGET_HAS_ThirdPartyEIGEN)
//You may have to change this path to match your folder organisation
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <iostream>
#include <fstream>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
/**
* \class CBoxAlgorithmEOG_Denoising_Calibration
* \author Joao-Pedro Berti-Ligabo / Inria
* \date Fri May 23 15:30:58 2014
* \brief The class CBoxAlgorithmEOG_Denoising_Calibration describes the box EOG_Denoising_Calibration.
*
*/
class CBoxAlgorithmEOG_Denoising_Calibration final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
void release() override { delete this; }
bool initialize() override;
bool uninitialize() override;
bool processClock(Kernel::CMessageClock& msg) override;
bool processInput(const size_t index) override;
// If you want to use processClock, you must provide the clock frequency.
uint64_t getClockFrequency() override { return 1LL << 32; } // the box clock frequency
bool process() override;
//virtual bool openfile();
// As we do with any class in openvibe, we use the macro below
// to associate this box to an unique identifier.
// The inheritance information is also made available,
// as we provide the superclass Toolkit::TBoxAlgorithm < IBoxAlgorithm >
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_EOG_Denoising_Calibration)
protected:
Toolkit::TSignalDecoder<CBoxAlgorithmEOG_Denoising_Calibration> m_algo0SignalDecoder;
Toolkit::TSignalDecoder<CBoxAlgorithmEOG_Denoising_Calibration> m_algo1SignalDecoder;
Toolkit::TStimulationDecoder<CBoxAlgorithmEOG_Denoising_Calibration> m_algo2StimulationDecoder;
Toolkit::TStimulationEncoder<CBoxAlgorithmEOG_Denoising_Calibration> m_stimulationEncoder;
CString m_calibrationFilename;
size_t m_chunksVerify = 0;
size_t m_nChunks = 0;
bool m_endProcess = false;
std::fstream m_eegFile;
std::fstream m_eogFile;
std::ofstream m_matrixFile;
double m_startTime = 0;
double m_endTime = 0;
size_t m_startTimeChunks = 0;
size_t m_endTimeChunks = 0;
uint64_t m_trainDate = 0;
uint64_t m_trainChunkStartTime = 0;
uint64_t m_trainChunkEndTime = 0;
double m_time = 0;
size_t m_nChannels0 = 0;
size_t m_nChannels1 = 0;
size_t m_nSamples0 = 0;
size_t m_nSamples1 = 0;
uint64_t m_stimID = 0;
CString m_eegTempFilename;
CString m_eogTempFilename;
};
/**
* \class CBoxAlgorithmEOG_Denoising_CalibrationDesc
* \author Joao-Pedro Berti-Ligabo / Inria
* \date Fri May 23 15:30:58 2014
* \brief Descriptor of the box EOG_Denoising_Calibration.
*
*/
class CBoxAlgorithmEOG_Denoising_CalibrationDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("EOG Denoising Calibration"); }
CString getAuthorName() const override { return CString("Joao-Pedro Berti-Ligabo"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("Algorithm implementation as suggested in Schlogl's article of 2007."); }
CString getDetailedDescription() const override
{
return CString("Press 'a' to set start point and 'u' to set end point, you can connect the Keyboard Stimulator for that");
}
CString getCategory() const override { return CString("Signal processing/Denoising"); }
CString getVersion() const override { return CString("1.0"); }
CString getStockItemName() const override { return CString("gnome-fs-regular.png"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_EOG_Denoising_Calibration; }
IPluginObject* create() override { return new CBoxAlgorithmEOG_Denoising_Calibration; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("EEG",OV_TypeId_Signal);
prototype.addInput("EOG",OV_TypeId_Signal);
prototype.addInput("Stimulations", OV_TypeId_Stimulations);
prototype.addSetting("Filename b Matrix", OV_TypeId_Filename, "b-Matrix-EEG.cfg");
prototype.addSetting("End trigger", OV_TypeId_Stimulation, "OVTK_GDF_End_Of_Session");
prototype.addOutput("Train-completed Flag",OV_TypeId_Stimulations);
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_EOG_Denoising_CalibrationDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif
@@ -0,0 +1,189 @@
#if defined(TARGET_HAS_ThirdPartyFFTW3) // required by wavelet2s
#include "ovpCBoxAlgorithmInverse_DWT.h"
#include <vector>
#include <map>
#include <math.h>
#include <iostream>
#include <string>
#include "../../../contrib/packages/wavelet2d/wavelet2s.h"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmInverse_DWT::initialize()
{
const size_t nInput = this->getStaticBoxContext().getInputCount();
m_algoInfoDecoder.initialize(*this, 0);
m_waveletType = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_decompositionLevel = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_algoXDecoder = new Toolkit::TSignalDecoder<CBoxAlgorithmInverse_DWT> [nInput];
for (size_t o = 0; o < nInput - 1; ++o) { m_algoXDecoder[o].initialize(*this, o + 1); }
m_encoder.initialize(*this, 0);
return true;
}
bool CBoxAlgorithmInverse_DWT::uninitialize()
{
const size_t nInput = this->getStaticBoxContext().getInputCount();
m_algoInfoDecoder.uninitialize();
for (size_t o = 0; o < nInput - 1; ++o) { m_algoXDecoder[o].uninitialize(); }
if (m_algoXDecoder)
{
delete[] m_algoXDecoder;
m_algoXDecoder = nullptr;
}
m_encoder.uninitialize();
return true;
}
bool CBoxAlgorithmInverse_DWT::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmInverse_DWT::process()
{
// the dynamic box context describes the current state of the box inputs and outputs (i.e. the chunks)
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
// size_t J = std::atoi(m_decompositionLevel);
const size_t nInput = this->getStaticBoxContext().getInputCount();
const std::string nm(m_waveletType.toASCIIString());
std::vector<std::vector<double>> dwtop;
std::vector<std::vector<double>> idwt_output;
std::vector<std::vector<double>> flag;
std::vector<std::vector<size_t>> length;
size_t flagReceveid = 0;
std::vector<size_t> nChannels(nInput);
std::vector<size_t> nSamples(nInput);
//Check if all inputs have some information to decode
if (boxContext.getInputChunkCount(nInput - 1) == 1)
{
//Decode the first input (Informations)
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
m_algoInfoDecoder.decode(i);
nChannels[0] = m_algoInfoDecoder.getOutputMatrix()->getDimensionSize(0);
nSamples[0] = m_algoInfoDecoder.getOutputMatrix()->getDimensionSize(1);
CMatrix* matrix = m_algoInfoDecoder.getOutputMatrix();
double* buffer = matrix->getBuffer();
//this->getLogManager() << Kernel::LogLevel_Warning << "buffer 0 " << (size_t)buffer0[0] << "\n";
length.resize(nChannels[0]);
flag.resize(nChannels[0]);
for (size_t j = 0; j < nChannels[0]; ++j)
{
size_t f = 0;
for (size_t l = 0; l < size_t(buffer[0]); ++l)
{
length[j].push_back(size_t(buffer[l + 1]));
f = l;
}
for (size_t l = 0; l < size_t(buffer[f + 2]); ++l) { flag[j].push_back(size_t(buffer[f + 3 + l])); }
}
flagReceveid = 1;
}
//If Informations is decoded
if (flagReceveid == 1)
{
//Decode each decomposition level
for (size_t o = 0; o < nInput - 1; ++o)
{
//Decode data of channels
for (size_t i = 0; i < boxContext.getInputChunkCount(o + 1); ++i)
{
m_algoXDecoder[o].decode(i);
nChannels[o + 1] = m_algoXDecoder[o].getOutputMatrix()->getDimensionSize(0);
nSamples[o + 1] = m_algoXDecoder[o].getOutputMatrix()->getDimensionSize(1);
CMatrix* matrix = m_algoXDecoder[o].getOutputMatrix();
double* buffer = matrix->getBuffer();
//dwtop is the dwt coefficients
dwtop.resize(nChannels[0]);
//Store input data (dwt coefficients) in just one vector (dwtop)
for (size_t j = 0; j < nChannels[0]; ++j)
{
for (size_t k = 0; k < nSamples[o + 1]; ++k) { dwtop[j].push_back(buffer[k + j * nSamples[o + 1]]); }
}
//Check if received informations about dwt box are coherent with inverse dwt box settings
if (!length[0].empty() && o == nInput - 2)
{
//Check if quantity of samples received are the same
if (length[0].at(nInput - 1) == dwtop[0].size())
{
//Resize idwt vector
idwt_output.resize(nChannels[0]);
//Calculate idwt for each channel
for (size_t j = 0; j < nChannels[0]; ++j) { idwt(dwtop[j], flag[j], nm, idwt_output[j], length[j]); }
m_encoder.getInputSamplingRate() = 2 * m_algoXDecoder[o].getOutputSamplingRate();
m_encoder.getInputMatrix()->resize(nChannels[0], length[0].at(nInput - 1));
for (size_t j = 0; j < nChannels[0]; j++)
{
m_encoder.getInputMatrix()->setDimensionLabel(0, j, m_algoXDecoder[o].getOutputMatrix()->getDimensionLabel(0, j));
}
//Encode resultant signal to output
for (size_t j = 0; j < nChannels[0]; ++j)
{
for (size_t k = 0; k < size_t(idwt_output[j].size()); ++k)
{
m_encoder.getInputMatrix()->getBuffer()[k + j * size_t(idwt_output[j].size())] = idwt_output[j][k];
}
}
m_encoder.encodeHeader();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
m_encoder.encodeBuffer();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
m_encoder.encodeEnd();
boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
}
}
}
}
}
}
return true;
}
#endif
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,140 @@
#pragma once
#if defined(TARGET_HAS_ThirdPartyFFTW3) // required by wavelet2s
//You may have to change this path to match your folder organisation
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <string>
#include <sstream>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
/**
* \class CBoxAlgorithmInverse_DWT
* \author Joao-Pedro Berti-Ligabo / Inria
* \date Thu Jul 24 10:57:05 2014
* \brief The class CBoxAlgorithmInverse_DWT describes the box Inverse DWT.
*
*/
class CBoxAlgorithmInverse_DWT final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
CBoxAlgorithmInverse_DWT() { }
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_Inverse_DWT)
protected:
// Codec algorithms specified in the skeleton-generator:
// Signal stream encoder
Toolkit::TSignalEncoder<CBoxAlgorithmInverse_DWT> m_encoder;
Toolkit::TSignalDecoder<CBoxAlgorithmInverse_DWT> m_algoInfoDecoder;
Toolkit::TSignalDecoder<CBoxAlgorithmInverse_DWT>* m_algoXDecoder = nullptr;
CString m_waveletType;
CString m_decompositionLevel;
};
class CBoxAlgorithmInverse_DWTListener final : public Toolkit::TBoxListener<IBoxListener>
{
public:
bool onSettingValueChanged(Kernel::IBox& box, const size_t index) override
{
if (index == 0) { return true; }
if (index == 1)
{
const size_t nInput = box.getInputCount();
CString nDecompositionLevels;
box.getSettingValue(1, nDecompositionLevels);
const size_t nDecompositionLevel = atoi(nDecompositionLevels);
if (nInput != nDecompositionLevel + 2)
{
for (size_t i = 0; i < nInput; ++i) { box.removeInput(nInput - i - 1); }
box.addInput("Info",OV_TypeId_Signal);
box.addInput("A",OV_TypeId_Signal);
for (size_t i = nDecompositionLevel; i > 0; i--) { box.addInput(("D" + std::to_string(i)).c_str(),OV_TypeId_Signal); }
}
}
return true;
}
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
};
/**
* \class CBoxAlgorithmInverse_DWTDesc
* \author Joao-Pedro Berti-Ligabo / Inria
* \date Thu Jul 24 10:57:05 2014
* \brief Descriptor of the box Inverse DWT.
*
*/
class CBoxAlgorithmInverse_DWTDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Inverse DWT"); }
CString getAuthorName() const override { return CString("Joao-Pedro Berti-Ligabo"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("Calculate Inverse DiscreteWaveletTransform"); }
CString getDetailedDescription() const override { return CString("Calculate Inverse DiscreteWaveletTransform using different types of wavelets"); }
CString getCategory() const override { return CString("Signal processing/Wavelets"); }
CString getVersion() const override { return CString("1.0"); }
CString getStockItemName() const override { return CString("gnome-fs-regular.png"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_Inverse_DWT; }
IPluginObject* create() override { return new CBoxAlgorithmInverse_DWT; }
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmInverse_DWTListener; }
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Info",OV_TypeId_Signal);
prototype.addInput("A",OV_TypeId_Signal);
prototype.addInput("D2",OV_TypeId_Signal);
prototype.addInput("D1",OV_TypeId_Signal);
prototype.addOutput("Signal",OV_TypeId_Signal);
prototype.addSetting("Wavelet type",OVP_TypeId_WaveletType, "");
prototype.addSetting("Wavelet decomposition levels",OVP_TypeId_WaveletLevel, "");
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_Inverse_DWTDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
#endif
@@ -0,0 +1,178 @@
//include OpenViBE
#include "ovpCBoxAlgorithmQuadraticForm.h"
//include C++ STL
#include <iostream>
#include <sstream>
//atoi
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
bool CBoxAlgorithmQuadraticForm::initialize()
{
//the algorithms that decode and encode the signals
m_decoder = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SignalDecoder));
m_encoder = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SignalEncoder));
m_decoder->initialize();
m_encoder->initialize();
m_decoder->getOutputParameter(OVP_GD_Algorithm_SignalDecoder_OutputParameterId_Sampling)->setReferenceTarget(
m_encoder->getInputParameter(OVP_GD_Algorithm_SignalEncoder_InputParameterId_Sampling));
//connecting the decoding and encoding the parameters
m_iEBMLBufferHandle.initialize(m_decoder->getInputParameter(OVP_GD_Algorithm_SignalDecoder_InputParameterId_MemoryBufferToDecode));
m_iMatrixHandle.initialize(m_decoder->getOutputParameter(OVP_GD_Algorithm_StreamedMatrixDecoder_OutputParameterId_Matrix));
m_oMatrixHandle.initialize(m_encoder->getInputParameter(OVP_GD_Algorithm_StreamedMatrixEncoder_InputParameterId_Matrix));
m_oEBMLBufferHandle.initialize(m_encoder->getOutputParameter(OVP_GD_Algorithm_SignalEncoder_OutputParameterId_EncodedMemoryBuffer));
//end and start time
m_startTime = 0;
m_endTime = 0;
//reading the quadratic operator (matrix) values
//the number of rows/columns
const size_t nRow = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
//setting the size of the matrix
m_quadraticOperator.resize(nRow, nRow);
//the coefficients
const CString coefs = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
const char* str = coefs.toASCIIString();
double* buffer = m_quadraticOperator.getBuffer();
std::istringstream iss(str); //the stream for parsing the matrix coefficient
double currentValue = 0.0; //the current coefficient being read
for (size_t i = 0; i < nRow; ++i)
{
for (size_t j = 0; j < nRow; ++j)
{
//actual parsing, checking and storing value if everything is OK
if (!(iss >> currentValue))
{
getBoxAlgorithmContext()->getPlayerContext()->getLogManager() << Kernel::LogLevel_Error <<
"Error reading quadratic operator coefficients\n The coefficients or the number of coefficient must be wrong\n";
return false;
}
buffer[i * nRow + j] = currentValue;
}
}
if (iss >> currentValue)
{
getBoxAlgorithmContext()->getPlayerContext()->getLogManager() << Kernel::LogLevel_Warning <<
"There may be more coefficients specified in the setting 'Matrix values' than the number of rows/columns can allow\n";
}
return true;
}
bool CBoxAlgorithmQuadraticForm::uninitialize()
{
//uninitializing algorithms and parameters handlers
m_decoder->uninitialize();
m_encoder->uninitialize();
m_iEBMLBufferHandle.uninitialize();
m_oEBMLBufferHandle.uninitialize();
m_iMatrixHandle.uninitialize();
m_oMatrixHandle.uninitialize();
//releasing algorithms
getAlgorithmManager().releaseAlgorithm(*m_decoder);
getAlgorithmManager().releaseAlgorithm(*m_encoder);
return true;
}
bool CBoxAlgorithmQuadraticForm::processInput(const size_t /*index*/)
{
//if input is arrived, processing it, i.e., computing the corresponding quadratic forms
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmQuadraticForm::process()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
//prcessing the input buffers
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
//decoding the input signal
m_iEBMLBufferHandle = boxContext.getInputChunk(0, i);
m_decoder->process();
//storing the start and end time of the chunk
m_startTime = boxContext.getInputChunkStartTime(0, i);
m_endTime = boxContext.getInputChunkEndTime(0, i);
//deal with the header if needed (initializations)
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_SignalDecoder_OutputTriggerId_ReceivedHeader))
{
//getting some input matrix properties
m_nChannels = m_iMatrixHandle->getDimensionSize(0);
m_nSamplesPerBuffer = m_iMatrixHandle->getDimensionSize(1);
//checking that the number of channels is compatible with the quadratic operator size
if (m_nChannels != m_quadraticOperator.getDimensionSize(0))
{
getBoxAlgorithmContext()->getPlayerContext()->getLogManager() << Kernel::LogLevel_Error <<
"The number of input channels is not compatible with the number of rows/columns of the quadratic operator matrix. This number of rows/columns must be equal to the number of input channels\n";
return false;
}
//setting the size of the output buffer
m_oMatrixHandle->resize(1, m_nSamplesPerBuffer);
m_oEBMLBufferHandle = boxContext.getOutputChunk(0);
//encoding the output
m_encoder->process(OVP_GD_Algorithm_SignalEncoder_InputTriggerId_EncodeHeader);
//sending the output
boxContext.markOutputAsReadyToSend(0, m_startTime, m_endTime);
}
//applying the quadratic operator
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_SignalDecoder_OutputTriggerId_ReceivedBuffer))
{
double* buffer = m_quadraticOperator.getBuffer();
double* iBuffer = m_iMatrixHandle->getBuffer();
double* oBuffer = m_oMatrixHandle->getBuffer();
//applying the quadratic operator for each sample: o = m^T * A * m
for (size_t j = 0; j < m_nSamplesPerBuffer; ++j)
{
std::vector<double> prime(m_nChannels); //performing m' = A * m (intermediate step 1)
for (size_t k = 0; k < prime.size(); ++k) { prime[k] = 0.0; } //initializing with zeros
//browsing the quadratic operator matrix (A) rows
for (size_t k = 0; k < m_quadraticOperator.getDimensionSize(0); ++k)
{
//browsing the quadratic operator matrix (A) columns
for (size_t l = 0; l < m_quadraticOperator.getDimensionSize(1); ++l)
{
prime[k] += buffer[k * m_quadraticOperator.getDimensionSize(0) + l] * iBuffer[l * m_nChannels + j];
}
}
//performing o = m^T * m' (intermediate step 2)
double output = 0.0;
for (size_t k = 0; k < prime.size(); ++k) { output += iBuffer[k * m_nChannels + j] * prime[k]; }
oBuffer[j] = output;
}
boxContext.markInputAsDeprecated(0, i);
m_oEBMLBufferHandle = boxContext.getOutputChunk(0);
m_encoder->process(OVP_GD_Algorithm_SignalEncoder_InputTriggerId_EncodeBuffer);
boxContext.markOutputAsReadyToSend(0, m_startTime, m_endTime);
}
}
return true;
}
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,90 @@
#pragma once
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
class CBoxAlgorithmQuadraticForm final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
void release() override { delete this; }
uint64_t getClockFrequency() override { return 0; } // the box clock frequency
bool initialize() override;
bool uninitialize() override;
bool processClock(Kernel::CMessageClock& /*msg*/) override { return true; }
bool processInput(const size_t index) override;
bool process() override;
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_QuadraticForm)
protected:
//algorithms for encoding and decoding EBML stream
Kernel::IAlgorithmProxy* m_encoder = nullptr;
Kernel::IAlgorithmProxy* m_decoder = nullptr;
//input and output buffers
Kernel::TParameterHandler<const IMemoryBuffer*> m_iEBMLBufferHandle;
Kernel::TParameterHandler<IMemoryBuffer*> m_oEBMLBufferHandle;
//the signal matrices (input and output)
Kernel::TParameterHandler<CMatrix*> m_iMatrixHandle;
Kernel::TParameterHandler<CMatrix*> m_oMatrixHandle;
//start and end times
uint64_t m_startTime = 0;
uint64_t m_endTime = 0;
//The matrix used in the quadratic form: the quadratic operator
CMatrix m_quadraticOperator;
//dimensions (number of input channels and number of samples) of the input buffer
size_t m_nChannels = 0;
size_t m_nSamplesPerBuffer = 0;
};
class CBoxAlgorithmQuadraticFormDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Quadratic Form"); }
CString getAuthorName() const override { return CString("Fabien Lotte"); }
CString getAuthorCompanyName() const override { return CString("IRISA-INSA Rennes"); }
CString getShortDescription() const override { return CString("Perform a quadratic matrix operation on the input signals m (result = m^T * A * m)"); }
CString getDetailedDescription() const override
{
return CString(
"a square matrix A (which can be seen as a spatial filter) is applied to the input signals m (a vector). Then the transpose m^T of the input signals is multiplied to the resulting vector. In other words the output o is such as: o = m^T * A * m.");
}
CString getCategory() const override { return CString("Signal processing/Basic"); }
CString getVersion() const override { return CString("0.1"); }
CString getStockItemName() const override { return CString("gtk-missing-image"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_QuadraticForm; }
IPluginObject* create() override { return new CBoxAlgorithmQuadraticForm; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("input signal", OV_TypeId_Signal);
prototype.addOutput("output signal", OV_TypeId_Signal);
prototype.addSetting("Matrix values", OV_TypeId_String, "1 0 0 1");
prototype.addSetting("Number of rows/columns (square matrix)", OV_TypeId_Integer, "2");
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_QuadraticFormDesc)
};
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,158 @@
#pragma once
// Boxes
//---------------------------------------------------------------------------------------------------
#define OVP_ClassId_Identity OpenViBE::CIdentifier(0x5DFFE431, 0x35215C50)
#define OVP_ClassId_IdentityDesc OpenViBE::CIdentifier(0x54743810, 0x6A1A88CC)
#define OVP_ClassId_TimeBasedEpoching OpenViBE::CIdentifier(0x00777FA0, 0x5DC3F560)
#define OVP_ClassId_TimeBasedEpochingDesc OpenViBE::CIdentifier(0x00ABDABE, 0x41381683)
#define OVP_ClassId_BoxAlgorithm_EOG_Denoising OpenViBE::CIdentifier(0xC223FF12, 0x069A987E)
#define OVP_ClassId_BoxAlgorithm_EOG_DenoisingDesc OpenViBE::CIdentifier(0x4F9BE623, 0xF2027046)
#define OVP_ClassId_BoxAlgorithm_EOG_Denoising_Calibration OpenViBE::CIdentifier(0xE8DFE002, 0x70389932)
#define OVP_ClassId_BoxAlgorithm_EOG_Denoising_CalibrationDesc OpenViBE::CIdentifier(0xF4D74831, 0x88B80DCF)
#define OVP_ClassId_BoxAlgorithm_Inverse_DWT OpenViBE::CIdentifier(0x5B5B8468, 0x212CF963)
#define OVP_ClassId_BoxAlgorithm_Inverse_DWTDesc OpenViBE::CIdentifier(0x01B9BC9A, 0x34766AE9)
#define OVP_ClassId_BoxAlgorithm_DiscreteWaveletTransform OpenViBE::CIdentifier(0x824194C5, 0x46D7FDE9)
#define OVP_ClassId_BoxAlgorithm_DiscreteWaveletTransformDesc OpenViBE::CIdentifier(0x6744711B, 0xF21B59EC)
#define OVP_ClassId_BoxAlgorithm_EpochAverage OpenViBE::CIdentifier(0x21283D9F, 0xE76FF640)
#define OVP_ClassId_BoxAlgorithm_EpochAverageDesc OpenViBE::CIdentifier(0x95F5F43E, 0xBE629D82)
#define OVP_ClassId_Algorithm_MatrixAverage OpenViBE::CIdentifier(0x5E5A6C1C, 0x6F6BEB03)
#define OVP_ClassId_Algorithm_MatrixAverageDesc OpenViBE::CIdentifier(0x1992881F, 0xC938C0F2)
#define OVP_ClassId_BoxAlgorithm_Crop OpenViBE::CIdentifier(0x7F1A3002, 0x358117BA)
#define OVP_ClassId_BoxAlgorithm_CropDesc OpenViBE::CIdentifier(0x64D619D7, 0x26CC42C9)
#define OVP_ClassId_BoxAlgorithm_DifferentialIntegral OpenViBE::CIdentifier(0xCE490CBF, 0xDF7BA2E2)
#define OVP_ClassId_BoxAlgorithm_DifferentialIntegralDesc OpenViBE::CIdentifier(0xCE490CBF, 0xDF7BA2E3)
#define OVP_ClassId_BoxAlgorithm_MatrixTranspose OpenViBE::CIdentifier(0x5E0F04B5, 0x5B5005CF)
#define OVP_ClassId_BoxAlgorithm_MatrixTransposeDesc OpenViBE::CIdentifier(0x119249F7, 0x556C7E0D)
#define OVP_ClassId_BoxAlgorithm_ERSPAverage OpenViBE::CIdentifier(0x3CDB4B72, 0x295D51F7)
#define OVP_ClassId_BoxAlgorithm_ERSPAverageDesc OpenViBE::CIdentifier(0x32C45B7E, 0x2F1B7D58)
#define OVP_ClassId_BoxAlgorithm_ARCoefficients OpenViBE::CIdentifier(0xBAADC2F3, 0xB556A07B)
#define OVP_ClassId_BoxAlgorithm_ARCoefficientsDesc OpenViBE::CIdentifier(0xBAADC2F3, 0xB556A07A)
#define OVP_ClassId_BoxAlgorithm_ConnectivityMeasure OpenViBE::CIdentifier(0x994a9a45, 0x4181a048)
#define OVP_ClassId_BoxAlgorithm_ConnectivityMeasureDesc OpenViBE::CIdentifier(0xaf5e56f9, 0xcbc54c18)
#define OVP_ClassId_ReferenceChannel OpenViBE::CIdentifier(0xEFA8E95B, 0x4F22551B)
#define OVP_ClassId_ReferenceChannelDesc OpenViBE::CIdentifier(0x1873B151, 0x969DD4E4)
#define OVP_ClassId_ChannelSelector OpenViBE::CIdentifier(0x39484563, 0x46386889)
#define OVP_ClassId_ChannelSelectorDesc OpenViBE::CIdentifier(0x34893489, 0x44934897)
#define OVP_ClassId_SimpleDSP OpenViBE::CIdentifier(0x00E26FA1, 0x1DBAB1B2)
#define OVP_ClassId_SimpleDSPDesc OpenViBE::CIdentifier(0x00C44BFE, 0x76C9269E)
#define OVP_ClassId_SignalAverage OpenViBE::CIdentifier(0x00642C4D, 0x5DF7E50A)
#define OVP_ClassId_SignalAverageDesc OpenViBE::CIdentifier(0x007CDCE9, 0x16034F77)
#define OVP_ClassId_SignalConcatenation OpenViBE::CIdentifier(0x6568D29B, 0x0D753CCA)
#define OVP_ClassId_SignalConcatenationDesc OpenViBE::CIdentifier(0x3921BACD, 0x1E9546FE)
#define OVP_ClassId_BoxAlgorithm_QuadraticForm OpenViBE::CIdentifier(0x54E73B81, 0x1AD356C6)
#define OVP_ClassId_BoxAlgorithm_QuadraticFormDesc OpenViBE::CIdentifier(0x31C11856, 0x3E4F7B67)
#define OVP_ClassId_BoxAlgorithm_EpochVariance OpenViBE::CIdentifier(0x335384EA, 0x88C917D9)
#define OVP_ClassId_BoxAlgorithm_EpochVarianceDesc OpenViBE::CIdentifier(0xA15EAEC5, 0xAB0CE73D)
#define OVP_ClassId_Algorithm_MatrixVariance OpenViBE::CIdentifier(0x7FEFDCA9, 0x816ED903)
#define OVP_ClassId_Algorithm_MatrixVarianceDesc OpenViBE::CIdentifier(0xE405260B, 0x59EEFAE4)
#define OVP_ClassId_Algorithm_HilbertTransform OpenViBE::CIdentifier(0x344B79DE, 0x89EAAABB)
#define OVP_ClassId_Algorithm_HilbertTransformDesc OpenViBE::CIdentifier(0x8CAB236A, 0xA789800D)
#define OVP_ClassId_BoxAlgorithm_Hilbert OpenViBE::CIdentifier(0x7878A47F, 0x9A8FE349)
#define OVP_ClassId_BoxAlgorithm_HilbertDesc OpenViBE::CIdentifier(0x2DB54E2F, 0x435675EF)
#define OVP_ClassId_Algorithm_ARBurgMethod OpenViBE::CIdentifier(0x3EC6A165, 0x2823A034)
#define OVP_ClassId_Algorithm_ARBurgMethodDesc OpenViBE::CIdentifier(0xD7234DFF, 0x55447A14)
#define OVP_ClassId_BoxAlgorithm_XDAWNSpatialFilterTrainer OpenViBE::CIdentifier(0xAE241F9F, 0x599FAD88)
#define OVP_ClassId_BoxAlgorithm_XDAWNSpatialFilterTrainerDesc OpenViBE::CIdentifier(0x46FFAD13, 0x5F5C68CE)
#define OVP_ClassId_BoxAlgorithm_IFFTbox OpenViBE::CIdentifier(0xD533E997, 0x4AFD2423)
#define OVP_ClassId_BoxAlgorithm_IFFTboxDesc OpenViBE::CIdentifier(0xD533E997, 0x4AFD2423)
#define OVP_ClassId_BoxAlgorithm_Matrix3dTo2d OpenViBE::CIdentifier(0x3ab2b81e, 0x73ef01a5)
#define OVP_ClassId_BoxAlgorithm_Matrix3dTo2dDesc OpenViBE::CIdentifier(0xb9099590, 0xae33d758)
// Type definitions
//---------------------------------------------------------------------------------------------------
#define OVP_TypeId_EpochAverageMethod OpenViBE::CIdentifier(0x6530BDB1, 0xD057BBFE)
#define OVP_TypeId_CropMethod OpenViBE::CIdentifier(0xD0643F9E, 0x8E35FE0A)
#define OVP_TypeId_SelectionMethod OpenViBE::CIdentifier(0x3BCF9E67, 0x0C23994D)
#define OVP_TypeId_MatchMethod OpenViBE::CIdentifier(0x666F25E9, 0x3E5738D6)
#define OVP_TypeId_DifferentialIntegralOperation OpenViBE::CIdentifier(0x6E6AD85D, 0x14FD203A)
#define OVP_TypeId_WindowType OpenViBE::CIdentifier(0x332BBB80, 0xC212810A)
#define OVP_TypeId_WaveletType OpenViBE::CIdentifier(0x393EAC3E, 0x793C0F1D)
#define OVP_TypeId_WaveletLevel OpenViBE::CIdentifier(0xF80A2144, 0x6E692C51)
enum class EEpochAverageMethod { Moving, MovingImmediate, Block, Cumulative };
enum class ECropMethod { Min, Max, MinMax };
enum class ESelectionMethod { Select, Reject, Select_EEG };
enum class EMatchMethod { Name, Index, Smart };
enum class EDifferentialIntegralOperation { Differential, Integral };
enum class EWaveletType
{
Haar,
Db1, Db2, Db3, Db4, Db5, Db6, Db7, Db8, Db9, Db10, Db11, Db12, Db13, Db14, Db15,
Bior11, Bior13, Bior15, Bior22, Bior24, Bior26, Bior28, Bior31, Bior33, Bior35, Bior37, Bior39, Bior44, Bior55, Bior68,
Coif1, Coif2, Coif3, Coif4, Coif5,
Sym1, Sym2, Sym3, Sym4, Sym5, Sym6, Sym7, Sym8, Sym9, Sym10
};
enum class EWaveletLevel { L1, L2, L3, L4, L5 };
// Global defines
//---------------------------------------------------------------------------------------------------
#ifdef TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
#include "ovp_global_defines.h"
#endif // TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
#define OVP_Value_CoupledStringSeparator '-'
//#define OVP_Value_AllSelection '*'
#define OVP_Algorithm_MatrixAverage_InputParameterId_Matrix OpenViBE::CIdentifier(0x913E9C3B, 0x8A62F5E3)
#define OVP_Algorithm_MatrixAverage_InputParameterId_MatrixCount OpenViBE::CIdentifier(0x08563191, 0xE78BB265)
#define OVP_Algorithm_MatrixAverage_InputParameterId_AveragingMethod OpenViBE::CIdentifier(0xE63CD759, 0xB6ECF6B7)
#define OVP_Algorithm_MatrixAverage_OutputParameterId_AveragedMatrix OpenViBE::CIdentifier(0x03CE5AE5, 0xBD9031E0)
#define OVP_Algorithm_MatrixAverage_InputTriggerId_Reset OpenViBE::CIdentifier(0x670EC053, 0xADFE3F5C)
#define OVP_Algorithm_MatrixAverage_InputTriggerId_FeedMatrix OpenViBE::CIdentifier(0x50B6EE87, 0xDC42E660)
#define OVP_Algorithm_MatrixAverage_InputTriggerId_ForceAverage OpenViBE::CIdentifier(0xBF597839, 0xCD6039F0)
#define OVP_Algorithm_MatrixAverage_OutputTriggerId_AveragePerformed OpenViBE::CIdentifier(0x2BFF029B, 0xD932A613)
#define OVP_Algorithm_StimulationBasedEpoching_InputParameterId_InputSignal OpenViBE::CIdentifier(0x0ED5C92B, 0xE16BEF25)
#define OVP_Algorithm_StimulationBasedEpoching_InputParameterId_OffsetSampleCount OpenViBE::CIdentifier(0x7646CE65, 0xE128FC4E)
#define OVP_Algorithm_StimulationBasedEpoching_OutputParameterId_OutputSignal OpenViBE::CIdentifier(0x00D331A2, 0xC13DF043)
#define OVP_Algorithm_StimulationBasedEpoching_InputTriggerId_Reset OpenViBE::CIdentifier(0x6BA44128, 0x418CF901)
#define OVP_Algorithm_StimulationBasedEpoching_InputTriggerId_PerformEpoching OpenViBE::CIdentifier(0xD05579B5, 0x2649A4B2)
#define OVP_Algorithm_StimulationBasedEpoching_OutputTriggerId_EpochingDone OpenViBE::CIdentifier(0x755BC3FE, 0x24F7B50F)
#define OVP_Algorithm_StimulationBasedEpoching_InputParameterId_EndTimeChunkToProcess OpenViBE::CIdentifier(0x8B552604, 0x10CD1F94)
#define OVP_Algorithm_MatrixVariance_InputParameterId_Matrix OpenViBE::CIdentifier(0x781F51CA, 0xE6E3B0B8)
#define OVP_Algorithm_MatrixVariance_InputParameterId_MatrixCount OpenViBE::CIdentifier(0xE5103C63, 0x08D825E0)
#define OVP_Algorithm_MatrixVariance_InputParameterId_AveragingMethod OpenViBE::CIdentifier(0x043A1BC4, 0x925D3CD6)
#define OVP_Algorithm_MatrixVariance_InputParameterId_SignificanceLevel OpenViBE::CIdentifier(0x1E1065B2, 0x2CA32013)
#define OVP_Algorithm_MatrixVariance_OutputParameterId_AveragedMatrix OpenViBE::CIdentifier(0x5CF66A73, 0xF5BBF0BF)
#define OVP_Algorithm_MatrixVariance_OutputParameterId_Variance OpenViBE::CIdentifier(0x1BD67420, 0x587600E6)
#define OVP_Algorithm_MatrixVariance_OutputParameterId_ConfidenceBound OpenViBE::CIdentifier(0x1E1065B2, 0x2CA32013)
#define OVP_Algorithm_MatrixVariance_InputTriggerId_Reset OpenViBE::CIdentifier(0xD5C5EF91, 0xE1B1C4F4)
#define OVP_Algorithm_MatrixVariance_InputTriggerId_FeedMatrix OpenViBE::CIdentifier(0xEBAEB213, 0xDD4735A0)
#define OVP_Algorithm_MatrixVariance_InputTriggerId_ForceAverage OpenViBE::CIdentifier(0x344A52F5, 0x489DB439)
#define OVP_Algorithm_MatrixVariance_OutputTriggerId_AveragePerformed OpenViBE::CIdentifier(0x2F9ECA0B, 0x8D3CA7BD)
#define OVP_Algorithm_ARBurgMethod_InputParameterId_Matrix OpenViBE::CIdentifier(0x36A69669, 0x3651271D)
#define OVP_Algorithm_ARBurgMethod_OutputParameterId_Matrix OpenViBE::CIdentifier(0x55EF8C81, 0x178A51B2)
#define OVP_Algorithm_ARBurgMethod_InputParameterId_UInteger OpenViBE::CIdentifier(0x33139BC1, 0x03D30D3B)
#define OVP_Algorithm_ARBurgMethod_InputTriggerId_Initialize OpenViBE::CIdentifier(0xC27B06C6, 0xB8EB5F8D)
#define OVP_Algorithm_ARBurgMethod_InputTriggerId_Process OpenViBE::CIdentifier(0xBEEBBE84, 0x4F14F8F8)
#define OVP_Algorithm_ARBurgMethod_OutputTriggerId_ProcessDone OpenViBE::CIdentifier(0xA5AAD435, 0x9EC3DB80)
#define OVP_Algorithm_MagnitudeSquaredCoherence_InputParameterId_SegLength OpenViBE::CIdentifier(0xA4826743, 0x0FA27C06)
#define OVP_Algorithm_MagnitudeSquaredCoherence_InputParameterId_Overlap OpenViBE::CIdentifier(0x527F8AEC, 0xA25F2EAB)
#define OVP_Algorithm_MagnitudeSquaredCoherence_InputParameterId_Window OpenViBE::CIdentifier(0x0EA349EE, 0xB9DC95D0)
#define OVP_Algorithm_MagnitudeSquaredCoherence_InputParameterId_Nfft OpenViBE::CIdentifier(0x7726C677, 0xE266C5A2)
#define OVP_Algorithm_MagnitudeSquaredCoherence_OutputParameterId_OutputMatrixSpectrum OpenViBE::CIdentifier(0x331326BA, 0xA94CFC8A)
#define OVP_Algorithm_MagnitudeSquaredCoherence_OutputParameterId_FreqVector OpenViBE::CIdentifier(0xD9FAA21C, 0x67D7C451)
#define OVP_Algorithm_HilbertTransform_InputParameterId_Matrix OpenViBE::CIdentifier(0xC117CE9A, 0x3FFCB156)
#define OVP_Algorithm_HilbertTransform_OutputParameterId_HilbertMatrix OpenViBE::CIdentifier(0xDAE13CB8, 0xEFF82E69)
#define OVP_Algorithm_HilbertTransform_OutputParameterId_EnvelopeMatrix OpenViBE::CIdentifier(0x9D0A023A, 0x7690C48E)
#define OVP_Algorithm_HilbertTransform_OutputParameterId_PhaseMatrix OpenViBE::CIdentifier(0x495B55E2, 0x8CAAC08E)
#define OVP_Algorithm_HilbertTransform_InputTriggerId_Initialize OpenViBE::CIdentifier(0xE4B3CB4A, 0xF0121A20)
#define OVP_Algorithm_HilbertTransform_InputTriggerId_Process OpenViBE::CIdentifier(0xC3DC087D, 0x4AAFC1F0)
#define OVP_Algorithm_HilbertTransform_OutputTriggerId_ProcessDone OpenViBE::CIdentifier(0xB0B2A2DD, 0x73529B46)
#define OVP_TypeId_Connectivity_Metric OpenViBE::CIdentifier(0x9188339d, 0x5da83a84)
#define OV_TypeId_ConnectivityMeasure_WindowMethod OpenViBE::CIdentifier(0x8815bfa7, 0x557b102f)
#define OV_AttributeId_Box_FlagIsUnstable OpenViBE::CIdentifier(0x666FFFFF, 0x666FFFFF)
@@ -0,0 +1,167 @@
#include "box-algorithms/basic/ovpCBoxAlgorithmMatrixTranspose.h"
#include "box-algorithms/basic/ovpCBoxAlgorithmDifferentialIntegral.h"
#include "box-algorithms/connectivity/CBoxAlgorithmConnectivityMeasure.hpp"
#include "box-algorithms/basic/ovpCBoxAlgorithmHilbert.h"
#include "algorithms/basic/ovpCHilbertTransform.h"
#include "box-algorithms/ovpCBoxAlgorithmQuadraticForm.h"
#include "box-algorithms/filters/ovpCBoxAlgorithmXDAWNSpatialFilterTrainer.h"
#include "box-algorithms/basic/ovpCBoxAlgorithmIFFTbox.h"
#include "algorithms/basic/ovpCAlgorithmARBurgMethod.h"
#include "box-algorithms/basic/ovpCBoxAlgorithmARCoefficients.h"
#include "algorithms/basic/ovpCMatrixVariance.h"
#include "box-algorithms/basic/ovpCBoxAlgorithmEpochVariance.h"
#include "box-algorithms/basic/ovpCBoxAlgorithmERSPAverage.h"
//#include "box-algorithms/basic/ovpCBoxAlgorithmNull.h"
#include "box-algorithms/ovpCBoxAlgorithmEOG_Denoising.h"
#include "box-algorithms/ovpCBoxAlgorithmEOG_Denoising_Calibration.h"
#include "box-algorithms/ovpCBoxAlgorithmDiscreteWaveletTransform.h"
#include "box-algorithms/ovpCBoxAlgorithmInverse_DWT.h"
#include "box-algorithms/CBoxAlgorithmMatrix3dTo2d.hpp"
namespace OpenViBE {
namespace Plugins {
namespace SignalProcessing {
OVP_Declare_Begin()
//*********** Boxes ***********
OVP_Declare_New(CBoxAlgorithmDifferentialIntegralDesc)
OVP_Declare_New(CBoxAlgorithmMatrixTransposeDesc)
//OVP_Declare_New(CBoxAlgorithmNullDesc)
OVP_Declare_New(CBoxAlgorithmERSPAverageDesc)
OVP_Declare_New(CBoxAlgorithmQuadraticFormDesc)
OVP_Declare_New(CEpochVarianceDesc);
OVP_Declare_New(CBoxAlgorithmMatrix3dTo2dDesc)
#if defined TARGET_HAS_ThirdPartyEIGEN
OVP_Declare_New(CBoxAlgorithmARCoefficientsDesc);
OVP_Declare_New(CAlgorithmARBurgMethodDesc);
OVP_Declare_New(CAlgorithmHilbertTransformDesc)
OVP_Declare_New(CBoxAlgorithmConnectivityMeasureDesc)
OVP_Declare_New(CBoxAlgorithmEOG_DenoisingDesc);
OVP_Declare_New(CBoxAlgorithmEOG_Denoising_CalibrationDesc);
OVP_Declare_New(CBoxAlgorithmHilbertDesc)
#endif
#if defined TARGET_HAS_ThirdPartyITPP
OVP_Declare_New(CBoxAlgorithmXDAWNSpatialFilterTrainerDesc)
OVP_Declare_New(CMatrixVarianceDesc)
OVP_Declare_New(CBoxAlgorithmIFFTboxDesc)
#endif // TARGET_HAS_ThirdPartyITPP
#if defined(TARGET_HAS_ThirdPartyFFTW3)
OVP_Declare_New(CBoxAlgorithmDiscreteWaveletTransformDesc)
OVP_Declare_New(CBoxAlgorithmInverse_DWTDesc)
//*********** Enumeration ***********
context.getTypeManager().registerEnumerationType(OVP_TypeId_WaveletType, "Wavelet type");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "haar", size_t(EWaveletType::Haar));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db1", size_t(EWaveletType::Db1));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db2", size_t(EWaveletType::Db2));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db3", size_t(EWaveletType::Db3));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db4", size_t(EWaveletType::Db4));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db5", size_t(EWaveletType::Db5));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db6", size_t(EWaveletType::Db6));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db7", size_t(EWaveletType::Db7));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db8", size_t(EWaveletType::Db8));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db9", size_t(EWaveletType::Db9));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db10", size_t(EWaveletType::Db10));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db11", size_t(EWaveletType::Db11));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db12", size_t(EWaveletType::Db12));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db13", size_t(EWaveletType::Db13));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db14", size_t(EWaveletType::Db14));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "db15", size_t(EWaveletType::Db15));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior1.1", size_t(EWaveletType::Bior11));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior1.3", size_t(EWaveletType::Bior13));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior1.5", size_t(EWaveletType::Bior15));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior2.2", size_t(EWaveletType::Bior22));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior2.4", size_t(EWaveletType::Bior24));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior2.6", size_t(EWaveletType::Bior26));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior2.8", size_t(EWaveletType::Bior28));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior3.1", size_t(EWaveletType::Bior31));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior3.3", size_t(EWaveletType::Bior33));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior3.5", size_t(EWaveletType::Bior35));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior3.7", size_t(EWaveletType::Bior37));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior3.9", size_t(EWaveletType::Bior39));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior4.4", size_t(EWaveletType::Bior44));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior5.5", size_t(EWaveletType::Bior55));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "bior6.8", size_t(EWaveletType::Bior68));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "coif1", size_t(EWaveletType::Coif1));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "coif2", size_t(EWaveletType::Coif2));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "coif3", size_t(EWaveletType::Coif3));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "coif4", size_t(EWaveletType::Coif4));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "coif5", size_t(EWaveletType::Coif5));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "sym1", size_t(EWaveletType::Sym1));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "sym2", size_t(EWaveletType::Sym2));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "sym3", size_t(EWaveletType::Sym3));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "sym4", size_t(EWaveletType::Sym4));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "sym5", size_t(EWaveletType::Sym5));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "sym6", size_t(EWaveletType::Sym6));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "sym7", size_t(EWaveletType::Sym7));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "sym8", size_t(EWaveletType::Sym8));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "sym9", size_t(EWaveletType::Sym9));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletType, "sym10", size_t(EWaveletType::Sym10));
context.getTypeManager().registerEnumerationType(OVP_TypeId_WaveletLevel, "Wavelet decomposition levels");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletLevel, "1", size_t(EWaveletLevel::L1));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletLevel, "2", size_t(EWaveletLevel::L2));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletLevel, "3", size_t(EWaveletLevel::L3));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletLevel, "4", size_t(EWaveletLevel::L4));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_WaveletLevel, "5", size_t(EWaveletLevel::L5));
#endif
context.getTypeManager().registerEnumerationEntry(OV_TypeId_BoxAlgorithmFlag, OV_AttributeId_Box_FlagIsUnstable.toString(),
OV_AttributeId_Box_FlagIsUnstable.id());
context.getTypeManager().registerEnumerationType(OVP_TypeId_EpochAverageMethod, "Epoch Average method");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_EpochAverageMethod, "Moving epoch average", size_t(EEpochAverageMethod::Moving));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_EpochAverageMethod, "Moving epoch average (Immediate)",
size_t(EEpochAverageMethod::MovingImmediate));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_EpochAverageMethod, "Epoch block average", size_t(EEpochAverageMethod::Block));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_EpochAverageMethod, "Cumulative average", size_t(EEpochAverageMethod::Cumulative));
context.getTypeManager().registerEnumerationType(OVP_TypeId_CropMethod, "Crop method");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_CropMethod, "Min", size_t(ECropMethod::Min));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_CropMethod, "Max", size_t(ECropMethod::Max));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_CropMethod, "Min/Max", size_t(ECropMethod::MinMax));
context.getTypeManager().registerEnumerationType(OVP_TypeId_SelectionMethod, "Selection method");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_SelectionMethod, "Select", size_t(ESelectionMethod::Select));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_SelectionMethod, "Reject", size_t(ESelectionMethod::Reject));
context.getTypeManager().registerEnumerationType(OVP_TypeId_MatchMethod, "Match method");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_MatchMethod, "Name", size_t(EMatchMethod::Name));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_MatchMethod, "Index", size_t(EMatchMethod::Index));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_MatchMethod, "Smart", size_t(EMatchMethod::Smart));
context.getTypeManager().registerEnumerationType(OVP_TypeId_DifferentialIntegralOperation, "Differential/Integral select");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_DifferentialIntegralOperation, "Differential",
size_t(EDifferentialIntegralOperation::Differential));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_DifferentialIntegralOperation, "Integral", size_t(EDifferentialIntegralOperation::Integral));
#if defined(TARGET_HAS_ThirdPartyEIGEN)
context.getTypeManager().registerEnumerationType(OV_TypeId_ConnectivityMeasure_WindowMethod, "Welch Window method");
context.getTypeManager().registerEnumerationEntry(OV_TypeId_ConnectivityMeasure_WindowMethod, "Hamming", size_t(EConnectWindowMethod::Hamming));
context.getTypeManager().registerEnumerationEntry(OV_TypeId_ConnectivityMeasure_WindowMethod, "Hann", size_t(EConnectWindowMethod::Hann));
context.getTypeManager().registerEnumerationEntry(OV_TypeId_ConnectivityMeasure_WindowMethod, "Welch", size_t(EConnectWindowMethod::Welch));
context.getTypeManager().registerEnumerationType(OVP_TypeId_Connectivity_Metric, "Metric method");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_Connectivity_Metric, toString(EConnectMetric::Coherence).c_str(), size_t(EConnectMetric::Coherence));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_Connectivity_Metric, toString(EConnectMetric::MagnitudeSquaredCoherence).c_str(), size_t(EConnectMetric::MagnitudeSquaredCoherence));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_Connectivity_Metric, toString(EConnectMetric::ImaginaryCoherence).c_str(), size_t(EConnectMetric::ImaginaryCoherence));
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_Connectivity_Metric, toString(EConnectMetric::AbsImaginaryCoherence).c_str(), size_t(EConnectMetric::AbsImaginaryCoherence));
#endif
OVP_Declare_End()
} // namespace SignalProcessing
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,5 @@
/ARFeatures.csv
/envelope_HilbertTransform.csv
/hilbert_HilbertTransform.csv
/phase_HilbertTransform.csv
/PhaseLockingValue.csv
@@ -0,0 +1,9 @@
Time (s);Channel 1
0.0000000000e+000;1.0000000000e+000
0.0000000000e+000;-1.3499924204e+000
0.0000000000e+000;7.1548116977e-001
0.0000000000e+000;-4.8823484546e-001
0.0000000000e+000;1.3773934216e-001
0.0000000000e+000;2.4122886822e-001
0.0000000000e+000;-4.1646742087e-001
0.0000000000e+000;1.6024997233e-001
1 Time (s) Channel 1
2 0.0000000000e+000 1.0000000000e+000
3 0.0000000000e+000 -1.3499924204e+000
4 0.0000000000e+000 7.1548116977e-001
5 0.0000000000e+000 -4.8823484546e-001
6 0.0000000000e+000 1.3773934216e-001
7 0.0000000000e+000 2.4122886822e-001
8 0.0000000000e+000 -4.1646742087e-001
9 0.0000000000e+000 1.6024997233e-001
@@ -0,0 +1,534 @@
<OpenViBE-Scenario>
<FormatVersion>2</FormatVersion>
<Creator>OpenViBE Designer</Creator>
<CreatorVersion>2.2.0</CreatorVersion>
<Settings></Settings>
<Inputs></Inputs>
<Outputs></Outputs>
<Boxes>
<Box>
<Identifier>(0x00000294, 0x00001670)</Identifier>
<Name>Channel Selector</Name>
<AlgorithmClassIdentifier>(0x361722e8, 0x311574e8)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Channel List</Name>
<DefaultValue>:</DefaultValue>
<Value>1</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x3bcf9e67, 0x0c23994d)</TypeIdentifier>
<Name>Action</Name>
<DefaultValue>Select</DefaultValue>
<Value>Select</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x666f25e9, 0x3e5738d6)</TypeIdentifier>
<Name>Channel Matching Method</Name>
<DefaultValue>Smart</DefaultValue>
<Value>Smart</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>112</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x277826e1, 0xa30a3bd0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x01dcd6d2)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00000344, 0x0000087c)</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.05</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>144</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>496</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x27b3ee3c, 0xc50527e6)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x018792f9)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000009d6, 0x0000143d)</Identifier>
<Name>AutoRegressive Coefficients</Name>
<AlgorithmClassIdentifier>(0xbaadc2f3, 0xb556a07b)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EEG Signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
<Name>AR Features</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Order</Name>
<DefaultValue>1</DefaultValue>
<Value>7</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>272</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x316b3b58, 0xa4f4e384)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x020a8c7a)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</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>
</Attributes>
</Box>
<Box>
<Identifier>(0x00002d56, 0x00007142)</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>208</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>496</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x568d148e, 0x650792b3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x01b260d4)</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00003560, 0x00001894)</Identifier>
<Name>Time based epoching</Name>
<AlgorithmClassIdentifier>(0x00777fa0, 0x5dc3f560)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Epoched signal 1</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Epoch 1 duration (in sec)</Name>
<DefaultValue>1</DefaultValue>
<Value>0.5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Epoch 1 intervals (in sec)</Name>
<DefaultValue>0.5</DefaultValue>
<Value>1.5</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>208</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xc5ff41e9, 0xccc59a01)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x05bd1106)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</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>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000566f, 0x00003f53)</Identifier>
<Name>GDF file reader</Name>
<AlgorithmClassIdentifier>(0x3eeb1264, 0x4edfbd9a)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x403488e7, 0x565d70b6)</TypeIdentifier>
<Name>Experiment information</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EEG stream</Name>
</Output>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue></DefaultValue>
<Value>${Path_Data}/scenarios/signals/real-hand-movements.gdf</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Samples per buffer</Name>
<DefaultValue>32</DefaultValue>
<Value>32</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Subtract physical minimum</Name>
<DefaultValue>False</DefaultValue>
<Value>False</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>31</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x78b8b69d, 0x27afe678)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x0144bf9d)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00007f36, 0x00004a0e)</Identifier>
<Name>CSV File Writer</Name>
<AlgorithmClassIdentifier>(0x2c9312f1, 0x2d6613e5)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
<Name>Streamed matrix</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue>record-[$core{date}-$core{time}].csv</DefaultValue>
<Value>${Player_ScenarioDirectory}/ARFeatures.csv</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Column separator</Name>
<DefaultValue>;</DefaultValue>
<Value>;</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Precision</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x229d1207, 0xebac8ab0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00eea8eb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x000007ef, 0x0000158b)</Identifier>
<Source>
<BoxIdentifier>(0x0000566f, 0x00003f53)</BoxIdentifier>
<BoxOutputIndex>1</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00000294, 0x00001670)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00001962, 0x00003ae4)</Identifier>
<Source>
<BoxIdentifier>(0x00003560, 0x00001894)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000009d6, 0x0000143d)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x0000207e, 0x00001215)</Identifier>
<Source>
<BoxIdentifier>(0x00000294, 0x00001670)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00003560, 0x00001894)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00005ea0, 0x00005581)</Identifier>
<Source>
<BoxIdentifier>(0x00000344, 0x0000087c)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00002d56, 0x00007142)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x0000631a, 0x000038c3)</Identifier>
<Source>
<BoxIdentifier>(0x000009d6, 0x0000143d)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00007f36, 0x00004a0e)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
</Links>
<Comments></Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":1,"identifier":"(0x000044f4, 0x00002c81)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":1},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00001207, 0x00004ca2)","index":0,"name":"Default tab","parentIdentifier":"(0x000044f4, 0x00002c81)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x00005c3e, 0x00002c50)","index":0,"name":"Empty","parentIdentifier":"(0x00001207, 0x00004ca2)","type":0}]</Data>
</Entry>
</Metadata>
</OpenViBE-Scenario>
@@ -0,0 +1,58 @@
PROJECT(test_thresholdDataComparison)
IF(WIN32)
ADD_DEFINITIONS(-DTARGET_OS_Windows)
ENDIF(WIN32)
IF(UNIX)
ADD_DEFINITIONS(-DTARGET_OS_Linux)
ENDIF(UNIX)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
ADD_DEFINITIONS(-DTARGET_ARCHITECTURE_i386)
INCLUDE_DIRECTORIES(../src)
ADD_EXECUTABLE(${PROJECT_NAME} test_thresholdDataComparison.cpp)
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${TESTS_FOLDER}) # Place project in folder unit-test (for some IDE)
INCLUDE("FindOpenViBE")
# Unfortunately we need to install the tests as any application to find .dll/.so files
# on both Windows and Linux.
OV_INSTALL_LAUNCH_SCRIPT(SCRIPT_PREFIX ${PROJECT_NAME} EXECUTABLE_NAME ${PROJECT_NAME})
INSTALL(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${DIST_BINDIR}
LIBRARY DESTINATION ${DIST_LIBDIR}
ARCHIVE DESTINATION ${DIST_LIBDIR})
PROJECT(test_eigen)
IF(WIN32)
ADD_DEFINITIONS(-DTARGET_OS_Windows)
ENDIF(WIN32)
IF(UNIX)
ADD_DEFINITIONS(-DTARGET_OS_Linux)
ENDIF(UNIX)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
ADD_DEFINITIONS(-DTARGET_ARCHITECTURE_i386)
INCLUDE_DIRECTORIES(../src)
ADD_EXECUTABLE(${PROJECT_NAME} test_eigen.cpp)
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${TESTS_FOLDER}) # Place project in folder unit-test (for some IDE)
INCLUDE("FindOpenViBE")
INCLUDE("FindOpenViBEModuleSystem")
INCLUDE("FindThirdPartyEigen")
IF(WIN32)
# Since cert, getting timeBeginPeriod() linker issues without this
TARGET_LINK_LIBRARIES(${PROJECT_NAME} winmm)
ENDIF(WIN32)
# Unfortunately we need to install the tests as any application to find .dll/.so files
# on both Windows and Linux.
OV_INSTALL_LAUNCH_SCRIPT(SCRIPT_PREFIX ${PROJECT_NAME} EXECUTABLE_NAME ${PROJECT_NAME})
INSTALL(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${DIST_BINDIR}
LIBRARY DESTINATION ${DIST_LIBDIR}
ARCHIVE DESTINATION ${DIST_LIBDIR})
@@ -0,0 +1,125 @@
# Basic Template Test for automatic run a scenario that produce a file to be compared to a reference file
# You need to set the name of the test according to name of scenario file and reference file
# Test Hilbert transform Box
SET(TEST_NAME "HilbertTransform")
SET(SCENARIO_TO_TEST "${TEST_NAME}.xml")
# These three tests are not yet working correctly...
# SET(SUBTEST1_NAME "hilbert")
# SET(SUBTEST2_NAME "phase")
# SET(SUBTEST3_NAME "envelope")
IF(WIN32)
SET(EXT cmd)
SET(OS_FLAGS "--no-pause")
ELSE()
SET(EXT sh)
SET(OS_FLAGS "")
ENDIF()
ADD_TEST(clean_${TEST_NAME} "${CMAKE_COMMAND}" "-E" "remove" "-f" "${SUBTEST1_NAME}.csv" "${SUBTEST2_NAME}.csv" "${SUBTEST3_NAME}.csv")
ADD_TEST(run_${TEST_NAME} "$ENV{OV_BINARY_PATH}/openvibe-designer.${EXT}" ${OS_FLAGS} "--no-session-management" "--invisible" "--play" ${SCENARIO_TO_TEST})
# ADD_TEST(compare_${SUBTEST1_NAME} "$ENV{OV_BINARY_PATH}/test_thresholdDataComparison.${EXT}" ${OS_FLAGS} "${SUBTEST1_NAME}_${TEST_NAME}.csv" "${SUBTEST1_NAME}_${TEST_NAME}.ref.csv" 0.1)
# ADD_TEST(compare_${SUBTEST2_NAME} "$ENV{OV_BINARY_PATH}/test_thresholdDataComparison.${EXT}" ${OS_FLAGS} "${SUBTEST2_NAME}_${TEST_NAME}.csv" "${SUBTEST2_NAME}_${TEST_NAME}.ref.csv" 0.1)
# ADD_TEST(compare_${SUBTEST3_NAME} "$ENV{OV_BINARY_PATH}/test_thresholdDataComparison.${EXT}" ${OS_FLAGS} "${SUBTEST3_NAME}_${TEST_NAME}.csv" "${SUBTEST3_NAME}_${TEST_NAME}.ref.csv" 0.1)
## add some properties that help to debug
SET_TESTS_PROPERTIES(run_${TEST_NAME} PROPERTIES ATTACHED_FILES_ON_FAIL ${OV_LOGFILE})
#SET_TESTS_PROPERTIES(compare_${SUBTEST1_NAME} PROPERTIES ATTACHED_FILES_ON_FAIL "${SUBTEST1_NAME}.csv")
#SET_TESTS_PROPERTIES(compare_${SUBTEST2_NAME} PROPERTIES ATTACHED_FILES_ON_FAIL "${SUBTEST2_NAME}.csv")
#SET_TESTS_PROPERTIES(compare_${SUBTEST3_NAME} PROPERTIES ATTACHED_FILES_ON_FAIL "${SUBTEST3_NAME}.csv")
#SET_TESTS_PROPERTIES(compare_${SUBTEST1_NAME} compare_${SUBTEST2_NAME} compare_${SUBTEST3_NAME} PROPERTIES DEPENDS run_${TEST_NAME})
#SET_TESTS_PROPERTIES(run_${TEST_NAME} PROPERTIES DEPENDS clean_${TEST_NAME})
# Test Connectivity Box - PLV algorithm
#SET(TEST_NAME "PhaseLockingValue")
#SET(SCENARIO_TO_TEST "${TEST_NAME}.xml")
#ADD_TEST(clean_${TEST_NAME} "${CMAKE_COMMAND}" "-E" "remove" "-f" "${TEST_NAME}.csv")
#ADD_TEST(run_${TEST_NAME} "$ENV{OV_BINARY_PATH}/openvibe-designer.${EXT}" ${OS_FLAGS} "--no-session-management" "--invisible" "--play" ${SCENARIO_TO_TEST})
#ADD_TEST(compare_${TEST_NAME} "$ENV{OV_BINARY_PATH}/test_thresholdDataComparison.${EXT}" ${OS_FLAGS} "${TEST_NAME}.csv" "${TEST_NAME}.ref.csv" 0.1)
## add some properties that help to debug
#SET_TESTS_PROPERTIES(run_${TEST_NAME} PROPERTIES ATTACHED_FILES_ON_FAIL ${OV_LOGFILE})
#SET_TESTS_PROPERTIES(compare_${TEST_NAME} PROPERTIES ATTACHED_FILES_ON_FAIL "${TEST_NAME}.csv")
#SET_TESTS_PROPERTIES(compare_${TEST_NAME} PROPERTIES DEPENDS run_${TEST_NAME})
#SET_TESTS_PROPERTIES(run_${TEST_NAME} PROPERTIES DEPENDS clean_${TEST_NAME})
# Test Auto-Regressive model
SET(TEST_NAME "ARFeatures")
SET(SCENARIO_TO_TEST "${TEST_NAME}.xml")
ADD_TEST(clean_${TEST_NAME} "${CMAKE_COMMAND}" "-E" "remove" "-f" "${TEST_NAME}.csv")
ADD_TEST(run_${TEST_NAME} "$ENV{OV_BINARY_PATH}/openvibe-designer.${EXT}" ${OS_FLAGS} "--no-session-management" "--invisible" "--play" ${SCENARIO_TO_TEST})
ADD_TEST(compare_${TEST_NAME} "$ENV{OV_BINARY_PATH}/test_thresholdDataComparison.${EXT}" ${OS_FLAGS} "${TEST_NAME}.csv" "${TEST_NAME}.ref.csv" 0.1)
## add some properties that help to debug
SET_TESTS_PROPERTIES(run_${TEST_NAME} PROPERTIES ATTACHED_FILES_ON_FAIL ${OV_LOGFILE})
SET_TESTS_PROPERTIES(compare_${TEST_NAME} PROPERTIES ATTACHED_FILES_ON_FAIL "${TEST_NAME}.csv")
SET_TESTS_PROPERTIES(compare_${TEST_NAME} PROPERTIES DEPENDS run_${TEST_NAME})
SET_TESTS_PROPERTIES(run_${TEST_NAME} PROPERTIES DEPENDS clean_${TEST_NAME})
### Do not enable the commented out sikuli tests unless you
### or your lab commits to keep them passing in the long term.
#FIND_PROGRAM(SIKULI NAMES sikuli-ide)
#IF(SIKULI)
# IF(UNIX)
# ADD_TEST(sikuli_crop "${SIKULI}" -t testCrop.UNIX.sikuli)
# ENDIF(UNIX)
#ENDIF(SIKULI)
# Test Regularized CSP
# @TODO There is a problem with this box
#SET(TEST_SCENARIOS "RegularizedCSP_None" "RegularizedCSP_Tikhonov" "RegularizedCSP_Shrink" "RegularizedCSP_Both")
#SET(TEST_SHRINKS 0.0 0.0 0.9 0.5)
#SET(TEST_TIKHONOVS 0.0 0.9 0.0 0.5)
#SET(TEST_THRESHOLDS 40 70 70 70)
#
#FOREACH(TEST_NAME ${TEST_SCENARIOS})
#
# ADD_TEST(clean_${TEST_NAME} "${CMAKE_COMMAND}" "-E" "remove" "-f" ${OV_LOGFILE} output-${TEST_NAME}.txt)
#
# LIST(GET TEST_SHRINKS 0 PARAM_SHRINK)
# LIST(GET TEST_TIKHONOVS 0 PARAM_TIKHONOV)
# LIST(GET TEST_THRESHOLDS 0 COMPARE_THRESHOLD)
#
# ADD_TEST(run_${TEST_NAME}_Train "$ENV{OV_BINARY_PATH}/openvibe-designer.${EXT}" ${OS_FLAGS} "--invisible" "--no-session-management" --define Plugin_Classification_RandomizeKFoldTestData true --random-seed 123 --define TEST_TIKHONOV ${PARAM_TIKHONOV} --define TEST_SHRINK ${PARAM_SHRINK} --define TEST_FILTER output-${TEST_NAME}.txt "--play-fast" "test-regularizedcsp-train.xml")
#
# ADD_TEST(run_${TEST_NAME}_Test "$ENV{OV_BINARY_PATH}/openvibe-designer.${EXT}" ${OS_FLAGS} "--invisible" "--no-session-management" --define Plugin_Classification_RandomizeKFoldTestData true --random-seed 456 --define TEST_FILTER output-${TEST_NAME}.txt "--play-fast" "test-regularizedcsp-test.xml")
#
# ADD_TEST(compare_${TEST_NAME} "$ENV{OV_BINARY_PATH}/test_accuracy.${EXT}" "${OS_FLAGS}" "${OV_LOGFILE}" ${COMPARE_THRESHOLD})
#
# # It would be better to clean last, but we can't do this as it will delete the
# # output we wish to include, and we can't prevent clean from running if a prev. test fails
# # We need the clean to be sure that the comparator stage is not getting data from a previous run.
# SET_TESTS_PROPERTIES(run_${TEST_NAME}_Train PROPERTIES DEPENDS clean_${TEST_NAME})
# SET_TESTS_PROPERTIES(run_${TEST_NAME}_Train PROPERTIES ATTACHED_FILES_ON_FAIL ${OV_LOGFILE})
#
# SET_TESTS_PROPERTIES(run_${TEST_NAME}_Test PROPERTIES DEPENDS run_${TEST_NAME}_Train)
# SET_TESTS_PROPERTIES(run_${TEST_NAME}_Test PROPERTIES ATTACHED_FILES_ON_FAIL ${OV_LOGFILE})
#
# SET_TESTS_PROPERTIES(compare_${TEST_NAME} PROPERTIES DEPENDS run_${TEST_NAME}_Test})
# SET_TESTS_PROPERTIES(compare_${TEST_NAME} PROPERTIES ATTACHED_FILES_ON_FAIL ${OV_LOGFILE})
#
# LIST(REMOVE_AT TEST_SHRINKS 0)
# LIST(REMOVE_AT TEST_TIKHONOVS 0)
# LIST(REMOVE_AT TEST_THRESHOLDS 0)
#
#ENDFOREACH(TEST_NAME)
@@ -0,0 +1,746 @@
<OpenViBE-Scenario>
<FormatVersion>1</FormatVersion>
<Creator>openvibe</Creator>
<CreatorVersion>2.0</CreatorVersion>
<Boxes>
<Box>
<Identifier>(0x00000073, 0x00000fa8)</Identifier>
<Name>Hilbert Transform</Name>
<AlgorithmClassIdentifier>(0x7878a47f, 0x9a8fe349)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input Signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Hilbert Transform</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Envelope</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Phase</Name>
</Output>
</Outputs>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>272</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xceff4a87, 0xffc5ce08)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>121</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00000f8a, 0x00002000)</Identifier>
<Name>CSV File Writer</Name>
<AlgorithmClassIdentifier>(0x2c9312f1, 0x2d6613e5)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Streamed matrix</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue>record-[$core{date}-$core{time}].csv</DefaultValue>
<Value>${Player_ScenarioDirectory}/phase_HilbertTransform.csv</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Column separator</Name>
<DefaultValue>;</DefaultValue>
<Value>;</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Precision</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>384</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>496</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x229d1207, 0xebac8ab0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>120</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00002df6, 0x0000453f)</Identifier>
<Name>CSV File Writer</Name>
<AlgorithmClassIdentifier>(0x2c9312f1, 0x2d6613e5)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Streamed matrix</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue>record-[$core{date}-$core{time}].csv</DefaultValue>
<Value>${Player_ScenarioDirectory}/envelope_HilbertTransform.csv</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Column separator</Name>
<DefaultValue>;</DefaultValue>
<Value>;</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Precision</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>384</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x229d1207, 0xebac8ab0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>120</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00003ea7, 0x0000084b)</Identifier>
<Name>Channel Selector</Name>
<AlgorithmClassIdentifier>(0x361722e8, 0x311574e8)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Channel List</Name>
<DefaultValue>:</DefaultValue>
<Value>1</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x3bcf9e67, 0x0c23994d)</TypeIdentifier>
<Name>Action</Name>
<DefaultValue>Select</DefaultValue>
<Value>Select</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x666f25e9, 0x3e5738d6)</TypeIdentifier>
<Name>Channel Matching Method</Name>
<DefaultValue>Smart</DefaultValue>
<Value>Smart</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>176</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x277826e1, 0xa30a3bd0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>134</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000468f, 0x00007d08)</Identifier>
<Name>GDF file reader</Name>
<AlgorithmClassIdentifier>(0x3eeb1264, 0x4edfbd9a)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x403488e7, 0x565d70b6)</TypeIdentifier>
<Name>Experiment information</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EEG stream</Name>
</Output>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue></DefaultValue>
<Value>${Path_Data}/scenarios/signals/real-hand-movements.gdf</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Samples per buffer</Name>
<DefaultValue>32</DefaultValue>
<Value>32</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Subtract physical minimum</Name>
<DefaultValue>False</DefaultValue>
<Value>False</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>64</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x78b8b69d, 0x27afe678)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>123</Value>
</Attribute>
<Attribute>
<Identifier>(0xc67a01dc, 0x28ce06c1)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000680a, 0x00004283)</Identifier>
<Name>CSV File Writer</Name>
<AlgorithmClassIdentifier>(0x2c9312f1, 0x2d6613e5)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Streamed matrix</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue>record-[$core{date}-$core{time}].csv</DefaultValue>
<Value>${Player_ScenarioDirectory}/hilbert_HilbertTransform.csv</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Column separator</Name>
<DefaultValue>;</DefaultValue>
<Value>;</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Precision</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>384</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>128</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x229d1207, 0xebac8ab0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>120</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000076e2, 0x00003b96)</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.05</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>176</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>496</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x27b3ee3c, 0xc50527e6)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>130</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00007e4d, 0x00004f1e)</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>240</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>496</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x568d148e, 0x650792b3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>133</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>(0x00000c00, 0x0000520c)</Identifier>
<Source>
<BoxIdentifier>(0x000076e2, 0x00003b96)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00007e4d, 0x00004f1e)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>195</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>496</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>223</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>496</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00000d5d, 0x000071c1)</Identifier>
<Source>
<BoxIdentifier>(0x0000468f, 0x00007d08)</BoxIdentifier>
<BoxOutputIndex>1</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00003ea7, 0x0000084b)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>83</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>152</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>304</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00002664, 0x0000778d)</Identifier>
<Source>
<BoxIdentifier>(0x00003ea7, 0x0000084b)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00000073, 0x00000fa8)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>201</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>248</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>304</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00004492, 0x00004a72)</Identifier>
<Source>
<BoxIdentifier>(0x00000073, 0x00000fa8)</BoxIdentifier>
<BoxOutputIndex>2</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00000f8a, 0x00002000)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>297</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>319</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>360</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>496</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00004a3f, 0x00004a44)</Identifier>
<Source>
<BoxIdentifier>(0x00000073, 0x00000fa8)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0000680a, 0x00004283)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>297</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>289</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>360</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>128</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00006420, 0x000075f2)</Identifier>
<Source>
<BoxIdentifier>(0x00000073, 0x00000fa8)</BoxIdentifier>
<BoxOutputIndex>1</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00002df6, 0x0000453f)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>297</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>360</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>304</Value>
</Attribute>
</Attributes>
</Link>
</Links>
<Comments></Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":1,"identifier":"(0x000036c7, 0x000030bb)","index":0,"name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":1},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00002384, 0x00003bec)","index":0,"name":"Default tab","parentIdentifier":"(0x000036c7, 0x000030bb)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x00002860, 0x00006a2e)","index":0,"name":"Empty","parentIdentifier":"(0x00002384, 0x00003bec)","type":0}]</Data>
</Entry>
</Metadata>
</OpenViBE-Scenario>
@@ -0,0 +1,452 @@
<OpenViBE-Scenario>
<FormatVersion>1</FormatVersion>
<Creator>openvibe</Creator>
<CreatorVersion>2.0</CreatorVersion>
<Boxes>
<Box>
<Identifier>(0x00000ed4, 0x0000252d)</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.05</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>144</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>496</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x27b3ee3c, 0xc50527e6)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>130</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000035a8, 0x0000075a)</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>208</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>496</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x568d148e, 0x650792b3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>133</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00003c03, 0x00004b5b)</Identifier>
<Name>Connectivity Measure</Name>
<AlgorithmClassIdentifier>(0x8e3a1aef, 0x7cacd368)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EEG Signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Connectivity measure</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0xdc90c94b, 0xf82ad423)</TypeIdentifier>
<Name>Method</Name>
<DefaultValue>Single-Trial Phase Locking Value</DefaultValue>
<Value>Single-Trial Phase Locking Value</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Pairs of channels</Name>
<DefaultValue>1-2</DefaultValue>
<Value>1-2</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x666f25e9, 0x3e5738d6)</TypeIdentifier>
<Name>Channel Matching Method</Name>
<DefaultValue>Smart</DefaultValue>
<Value>Smart</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>240</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>51</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xadf93ac3, 0x3981887a)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>168</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00004fc8, 0x00002927)</Identifier>
<Name>CSV File Writer</Name>
<AlgorithmClassIdentifier>(0x2c9312f1, 0x2d6613e5)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Streamed matrix</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue>record-[$core{date}-$core{time}].csv</DefaultValue>
<Value>/home/ac-inria/work/git/openvibe/plugins/processing/signal-processing/test/PhaseLockingValue.csv</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Column separator</Name>
<DefaultValue>;</DefaultValue>
<Value>;</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Precision</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>352</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x229d1207, 0xebac8ab0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>120</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000057ba, 0x0000351c)</Identifier>
<Name>GDF file reader</Name>
<AlgorithmClassIdentifier>(0x3eeb1264, 0x4edfbd9a)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x403488e7, 0x565d70b6)</TypeIdentifier>
<Name>Experiment information</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>EEG stream</Name>
</Output>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue></DefaultValue>
<Value>${Path_Data}/scenarios/signals/real-hand-movements.gdf</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Samples per buffer</Name>
<DefaultValue>32</DefaultValue>
<Value>32</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Subtract physical minimum</Name>
<DefaultValue>False</DefaultValue>
<Value>False</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>112</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x78b8b69d, 0x27afe678)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>123</Value>
</Attribute>
<Attribute>
<Identifier>(0xc67a01dc, 0x28ce06c1)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x00000a72, 0x00004189)</Identifier>
<Source>
<BoxIdentifier>(0x00003c03, 0x00004b5b)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00004fc8, 0x00002927)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>272</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>328</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>304</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00004c1a, 0x00003616)</Identifier>
<Source>
<BoxIdentifier>(0x00000ed4, 0x0000252d)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000035a8, 0x0000075a)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>163</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>496</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>191</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>496</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00004c86, 0x000076d6)</Identifier>
<Source>
<BoxIdentifier>(0x000057ba, 0x0000351c)</BoxIdentifier>
<BoxOutputIndex>1</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00003c03, 0x00004b5b)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>131</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>210</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>304</Value>
</Attribute>
</Attributes>
</Link>
</Links>
<Comments></Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":1,"identifier":"(0x000030b1, 0x0000307f)","index":0,"name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":1},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x000031f8, 0x00006493)","index":0,"name":"Default tab","parentIdentifier":"(0x000030b1, 0x0000307f)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x00003a9b, 0x0000762a)","index":0,"name":"Empty","parentIdentifier":"(0x000031f8, 0x00006493)","type":0}]</Data>
</Entry>
</Metadata>
</OpenViBE-Scenario>
@@ -0,0 +1,513 @@
Time(s);Time signal;Sampling Rate
0;652.872498;512
0.001953;652.19104;
0.003906;657.344299;
0.005859;664.963318;
0.007812;656.915527;
0.009766;655.371399;
0.011719;657.471802;
0.013672;658.235474;
0.015625;664.248108;
0.017578;674.710754;
0.019531;682.88208;
0.021484;682.181335;
0.023438;681.047119;
0.025391;682.49353;
0.027344;677.410706;
0.029297;675.140198;
0.03125;675.338806;
0.033203;676.888733;
0.035156;673.527466;
0.037109;674.533203;
0.039062;682.795044;
0.041016;679.734009;
0.042969;672.321289;
0.044922;680.832581;
0.046875;683.851868;
0.048828;678.300659;
0.050781;673.874207;
0.052734;675.565979;
0.054688;679.920593;
0.056641;678.692017;
0.058594;682.402466;
0.060547;689.995422;
0.0625;691.424316;
0.064453;691.300476;
0.066406;690.543274;
0.068359;682.410767;
0.070312;683.489014;
0.072266;688.083862;
0.074219;686.011292;
0.076172;688.92627;
0.078125;689.18457;
0.080078;681.577759;
0.082031;679.421631;
0.083984;687.520264;
0.085938;686.596436;
0.087891;682.279297;
0.089844;681.752197;
0.091797;684.096069;
0.09375;684.885559;
0.095703;689.826965;
0.097656;697.967834;
0.099609;697.75354;
0.101562;694.126099;
0.103516;695.985474;
0.105469;701.214233;
0.107422;699.951416;
0.109375;700.415161;
0.111328;704.063416;
0.113281;707.642029;
0.115234;705.747131;
0.117188;710.762512;
0.119141;716.723022;
0.121094;713.036072;
0.123047;702.467102;
0.125;700.49176;
0.126953;695.235779;
0.128906;693.326416;
0.130859;692.633789;
0.132812;697.07019;
0.134766;694.940063;
0.136719;698.449158;
0.138672;699.3078;
0.140625;706.356812;
0.142578;701.057068;
0.144531;693.636353;
0.146484;694.458801;
0.148438;693.858765;
0.150391;695.506165;
0.152344;702.778503;
0.154297;706.466675;
0.15625;709.081482;
0.158203;715.37915;
0.160156;717.837708;
0.162109;715.575256;
0.164062;717.56012;
0.166016;718.96344;
0.167969;713.475647;
0.169922;709.944824;
0.171875;714.215515;
0.173828;710.718018;
0.175781;705.600464;
0.177734;705.312073;
0.179688;702.755615;
0.181641;702.19281;
0.183594;701.789795;
0.185547;702.207581;
0.1875;699.532349;
0.189453;702.352722;
0.191406;712.023438;
0.193359;709.434143;
0.195312;698.961304;
0.197266;710.270508;
0.199219;720.372314;
0.201172;719.837769;
0.203125;712.992432;
0.205078;715.572998;
0.207031;706.798157;
0.208984;700.738403;
0.210938;703.149475;
0.212891;707.28595;
0.214844;710.143005;
0.216797;713.367981;
0.21875;703.395081;
0.220703;697.204773;
0.222656;691.441772;
0.224609;693.796814;
0.226562;691.035156;
0.228516;684.115173;
0.230469;682.491638;
0.232422;683.610413;
0.234375;682.61145;
0.236328;681.345642;
0.238281;686.227783;
0.240234;689.364868;
0.242188;689.361145;
0.244141;692.280884;
0.246094;698.92334;
0.248047;695.322327;
0.25;695.928284;
0.251953;699.760132;
0.253906;699.456238;
0.255859;699.879272;
0.257812;699.874207;
0.259766;700.439453;
0.261719;694.306824;
0.263672;696.337463;
0.265625;702.438293;
0.267578;696.01825;
0.269531;695.467224;
0.271484;701.61731;
0.273438;706.004578;
0.275391;702.445618;
0.277344;698.014709;
0.279297;703.722656;
0.28125;704.028381;
0.283203;698.89209;
0.285156;697.758301;
0.287109;691.328186;
0.289062;689.18396;
0.291016;697.245422;
0.292969;702.900818;
0.294922;702.067627;
0.296875;709.707397;
0.298828;724.752747;
0.300781;727.492371;
0.302734;710.738708;
0.304688;711.624146;
0.306641;712.542297;
0.308594;710.156311;
0.310547;706.551819;
0.3125;711.784912;
0.314453;713.494324;
0.316406;709.538818;
0.318359;708.983276;
0.320312;705.139343;
0.322266;706.221191;
0.324219;723.512329;
0.326172;726.747314;
0.328125;722.273499;
0.330078;712.007629;
0.332031;698.131775;
0.333984;687.199036;
0.335938;680.049622;
0.337891;693.525757;
0.339844;702.886414;
0.341797;699.834473;
0.34375;693.821655;
0.345703;686.726807;
0.347656;678.107727;
0.349609;675.852051;
0.351562;678.505066;
0.353516;674.982178;
0.355469;670.409058;
0.357422;674.498962;
0.359375;671.203613;
0.361328;664.660706;
0.363281;663.051025;
0.365234;660.903992;
0.367188;655.797607;
0.369141;652.106873;
0.371094;655.176392;
0.373047;657.233154;
0.375;652.580444;
0.376953;654.626465;
0.378906;653.463684;
0.380859;652.688171;
0.382812;654.226074;
0.384766;660.364136;
0.386719;663.49823;
0.388672;664.639709;
0.390625;666.496582;
0.392578;668.061584;
0.394531;665.931091;
0.396484;672.945435;
0.398438;676.477295;
0.400391;674.486816;
0.402344;669.779358;
0.404297;670.058228;
0.40625;668.061401;
0.408203;667.655762;
0.410156;669.969543;
0.412109;675.294861;
0.414062;679.096069;
0.416016;679.948181;
0.417969;680.92511;
0.419922;680.642456;
0.421875;678.643799;
0.423828;679.495728;
0.425781;692.933594;
0.427734;699.030334;
0.429688;690.31427;
0.431641;690.498047;
0.433594;699.729614;
0.435547;697.159485;
0.4375;703.307434;
0.439453;699.613892;
0.441406;690.088806;
0.443359;687.119934;
0.445312;689.565552;
0.447266;685.292297;
0.449219;684.258606;
0.451172;683.349365;
0.453125;689.053528;
0.455078;686.921387;
0.457031;693.03595;
0.458984;694.41925;
0.460938;688.307007;
0.462891;687.354919;
0.464844;697.202942;
0.466797;695.407776;
0.46875;688.515198;
0.470703;690.002502;
0.472656;694.465637;
0.474609;691.710022;
0.476562;692.325073;
0.478516;699.274048;
0.480469;698.283752;
0.482422;694.051758;
0.484375;689.861389;
0.486328;681.534729;
0.488281;674.988953;
0.490234;670.250732;
0.492188;674.838623;
0.494141;671.986084;
0.496094;668.887207;
0.498047;665.776855;
0.5;669.816101;
0.501953;665.739136;
0.503906;659.799988;
0.505859;658.712219;
0.507812;656.40741;
0.509766;663.074097;
0.511719;679.350891;
0.513672;688.225586;
0.515625;687.647949;
0.517578;686.26709;
0.519531;669.194885;
0.521484;654.585266;
0.523438;649.088074;
0.525391;655.951904;
0.527344;661.500305;
0.529297;668.91925;
0.53125;670.090271;
0.533203;665.431274;
0.535156;657.512634;
0.537109;663.687683;
0.539062;673.667297;
0.541016;674.910461;
0.542969;674.081299;
0.544922;683.475586;
0.546875;678.487244;
0.548828;673.630066;
0.550781;681.811768;
0.552734;689.033569;
0.554688;686.033325;
0.556641;689.177368;
0.558594;697.444214;
0.560547;699.110291;
0.5625;693.176025;
0.564453;693.561462;
0.566406;686.230286;
0.568359;682.510132;
0.570312;675.486328;
0.572266;686.663818;
0.574219;684.883179;
0.576172;680.887878;
0.578125;687.027466;
0.580078;688.646545;
0.582031;678.338684;
0.583984;678.789551;
0.585938;681.331421;
0.587891;678.272583;
0.589844;678.695068;
0.591797;681.442383;
0.59375;688.903564;
0.595703;682.258362;
0.597656;679.974487;
0.599609;676.200806;
0.601562;671.150391;
0.603516;669.976929;
0.605469;672.728027;
0.607422;667.427673;
0.609375;659.651062;
0.611328;663.85553;
0.613281;668.456421;
0.615234;667.265991;
0.617188;671.815918;
0.619141;674.233948;
0.621094;678.567688;
0.623047;675.043823;
0.625;676.161865;
0.626953;675.914001;
0.628906;673.483826;
0.630859;674.821716;
0.632812;681.872803;
0.634766;678.102356;
0.636719;679.971741;
0.638672;675.819397;
0.640625;672.045898;
0.642578;669.679443;
0.644531;672.906067;
0.646484;671.237793;
0.648438;670.16571;
0.650391;670.394592;
0.652344;678.347229;
0.654297;681.720337;
0.65625;680.292969;
0.658203;682.934631;
0.660156;679.593079;
0.662109;676.283142;
0.664062;677.345581;
0.666016;679.686707;
0.667969;676.852173;
0.669922;676.642395;
0.671875;680.181885;
0.673828;682.402588;
0.675781;680.5802;
0.677734;681.406555;
0.679688;684.013855;
0.681641;683.778564;
0.683594;688.911316;
0.685547;692.84491;
0.6875;679.803955;
0.689453;668.471191;
0.691406;667.106995;
0.693359;668.250977;
0.695312;671.102417;
0.697266;679.14801;
0.699219;680.746338;
0.701172;669.396301;
0.703125;660.809753;
0.705078;664.460632;
0.707031;663.041809;
0.708984;664.592041;
0.710938;668.405273;
0.712891;665.529236;
0.714844;662.243225;
0.716797;658.81781;
0.71875;662.719116;
0.720703;659.927185;
0.722656;652.529053;
0.724609;658.648926;
0.726562;659.833252;
0.728516;658.903503;
0.730469;662.409668;
0.732422;667.693542;
0.734375;667.575745;
0.736328;670.942627;
0.738281;679.407349;
0.740234;679.977356;
0.742188;677.550415;
0.744141;673.245544;
0.746094;675.380981;
0.748047;673.00238;
0.75;675.703186;
0.751953;671.788635;
0.753906;665.445496;
0.755859;667.666626;
0.757812;677.88208;
0.759766;682.865051;
0.761719;678.304626;
0.763672;674.659851;
0.765625;672.701172;
0.767578;682.170105;
0.769531;679.32489;
0.771484;678.649231;
0.773438;681.970276;
0.775391;679.308411;
0.777344;679.949829;
0.779297;677.177856;
0.78125;664.491089;
0.783203;664.837341;
0.785156;672.92334;
0.787109;676.017578;
0.789062;673.882507;
0.791016;675.458923;
0.792969;681.763733;
0.794922;678.458313;
0.796875;674.974854;
0.798828;673.329163;
0.800781;670.157288;
0.802734;668.537476;
0.804688;671.010498;
0.806641;666.601807;
0.808594;661.410767;
0.810547;665.279053;
0.8125;666.392334;
0.814453;662.331848;
0.816406;653.432068;
0.818359;655.363708;
0.820312;658.257629;
0.822266;648.640381;
0.824219;640.110779;
0.826172;631.641174;
0.828125;620.967773;
0.830078;615.977905;
0.832031;612.672424;
0.833984;609.831665;
0.835938;601.372314;
0.837891;595.485596;
0.839844;589.810425;
0.841797;585.12323;
0.84375;579.608276;
0.845703;582.709656;
0.847656;580.177246;
0.849609;575.39917;
0.851562;574.131409;
0.853516;575.011475;
0.855469;570.915222;
0.857422;568.846863;
0.859375;564.63678;
0.861328;556.245422;
0.863281;554.104431;
0.865234;563.10321;
0.867188;563.672424;
0.869141;561.671387;
0.871094;568.506287;
0.873047;575.075989;
0.875;574.860413;
0.876953;578.382874;
0.878906;582.723694;
0.880859;584.168152;
0.882812;583.604431;
0.884766;585.24054;
0.886719;590.444824;
0.888672;596.945923;
0.890625;600.204895;
0.892578;598.114441;
0.894531;602.153442;
0.896484;609.802002;
0.898438;609.36322;
0.900391;619.398682;
0.902344;619.511292;
0.904297;614.911499;
0.90625;611.925903;
0.908203;606.397217;
0.910156;605.44281;
0.912109;616.871704;
0.914062;629.886719;
0.916016;635.963623;
0.917969;641.252197;
0.919922;644.724121;
0.921875;636.687134;
0.923828;642.013428;
0.925781;645.872314;
0.927734;640.324097;
0.929688;646.744385;
0.931641;650.049866;
0.933594;648.357483;
0.935547;645.675232;
0.9375;650.957153;
0.939453;655.659302;
0.941406;652.33313;
0.943359;648.758362;
0.945312;651.058838;
0.947266;655.05365;
0.949219;653.973022;
0.951172;656.587891;
0.953125;655.664368;
0.955078;655.298584;
0.957031;663.684753;
0.958984;665.117493;
0.960938;659.85498;
0.962891;654.232422;
0.964844;659.254333;
0.966797;660.307983;
0.96875;654.838379;
0.970703;661.702332;
0.972656;668.319153;
0.974609;667.06842;
0.976562;669.422668;
0.978516;669.911194;
0.980469;664.245239;
0.982422;655.385925;
0.984375;659.391052;
0.986328;663.098572;
0.988281;651.90271;
0.990234;647.950806;
0.992188;657.725586;
0.994141;661.506836;
0.996094;665.620667;
0.998047;672.148987;
1 Time(s) Time signal Sampling Rate
2 0 652.872498 512
3 0.001953 652.19104
4 0.003906 657.344299
5 0.005859 664.963318
6 0.007812 656.915527
7 0.009766 655.371399
8 0.011719 657.471802
9 0.013672 658.235474
10 0.015625 664.248108
11 0.017578 674.710754
12 0.019531 682.88208
13 0.021484 682.181335
14 0.023438 681.047119
15 0.025391 682.49353
16 0.027344 677.410706
17 0.029297 675.140198
18 0.03125 675.338806
19 0.033203 676.888733
20 0.035156 673.527466
21 0.037109 674.533203
22 0.039062 682.795044
23 0.041016 679.734009
24 0.042969 672.321289
25 0.044922 680.832581
26 0.046875 683.851868
27 0.048828 678.300659
28 0.050781 673.874207
29 0.052734 675.565979
30 0.054688 679.920593
31 0.056641 678.692017
32 0.058594 682.402466
33 0.060547 689.995422
34 0.0625 691.424316
35 0.064453 691.300476
36 0.066406 690.543274
37 0.068359 682.410767
38 0.070312 683.489014
39 0.072266 688.083862
40 0.074219 686.011292
41 0.076172 688.92627
42 0.078125 689.18457
43 0.080078 681.577759
44 0.082031 679.421631
45 0.083984 687.520264
46 0.085938 686.596436
47 0.087891 682.279297
48 0.089844 681.752197
49 0.091797 684.096069
50 0.09375 684.885559
51 0.095703 689.826965
52 0.097656 697.967834
53 0.099609 697.75354
54 0.101562 694.126099
55 0.103516 695.985474
56 0.105469 701.214233
57 0.107422 699.951416
58 0.109375 700.415161
59 0.111328 704.063416
60 0.113281 707.642029
61 0.115234 705.747131
62 0.117188 710.762512
63 0.119141 716.723022
64 0.121094 713.036072
65 0.123047 702.467102
66 0.125 700.49176
67 0.126953 695.235779
68 0.128906 693.326416
69 0.130859 692.633789
70 0.132812 697.07019
71 0.134766 694.940063
72 0.136719 698.449158
73 0.138672 699.3078
74 0.140625 706.356812
75 0.142578 701.057068
76 0.144531 693.636353
77 0.146484 694.458801
78 0.148438 693.858765
79 0.150391 695.506165
80 0.152344 702.778503
81 0.154297 706.466675
82 0.15625 709.081482
83 0.158203 715.37915
84 0.160156 717.837708
85 0.162109 715.575256
86 0.164062 717.56012
87 0.166016 718.96344
88 0.167969 713.475647
89 0.169922 709.944824
90 0.171875 714.215515
91 0.173828 710.718018
92 0.175781 705.600464
93 0.177734 705.312073
94 0.179688 702.755615
95 0.181641 702.19281
96 0.183594 701.789795
97 0.185547 702.207581
98 0.1875 699.532349
99 0.189453 702.352722
100 0.191406 712.023438
101 0.193359 709.434143
102 0.195312 698.961304
103 0.197266 710.270508
104 0.199219 720.372314
105 0.201172 719.837769
106 0.203125 712.992432
107 0.205078 715.572998
108 0.207031 706.798157
109 0.208984 700.738403
110 0.210938 703.149475
111 0.212891 707.28595
112 0.214844 710.143005
113 0.216797 713.367981
114 0.21875 703.395081
115 0.220703 697.204773
116 0.222656 691.441772
117 0.224609 693.796814
118 0.226562 691.035156
119 0.228516 684.115173
120 0.230469 682.491638
121 0.232422 683.610413
122 0.234375 682.61145
123 0.236328 681.345642
124 0.238281 686.227783
125 0.240234 689.364868
126 0.242188 689.361145
127 0.244141 692.280884
128 0.246094 698.92334
129 0.248047 695.322327
130 0.25 695.928284
131 0.251953 699.760132
132 0.253906 699.456238
133 0.255859 699.879272
134 0.257812 699.874207
135 0.259766 700.439453
136 0.261719 694.306824
137 0.263672 696.337463
138 0.265625 702.438293
139 0.267578 696.01825
140 0.269531 695.467224
141 0.271484 701.61731
142 0.273438 706.004578
143 0.275391 702.445618
144 0.277344 698.014709
145 0.279297 703.722656
146 0.28125 704.028381
147 0.283203 698.89209
148 0.285156 697.758301
149 0.287109 691.328186
150 0.289062 689.18396
151 0.291016 697.245422
152 0.292969 702.900818
153 0.294922 702.067627
154 0.296875 709.707397
155 0.298828 724.752747
156 0.300781 727.492371
157 0.302734 710.738708
158 0.304688 711.624146
159 0.306641 712.542297
160 0.308594 710.156311
161 0.310547 706.551819
162 0.3125 711.784912
163 0.314453 713.494324
164 0.316406 709.538818
165 0.318359 708.983276
166 0.320312 705.139343
167 0.322266 706.221191
168 0.324219 723.512329
169 0.326172 726.747314
170 0.328125 722.273499
171 0.330078 712.007629
172 0.332031 698.131775
173 0.333984 687.199036
174 0.335938 680.049622
175 0.337891 693.525757
176 0.339844 702.886414
177 0.341797 699.834473
178 0.34375 693.821655
179 0.345703 686.726807
180 0.347656 678.107727
181 0.349609 675.852051
182 0.351562 678.505066
183 0.353516 674.982178
184 0.355469 670.409058
185 0.357422 674.498962
186 0.359375 671.203613
187 0.361328 664.660706
188 0.363281 663.051025
189 0.365234 660.903992
190 0.367188 655.797607
191 0.369141 652.106873
192 0.371094 655.176392
193 0.373047 657.233154
194 0.375 652.580444
195 0.376953 654.626465
196 0.378906 653.463684
197 0.380859 652.688171
198 0.382812 654.226074
199 0.384766 660.364136
200 0.386719 663.49823
201 0.388672 664.639709
202 0.390625 666.496582
203 0.392578 668.061584
204 0.394531 665.931091
205 0.396484 672.945435
206 0.398438 676.477295
207 0.400391 674.486816
208 0.402344 669.779358
209 0.404297 670.058228
210 0.40625 668.061401
211 0.408203 667.655762
212 0.410156 669.969543
213 0.412109 675.294861
214 0.414062 679.096069
215 0.416016 679.948181
216 0.417969 680.92511
217 0.419922 680.642456
218 0.421875 678.643799
219 0.423828 679.495728
220 0.425781 692.933594
221 0.427734 699.030334
222 0.429688 690.31427
223 0.431641 690.498047
224 0.433594 699.729614
225 0.435547 697.159485
226 0.4375 703.307434
227 0.439453 699.613892
228 0.441406 690.088806
229 0.443359 687.119934
230 0.445312 689.565552
231 0.447266 685.292297
232 0.449219 684.258606
233 0.451172 683.349365
234 0.453125 689.053528
235 0.455078 686.921387
236 0.457031 693.03595
237 0.458984 694.41925
238 0.460938 688.307007
239 0.462891 687.354919
240 0.464844 697.202942
241 0.466797 695.407776
242 0.46875 688.515198
243 0.470703 690.002502
244 0.472656 694.465637
245 0.474609 691.710022
246 0.476562 692.325073
247 0.478516 699.274048
248 0.480469 698.283752
249 0.482422 694.051758
250 0.484375 689.861389
251 0.486328 681.534729
252 0.488281 674.988953
253 0.490234 670.250732
254 0.492188 674.838623
255 0.494141 671.986084
256 0.496094 668.887207
257 0.498047 665.776855
258 0.5 669.816101
259 0.501953 665.739136
260 0.503906 659.799988
261 0.505859 658.712219
262 0.507812 656.40741
263 0.509766 663.074097
264 0.511719 679.350891
265 0.513672 688.225586
266 0.515625 687.647949
267 0.517578 686.26709
268 0.519531 669.194885
269 0.521484 654.585266
270 0.523438 649.088074
271 0.525391 655.951904
272 0.527344 661.500305
273 0.529297 668.91925
274 0.53125 670.090271
275 0.533203 665.431274
276 0.535156 657.512634
277 0.537109 663.687683
278 0.539062 673.667297
279 0.541016 674.910461
280 0.542969 674.081299
281 0.544922 683.475586
282 0.546875 678.487244
283 0.548828 673.630066
284 0.550781 681.811768
285 0.552734 689.033569
286 0.554688 686.033325
287 0.556641 689.177368
288 0.558594 697.444214
289 0.560547 699.110291
290 0.5625 693.176025
291 0.564453 693.561462
292 0.566406 686.230286
293 0.568359 682.510132
294 0.570312 675.486328
295 0.572266 686.663818
296 0.574219 684.883179
297 0.576172 680.887878
298 0.578125 687.027466
299 0.580078 688.646545
300 0.582031 678.338684
301 0.583984 678.789551
302 0.585938 681.331421
303 0.587891 678.272583
304 0.589844 678.695068
305 0.591797 681.442383
306 0.59375 688.903564
307 0.595703 682.258362
308 0.597656 679.974487
309 0.599609 676.200806
310 0.601562 671.150391
311 0.603516 669.976929
312 0.605469 672.728027
313 0.607422 667.427673
314 0.609375 659.651062
315 0.611328 663.85553
316 0.613281 668.456421
317 0.615234 667.265991
318 0.617188 671.815918
319 0.619141 674.233948
320 0.621094 678.567688
321 0.623047 675.043823
322 0.625 676.161865
323 0.626953 675.914001
324 0.628906 673.483826
325 0.630859 674.821716
326 0.632812 681.872803
327 0.634766 678.102356
328 0.636719 679.971741
329 0.638672 675.819397
330 0.640625 672.045898
331 0.642578 669.679443
332 0.644531 672.906067
333 0.646484 671.237793
334 0.648438 670.16571
335 0.650391 670.394592
336 0.652344 678.347229
337 0.654297 681.720337
338 0.65625 680.292969
339 0.658203 682.934631
340 0.660156 679.593079
341 0.662109 676.283142
342 0.664062 677.345581
343 0.666016 679.686707
344 0.667969 676.852173
345 0.669922 676.642395
346 0.671875 680.181885
347 0.673828 682.402588
348 0.675781 680.5802
349 0.677734 681.406555
350 0.679688 684.013855
351 0.681641 683.778564
352 0.683594 688.911316
353 0.685547 692.84491
354 0.6875 679.803955
355 0.689453 668.471191
356 0.691406 667.106995
357 0.693359 668.250977
358 0.695312 671.102417
359 0.697266 679.14801
360 0.699219 680.746338
361 0.701172 669.396301
362 0.703125 660.809753
363 0.705078 664.460632
364 0.707031 663.041809
365 0.708984 664.592041
366 0.710938 668.405273
367 0.712891 665.529236
368 0.714844 662.243225
369 0.716797 658.81781
370 0.71875 662.719116
371 0.720703 659.927185
372 0.722656 652.529053
373 0.724609 658.648926
374 0.726562 659.833252
375 0.728516 658.903503
376 0.730469 662.409668
377 0.732422 667.693542
378 0.734375 667.575745
379 0.736328 670.942627
380 0.738281 679.407349
381 0.740234 679.977356
382 0.742188 677.550415
383 0.744141 673.245544
384 0.746094 675.380981
385 0.748047 673.00238
386 0.75 675.703186
387 0.751953 671.788635
388 0.753906 665.445496
389 0.755859 667.666626
390 0.757812 677.88208
391 0.759766 682.865051
392 0.761719 678.304626
393 0.763672 674.659851
394 0.765625 672.701172
395 0.767578 682.170105
396 0.769531 679.32489
397 0.771484 678.649231
398 0.773438 681.970276
399 0.775391 679.308411
400 0.777344 679.949829
401 0.779297 677.177856
402 0.78125 664.491089
403 0.783203 664.837341
404 0.785156 672.92334
405 0.787109 676.017578
406 0.789062 673.882507
407 0.791016 675.458923
408 0.792969 681.763733
409 0.794922 678.458313
410 0.796875 674.974854
411 0.798828 673.329163
412 0.800781 670.157288
413 0.802734 668.537476
414 0.804688 671.010498
415 0.806641 666.601807
416 0.808594 661.410767
417 0.810547 665.279053
418 0.8125 666.392334
419 0.814453 662.331848
420 0.816406 653.432068
421 0.818359 655.363708
422 0.820312 658.257629
423 0.822266 648.640381
424 0.824219 640.110779
425 0.826172 631.641174
426 0.828125 620.967773
427 0.830078 615.977905
428 0.832031 612.672424
429 0.833984 609.831665
430 0.835938 601.372314
431 0.837891 595.485596
432 0.839844 589.810425
433 0.841797 585.12323
434 0.84375 579.608276
435 0.845703 582.709656
436 0.847656 580.177246
437 0.849609 575.39917
438 0.851562 574.131409
439 0.853516 575.011475
440 0.855469 570.915222
441 0.857422 568.846863
442 0.859375 564.63678
443 0.861328 556.245422
444 0.863281 554.104431
445 0.865234 563.10321
446 0.867188 563.672424
447 0.869141 561.671387
448 0.871094 568.506287
449 0.873047 575.075989
450 0.875 574.860413
451 0.876953 578.382874
452 0.878906 582.723694
453 0.880859 584.168152
454 0.882812 583.604431
455 0.884766 585.24054
456 0.886719 590.444824
457 0.888672 596.945923
458 0.890625 600.204895
459 0.892578 598.114441
460 0.894531 602.153442
461 0.896484 609.802002
462 0.898438 609.36322
463 0.900391 619.398682
464 0.902344 619.511292
465 0.904297 614.911499
466 0.90625 611.925903
467 0.908203 606.397217
468 0.910156 605.44281
469 0.912109 616.871704
470 0.914062 629.886719
471 0.916016 635.963623
472 0.917969 641.252197
473 0.919922 644.724121
474 0.921875 636.687134
475 0.923828 642.013428
476 0.925781 645.872314
477 0.927734 640.324097
478 0.929688 646.744385
479 0.931641 650.049866
480 0.933594 648.357483
481 0.935547 645.675232
482 0.9375 650.957153
483 0.939453 655.659302
484 0.941406 652.33313
485 0.943359 648.758362
486 0.945312 651.058838
487 0.947266 655.05365
488 0.949219 653.973022
489 0.951172 656.587891
490 0.953125 655.664368
491 0.955078 655.298584
492 0.957031 663.684753
493 0.958984 665.117493
494 0.960938 659.85498
495 0.962891 654.232422
496 0.964844 659.254333
497 0.966797 660.307983
498 0.96875 654.838379
499 0.970703 661.702332
500 0.972656 668.319153
501 0.974609 667.06842
502 0.976562 669.422668
503 0.978516 669.911194
504 0.980469 664.245239
505 0.982422 655.385925
506 0.984375 659.391052
507 0.986328 663.098572
508 0.988281 651.90271
509 0.990234 647.950806
510 0.992188 657.725586
511 0.994141 661.506836
512 0.996094 665.620667
513 0.998047 672.148987
@@ -0,0 +1,513 @@
Time(s);Time signal;Sampling Rate
0;28.981428;512
0.001953;42.533489;
0.003906;47.134895;
0.005859;44.134022;
0.007812;38.354893;
0.009766;47.397827;
0.011719;48.880821;
0.013672;54.954945;
0.015625;60.355793;
0.017578;62.928974;
0.019531;55.618874;
0.021484;48.280991;
0.023438;46.291126;
0.025391;42.262794;
0.027344;38.17527;
0.029297;40.746456;
0.03125;41.668076;
0.033203;41.406368;
0.035156;39.970119;
0.037109;46.752495;
0.039062;44.760719;
0.041016;36.394112;
0.042969;41.215172;
0.044922;47.307755;
0.046875;38.753983;
0.048828;36.225052;
0.050781;38.588387;
0.052734;45.200058;
0.054688;44.333199;
0.056641;45.128956;
0.058594;49.382904;
0.060547;48.119011;
0.0625;41.630928;
0.064453;39.523262;
0.066406;33.259003;
0.068359;33.013283;
0.070312;39.875595;
0.072266;38.035378;
0.074219;36.587803;
0.076172;37.818752;
0.078125;31.631701;
0.080078;30.422977;
0.082031;38.480396;
0.083984;40.629364;
0.085938;34.120766;
0.087891;36.048504;
0.089844;39.391136;
0.091797;42.849953;
0.09375;44.074574;
0.095703;49.756237;
0.097656;46.069683;
0.099609;40.308197;
0.101562;39.125095;
0.103516;44.027828;
0.105469;41.049587;
0.107422;38.883476;
0.109375;39.536407;
0.111328;41.074429;
0.113281;36.20052;
0.115234;35.350887;
0.117188;35.939304;
0.119141;29.167889;
0.121094;16.342152;
0.123047;15.611171;
0.125;16.522947;
0.126953;17.34523;
0.128906;20.528202;
0.130859;25.429874;
0.132812;25.915106;
0.134766;26.125984;
0.136719;28.386164;
0.138672;28.47311;
0.140625;26.497925;
0.142578;16.317856;
0.144531;21.346485;
0.146484;24.65727;
0.148438;27.646727;
0.150391;32.761471;
0.152344;35.805737;
0.154297;32.539322;
0.15625;33.611752;
0.158203;31.097401;
0.160156;24.689838;
0.162109;20.777893;
0.164062;20.389;
0.166016;13.356441;
0.167969;8.95355;
0.169922;11.394264;
0.171875;10.890619;
0.173828;3.556692;
0.175781;6.071507;
0.177734;5.692522;
0.179688;6.904676;
0.181641;7.662472;
0.183594;9.668074;
0.185547;8.913792;
0.1875;11.29628;
0.189453;16.825912;
0.191406;15.69923;
0.193359;3.50449;
0.195312;11.271118;
0.197266;19.747177;
0.199219;12.399529;
0.201172;0.317879;
0.203125;-1.185936;
0.205078;-4.533199;
0.207031;-10.806082;
0.208984;-4.382572;
0.210938;0.186535;
0.212891;-0.43792;
0.214844;-2.473999;
0.216797;-11.413265;
0.21875;-18.581396;
0.220703;-16.212601;
0.222656;-13.448292;
0.224609;-9.205908;
0.226562;-14.506624;
0.228516;-10.37158;
0.230469;-5.72301;
0.232422;-1.522777;
0.234375;-1.331841;
0.236328;5.124865;
0.238281;8.421141;
0.240234;8.371645;
0.242188;8.058283;
0.244141;12.570879;
0.246094;8.602376;
0.248047;4.954411;
0.25;8.588469;
0.251953;6.878901;
0.253906;4.615979;
0.255859;3.792181;
0.257812;2.705427;
0.259766;-0.018886;
0.261719;-0.916425;
0.263672;6.931719;
0.265625;1.579266;
0.267578;-0.908307;
0.269531;5.263636;
0.271484;7.18133;
0.273438;1.801591;
0.275391;-3.627119;
0.277344;-0.388535;
0.279297;1.920504;
0.28125;-5.695572;
0.283203;-5.50612;
0.285156;-6.346354;
0.287109;-4.891275;
0.289062;4.177402;
0.291016;10.980614;
0.292969;7.157789;
0.294922;9.104038;
0.296875;14.05229;
0.298828;9.732626;
0.300781;-11.75359;
0.302734;-15.643543;
0.304688;-9.173111;
0.306641;-13.160055;
0.308594;-15.084597;
0.310547;-13.11615;
0.3125;-10.476772;
0.314453;-17.623634;
0.316406;-19.057949;
0.318359;-19.598183;
0.320312;-19.80681;
0.322266;-10.379875;
0.324219;-12.544847;
0.326172;-30.341568;
0.328125;-40.775764;
0.330078;-51.556679;
0.332031;-50.497475;
0.333984;-46.771263;
0.335938;-31.288355;
0.337891;-22.366844;
0.339844;-32.141407;
0.341797;-41.79649;
0.34375;-45.785782;
0.345703;-48.17548;
0.347656;-44.900505;
0.349609;-38.311737;
0.351562;-37.367516;
0.353516;-40.48661;
0.355469;-35.133568;
0.357422;-34.340218;
0.359375;-39.194832;
0.361328;-36.827976;
0.363281;-33.317528;
0.365234;-33.113281;
0.367188;-30.635273;
0.369141;-24.17881;
0.371094;-17.633192;
0.373047;-19.765018;
0.375;-16.504395;
0.376953;-12.284139;
0.378906;-11.065642;
0.380859;-6.38865;
0.382812;-0.581916;
0.384766;2.60288;
0.386719;1.224438;
0.388672;1.432685;
0.390625;2.356782;
0.392578;0.761961;
0.394531;3.498625;
0.396484;6.798368;
0.398438;0.842165;
0.400391;-3.030771;
0.402344;-2.93461;
0.404297;0.185988;
0.40625;0.083027;
0.408203;5.458356;
0.410156;8.497641;
0.412109;11.718945;
0.414062;8.389228;
0.416016;8.086557;
0.417969;6.000816;
0.419922;6.303391;
0.421875;6.098473;
0.423828;15.029612;
0.425781;16.495472;
0.427734;4.912612;
0.429688;-1.61569;
0.431641;7.710682;
0.433594;2.166585;
0.435547;-0.923061;
0.4375;-4.607342;
0.439453;-15.554612;
0.441406;-16.789404;
0.443359;-10.996284;
0.445312;-12.261397;
0.447266;-12.54049;
0.449219;-10.433497;
0.451172;-5.979844;
0.453125;-5.845973;
0.455078;-6.662134;
0.457031;-4.312693;
0.458984;-12.525909;
0.460938;-13.590454;
0.462891;-7.217076;
0.464844;-7.839628;
0.466797;-18.489054;
0.46875;-16.579653;
0.470703;-12.763157;
0.472656;-14.876695;
0.474609;-18.835867;
0.476562;-14.807649;
0.478516;-19.098183;
0.480469;-27.818377;
0.482422;-32.125648;
0.484375;-36.669605;
0.486328;-38.071255;
0.488281;-35.550213;
0.490234;-28.829878;
0.492188;-26.002678;
0.494141;-29.416748;
0.496094;-26.885658;
0.498047;-23.801216;
0.5;-20.967913;
0.501953;-26.569622;
0.503906;-19.780062;
0.505859;-16.524708;
0.507812;-7.422965;
0.509766;2.54991;
0.511719;5.376379;
0.513672;-8.515041;
0.515625;-16.082638;
0.517578;-30.128292;
0.519531;-36.401924;
0.521484;-29.043749;
0.523438;-13.4687;
0.525391;-4.369614;
0.527344;-0.444382;
0.529297;-1.65538;
0.53125;-6.541185;
0.533203;-10.313373;
0.535156;-2.848709;
0.537109;7.973608;
0.539062;7.621712;
0.541016;1.870394;
0.542969;6.26248;
0.544922;3.605522;
0.546875;-4.265451;
0.548828;2.832884;
0.550781;8.85619;
0.552734;2.569117;
0.554688;-0.294737;
0.556641;2.899448;
0.558594;-0.150892;
0.560547;-11.660822;
0.5625;-14.585499;
0.564453;-18.761417;
0.566406;-21.585199;
0.568359;-21.150761;
0.570312;-14.26481;
0.572266;-9.068488;
0.574219;-19.449661;
0.576172;-13.409808;
0.578125;-13.781729;
0.580078;-21.354212;
0.582031;-24.304899;
0.583984;-15.328108;
0.585938;-19.888649;
0.587891;-17.537773;
0.589844;-17.33357;
0.591797;-12.574266;
0.59375;-20.420633;
0.595703;-26.222927;
0.597656;-26.131714;
0.599609;-27.994799;
0.601562;-26.453037;
0.603516;-21.545654;
0.605469;-22.829664;
0.607422;-26.017242;
0.609375;-19.569988;
0.611328;-9.85809;
0.613281;-12.111512;
0.615234;-8.977678;
0.617188;-7.870711;
0.619141;-7.277023;
0.621094;-11.289501;
0.623047;-13.551187;
0.625;-12.348896;
0.626953;-14.252629;
0.628906;-13.97334;
0.630859;-8.721448;
0.632812;-12.712111;
0.634766;-16.439648;
0.636719;-17.070927;
0.638672;-21.466576;
0.640625;-19.258118;
0.642578;-16.029755;
0.644531;-13.608301;
0.646484;-15.584887;
0.648438;-12.004454;
0.650391;-8.278635;
0.652344;-4.681227;
0.654297;-12.171358;
0.65625;-12.097797;
0.658203;-15.762055;
0.660156;-18.922739;
0.662109;-17.793118;
0.664062;-14.515574;
0.666016;-17.074293;
0.667969;-17.741032;
0.669922;-14.970133;
0.671875;-13.756622;
0.673828;-17.34057;
0.675781;-18.527271;
0.677734;-17.425152;
0.679688;-18.953657;
0.681641;-20.677002;
0.683594;-20.682098;
0.685547;-33.717083;
0.6875;-42.506023;
0.689453;-36.189964;
0.691406;-28.62817;
0.693359;-25.185814;
0.695312;-21.073503;
0.697266;-22.982399;
0.699219;-33.934113;
0.701172;-39.937294;
0.703125;-31.177008;
0.705078;-26.676254;
0.707031;-26.831457;
0.708984;-22.519188;
0.710938;-25.49917;
0.712891;-28.394005;
0.714844;-28.193729;
0.716797;-24.496189;
0.71875;-21.937508;
0.720703;-27.340191;
0.722656;-19.784828;
0.724609;-13.77107;
0.726562;-15.72123;
0.728516;-12.220594;
0.730469;-8.430219;
0.732422;-8.944901;
0.734375;-10.647974;
0.736328;-6.189204;
0.738281;-10.279736;
0.740234;-17.289806;
0.742188;-22.094177;
0.744141;-21.220901;
0.746094;-21.12491;
0.748047;-22.512951;
0.75;-22.276014;
0.751953;-28.131899;
0.753906;-22.465721;
0.755859;-15.313993;
0.757812;-12.834;
0.759766;-23.297848;
0.761719;-27.161999;
0.763672;-28.631807;
0.765625;-22.023411;
0.767578;-23.817234;
0.769531;-31.017111;
0.771484;-28.612268;
0.773438;-32.742943;
0.775391;-36.427017;
0.777344;-37.741524;
0.779297;-45.891945;
0.78125;-43.447292;
0.783203;-31.983376;
0.785156;-31.239862;
0.787109;-36.147438;
0.789062;-38.734592;
0.791016;-36.35006;
0.792969;-41.969215;
0.794922;-49.916225;
0.796875;-50.889374;
0.798828;-53.51223;
0.800781;-54.729183;
0.802734;-54.039257;
0.804688;-56.449074;
0.806641;-62.772858;
0.808594;-58.819664;
0.810547;-59.186142;
0.8125;-65.028801;
0.814453;-72.406403;
0.816406;-71.404678;
0.818359;-68.241959;
0.820312;-77.704552;
0.822266;-85.671982;
0.824219;-85.317375;
0.826172;-87.464462;
0.828125;-82.750923;
0.830078;-78.093674;
0.832031;-74.263969;
0.833984;-75.343262;
0.835938;-73.315063;
0.837891;-69.068573;
0.839844;-63.963844;
0.841797;-59.865406;
0.84375;-51.162689;
0.845703;-45.742615;
0.847656;-46.08131;
0.849609;-41.196548;
0.851562;-34.949158;
0.853516;-32.976646;
0.855469;-31.026146;
0.857422;-26.757;
0.859375;-25.051701;
0.861328;-18.111897;
0.863281;-2.986727;
0.865234;4.847693;
0.867188;4.704545;
0.869141;13.324215;
0.871094;22.152439;
0.873047;22.501133;
0.875;24.208532;
0.876953;29.481262;
0.878906;30.783379;
0.880859;31.160419;
0.882812;33.827423;
0.884766;39.488701;
0.886719;44.619728;
0.888672;45.946201;
0.890625;43.886444;
0.892578;44.473694;
0.894531;52.25256;
0.896484;50.263031;
0.898438;51.813675;
0.900391;52.838123;
0.902344;43.295834;
0.904297;42.62706;
0.90625;42.661541;
0.908203;46.795666;
0.910156;58.684368;
0.912109;70.222183;
0.914062;70.008232;
0.916016;65.848495;
0.917969;63.420532;
0.919922;54.845673;
0.921875;52.216751;
0.923828;59.512566;
0.925781;51.527935;
0.927734;53.226189;
0.929688;56.845215;
0.931641;52.209785;
0.933594;48.73185;
0.935547;50.836895;
0.9375;54.601982;
0.939453;49.370476;
0.941406;44.658783;
0.943359;46.438972;
0.945312;50.582191;
0.947266;48.878654;
0.949219;47.730755;
0.951172;48.471378;
0.953125;45.506866;
0.955078;50.238186;
0.957031;50.173634;
0.958984;42.120224;
0.960938;37.473175;
0.962891;41.070911;
0.964844;45.978966;
0.966797;40.326958;
0.96875;43.826504;
0.970703;50.288212;
0.972656;45.363804;
0.974609;41.452553;
0.976562;40.376003;
0.978516;33.762836;
0.980469;28.353556;
0.982422;30.967506;
0.984375;39.286591;
0.986328;31.373966;
0.988281;29.597958;
0.990234;40.77985;
0.992188;48.465214;
0.994141;43.518177;
0.996094;47.480377;
0.998047;32.929554;
1 Time(s) Time signal Sampling Rate
2 0 28.981428 512
3 0.001953 42.533489
4 0.003906 47.134895
5 0.005859 44.134022
6 0.007812 38.354893
7 0.009766 47.397827
8 0.011719 48.880821
9 0.013672 54.954945
10 0.015625 60.355793
11 0.017578 62.928974
12 0.019531 55.618874
13 0.021484 48.280991
14 0.023438 46.291126
15 0.025391 42.262794
16 0.027344 38.17527
17 0.029297 40.746456
18 0.03125 41.668076
19 0.033203 41.406368
20 0.035156 39.970119
21 0.037109 46.752495
22 0.039062 44.760719
23 0.041016 36.394112
24 0.042969 41.215172
25 0.044922 47.307755
26 0.046875 38.753983
27 0.048828 36.225052
28 0.050781 38.588387
29 0.052734 45.200058
30 0.054688 44.333199
31 0.056641 45.128956
32 0.058594 49.382904
33 0.060547 48.119011
34 0.0625 41.630928
35 0.064453 39.523262
36 0.066406 33.259003
37 0.068359 33.013283
38 0.070312 39.875595
39 0.072266 38.035378
40 0.074219 36.587803
41 0.076172 37.818752
42 0.078125 31.631701
43 0.080078 30.422977
44 0.082031 38.480396
45 0.083984 40.629364
46 0.085938 34.120766
47 0.087891 36.048504
48 0.089844 39.391136
49 0.091797 42.849953
50 0.09375 44.074574
51 0.095703 49.756237
52 0.097656 46.069683
53 0.099609 40.308197
54 0.101562 39.125095
55 0.103516 44.027828
56 0.105469 41.049587
57 0.107422 38.883476
58 0.109375 39.536407
59 0.111328 41.074429
60 0.113281 36.20052
61 0.115234 35.350887
62 0.117188 35.939304
63 0.119141 29.167889
64 0.121094 16.342152
65 0.123047 15.611171
66 0.125 16.522947
67 0.126953 17.34523
68 0.128906 20.528202
69 0.130859 25.429874
70 0.132812 25.915106
71 0.134766 26.125984
72 0.136719 28.386164
73 0.138672 28.47311
74 0.140625 26.497925
75 0.142578 16.317856
76 0.144531 21.346485
77 0.146484 24.65727
78 0.148438 27.646727
79 0.150391 32.761471
80 0.152344 35.805737
81 0.154297 32.539322
82 0.15625 33.611752
83 0.158203 31.097401
84 0.160156 24.689838
85 0.162109 20.777893
86 0.164062 20.389
87 0.166016 13.356441
88 0.167969 8.95355
89 0.169922 11.394264
90 0.171875 10.890619
91 0.173828 3.556692
92 0.175781 6.071507
93 0.177734 5.692522
94 0.179688 6.904676
95 0.181641 7.662472
96 0.183594 9.668074
97 0.185547 8.913792
98 0.1875 11.29628
99 0.189453 16.825912
100 0.191406 15.69923
101 0.193359 3.50449
102 0.195312 11.271118
103 0.197266 19.747177
104 0.199219 12.399529
105 0.201172 0.317879
106 0.203125 -1.185936
107 0.205078 -4.533199
108 0.207031 -10.806082
109 0.208984 -4.382572
110 0.210938 0.186535
111 0.212891 -0.43792
112 0.214844 -2.473999
113 0.216797 -11.413265
114 0.21875 -18.581396
115 0.220703 -16.212601
116 0.222656 -13.448292
117 0.224609 -9.205908
118 0.226562 -14.506624
119 0.228516 -10.37158
120 0.230469 -5.72301
121 0.232422 -1.522777
122 0.234375 -1.331841
123 0.236328 5.124865
124 0.238281 8.421141
125 0.240234 8.371645
126 0.242188 8.058283
127 0.244141 12.570879
128 0.246094 8.602376
129 0.248047 4.954411
130 0.25 8.588469
131 0.251953 6.878901
132 0.253906 4.615979
133 0.255859 3.792181
134 0.257812 2.705427
135 0.259766 -0.018886
136 0.261719 -0.916425
137 0.263672 6.931719
138 0.265625 1.579266
139 0.267578 -0.908307
140 0.269531 5.263636
141 0.271484 7.18133
142 0.273438 1.801591
143 0.275391 -3.627119
144 0.277344 -0.388535
145 0.279297 1.920504
146 0.28125 -5.695572
147 0.283203 -5.50612
148 0.285156 -6.346354
149 0.287109 -4.891275
150 0.289062 4.177402
151 0.291016 10.980614
152 0.292969 7.157789
153 0.294922 9.104038
154 0.296875 14.05229
155 0.298828 9.732626
156 0.300781 -11.75359
157 0.302734 -15.643543
158 0.304688 -9.173111
159 0.306641 -13.160055
160 0.308594 -15.084597
161 0.310547 -13.11615
162 0.3125 -10.476772
163 0.314453 -17.623634
164 0.316406 -19.057949
165 0.318359 -19.598183
166 0.320312 -19.80681
167 0.322266 -10.379875
168 0.324219 -12.544847
169 0.326172 -30.341568
170 0.328125 -40.775764
171 0.330078 -51.556679
172 0.332031 -50.497475
173 0.333984 -46.771263
174 0.335938 -31.288355
175 0.337891 -22.366844
176 0.339844 -32.141407
177 0.341797 -41.79649
178 0.34375 -45.785782
179 0.345703 -48.17548
180 0.347656 -44.900505
181 0.349609 -38.311737
182 0.351562 -37.367516
183 0.353516 -40.48661
184 0.355469 -35.133568
185 0.357422 -34.340218
186 0.359375 -39.194832
187 0.361328 -36.827976
188 0.363281 -33.317528
189 0.365234 -33.113281
190 0.367188 -30.635273
191 0.369141 -24.17881
192 0.371094 -17.633192
193 0.373047 -19.765018
194 0.375 -16.504395
195 0.376953 -12.284139
196 0.378906 -11.065642
197 0.380859 -6.38865
198 0.382812 -0.581916
199 0.384766 2.60288
200 0.386719 1.224438
201 0.388672 1.432685
202 0.390625 2.356782
203 0.392578 0.761961
204 0.394531 3.498625
205 0.396484 6.798368
206 0.398438 0.842165
207 0.400391 -3.030771
208 0.402344 -2.93461
209 0.404297 0.185988
210 0.40625 0.083027
211 0.408203 5.458356
212 0.410156 8.497641
213 0.412109 11.718945
214 0.414062 8.389228
215 0.416016 8.086557
216 0.417969 6.000816
217 0.419922 6.303391
218 0.421875 6.098473
219 0.423828 15.029612
220 0.425781 16.495472
221 0.427734 4.912612
222 0.429688 -1.61569
223 0.431641 7.710682
224 0.433594 2.166585
225 0.435547 -0.923061
226 0.4375 -4.607342
227 0.439453 -15.554612
228 0.441406 -16.789404
229 0.443359 -10.996284
230 0.445312 -12.261397
231 0.447266 -12.54049
232 0.449219 -10.433497
233 0.451172 -5.979844
234 0.453125 -5.845973
235 0.455078 -6.662134
236 0.457031 -4.312693
237 0.458984 -12.525909
238 0.460938 -13.590454
239 0.462891 -7.217076
240 0.464844 -7.839628
241 0.466797 -18.489054
242 0.46875 -16.579653
243 0.470703 -12.763157
244 0.472656 -14.876695
245 0.474609 -18.835867
246 0.476562 -14.807649
247 0.478516 -19.098183
248 0.480469 -27.818377
249 0.482422 -32.125648
250 0.484375 -36.669605
251 0.486328 -38.071255
252 0.488281 -35.550213
253 0.490234 -28.829878
254 0.492188 -26.002678
255 0.494141 -29.416748
256 0.496094 -26.885658
257 0.498047 -23.801216
258 0.5 -20.967913
259 0.501953 -26.569622
260 0.503906 -19.780062
261 0.505859 -16.524708
262 0.507812 -7.422965
263 0.509766 2.54991
264 0.511719 5.376379
265 0.513672 -8.515041
266 0.515625 -16.082638
267 0.517578 -30.128292
268 0.519531 -36.401924
269 0.521484 -29.043749
270 0.523438 -13.4687
271 0.525391 -4.369614
272 0.527344 -0.444382
273 0.529297 -1.65538
274 0.53125 -6.541185
275 0.533203 -10.313373
276 0.535156 -2.848709
277 0.537109 7.973608
278 0.539062 7.621712
279 0.541016 1.870394
280 0.542969 6.26248
281 0.544922 3.605522
282 0.546875 -4.265451
283 0.548828 2.832884
284 0.550781 8.85619
285 0.552734 2.569117
286 0.554688 -0.294737
287 0.556641 2.899448
288 0.558594 -0.150892
289 0.560547 -11.660822
290 0.5625 -14.585499
291 0.564453 -18.761417
292 0.566406 -21.585199
293 0.568359 -21.150761
294 0.570312 -14.26481
295 0.572266 -9.068488
296 0.574219 -19.449661
297 0.576172 -13.409808
298 0.578125 -13.781729
299 0.580078 -21.354212
300 0.582031 -24.304899
301 0.583984 -15.328108
302 0.585938 -19.888649
303 0.587891 -17.537773
304 0.589844 -17.33357
305 0.591797 -12.574266
306 0.59375 -20.420633
307 0.595703 -26.222927
308 0.597656 -26.131714
309 0.599609 -27.994799
310 0.601562 -26.453037
311 0.603516 -21.545654
312 0.605469 -22.829664
313 0.607422 -26.017242
314 0.609375 -19.569988
315 0.611328 -9.85809
316 0.613281 -12.111512
317 0.615234 -8.977678
318 0.617188 -7.870711
319 0.619141 -7.277023
320 0.621094 -11.289501
321 0.623047 -13.551187
322 0.625 -12.348896
323 0.626953 -14.252629
324 0.628906 -13.97334
325 0.630859 -8.721448
326 0.632812 -12.712111
327 0.634766 -16.439648
328 0.636719 -17.070927
329 0.638672 -21.466576
330 0.640625 -19.258118
331 0.642578 -16.029755
332 0.644531 -13.608301
333 0.646484 -15.584887
334 0.648438 -12.004454
335 0.650391 -8.278635
336 0.652344 -4.681227
337 0.654297 -12.171358
338 0.65625 -12.097797
339 0.658203 -15.762055
340 0.660156 -18.922739
341 0.662109 -17.793118
342 0.664062 -14.515574
343 0.666016 -17.074293
344 0.667969 -17.741032
345 0.669922 -14.970133
346 0.671875 -13.756622
347 0.673828 -17.34057
348 0.675781 -18.527271
349 0.677734 -17.425152
350 0.679688 -18.953657
351 0.681641 -20.677002
352 0.683594 -20.682098
353 0.685547 -33.717083
354 0.6875 -42.506023
355 0.689453 -36.189964
356 0.691406 -28.62817
357 0.693359 -25.185814
358 0.695312 -21.073503
359 0.697266 -22.982399
360 0.699219 -33.934113
361 0.701172 -39.937294
362 0.703125 -31.177008
363 0.705078 -26.676254
364 0.707031 -26.831457
365 0.708984 -22.519188
366 0.710938 -25.49917
367 0.712891 -28.394005
368 0.714844 -28.193729
369 0.716797 -24.496189
370 0.71875 -21.937508
371 0.720703 -27.340191
372 0.722656 -19.784828
373 0.724609 -13.77107
374 0.726562 -15.72123
375 0.728516 -12.220594
376 0.730469 -8.430219
377 0.732422 -8.944901
378 0.734375 -10.647974
379 0.736328 -6.189204
380 0.738281 -10.279736
381 0.740234 -17.289806
382 0.742188 -22.094177
383 0.744141 -21.220901
384 0.746094 -21.12491
385 0.748047 -22.512951
386 0.75 -22.276014
387 0.751953 -28.131899
388 0.753906 -22.465721
389 0.755859 -15.313993
390 0.757812 -12.834
391 0.759766 -23.297848
392 0.761719 -27.161999
393 0.763672 -28.631807
394 0.765625 -22.023411
395 0.767578 -23.817234
396 0.769531 -31.017111
397 0.771484 -28.612268
398 0.773438 -32.742943
399 0.775391 -36.427017
400 0.777344 -37.741524
401 0.779297 -45.891945
402 0.78125 -43.447292
403 0.783203 -31.983376
404 0.785156 -31.239862
405 0.787109 -36.147438
406 0.789062 -38.734592
407 0.791016 -36.35006
408 0.792969 -41.969215
409 0.794922 -49.916225
410 0.796875 -50.889374
411 0.798828 -53.51223
412 0.800781 -54.729183
413 0.802734 -54.039257
414 0.804688 -56.449074
415 0.806641 -62.772858
416 0.808594 -58.819664
417 0.810547 -59.186142
418 0.8125 -65.028801
419 0.814453 -72.406403
420 0.816406 -71.404678
421 0.818359 -68.241959
422 0.820312 -77.704552
423 0.822266 -85.671982
424 0.824219 -85.317375
425 0.826172 -87.464462
426 0.828125 -82.750923
427 0.830078 -78.093674
428 0.832031 -74.263969
429 0.833984 -75.343262
430 0.835938 -73.315063
431 0.837891 -69.068573
432 0.839844 -63.963844
433 0.841797 -59.865406
434 0.84375 -51.162689
435 0.845703 -45.742615
436 0.847656 -46.08131
437 0.849609 -41.196548
438 0.851562 -34.949158
439 0.853516 -32.976646
440 0.855469 -31.026146
441 0.857422 -26.757
442 0.859375 -25.051701
443 0.861328 -18.111897
444 0.863281 -2.986727
445 0.865234 4.847693
446 0.867188 4.704545
447 0.869141 13.324215
448 0.871094 22.152439
449 0.873047 22.501133
450 0.875 24.208532
451 0.876953 29.481262
452 0.878906 30.783379
453 0.880859 31.160419
454 0.882812 33.827423
455 0.884766 39.488701
456 0.886719 44.619728
457 0.888672 45.946201
458 0.890625 43.886444
459 0.892578 44.473694
460 0.894531 52.25256
461 0.896484 50.263031
462 0.898438 51.813675
463 0.900391 52.838123
464 0.902344 43.295834
465 0.904297 42.62706
466 0.90625 42.661541
467 0.908203 46.795666
468 0.910156 58.684368
469 0.912109 70.222183
470 0.914062 70.008232
471 0.916016 65.848495
472 0.917969 63.420532
473 0.919922 54.845673
474 0.921875 52.216751
475 0.923828 59.512566
476 0.925781 51.527935
477 0.927734 53.226189
478 0.929688 56.845215
479 0.931641 52.209785
480 0.933594 48.73185
481 0.935547 50.836895
482 0.9375 54.601982
483 0.939453 49.370476
484 0.941406 44.658783
485 0.943359 46.438972
486 0.945312 50.582191
487 0.947266 48.878654
488 0.949219 47.730755
489 0.951172 48.471378
490 0.953125 45.506866
491 0.955078 50.238186
492 0.957031 50.173634
493 0.958984 42.120224
494 0.960938 37.473175
495 0.962891 41.070911
496 0.964844 45.978966
497 0.966797 40.326958
498 0.96875 43.826504
499 0.970703 50.288212
500 0.972656 45.363804
501 0.974609 41.452553
502 0.976562 40.376003
503 0.978516 33.762836
504 0.980469 28.353556
505 0.982422 30.967506
506 0.984375 39.286591
507 0.986328 31.373966
508 0.988281 29.597958
509 0.990234 40.77985
510 0.992188 48.465214
511 0.994141 43.518177
512 0.996094 47.480377
513 0.998047 32.929554
@@ -0,0 +1,513 @@
Time(s);Time signal;Sampling Rate
0;3.097188;512
0.001953;3.07633;
0.003906;3.069826;
0.005859;3.075173;
0.007812;3.083173;
0.009766;3.069207;
0.011719;3.067177;
0.013672;3.058007;
0.015625;3.050604;
0.017578;3.048189;
0.019531;3.060055;
0.021484;3.070759;
0.023438;3.07357;
0.025391;3.079629;
0.027344;3.085208;
0.029297;3.081203;
0.03125;3.079854;
0.033203;3.080383;
0.035156;3.082213;
0.037109;3.072226;
0.039062;3.07599;
0.041016;3.088025;
0.042969;3.080251;
0.044922;3.072052;
0.046875;3.084892;
0.048828;3.088162;
0.050781;3.084298;
0.052734;3.074636;
0.054688;3.076343;
0.056641;3.07505;
0.058594;3.069163;
0.060547;3.071798;
0.0625;3.081346;
0.064453;3.084389;
0.066406;3.09341;
0.068359;3.093196;
0.070312;3.083218;
0.072266;3.086287;
0.074219;3.088233;
0.076172;3.08667;
0.078125;3.095679;
0.080078;3.096942;
0.082031;3.084925;
0.083984;3.082463;
0.085938;3.091877;
0.087891;3.088733;
0.089844;3.083781;
0.091797;3.078914;
0.09375;3.077195;
0.095703;3.069401;
0.097656;3.075539;
0.099609;3.083792;
0.101562;3.085197;
0.103516;3.078291;
0.105469;3.083019;
0.107422;3.086012;
0.109375;3.085115;
0.111328;3.08322;
0.113281;3.090414;
0.115234;3.091482;
0.117188;3.091007;
0.119141;3.100885;
0.121094;3.118671;
0.123047;3.119367;
0.125;3.118003;
0.126953;3.116641;
0.128906;3.11198;
0.130859;3.10487;
0.132812;3.104407;
0.134766;3.103989;
0.136719;3.10094;
0.138672;3.100865;
0.140625;3.10407;
0.142578;3.118315;
0.144531;3.110813;
0.146484;3.10608;
0.148438;3.101737;
0.150391;3.094471;
0.152344;3.090622;
0.154297;3.095517;
0.15625;3.094173;
0.158203;3.098109;
0.160156;3.107191;
0.162109;3.112552;
0.164062;3.113174;
0.166016;3.123014;
0.167969;3.129043;
0.169922;3.125542;
0.171875;3.126344;
0.173828;3.136588;
0.175781;3.132988;
0.177734;3.133522;
0.179688;3.131767;
0.181641;3.13068;
0.183594;3.127816;
0.185547;3.128898;
0.1875;3.125444;
0.189453;3.117634;
0.191406;3.119542;
0.193359;3.136653;
0.195312;3.125466;
0.197266;3.113787;
0.199219;3.124379;
0.201172;3.141151;
0.203125;-3.139929;
0.205078;-3.135257;
0.207031;-3.126303;
0.208984;-3.135338;
0.210938;3.141327;
0.212891;-3.140974;
0.214844;-3.138109;
0.216797;-3.125593;
0.21875;-3.115173;
0.220703;-3.118337;
0.222656;-3.122142;
0.224609;-3.128323;
0.226562;-3.120599;
0.228516;-3.126431;
0.230469;-3.133207;
0.232422;-3.139365;
0.234375;-3.139642;
0.236328;3.134071;
0.238281;3.129321;
0.240234;3.129448;
0.242188;3.129903;
0.244141;3.123433;
0.246094;3.129284;
0.248047;3.134467;
0.25;3.129251;
0.251953;3.131762;
0.253906;3.134993;
0.255859;3.136174;
0.257812;3.137727;
0.259766;-3.141566;
0.261719;-3.140273;
0.263672;3.131638;
0.265625;3.139344;
0.267578;-3.140288;
0.269531;3.134024;
0.271484;3.131357;
0.273438;3.139041;
0.275391;-3.136429;
0.277344;-3.141036;
0.279297;3.138864;
0.28125;-3.133502;
0.283203;-3.133714;
0.285156;-3.132497;
0.287109;-3.134517;
0.289062;3.135531;
0.291016;3.125844;
0.292969;3.131409;
0.294922;3.128625;
0.296875;3.121791;
0.298828;3.128163;
0.300781;-3.125436;
0.302734;-3.119581;
0.304688;-3.128702;
0.306641;-3.123122;
0.308594;-3.12035;
0.310547;-3.123028;
0.3125;-3.126873;
0.314453;-3.11689;
0.316406;-3.11473;
0.318359;-3.113946;
0.320312;-3.1135;
0.322266;-3.126894;
0.324219;-3.124253;
0.326172;-3.099831;
0.328125;-3.085108;
0.330078;-3.069119;
0.332031;-3.069197;
0.333984;-3.073479;
0.335938;-3.095567;
0.337891;-3.109336;
0.339844;-3.095849;
0.341797;-3.081834;
0.34375;-3.075554;
0.345703;-3.071383;
0.347656;-3.07533;
0.349609;-3.084876;
0.351562;-3.086492;
0.353516;-3.081575;
0.355469;-3.089163;
0.357422;-3.090658;
0.359375;-3.083164;
0.361328;-3.086156;
0.363281;-3.091323;
0.365234;-3.091469;
0.367188;-3.094861;
0.369141;-3.104506;
0.371094;-3.114676;
0.373047;-3.111515;
0.375;-3.116299;
0.376953;-3.122826;
0.378906;-3.124658;
0.380859;-3.131804;
0.382812;-3.140703;
0.384766;3.137651;
0.386719;3.139747;
0.388672;3.139437;
0.390625;3.138057;
0.392578;3.140452;
0.394531;3.136339;
0.396484;3.13149;
0.398438;3.140348;
0.400391;-3.137099;
0.402344;-3.137211;
0.404297;3.141315;
0.40625;3.141468;
0.408203;3.133417;
0.410156;3.128909;
0.412109;3.124238;
0.414062;3.129239;
0.416016;3.129699;
0.417969;3.13278;
0.419922;3.132332;
0.421875;3.132606;
0.423828;3.119472;
0.425781;3.117785;
0.427734;3.134565;
0.429688;-3.139252;
0.431641;3.130426;
0.433594;3.138496;
0.435547;-3.140269;
0.4375;-3.135042;
0.439453;-3.119358;
0.441406;-3.117261;
0.443359;-3.125588;
0.445312;-3.12381;
0.447266;-3.123292;
0.449219;-3.126344;
0.451172;-3.132842;
0.453125;-3.133108;
0.455078;-3.131894;
0.457031;-3.13537;
0.458984;-3.123554;
0.460938;-3.121847;
0.462891;-3.131093;
0.464844;-3.130348;
0.466797;-3.115002;
0.46875;-3.11751;
0.470703;-3.123094;
0.472656;-3.120169;
0.474609;-3.114358;
0.476562;-3.120203;
0.478516;-3.114278;
0.480469;-3.101744;
0.482422;-3.095289;
0.484375;-3.088413;
0.486328;-3.085702;
0.488281;-3.0889;
0.490234;-3.098566;
0.492188;-3.103051;
0.494141;-3.097803;
0.496094;-3.101387;
0.498047;-3.105835;
0.5;-3.110284;
0.501953;-3.101672;
0.503906;-3.111609;
0.505859;-3.116504;
0.507812;-3.130284;
0.509766;3.137747;
0.511719;3.133679;
0.513672;-3.12922;
0.515625;-3.118203;
0.517578;-3.097677;
0.519531;-3.087169;
0.521484;-3.097208;
0.523438;-3.120841;
0.525391;-3.134931;
0.527344;-3.140921;
0.529297;-3.139118;
0.53125;-3.131831;
0.533203;-3.126093;
0.535156;-3.13726;
0.537109;3.129578;
0.539062;3.130279;
0.541016;3.138821;
0.542969;3.132302;
0.544922;3.136317;
0.546875;-3.135306;
0.548828;3.137387;
0.550781;3.128603;
0.552734;3.137864;
0.554688;-3.141163;
0.556641;3.137386;
0.558594;-3.141376;
0.560547;-3.124912;
0.5625;-3.120549;
0.564453;-3.114538;
0.566406;-3.110133;
0.568359;-3.110598;
0.570312;-3.120473;
0.572266;-3.128386;
0.574219;-3.11319;
0.576172;-3.121897;
0.578125;-3.121531;
0.580078;-3.110579;
0.582031;-3.105755;
0.583984;-3.119009;
0.585938;-3.112398;
0.587891;-3.115733;
0.589844;-3.11605;
0.591797;-3.123139;
0.59375;-3.111946;
0.595703;-3.103148;
0.597656;-3.103153;
0.599609;-3.100181;
0.601562;-3.102168;
0.603516;-3.109428;
0.605469;-3.10765;
0.607422;-3.102602;
0.609375;-3.111921;
0.611328;-3.126742;
0.613281;-3.123473;
0.615234;-3.128138;
0.617188;-3.129877;
0.619141;-3.1308;
0.621094;-3.124955;
0.623047;-3.121517;
0.625;-3.123328;
0.626953;-3.120505;
0.628906;-3.120843;
0.630859;-3.128668;
0.632812;-3.122949;
0.634766;-3.117347;
0.636719;-3.116485;
0.638672;-3.109823;
0.640625;-3.112933;
0.642578;-3.117654;
0.644531;-3.121368;
0.646484;-3.118372;
0.648438;-3.123679;
0.650391;-3.129243;
0.652344;-3.134692;
0.654297;-3.123738;
0.65625;-3.123808;
0.658203;-3.118511;
0.660156;-3.113745;
0.662109;-3.115279;
0.664062;-3.120161;
0.666016;-3.116469;
0.667969;-3.115379;
0.669922;-3.119467;
0.671875;-3.121366;
0.673828;-3.116179;
0.675781;-3.114367;
0.677734;-3.116018;
0.679688;-3.11388;
0.681641;-3.111349;
0.683594;-3.111567;
0.685547;-3.092909;
0.6875;-3.079025;
0.689453;-3.087428;
0.691406;-3.098665;
0.693359;-3.103894;
0.695312;-3.110186;
0.697266;-3.107746;
0.699219;-3.091724;
0.701172;-3.081896;
0.703125;-3.094395;
0.705078;-3.101435;
0.707031;-3.101114;
0.708984;-3.107702;
0.710938;-3.103434;
0.712891;-3.098916;
0.714844;-3.099007;
0.716797;-3.104402;
0.71875;-3.108484;
0.720703;-3.100152;
0.722656;-3.111268;
0.724609;-3.120683;
0.726562;-3.117764;
0.728516;-3.123045;
0.730469;-3.128866;
0.732422;-3.128196;
0.734375;-3.125642;
0.736328;-3.132368;
0.738281;-3.126462;
0.740234;-3.116163;
0.742188;-3.108978;
0.744141;-3.110067;
0.746094;-3.110309;
0.748047;-3.108135;
0.75;-3.108619;
0.751953;-3.099704;
0.753906;-3.107826;
0.755859;-3.118654;
0.757812;-3.122659;
0.759766;-3.107468;
0.761719;-3.101538;
0.763672;-3.099141;
0.765625;-3.108848;
0.767578;-3.106672;
0.769531;-3.095918;
0.771484;-3.09942;
0.773438;-3.093562;
0.775391;-3.087943;
0.777344;-3.086058;
0.779297;-3.073771;
0.78125;-3.076162;
0.783203;-3.093467;
0.785156;-3.095152;
0.787109;-3.088096;
0.789062;-3.084081;
0.791016;-3.087751;
0.792969;-3.079994;
0.794922;-3.067953;
0.796875;-3.066127;
0.798828;-3.062035;
0.800781;-3.059835;
0.802734;-3.060672;
0.804688;-3.057368;
0.806641;-3.047284;
0.808594;-3.052544;
0.810547;-3.05251;
0.8125;-3.043854;
0.814453;-3.032053;
0.816406;-3.032098;
0.818359;-3.037275;
0.820312;-3.023271;
0.822266;-3.009126;
0.824219;-3.00791;
0.826172;-3.002675;
0.828125;-3.007934;
0.830078;-3.014471;
0.832031;-3.020081;
0.833984;-3.017729;
0.835938;-3.019376;
0.837891;-3.025344;
0.839844;-3.032931;
0.841797;-3.039101;
0.84375;-3.053206;
0.845703;-3.063012;
0.847656;-3.062083;
0.849609;-3.069935;
0.851562;-3.080682;
0.853516;-3.084212;
0.855469;-3.087221;
0.857422;-3.094538;
0.859375;-3.09721;
0.861328;-3.109026;
0.863281;-3.136202;
0.865234;3.132984;
0.867188;3.133246;
0.869141;3.117868;
0.871094;3.102617;
0.873047;3.102455;
0.875;3.099468;
0.876953;3.090599;
0.878906;3.088741;
0.880859;3.088226;
0.882812;3.083597;
0.884766;3.074067;
0.886719;3.065951;
0.888672;3.064548;
0.890625;3.068408;
0.892578;3.067168;
0.894531;3.054707;
0.896484;3.059074;
0.898438;3.056461;
0.900391;3.056183;
0.902344;3.071649;
0.904297;3.072215;
0.90625;3.071819;
0.908203;3.064346;
0.910156;3.044512;
0.912109;3.027509;
0.914062;3.030218;
0.916016;3.037865;
0.917969;3.04253;
0.919922;3.056421;
0.921875;3.059487;
0.923828;3.048763;
0.925781;3.061728;
0.927734;3.058373;
0.929688;3.053585;
0.931641;3.061189;
0.933594;3.06636;
0.935547;3.062777;
0.9375;3.057614;
0.939453;3.066222;
0.941406;3.073079;
0.943359;3.06995;
0.945312;3.063822;
0.947266;3.066905;
0.949219;3.068542;
0.951172;3.067702;
0.953125;3.072131;
0.955078;3.064853;
0.957031;3.065922;
0.958984;3.078223;
0.960938;3.084772;
0.962891;3.078774;
0.964844;3.071792;
0.966797;3.080482;
0.96875;3.074615;
0.970703;3.065521;
0.972656;3.073663;
0.974609;3.079411;
0.976562;3.081241;
0.978516;3.091172;
0.980469;3.098894;
0.982422;3.094324;
0.984375;3.081977;
0.986328;3.094261;
0.988281;3.096175;
0.990234;3.078614;
0.992188;3.06784;
0.994141;3.075759;
0.996094;3.070199;
0.998047;3.092582;
1 Time(s) Time signal Sampling Rate
2 0 3.097188 512
3 0.001953 3.07633
4 0.003906 3.069826
5 0.005859 3.075173
6 0.007812 3.083173
7 0.009766 3.069207
8 0.011719 3.067177
9 0.013672 3.058007
10 0.015625 3.050604
11 0.017578 3.048189
12 0.019531 3.060055
13 0.021484 3.070759
14 0.023438 3.07357
15 0.025391 3.079629
16 0.027344 3.085208
17 0.029297 3.081203
18 0.03125 3.079854
19 0.033203 3.080383
20 0.035156 3.082213
21 0.037109 3.072226
22 0.039062 3.07599
23 0.041016 3.088025
24 0.042969 3.080251
25 0.044922 3.072052
26 0.046875 3.084892
27 0.048828 3.088162
28 0.050781 3.084298
29 0.052734 3.074636
30 0.054688 3.076343
31 0.056641 3.07505
32 0.058594 3.069163
33 0.060547 3.071798
34 0.0625 3.081346
35 0.064453 3.084389
36 0.066406 3.09341
37 0.068359 3.093196
38 0.070312 3.083218
39 0.072266 3.086287
40 0.074219 3.088233
41 0.076172 3.08667
42 0.078125 3.095679
43 0.080078 3.096942
44 0.082031 3.084925
45 0.083984 3.082463
46 0.085938 3.091877
47 0.087891 3.088733
48 0.089844 3.083781
49 0.091797 3.078914
50 0.09375 3.077195
51 0.095703 3.069401
52 0.097656 3.075539
53 0.099609 3.083792
54 0.101562 3.085197
55 0.103516 3.078291
56 0.105469 3.083019
57 0.107422 3.086012
58 0.109375 3.085115
59 0.111328 3.08322
60 0.113281 3.090414
61 0.115234 3.091482
62 0.117188 3.091007
63 0.119141 3.100885
64 0.121094 3.118671
65 0.123047 3.119367
66 0.125 3.118003
67 0.126953 3.116641
68 0.128906 3.11198
69 0.130859 3.10487
70 0.132812 3.104407
71 0.134766 3.103989
72 0.136719 3.10094
73 0.138672 3.100865
74 0.140625 3.10407
75 0.142578 3.118315
76 0.144531 3.110813
77 0.146484 3.10608
78 0.148438 3.101737
79 0.150391 3.094471
80 0.152344 3.090622
81 0.154297 3.095517
82 0.15625 3.094173
83 0.158203 3.098109
84 0.160156 3.107191
85 0.162109 3.112552
86 0.164062 3.113174
87 0.166016 3.123014
88 0.167969 3.129043
89 0.169922 3.125542
90 0.171875 3.126344
91 0.173828 3.136588
92 0.175781 3.132988
93 0.177734 3.133522
94 0.179688 3.131767
95 0.181641 3.13068
96 0.183594 3.127816
97 0.185547 3.128898
98 0.1875 3.125444
99 0.189453 3.117634
100 0.191406 3.119542
101 0.193359 3.136653
102 0.195312 3.125466
103 0.197266 3.113787
104 0.199219 3.124379
105 0.201172 3.141151
106 0.203125 -3.139929
107 0.205078 -3.135257
108 0.207031 -3.126303
109 0.208984 -3.135338
110 0.210938 3.141327
111 0.212891 -3.140974
112 0.214844 -3.138109
113 0.216797 -3.125593
114 0.21875 -3.115173
115 0.220703 -3.118337
116 0.222656 -3.122142
117 0.224609 -3.128323
118 0.226562 -3.120599
119 0.228516 -3.126431
120 0.230469 -3.133207
121 0.232422 -3.139365
122 0.234375 -3.139642
123 0.236328 3.134071
124 0.238281 3.129321
125 0.240234 3.129448
126 0.242188 3.129903
127 0.244141 3.123433
128 0.246094 3.129284
129 0.248047 3.134467
130 0.25 3.129251
131 0.251953 3.131762
132 0.253906 3.134993
133 0.255859 3.136174
134 0.257812 3.137727
135 0.259766 -3.141566
136 0.261719 -3.140273
137 0.263672 3.131638
138 0.265625 3.139344
139 0.267578 -3.140288
140 0.269531 3.134024
141 0.271484 3.131357
142 0.273438 3.139041
143 0.275391 -3.136429
144 0.277344 -3.141036
145 0.279297 3.138864
146 0.28125 -3.133502
147 0.283203 -3.133714
148 0.285156 -3.132497
149 0.287109 -3.134517
150 0.289062 3.135531
151 0.291016 3.125844
152 0.292969 3.131409
153 0.294922 3.128625
154 0.296875 3.121791
155 0.298828 3.128163
156 0.300781 -3.125436
157 0.302734 -3.119581
158 0.304688 -3.128702
159 0.306641 -3.123122
160 0.308594 -3.12035
161 0.310547 -3.123028
162 0.3125 -3.126873
163 0.314453 -3.11689
164 0.316406 -3.11473
165 0.318359 -3.113946
166 0.320312 -3.1135
167 0.322266 -3.126894
168 0.324219 -3.124253
169 0.326172 -3.099831
170 0.328125 -3.085108
171 0.330078 -3.069119
172 0.332031 -3.069197
173 0.333984 -3.073479
174 0.335938 -3.095567
175 0.337891 -3.109336
176 0.339844 -3.095849
177 0.341797 -3.081834
178 0.34375 -3.075554
179 0.345703 -3.071383
180 0.347656 -3.07533
181 0.349609 -3.084876
182 0.351562 -3.086492
183 0.353516 -3.081575
184 0.355469 -3.089163
185 0.357422 -3.090658
186 0.359375 -3.083164
187 0.361328 -3.086156
188 0.363281 -3.091323
189 0.365234 -3.091469
190 0.367188 -3.094861
191 0.369141 -3.104506
192 0.371094 -3.114676
193 0.373047 -3.111515
194 0.375 -3.116299
195 0.376953 -3.122826
196 0.378906 -3.124658
197 0.380859 -3.131804
198 0.382812 -3.140703
199 0.384766 3.137651
200 0.386719 3.139747
201 0.388672 3.139437
202 0.390625 3.138057
203 0.392578 3.140452
204 0.394531 3.136339
205 0.396484 3.13149
206 0.398438 3.140348
207 0.400391 -3.137099
208 0.402344 -3.137211
209 0.404297 3.141315
210 0.40625 3.141468
211 0.408203 3.133417
212 0.410156 3.128909
213 0.412109 3.124238
214 0.414062 3.129239
215 0.416016 3.129699
216 0.417969 3.13278
217 0.419922 3.132332
218 0.421875 3.132606
219 0.423828 3.119472
220 0.425781 3.117785
221 0.427734 3.134565
222 0.429688 -3.139252
223 0.431641 3.130426
224 0.433594 3.138496
225 0.435547 -3.140269
226 0.4375 -3.135042
227 0.439453 -3.119358
228 0.441406 -3.117261
229 0.443359 -3.125588
230 0.445312 -3.12381
231 0.447266 -3.123292
232 0.449219 -3.126344
233 0.451172 -3.132842
234 0.453125 -3.133108
235 0.455078 -3.131894
236 0.457031 -3.13537
237 0.458984 -3.123554
238 0.460938 -3.121847
239 0.462891 -3.131093
240 0.464844 -3.130348
241 0.466797 -3.115002
242 0.46875 -3.11751
243 0.470703 -3.123094
244 0.472656 -3.120169
245 0.474609 -3.114358
246 0.476562 -3.120203
247 0.478516 -3.114278
248 0.480469 -3.101744
249 0.482422 -3.095289
250 0.484375 -3.088413
251 0.486328 -3.085702
252 0.488281 -3.0889
253 0.490234 -3.098566
254 0.492188 -3.103051
255 0.494141 -3.097803
256 0.496094 -3.101387
257 0.498047 -3.105835
258 0.5 -3.110284
259 0.501953 -3.101672
260 0.503906 -3.111609
261 0.505859 -3.116504
262 0.507812 -3.130284
263 0.509766 3.137747
264 0.511719 3.133679
265 0.513672 -3.12922
266 0.515625 -3.118203
267 0.517578 -3.097677
268 0.519531 -3.087169
269 0.521484 -3.097208
270 0.523438 -3.120841
271 0.525391 -3.134931
272 0.527344 -3.140921
273 0.529297 -3.139118
274 0.53125 -3.131831
275 0.533203 -3.126093
276 0.535156 -3.13726
277 0.537109 3.129578
278 0.539062 3.130279
279 0.541016 3.138821
280 0.542969 3.132302
281 0.544922 3.136317
282 0.546875 -3.135306
283 0.548828 3.137387
284 0.550781 3.128603
285 0.552734 3.137864
286 0.554688 -3.141163
287 0.556641 3.137386
288 0.558594 -3.141376
289 0.560547 -3.124912
290 0.5625 -3.120549
291 0.564453 -3.114538
292 0.566406 -3.110133
293 0.568359 -3.110598
294 0.570312 -3.120473
295 0.572266 -3.128386
296 0.574219 -3.11319
297 0.576172 -3.121897
298 0.578125 -3.121531
299 0.580078 -3.110579
300 0.582031 -3.105755
301 0.583984 -3.119009
302 0.585938 -3.112398
303 0.587891 -3.115733
304 0.589844 -3.11605
305 0.591797 -3.123139
306 0.59375 -3.111946
307 0.595703 -3.103148
308 0.597656 -3.103153
309 0.599609 -3.100181
310 0.601562 -3.102168
311 0.603516 -3.109428
312 0.605469 -3.10765
313 0.607422 -3.102602
314 0.609375 -3.111921
315 0.611328 -3.126742
316 0.613281 -3.123473
317 0.615234 -3.128138
318 0.617188 -3.129877
319 0.619141 -3.1308
320 0.621094 -3.124955
321 0.623047 -3.121517
322 0.625 -3.123328
323 0.626953 -3.120505
324 0.628906 -3.120843
325 0.630859 -3.128668
326 0.632812 -3.122949
327 0.634766 -3.117347
328 0.636719 -3.116485
329 0.638672 -3.109823
330 0.640625 -3.112933
331 0.642578 -3.117654
332 0.644531 -3.121368
333 0.646484 -3.118372
334 0.648438 -3.123679
335 0.650391 -3.129243
336 0.652344 -3.134692
337 0.654297 -3.123738
338 0.65625 -3.123808
339 0.658203 -3.118511
340 0.660156 -3.113745
341 0.662109 -3.115279
342 0.664062 -3.120161
343 0.666016 -3.116469
344 0.667969 -3.115379
345 0.669922 -3.119467
346 0.671875 -3.121366
347 0.673828 -3.116179
348 0.675781 -3.114367
349 0.677734 -3.116018
350 0.679688 -3.11388
351 0.681641 -3.111349
352 0.683594 -3.111567
353 0.685547 -3.092909
354 0.6875 -3.079025
355 0.689453 -3.087428
356 0.691406 -3.098665
357 0.693359 -3.103894
358 0.695312 -3.110186
359 0.697266 -3.107746
360 0.699219 -3.091724
361 0.701172 -3.081896
362 0.703125 -3.094395
363 0.705078 -3.101435
364 0.707031 -3.101114
365 0.708984 -3.107702
366 0.710938 -3.103434
367 0.712891 -3.098916
368 0.714844 -3.099007
369 0.716797 -3.104402
370 0.71875 -3.108484
371 0.720703 -3.100152
372 0.722656 -3.111268
373 0.724609 -3.120683
374 0.726562 -3.117764
375 0.728516 -3.123045
376 0.730469 -3.128866
377 0.732422 -3.128196
378 0.734375 -3.125642
379 0.736328 -3.132368
380 0.738281 -3.126462
381 0.740234 -3.116163
382 0.742188 -3.108978
383 0.744141 -3.110067
384 0.746094 -3.110309
385 0.748047 -3.108135
386 0.75 -3.108619
387 0.751953 -3.099704
388 0.753906 -3.107826
389 0.755859 -3.118654
390 0.757812 -3.122659
391 0.759766 -3.107468
392 0.761719 -3.101538
393 0.763672 -3.099141
394 0.765625 -3.108848
395 0.767578 -3.106672
396 0.769531 -3.095918
397 0.771484 -3.09942
398 0.773438 -3.093562
399 0.775391 -3.087943
400 0.777344 -3.086058
401 0.779297 -3.073771
402 0.78125 -3.076162
403 0.783203 -3.093467
404 0.785156 -3.095152
405 0.787109 -3.088096
406 0.789062 -3.084081
407 0.791016 -3.087751
408 0.792969 -3.079994
409 0.794922 -3.067953
410 0.796875 -3.066127
411 0.798828 -3.062035
412 0.800781 -3.059835
413 0.802734 -3.060672
414 0.804688 -3.057368
415 0.806641 -3.047284
416 0.808594 -3.052544
417 0.810547 -3.05251
418 0.8125 -3.043854
419 0.814453 -3.032053
420 0.816406 -3.032098
421 0.818359 -3.037275
422 0.820312 -3.023271
423 0.822266 -3.009126
424 0.824219 -3.00791
425 0.826172 -3.002675
426 0.828125 -3.007934
427 0.830078 -3.014471
428 0.832031 -3.020081
429 0.833984 -3.017729
430 0.835938 -3.019376
431 0.837891 -3.025344
432 0.839844 -3.032931
433 0.841797 -3.039101
434 0.84375 -3.053206
435 0.845703 -3.063012
436 0.847656 -3.062083
437 0.849609 -3.069935
438 0.851562 -3.080682
439 0.853516 -3.084212
440 0.855469 -3.087221
441 0.857422 -3.094538
442 0.859375 -3.09721
443 0.861328 -3.109026
444 0.863281 -3.136202
445 0.865234 3.132984
446 0.867188 3.133246
447 0.869141 3.117868
448 0.871094 3.102617
449 0.873047 3.102455
450 0.875 3.099468
451 0.876953 3.090599
452 0.878906 3.088741
453 0.880859 3.088226
454 0.882812 3.083597
455 0.884766 3.074067
456 0.886719 3.065951
457 0.888672 3.064548
458 0.890625 3.068408
459 0.892578 3.067168
460 0.894531 3.054707
461 0.896484 3.059074
462 0.898438 3.056461
463 0.900391 3.056183
464 0.902344 3.071649
465 0.904297 3.072215
466 0.90625 3.071819
467 0.908203 3.064346
468 0.910156 3.044512
469 0.912109 3.027509
470 0.914062 3.030218
471 0.916016 3.037865
472 0.917969 3.04253
473 0.919922 3.056421
474 0.921875 3.059487
475 0.923828 3.048763
476 0.925781 3.061728
477 0.927734 3.058373
478 0.929688 3.053585
479 0.931641 3.061189
480 0.933594 3.06636
481 0.935547 3.062777
482 0.9375 3.057614
483 0.939453 3.066222
484 0.941406 3.073079
485 0.943359 3.06995
486 0.945312 3.063822
487 0.947266 3.066905
488 0.949219 3.068542
489 0.951172 3.067702
490 0.953125 3.072131
491 0.955078 3.064853
492 0.957031 3.065922
493 0.958984 3.078223
494 0.960938 3.084772
495 0.962891 3.078774
496 0.964844 3.071792
497 0.966797 3.080482
498 0.96875 3.074615
499 0.970703 3.065521
500 0.972656 3.073663
501 0.974609 3.079411
502 0.976562 3.081241
503 0.978516 3.091172
504 0.980469 3.098894
505 0.982422 3.094324
506 0.984375 3.081977
507 0.986328 3.094261
508 0.988281 3.096175
509 0.990234 3.078614
510 0.992188 3.06784
511 0.994141 3.075759
512 0.996094 3.070199
513 0.998047 3.092582
@@ -0,0 +1,823 @@
<OpenViBE-Scenario>
<FormatVersion>2</FormatVersion>
<Creator>OpenViBE Designer</Creator>
<CreatorVersion>2.1.0</CreatorVersion>
<Settings></Settings>
<Inputs></Inputs>
<Outputs></Outputs>
<Boxes>
<Box>
<Identifier>(0x000001bf, 0x0000774e)</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(2*m_PI*x*10)</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>96</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>176</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>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x0034f03c)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</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>(0x0000099b, 0x0000516a)</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>100</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>48</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>176</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x9e5ca01e, 0x30a4d8c3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x003baff6)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000015f4, 0x00003233)</Identifier>
<Name>Regularized CSP Trainer</Name>
<AlgorithmClassIdentifier>(0x2ec14cc0, 0x428c48bd)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Signal condition 1</Name>
</Input>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Signal condition 2</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Train-completed Flag</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Train Trigger</Name>
<DefaultValue>OVTK_GDF_End_Of_Session</DefaultValue>
<Value>OVTK_GDF_End_Of_Session</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Spatial filter configuration</Name>
<DefaultValue></DefaultValue>
<Value>${Player_ScenarioDirectory}/${TEST_FILTER}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Filters per condition</Name>
<DefaultValue>2</DefaultValue>
<Value>2</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Save filters as box config</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x59e83f33, 0x592f1dd0)</TypeIdentifier>
<Name>Covariance update</Name>
<DefaultValue>Chunk average</DefaultValue>
<Value>Chunk average</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Trace normalization</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Shrinkage coefficient</Name>
<DefaultValue>0.0</DefaultValue>
<Value>${TEST_SHRINK}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Tikhonov coefficient</Name>
<DefaultValue>0.0</DefaultValue>
<Value>${TEST_TIKHONOV}</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>448</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x97c37a70, 0xbc9fecff)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>8</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00001d79, 0x0000094b)</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_TrainCompleted</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>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>448</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x568d148e, 0x650792b3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x002b77a0)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00004f85, 0x000075c2)</Identifier>
<Name>Simple DSP</Name>
<AlgorithmClassIdentifier>(0x00e26fa1, 0x1dbab1b2)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input - A</Name>
</Input>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input - B</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>A+2*(B-0.5)</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>144</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>288</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>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x003b9892)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</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>(0x00005cd1, 0x00002308)</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>2</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Stimulation</Name>
<DefaultValue>OVTK_StimulationId_Label_00</DefaultValue>
<Value>OVTK_GDF_End_Of_Session</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>240</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>160</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x27b3ee3c, 0xc50527e6)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00625f88)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00005dde, 0x000059bc)</Identifier>
<Name>Signal Merger</Name>
<AlgorithmClassIdentifier>(0x4bf9326f, 0x75603102)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input 1</Name>
</Input>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input 2</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Merged</Name>
</Output>
</Outputs>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>256</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>416</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x990c5a68, 0x0d4024a3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x004856b6)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>2</Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000678f, 0x000007a1)</Identifier>
<Name>Noise generator</Name>
<AlgorithmClassIdentifier>(0x0e3929f1, 0x15af76b9)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Generated signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Channel count</Name>
<DefaultValue>4</DefaultValue>
<Value>255</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Sampling frequency</Name>
<DefaultValue>512</DefaultValue>
<Value>100</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>
<Setting>
<TypeIdentifier>(0x2e85e95e, 0x8a1a8365)</TypeIdentifier>
<Name>Noise type</Name>
<DefaultValue>Uniform</DefaultValue>
<Value>Uniform</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>48</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>415</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x0b214ed8, 0x1f9ad83a)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00374b76)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>4</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000678f, 0x000007a2)</Identifier>
<Name>Noise generator</Name>
<AlgorithmClassIdentifier>(0x0e3929f1, 0x15af76b9)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Generated signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Channel count</Name>
<DefaultValue>4</DefaultValue>
<Value>1</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Sampling frequency</Name>
<DefaultValue>512</DefaultValue>
<Value>100</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>
<Setting>
<TypeIdentifier>(0x2e85e95e, 0x8a1a8365)</TypeIdentifier>
<Name>Noise type</Name>
<DefaultValue>Uniform</DefaultValue>
<Value>Uniform</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>48</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>288</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x0b214ed8, 0x1f9ad83a)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x002f3df8)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>4</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00006bb1, 0x00002e53)</Identifier>
<Name>Noise generator</Name>
<AlgorithmClassIdentifier>(0x0e3929f1, 0x15af76b9)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Generated signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Channel count</Name>
<DefaultValue>4</DefaultValue>
<Value>256</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Sampling frequency</Name>
<DefaultValue>512</DefaultValue>
<Value>100</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>
<Setting>
<TypeIdentifier>(0x2e85e95e, 0x8a1a8365)</TypeIdentifier>
<Name>Noise type</Name>
<DefaultValue>Uniform</DefaultValue>
<Value>Uniform</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>48</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>544</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x0b214ed8, 0x1f9ad83a)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x0038bc7e)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>4</Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x0000148b, 0x00001055)</Identifier>
<Source>
<BoxIdentifier>(0x0000678f, 0x000007a1)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00005dde, 0x000059bc)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x000031f9, 0x000000fb)</Identifier>
<Source>
<BoxIdentifier>(0x00004f85, 0x000075c2)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00005dde, 0x000059bc)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00003b1c, 0x0000744b)</Identifier>
<Source>
<BoxIdentifier>(0x0000678f, 0x000007a2)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00004f85, 0x000075c2)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00004a2f, 0x000027c8)</Identifier>
<Source>
<BoxIdentifier>(0x000015f4, 0x00003233)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00001d79, 0x0000094b)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x000051a5, 0x00006b77)</Identifier>
<Source>
<BoxIdentifier>(0x00006bb1, 0x00002e53)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000015f4, 0x00003233)</BoxIdentifier>
<BoxInputIndex>2</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00005af9, 0x000060fc)</Identifier>
<Source>
<BoxIdentifier>(0x000001bf, 0x0000774e)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00004f85, 0x000075c2)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00006209, 0x000016ec)</Identifier>
<Source>
<BoxIdentifier>(0x0000099b, 0x0000516a)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000001bf, 0x0000774e)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00006c27, 0x00001ea0)</Identifier>
<Source>
<BoxIdentifier>(0x00005cd1, 0x00002308)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000015f4, 0x00003233)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x0000777a, 0x00004134)</Identifier>
<Source>
<BoxIdentifier>(0x00005dde, 0x000059bc)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000015f4, 0x00003233)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
</Links>
<Comments></Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":320,"identifier":"(0x00004b31, 0x000075b1)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":480},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00007e8e, 0x00001b92)","index":0,"name":"Default tab","parentIdentifier":"(0x00004b31, 0x000075b1)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x00006ba8, 0x00005c33)","index":0,"name":"Empty","parentIdentifier":"(0x00007e8e, 0x00001b92)","type":0}]</Data>
</Entry>
</Metadata>
</OpenViBE-Scenario>
Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

@@ -0,0 +1,93 @@
<html>
<head>
<style type="text/css">
.sikuli-code {
font-size: 20px;
font-family: "Osaka-mono", Monospace;
line-height: 1.5em;
display:table-cell;
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
width: 99%; /* remove horizontal scroll-bar when viewing in IE7 */
}
.sikuli-code img {
vertical-align: middle;
margin: 2px;
border: 1px solid #ccc;
padding: 2px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-moz-box-shadow: 1px 1px 1px gray;
-webkit-box-shadow: 1px 1px 2px gray;
}
.kw {
color: blue;
}
.skw {
color: rgb(63, 127, 127);
}
.str {
color: rgb(128, 0, 0);
}
.dig {
color: rgb(128, 64, 0);
}
.cmt {
color: rgb(200, 0, 200);
}
h2 {
display: inline;
font-weight: normal;
}
.info {
border-bottom: 1px solid #ddd;
padding-bottom: 5px;
margin-bottom: 20px;
display: none;
}
a {
color: #9D2900;
}
body {
font-family: "Trebuchet MS", Arial, Sans-Serif;
}
</style>
</head>
<body>
<div class="info">
<h2>testCrop.sikuli</h2> <a href="testCrop.zip">(Download this script)</a>
</div>
<pre class="sikuli-code">
<span class="kw">def</span> setUp(self):
<span class="kw">import</span> os
ov_binany_path=os.environ[<span class="str">'OV_BINARY_PATH'</span>]
self.terminal = App.open(<span class="str">"xterm -e "</span> +
ov_binany_path +<span class="str">"/openvibe-designer.sh --no-session-management --open "</span> +
ov_binany_path +<span class="str">"/share/openvibe/scenarios/box-tutorials/crop.xml"</span>)
<span class="kw">while</span> <span class="kw">not</span> self.terminal.window():
<span class="skw">wait</span>(<span class="dig">1</span>)
<span class="skw">wait</span>(<img src="play.png" />,<span class="dig">10</span>)
<span class="kw">def</span> testRunCrop(self):
<span class="skw">click</span>(<img src="play.png" />)
<span class="skw">wait</span>(<img src="timesignal.png" />,<span class="dig">10</span>)
<span class="kw">def</span> tearDown(self):
mouseMove(Location(<span class="dig">0</span>,<span class="dig">0</span>))
<span class="kw">if</span> self.terminal.window():
App.close(self.terminal)
self.terminal= None
</pre>
</body>
</html>
@@ -0,0 +1,19 @@
def setUp(self):
import os
ov_binany_path=os.environ['OV_BINARY_PATH']
self.terminal = App.open("xterm -e " +
ov_binany_path +"/openvibe-designer.sh --no-session-management --open " +
ov_binany_path +"/share/openvibe/scenarios/box-tutorials/crop.xml")
while not self.terminal.window():
wait(1)
wait("play.png",10)
def testRunCrop(self):
click("play.png")
wait("timesignal.png",10)
def tearDown(self):
mouseMove(Location(0,0))
if self.terminal.window():
App.close(self.terminal)
self.terminal= None
@@ -0,0 +1,89 @@
<html>
<head>
<style type="text/css">
.sikuli-code {
font-size: 20px;
font-family: "Osaka-mono", Monospace;
line-height: 1.5em;
display:table-cell;
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
width: 99%; /* remove horizontal scroll-bar when viewing in IE7 */
}
.sikuli-code img {
vertical-align: middle;
margin: 2px;
border: 1px solid #ccc;
padding: 2px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-moz-box-shadow: 1px 1px 1px gray;
-webkit-box-shadow: 1px 1px 2px gray;
}
.kw {
color: blue;
}
.skw {
color: rgb(63, 127, 127);
}
.str {
color: rgb(128, 0, 0);
}
.dig {
color: rgb(128, 64, 0);
}
.cmt {
color: rgb(200, 0, 200);
}
h2 {
display: inline;
font-weight: normal;
}
.info {
border-bottom: 1px solid #ddd;
padding-bottom: 5px;
margin-bottom: 20px;
display: none;
}
a {
color: #9D2900;
}
body {
font-family: "Trebuchet MS", Arial, Sans-Serif;
}
</style>
</head>
<body>
<div class="info">
<h2>testCrop.sikuli</h2> <a href="testCrop.zip">(Download this script)</a>
</div>
<pre class="sikuli-code">
<span class="kw">def</span> setUp(self):
<span class="kw">import</span> os
ov_binany_path=os.environ[<span class="str">'OV_BINARY_PATH'</span>]
self.terminal = App.open(<span class="str">"xterm -e "</span> +
ov_binany_path +<span class="str">"/openvibe-designer.sh --no-session-management --play "</span> +
ov_binany_path +<span class="str">"/share/openvibe/scenarios/box-tutorials/crop.xml"</span>)
<span class="kw">while</span> <span class="kw">not</span> self.terminal.window():
<span class="skw">wait</span>(<span class="dig">1</span>)
<span class="kw">def</span> testRunOgreVisual(self):
<span class="kw">assert</span>(exists(<img src="timesignal.png" />))
<span class="kw">def</span> tearDown(self):
<span class="kw">if</span> self.terminal.window():
App.close(self.terminal)
self.terminal= None
</pre>
</body>
</html>
@@ -0,0 +1,15 @@
def setUp(self):
import os
ov_binany_path=os.environ['OV_BINARY_PATH']
self.terminal = App.open("xterm -e " +
ov_binany_path +"/openvibe-designer.sh --no-session-management --play " +
ov_binany_path +"/share/openvibe/scenarios/box-tutorials/crop.xml")
while not self.terminal.window():
wait(1)
def testRunOgreVisual(self):
assert(exists("timesignal.png"))
def tearDown(self):
if self.terminal.window():
App.close(self.terminal)
self.terminal= None
@@ -0,0 +1,89 @@
<html>
<head>
<style type="text/css">
.sikuli-code {
font-size: 20px;
font-family: "Osaka-mono", Monospace;
line-height: 1.5em;
display:table-cell;
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
width: 99%; /* remove horizontal scroll-bar when viewing in IE7 */
}
.sikuli-code img {
vertical-align: middle;
margin: 2px;
border: 1px solid #ccc;
padding: 2px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-moz-box-shadow: 1px 1px 1px gray;
-webkit-box-shadow: 1px 1px 2px gray;
}
.kw {
color: blue;
}
.skw {
color: rgb(63, 127, 127);
}
.str {
color: rgb(128, 0, 0);
}
.dig {
color: rgb(128, 64, 0);
}
.cmt {
color: rgb(200, 0, 200);
}
h2 {
display: inline;
font-weight: normal;
}
.info {
border-bottom: 1px solid #ddd;
padding-bottom: 5px;
margin-bottom: 20px;
display: none;
}
a {
color: #9D2900;
}
body {
font-family: "Trebuchet MS", Arial, Sans-Serif;
}
</style>
</head>
<body>
<div class="info">
<h2>testCrop.sikuli</h2> <a href="testCrop.zip">(Download this script)</a>
</div>
<pre class="sikuli-code">
<span class="kw">def</span> setUp(self):
<span class="kw">import</span> os
ov_binany_path=os.environ[<span class="str">'OV_BINARY_PATH'</span>]
self.terminal = App.open(<span class="str">"xterm -e "</span> + ov_binany_path +<span class="str">"/openvibe-designer.sh --no-session-management --play testOgreContext.xml"</span>)
<span class="kw">while</span> <span class="kw">not</span> self.terminal.window():
<span class="skw">wait</span>(<span class="dig">1</span>)
<span class="skw">wait</span>(<img src="Simple3Dview.png" />,<span class="dig">10</span>)
<span class="kw">def</span> testRunOgreVisual(self):
waitVanish(<img src="Simple3Dview.png" />,<span class="dig">10</span>)
<span class="kw">assert</span>(exists(<img src="designerScreen.png" />))
<span class="kw">def</span> tearDown(self):
<span class="kw">if</span> self.terminal.window():
App.close(self.terminal)
self.terminal= None
</pre>
</body>
</html>
@@ -0,0 +1,15 @@
def setUp(self):
import os
ov_binany_path=os.environ['OV_BINARY_PATH']
self.terminal = App.open("xterm -e " + ov_binany_path +"/openvibe-designer.sh --no-session-management --play testOgreContext.xml")
while not self.terminal.window():
wait(1)
wait("Simple3Dview.png",10)
def testRunOgreVisual(self):
waitVanish("Simple3Dview.png",10)
assert(exists("designerScreen.png"))
def tearDown(self):
if self.terminal.window():
App.close(self.terminal)
self.terminal= None

Some files were not shown because too many files have changed in this diff Show More