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,29 @@
PROJECT(openvibe-plugins-acquisition)
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/*.inl)
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRC_FILES})
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
FOLDER ${PLUGINS_FOLDER}
COMPILE_FLAGS "-DOVP_Exports -DOVP_Shared")
# ---------------------------------
INCLUDE("FindOpenViBE")
INCLUDE("FindOpenViBECommon")
INCLUDE("FindOpenViBEToolkit")
INCLUDE("FindOpenViBEModuleEBML")
INCLUDE("FindOpenViBEModuleSocket")
# -----------------------------
# Install files
# -----------------------------
INSTALL(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${DIST_BINDIR}
LIBRARY DESTINATION ${DIST_LIBDIR}
ARCHIVE DESTINATION ${DIST_LIBDIR})
INSTALL(DIRECTORY box-tutorials DESTINATION ${DIST_DATADIR}/openvibe/scenarios/)
@@ -0,0 +1,387 @@
<OpenViBE-Scenario>
<FormatVersion>1</FormatVersion>
<Creator>openvibe</Creator>
<CreatorVersion>2.0</CreatorVersion>
<Boxes>
<Box>
<Identifier>(0x000029b8, 0x00004235)</Identifier>
<Name>Acquisition client</Name>
<AlgorithmClassIdentifier>(0x35d225cb, 0x3e6e3a5f)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x403488e7, 0x565d70b6)</TypeIdentifier>
<Name>Experiment information</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Signal stream</Name>
</Output>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Output>
<Output>
<TypeIdentifier>(0x013df452, 0xa3a8879a)</TypeIdentifier>
<Name>Channel localisation</Name>
</Output>
<Output>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel units</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Acquisition server hostname</Name>
<DefaultValue>${AcquisitionServer_HostName}</DefaultValue>
<Value>${AcquisitionServer_HostName}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Acquisition server port</Name>
<DefaultValue>1024</DefaultValue>
<Value>1024</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>48.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>25</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>352.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x0d4656c0, 0xc95b1fa8)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
<Value>136</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x005c0f5a)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>5</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000044d9, 0x0000415f)</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>160.000000</Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa963f5, 0x1a638cd4)</Identifier>
<Value>38</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>368.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>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00276b19)</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>(0x000019c2, 0x00003e36)</Identifier>
<Source>
<BoxIdentifier>(0x000029b8, 0x00004235)</BoxIdentifier>
<BoxOutputIndex>1</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000044d9, 0x0000415f)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>67</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>337</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>136</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>353</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00002352, 0x00007dcd)</Identifier>
<Source>
<BoxIdentifier>(0x000029b8, 0x00004235)</BoxIdentifier>
<BoxOutputIndex>4</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000044d9, 0x0000415f)</BoxIdentifier>
<BoxInputIndex>2</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>67</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>382</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>136</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>383</Value>
</Attribute>
</Attributes>
</Link>
<Link>
<Identifier>(0x00005ba9, 0x00007356)</Identifier>
<Source>
<BoxIdentifier>(0x000029b8, 0x00004235)</BoxIdentifier>
<BoxOutputIndex>2</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000044d9, 0x0000415f)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
<Attributes>
<Attribute>
<Identifier>(0x1b32c44c, 0x1905e0e9)</Identifier>
<Value>67</Value>
</Attribute>
<Attribute>
<Identifier>(0x358ae8b5, 0x0f8bacd1)</Identifier>
<Value>352</Value>
</Attribute>
<Attribute>
<Identifier>(0x3f0a3b27, 0x570913d2)</Identifier>
<Value>136</Value>
</Attribute>
<Attribute>
<Identifier>(0x6267b5c5, 0x676e3e42)</Identifier>
<Value>368</Value>
</Attribute>
</Attributes>
</Link>
</Links>
<Comments>
<Comment>
<Identifier>(0x00002398, 0x00002d9d)</Identifier>
<Text>The &lt;i&gt;&lt;b&gt;Acquisition Client&lt;/b&gt;&lt;/i&gt; box
receives data from the OpenViBE acquisition
server. You should have the OpenViBE
acquisition server started and acquiring to
let this scenario work correctly. In case
of connection errors, you should read a
message in the console.</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>624</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>64</Value>
</Attribute>
</Attributes>
</Comment>
<Comment>
<Identifier>(0x00005018, 0x00007ee0)</Identifier>
<Text>The &lt;i&gt;Signal Display&lt;/i&gt; box display the
acquired data.</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>624</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>176</Value>
</Attribute>
</Attributes>
</Comment>
<Comment>
<Identifier>(0x00005a08, 0x00002b8c)</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>512</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>240</Value>
</Attribute>
</Attributes>
</Comment>
</Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":1,"identifier":"(0x0000228a, 0x0000253b)","index":0,"name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":1},{"boxIdentifier":"(0x000044d9, 0x0000415f)","childCount":0,"identifier":"(0x00005a9f, 0x00004ede)","index":0,"parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00001786, 0x00000497)","index":0,"name":"Default tab","parentIdentifier":"(0x0000228a, 0x0000253b)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x00005f28, 0x000016db)","index":0,"name":"Empty","parentIdentifier":"(0x00001786, 0x00000497)","type":0}]</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>Network acquisition example</Value>
</Attribute>
<Attribute>
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
<Value>http://openvibe.inria.fr/tutorial-the-most-basic-openvibe-setup/</Value>
</Attribute>
<Attribute>
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
<Value>box-tutorials</Value>
</Attribute>
<Attribute>
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
<Value>Inria</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>
@@ -0,0 +1,61 @@
/**
* \page BoxAlgorithm_AcquisitionClient Acquisition client
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_AcquisitionClient_Description|
Opens a socket to read experiment information, signal, stimulations and channel localization data sent across the network.
* |OVP_DocEnd_BoxAlgorithm_AcquisitionClient_Description|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_AcquisitionClient_Outputs|
* |OVP_DocEnd_BoxAlgorithm_AcquisitionClient_Outputs|
* |OVP_DocBegin_BoxAlgorithm_AcquisitionClient_Output1|
* |OVP_DocEnd_BoxAlgorithm_AcquisitionClient_Output1|
* |OVP_DocBegin_BoxAlgorithm_AcquisitionClient_Output2|
* |OVP_DocEnd_BoxAlgorithm_AcquisitionClient_Output2|
* |OVP_DocBegin_BoxAlgorithm_AcquisitionClient_Output3|
* |OVP_DocEnd_BoxAlgorithm_AcquisitionClient_Output3|
* |OVP_DocBegin_BoxAlgorithm_AcquisitionClient_Output4|
Channel localisation flow
* |OVP_DocEnd_BoxAlgorithm_AcquisitionClient_Output4|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_AcquisitionClient_Settings|
* |OVP_DocEnd_BoxAlgorithm_AcquisitionClient_Settings|
* |OVP_DocBegin_BoxAlgorithm_AcquisitionClient_Setting1|
EEG server hostname
* |OVP_DocEnd_BoxAlgorithm_AcquisitionClient_Setting1|
* |OVP_DocBegin_BoxAlgorithm_AcquisitionClient_Setting2|
EEG server port
* |OVP_DocEnd_BoxAlgorithm_AcquisitionClient_Setting2|
__________________________________________________________________
Examples description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_AcquisitionClient_Examples|
* |OVP_DocEnd_BoxAlgorithm_AcquisitionClient_Examples|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_AcquisitionClient_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_AcquisitionClient_Miscellaneous|
*/
@@ -0,0 +1,159 @@
#include "ovpCBoxAlgorithmAcquisitionClient.h"
#include <limits>
namespace OpenViBE {
namespace Plugins {
namespace Acquisition {
uint64_t CBoxAlgorithmAcquisitionClient::getClockFrequency() { return 64LL << 32; }
bool CBoxAlgorithmAcquisitionClient::initialize()
{
m_decoder = &getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_AcquisitionDecoder));
m_decoder->initialize();
ip_acquisitionBuffer.initialize(m_decoder->getInputParameter(OVP_GD_Algorithm_AcquisitionDecoder_InputParameterId_MemoryBufferToDecode));
op_bufferDuration.initialize(m_decoder->getOutputParameter(OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_BufferDuration));
op_experimentInfoBuffer.initialize(m_decoder->getOutputParameter(OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_ExperimentInfoStream));
op_signalBuffer.initialize(m_decoder->getOutputParameter(OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_SignalStream));
op_stimulationBuffer.initialize(m_decoder->getOutputParameter(OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_StimulationStream));
op_channelLocalisationBuffer.initialize(m_decoder->getOutputParameter(OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_ChannelLocalisationStream));
op_channelUnitsBuffer.initialize(m_decoder->getOutputParameter(OVP_GD_Algorithm_AcquisitionDecoder_OutputParameterId_ChannelUnitsStream));
m_lastStartTime = 0;
m_lastEndTime = 0;
m_connectionClient = nullptr;
if (getStaticBoxContext().getOutputCount() < 5)
{
this->getLogManager() << Kernel::LogLevel_Error << "Code expects at least 5 box outputs. Did you update the box?\n";
return false;
}
return true;
}
bool CBoxAlgorithmAcquisitionClient::uninitialize()
{
if (m_connectionClient)
{
m_connectionClient->close();
m_connectionClient->release();
m_connectionClient = nullptr;
}
op_channelUnitsBuffer.uninitialize();
op_channelLocalisationBuffer.uninitialize();
op_stimulationBuffer.uninitialize();
op_signalBuffer.uninitialize();
op_experimentInfoBuffer.uninitialize();
op_bufferDuration.uninitialize();
ip_acquisitionBuffer.uninitialize();
m_decoder->uninitialize();
getAlgorithmManager().releaseAlgorithm(*m_decoder);
m_decoder = nullptr;
return true;
}
bool CBoxAlgorithmAcquisitionClient::processClock(Kernel::CMessageClock& /*msg*/)
{
if (!m_connectionClient)
{
CString name = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
const size_t port = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
if (name.length() == 0)
{
this->getLogManager() << Kernel::LogLevel_Warning <<
"Empty server name, please set it to a correct value or set AcquisitionServer_HostName in config files. Defaulting to \"localhost\".\n";
name = "localhost";
}
if (port == std::numeric_limits<size_t>::max() || port == std::numeric_limits<size_t>::min())
{
this->getLogManager() << Kernel::LogLevel_Error << "Invalid value for port : " << port <<
". Please set the port to a positive non-zero integer value.\n";
return false;
}
m_connectionClient = Socket::createConnectionClient();
m_connectionClient->connect(name, port);
if (!m_connectionClient->isConnected())
{
this->getLogManager() << Kernel::LogLevel_Error << "Could not connect to server " << name << ":" << port <<
". Make sure the server is running and in Play state.\n";
return false;
}
}
if (m_connectionClient && m_connectionClient->isReadyToReceive() /* && getPlayerContext().getCurrentTime()>m_lastChunkEndTime */)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
}
return true;
}
bool CBoxAlgorithmAcquisitionClient::process()
{
if (!m_connectionClient || !m_connectionClient->isConnected()) { return false; }
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
op_experimentInfoBuffer = boxContext.getOutputChunk(0);
op_signalBuffer = boxContext.getOutputChunk(1);
op_stimulationBuffer = boxContext.getOutputChunk(2);
op_channelLocalisationBuffer = boxContext.getOutputChunk(3);
op_channelUnitsBuffer = boxContext.getOutputChunk(4);
while (m_connectionClient->isReadyToReceive())
{
size_t size = 0;
if (!m_connectionClient->receiveBufferBlocking(&size, sizeof(size)))
{
getLogManager() << Kernel::LogLevel_Error << "Could not receive memory buffer size from the server. Is the server on 'Play'?\n";
return false;
}
if (!ip_acquisitionBuffer->setSize(size, true))
{
getLogManager() << Kernel::LogLevel_Error << "Could not re allocate memory buffer with size " << size << "\n";
return false;
}
if (!m_connectionClient->receiveBufferBlocking(ip_acquisitionBuffer->getDirectPointer(), size))
{
getLogManager() << Kernel::LogLevel_Error << "Could not receive memory buffer content of size " << size << "\n";
return false;
}
m_decoder->process();
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_AcquisitionDecoder_OutputTriggerId_ReceivedHeader)
|| m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_AcquisitionDecoder_OutputTriggerId_ReceivedBuffer)
|| m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_AcquisitionDecoder_OutputTriggerId_ReceivedEnd))
{
boxContext.markOutputAsReadyToSend(0, m_lastStartTime, m_lastEndTime);
boxContext.markOutputAsReadyToSend(1, m_lastStartTime, m_lastEndTime);
boxContext.markOutputAsReadyToSend(2, m_lastStartTime, m_lastEndTime);
if (op_channelLocalisationBuffer->getSize() > 0) { boxContext.markOutputAsReadyToSend(3, m_lastStartTime, m_lastEndTime); }
else { boxContext.setOutputChunkSize(3, 0, true); }
if (op_channelUnitsBuffer->getSize() > 0) { boxContext.markOutputAsReadyToSend(4, m_lastStartTime, m_lastEndTime); }
else { boxContext.setOutputChunkSize(4, 0, true); }
m_lastStartTime = m_lastEndTime;
m_lastEndTime += op_bufferDuration;
// @todo ?
// const double latency=CTime(m_lastChunkEndTime).toSeconds() - CTime(this->getPlayerContext().getCurrentTime()).toSeconds();
const double latency = double(int64_t(m_lastEndTime - this->getPlayerContext().getCurrentTime()) / (1LL << 22)) / 1024.0;
this->getLogManager() << Kernel::LogLevel_Debug << "Acquisition inner latency : " << latency << "\n";
}
}
return true;
}
} // namespace Acquisition
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,83 @@
#pragma once
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <socket/IConnectionClient.h>
namespace OpenViBE {
namespace Plugins {
namespace Acquisition {
class CBoxAlgorithmAcquisitionClient final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
void release() override { delete this; }
uint64_t getClockFrequency() override;
bool initialize() override;
bool uninitialize() override;
bool processClock(Kernel::CMessageClock& msg) override;
bool process() override;
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_AcquisitionClient)
protected:
Kernel::IAlgorithmProxy* m_decoder = nullptr;
Kernel::TParameterHandler<IMemoryBuffer*> ip_acquisitionBuffer;
Kernel::TParameterHandler<uint64_t> op_bufferDuration;
Kernel::TParameterHandler<IMemoryBuffer*> op_experimentInfoBuffer;
Kernel::TParameterHandler<IMemoryBuffer*> op_signalBuffer;
Kernel::TParameterHandler<IMemoryBuffer*> op_stimulationBuffer;
Kernel::TParameterHandler<IMemoryBuffer*> op_channelLocalisationBuffer;
Kernel::TParameterHandler<IMemoryBuffer*> op_channelUnitsBuffer;
Socket::IConnectionClient* m_connectionClient = nullptr;
uint64_t m_lastStartTime = 0;
uint64_t m_lastEndTime = 0;
};
class CBoxAlgorithmAcquisitionClientDesc final : public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Acquisition client"); }
CString getAuthorName() const override { return CString("Yann Renard"); }
CString getAuthorCompanyName() const override { return CString("INRIA/IRISA"); }
CString getShortDescription() const override { return CString("A generic network based acquisition client"); }
CString getDetailedDescription() const override
{
return CString("This algorithm waits for EEG data from the network and distributes it into the scenario");
}
CString getCategory() const override { return CString("Acquisition and network IO"); }
CString getVersion() const override { return CString("1.0"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_AcquisitionClient; }
IPluginObject* create() override { return new CBoxAlgorithmAcquisitionClient; }
CString getStockItemName() const override { return CString("gtk-connect"); }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addOutput("Experiment information", OV_TypeId_ExperimentInfo);
prototype.addOutput("Signal stream", OV_TypeId_Signal);
prototype.addOutput("Stimulations", OV_TypeId_Stimulations);
prototype.addOutput("Channel localisation", OV_TypeId_ChannelLocalisation);
prototype.addOutput("Channel units", OV_TypeId_ChannelUnits);
prototype.addSetting("Acquisition server hostname", OV_TypeId_String, "${AcquisitionServer_HostName}");
prototype.addSetting("Acquisition server port", OV_TypeId_Integer, "1024");
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_AcquisitionClientDesc)
};
} // namespace Acquisition
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,12 @@
#pragma once
// Boxes
//---------------------------------------------------------------------------------------------------
#define OVP_ClassId_BoxAlgorithm_AcquisitionClient OpenViBE::CIdentifier(0x35D225CB, 0x3E6E3A5F)
#define OVP_ClassId_BoxAlgorithm_AcquisitionClientDesc OpenViBE::CIdentifier(0x7D3061B9, 0x43565E8C)
// Global defines
//---------------------------------------------------------------------------------------------------
#ifdef TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
#include "ovp_global_defines.h"
#endif // TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
@@ -0,0 +1,15 @@
#include "ovp_defines.h"
#include "box-algorithms/ovpCBoxAlgorithmAcquisitionClient.h"
namespace OpenViBE {
namespace Plugins {
namespace Acquisition {
OVP_Declare_Begin()
OVP_Declare_New(CBoxAlgorithmAcquisitionClientDesc)
OVP_Declare_End()
} // namespace Acquisition
} // namespace Plugins
} // namespace OpenViBE