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,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