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,74 @@
#include "ovpCBoxAlgorithmClockStimulator.h"
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
bool CBoxAlgorithmClockStimulator::initialize()
{
const double interstimulationInterval = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
const double minInterstimulationInterval = 0.0001;
OV_ERROR_UNLESS_KRF(!(interstimulationInterval < minInterstimulationInterval),
"Invalid stimulation interval [" << interstimulationInterval << "] (expected value > " << minInterstimulationInterval << ")",
Kernel::ErrorType::BadSetting);
m_stimulationInterval = interstimulationInterval;
m_nSentStimulation = 0;
m_stimulationID = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_lastStimulationDate = 0;
m_lastEndTime = 0;
m_encoder.initialize(*this, 0);
return true;
}
bool CBoxAlgorithmClockStimulator::uninitialize()
{
m_encoder.uninitialize();
return true;
}
bool CBoxAlgorithmClockStimulator::processClock(Kernel::CMessageClock& /*msg*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmClockStimulator::process()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
const uint64_t currentTime = getPlayerContext().getCurrentTime();
CStimulationSet stimulationSet;
stimulationSet.setStimulationCount(0);
while (CTime(double(m_nSentStimulation + 1) * m_stimulationInterval).time() < currentTime)
{
m_nSentStimulation += 1;
m_lastStimulationDate = CTime(double(m_nSentStimulation) * m_stimulationInterval).time();
stimulationSet.appendStimulation(m_stimulationID, m_lastStimulationDate, 0);
}
if (currentTime == 0)
{
m_encoder.encodeHeader();
boxContext.markOutputAsReadyToSend(0, m_lastEndTime, m_lastEndTime);
}
m_encoder.getInputStimulationSet() = &stimulationSet;
m_encoder.encodeBuffer();
boxContext.markOutputAsReadyToSend(0, m_lastEndTime, currentTime);
m_lastEndTime = currentTime;
return true;
}
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,62 @@
#pragma once
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
class CBoxAlgorithmClockStimulator final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
void release() override { delete this; }
uint64_t getClockFrequency() override { return (1LL << 32) * 32; }
bool initialize() override;
bool uninitialize() override;
bool processClock(Kernel::CMessageClock& msg) override;
bool process() override;
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_ClockStimulator)
protected:
Toolkit::TStimulationEncoder<CBoxAlgorithmClockStimulator> m_encoder;
uint64_t m_stimulationID = 0;
uint64_t m_lastStimulationDate = 0;
uint64_t m_lastEndTime = 0;
uint64_t m_nSentStimulation = 0;
double m_stimulationInterval = 0;
};
class CBoxAlgorithmClockStimulatorDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Clock stimulator"); }
CString getAuthorName() const override { return CString("Yann Renard"); }
CString getAuthorCompanyName() const override { return CString("INRIA/IRISA"); }
CString getShortDescription() const override { return CString("Periodic stimulation generator"); }
CString getDetailedDescription() const override { return CString("Triggers stimulation at fixed frequency"); }
CString getCategory() const override { return CString("Stimulation"); }
CString getVersion() const override { return CString("1.0"); }
CString getSoftwareComponent() const override { return CString("openvibe-sdk"); }
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_ClockStimulator; }
IPluginObject* create() override { return new CBoxAlgorithmClockStimulator; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addOutput("Generated stimulations", OV_TypeId_Stimulations);
prototype.addSetting("Interstimulation interval (in sec)", OV_TypeId_Float, "1.0");
prototype.addSetting("Stimulation", OV_TypeId_Stimulation, "OVTK_StimulationId_Label_00");
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_ClockStimulatorDesc)
};
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,84 @@
#include "ovpCBoxAlgorithmPlayerController.h"
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
bool CBoxAlgorithmPlayerController::initialize()
{
m_stimulationID = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_actionID = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_decoder = &this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationDecoder));
m_decoder->initialize();
ip_buffer.initialize(m_decoder->getInputParameter(OVP_GD_Algorithm_StimulationDecoder_InputParameterId_MemoryBufferToDecode));
op_stimulationSet.initialize(m_decoder->getOutputParameter(OVP_GD_Algorithm_StimulationDecoder_OutputParameterId_StimulationSet));
return true;
}
bool CBoxAlgorithmPlayerController::uninitialize()
{
op_stimulationSet.uninitialize();
ip_buffer.uninitialize();
if (m_decoder)
{
m_decoder->uninitialize();
this->getAlgorithmManager().releaseAlgorithm(*m_decoder);
m_decoder = nullptr;
}
return true;
}
bool CBoxAlgorithmPlayerController::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmPlayerController::process()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
ip_buffer = boxContext.getInputChunk(0, i);
m_decoder->process();
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedHeader)) { }
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedBuffer))
{
IStimulationSet* stimSet = op_stimulationSet;
for (size_t j = 0; j < stimSet->getStimulationCount(); ++j)
{
if (stimSet->getStimulationIdentifier(j) == m_stimulationID)
{
this->getLogManager() << Kernel::LogLevel_Trace << "Received stimulation ["
<< this->getTypeManager().getEnumerationEntryNameFromValue(OV_TypeId_Stimulation, m_stimulationID) << "] causing action ["
<< this->getTypeManager().getEnumerationEntryNameFromValue(OV_TypeId_PlayerAction, m_actionID) << "]\n";
bool res = false;
if (m_actionID == OV_TypeId_PlayerAction_Play.id()) { res = this->getPlayerContext().play(); }
if (m_actionID == OV_TypeId_PlayerAction_Stop.id()) { res = this->getPlayerContext().stop(); }
if (m_actionID == OV_TypeId_PlayerAction_Pause.id()) { res = this->getPlayerContext().pause(); }
if (m_actionID == OV_TypeId_PlayerAction_Forward.id()) { res = this->getPlayerContext().forward(); }
OV_ERROR_UNLESS_KRF(res, "Failed to request player action ["
<< this->getTypeManager().getEnumerationEntryNameFromValue(OV_TypeId_PlayerAction, m_actionID) << "]",
Kernel::ErrorType::BadConfig);
}
}
}
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedEnd)) { }
boxContext.markInputAsDeprecated(0, i);
}
return true;
}
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,63 @@
#pragma once
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
class CBoxAlgorithmPlayerController 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_PlayerController)
protected:
Kernel::IAlgorithmProxy* m_decoder = nullptr;
Kernel::TParameterHandler<const IMemoryBuffer*> ip_buffer;
Kernel::TParameterHandler<IStimulationSet*> op_stimulationSet;
uint64_t m_stimulationID = 0;
uint64_t m_actionID = 0;
};
class CBoxAlgorithmPlayerControllerDesc final : public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Player Controller"); }
CString getAuthorName() const override { return CString("Yann Renard"); }
CString getAuthorCompanyName() const override { return CString("INRIA"); }
CString getShortDescription() const override { return CString("Controls the player execution"); }
CString getDetailedDescription() const override { return CString("Add some settings to configure the way you want to control the player"); }
CString getCategory() const override { return CString("Stimulation"); }
CString getVersion() const override { return CString("1.0"); }
CString getSoftwareComponent() const override { return CString("openvibe-sdk"); }
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_PlayerController; }
IPluginObject* create() override { return new CBoxAlgorithmPlayerController; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Stimulations", OV_TypeId_Stimulations);
prototype.addSetting("Stimulation name", OV_TypeId_Stimulation, "OVTK_StimulationId_Label_00");
prototype.addSetting("Action to perform", OV_TypeId_PlayerAction, OV_TypeId_PlayerAction_Pause.toString());
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_PlayerControllerDesc)
};
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,112 @@
#include "ovpCBoxAlgorithmStimulationMultiplexer.h"
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
bool CBoxAlgorithmStimulationMultiplexer::initialize()
{
const Kernel::IBox& staticBoxContext = this->getStaticBoxContext();
m_decoders.resize(staticBoxContext.getInputCount());
size_t index = 0;
for (auto& stimulationDecoder : m_decoders)
{
stimulationDecoder.initialize(*this, index);
index += 1;
}
m_encoder.initialize(*this, 0);
m_decoderEndTimes = std::vector<uint64_t>(staticBoxContext.getInputCount(), 0ULL);
m_lastStartTime = 0;
m_lastEndTime = 0;
m_wasHeaderSent = false;
return true;
}
bool CBoxAlgorithmStimulationMultiplexer::uninitialize()
{
for (auto& stimulationDecoder : m_decoders) { stimulationDecoder.uninitialize(); }
m_encoder.uninitialize();
return true;
}
bool CBoxAlgorithmStimulationMultiplexer::processInput(const size_t /*index*/)
{
this->getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmStimulationMultiplexer::process()
{
const Kernel::IBox& staticBoxContext = this->getStaticBoxContext();
Kernel::IBoxIO& dynamicBoxContext = this->getDynamicBoxContext();
if (!m_wasHeaderSent)
{
m_encoder.encodeHeader();
dynamicBoxContext.markOutputAsReadyToSend(0, m_lastEndTime, m_lastEndTime);
m_wasHeaderSent = true;
}
uint64_t earliestReceivedChunkEndTime = 0xffffffffffffffffULL;
for (size_t input = 0; input < staticBoxContext.getInputCount(); ++input)
{
for (size_t chunk = 0; chunk < dynamicBoxContext.getInputChunkCount(input); ++chunk)
{
m_decoders[input].decode(chunk);
if (m_decoders[input].isBufferReceived())
{
for (size_t stimulation = 0; stimulation < m_decoders[input].getOutputStimulationSet()->getStimulationCount(); ++stimulation)
{
m_stimulations.insert(std::make_pair(m_decoders[input].getOutputStimulationSet()->getStimulationDate(stimulation),
std::make_tuple(
m_decoders[input].getOutputStimulationSet()->getStimulationIdentifier(stimulation),
m_decoders[input].getOutputStimulationSet()->getStimulationDate(stimulation),
m_decoders[input].getOutputStimulationSet()->getStimulationDuration(stimulation))));
}
}
m_decoderEndTimes[input] = dynamicBoxContext.getInputChunkEndTime(input, chunk);
}
if (earliestReceivedChunkEndTime > m_decoderEndTimes[input]) { earliestReceivedChunkEndTime = m_decoderEndTimes[input]; }
}
if (earliestReceivedChunkEndTime >= m_lastEndTime)
{
m_encoder.getInputStimulationSet()->clear();
for (auto stimulation = m_stimulations.begin(); stimulation != m_stimulations.end();)
{
if (stimulation->first < earliestReceivedChunkEndTime)
{
m_encoder.getInputStimulationSet()->appendStimulation(std::get<0>(stimulation->second), std::get<1>(stimulation->second),
std::get<2>(stimulation->second));
stimulation = m_stimulations.erase(stimulation);
}
else { ++stimulation; }
}
m_encoder.encodeBuffer();
dynamicBoxContext.markOutputAsReadyToSend(0, m_lastEndTime, earliestReceivedChunkEndTime);
m_lastStartTime = m_lastEndTime;
m_lastEndTime = earliestReceivedChunkEndTime;
}
return true;
}
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,103 @@
#pragma once
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <vector>
#include <map>
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
class CBoxAlgorithmStimulationMultiplexer 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_StimulationMultiplexer)
private:
std::vector<Toolkit::TStimulationDecoder<CBoxAlgorithmStimulationMultiplexer>> m_decoders;
Toolkit::TStimulationEncoder<CBoxAlgorithmStimulationMultiplexer> m_encoder;
std::vector<uint64_t> m_decoderEndTimes;
uint64_t m_lastStartTime = 0;
uint64_t m_lastEndTime = 0;
bool m_wasHeaderSent = false;
std::multimap<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> m_stimulations;
};
class CBoxAlgorithmStimulationMultiplexerListener final : public Toolkit::TBoxListener<IBoxListener>
{
public:
bool check(Kernel::IBox& box) const
{
for (size_t input = 0; input < box.getInputCount(); ++input)
{
box.setInputName(input, ("Input stimulations " + std::to_string(input + 1)).c_str());
box.setInputType(input, OV_TypeId_Stimulations);
}
return true;
}
bool onInputRemoved(Kernel::IBox& box, const size_t /*index*/) override { return this->check(box); }
bool onInputAdded(Kernel::IBox& box, const size_t /*index*/) override { return this->check(box); }
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
};
class CBoxAlgorithmStimulationMultiplexerDesc final : public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Stimulation multiplexer"); }
CString getAuthorName() const override { return CString("Yann Renard"); }
CString getAuthorCompanyName() const override { return CString("INRIA/IRISA"); }
CString getShortDescription() const override { return CString("Merges several stimulation streams into one."); }
CString getDetailedDescription() const override
{
return CString(
"The stimulations are ordered according to their start date. Thus each time all the input have chunks covering a period of time, a new output chunk is sent. This box may eventually produce output chunk reflecting a different duration depending on the inputs.");
}
CString getCategory() const override { return CString("Streaming"); }
CString getVersion() const override { return CString("1.1"); }
CString getStockItemName() const override { return CString("gtk-sort-ascending"); }
CString getSoftwareComponent() const override { return CString("openvibe-sdk"); }
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_StimulationMultiplexer; }
IPluginObject* create() override { return new CBoxAlgorithmStimulationMultiplexer; }
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmStimulationMultiplexerListener; }
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Input stimulations 1", OV_TypeId_Stimulations);
prototype.addInput("Input stimulations 2", OV_TypeId_Stimulations);
prototype.addOutput("Multiplexed stimulations", OV_TypeId_Stimulations);
prototype.addFlag(Kernel::BoxFlag_CanAddInput);
prototype.addInputSupport(OV_TypeId_Stimulations);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_StimulationMultiplexerDesc)
};
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,209 @@
#include "ovpCBoxAlgorithmStimulationVoter.h"
#include <system/ovCMath.h>
#include <string>
#include <algorithm>
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
bool CBoxAlgorithmStimulationVoter::initialize()
{
const Kernel::IBox& boxContext = this->getStaticBoxContext();
OV_ERROR_UNLESS_KRF(boxContext.getInputCount() == 1, "Invalid number of inputs [" << boxContext.getInputCount() << "] (expected 1 single input)",
Kernel::ErrorType::BadInput);
CIdentifier typeID;
boxContext.getInputType(0, typeID);
OV_ERROR_UNLESS_KRF(typeID == OV_TypeId_Stimulations, "Invalid input type [" << typeID.str() << "] (expected OV_TypeId_Stimulations type)",
Kernel::ErrorType::BadInput);
m_encoder = &this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationEncoder));
m_encoder->initialize();
m_decoder = &this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationDecoder));
m_decoder->initialize();
ip_buffer.initialize(m_decoder->getInputParameter(OVP_GD_Algorithm_StimulationDecoder_InputParameterId_MemoryBufferToDecode));
op_stimulationSet.initialize(m_decoder->getOutputParameter(OVP_GD_Algorithm_StimulationDecoder_OutputParameterId_StimulationSet));
m_minimumVotes = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_timeWindow = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_clearVotes = uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2));
m_outputDateMode = uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3));
m_rejectClassLabel = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 4);
m_rejectClassCanWin = uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 5));
this->getLogManager() << Kernel::LogLevel_Debug << "Vote clear mode " << m_clearVotes << ", timestamp at " << m_outputDateMode << ", reject mode " <<
m_rejectClassCanWin << "\n";
m_latestStimulusDate = 0;
m_lastTime = 0;
m_oStimulusDeque.clear();
return true;
}
bool CBoxAlgorithmStimulationVoter::uninitialize()
{
m_decoder->uninitialize();
this->getAlgorithmManager().releaseAlgorithm(*m_decoder);
m_encoder->uninitialize();
this->getAlgorithmManager().releaseAlgorithm(*m_encoder);
return true;
}
bool CBoxAlgorithmStimulationVoter::processInput(const size_t /*index*/)
{
this->getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmStimulationVoter::process()
{
Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
Kernel::TParameterHandler<IStimulationSet*> ip_stimSet(m_encoder->getInputParameter(OVP_GD_Algorithm_StimulationEncoder_InputParameterId_StimulationSet));
Kernel::TParameterHandler<IMemoryBuffer*> op_buffer(m_encoder->getOutputParameter(OVP_GD_Algorithm_StimulationEncoder_OutputParameterId_EncodedMemoryBuffer));
op_buffer = boxContext.getOutputChunk(0);
// Push the stimulations to a queue
bool newStimulus = false;
for (size_t j = 0; j < boxContext.getInputChunkCount(0); ++j)
{
ip_buffer = boxContext.getInputChunk(0, j);
m_decoder->process();
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedHeader)) { }
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedBuffer))
{
for (size_t k = 0; k < op_stimulationSet->getStimulationCount(); ++k)
{
uint64_t stimulationId = op_stimulationSet->getStimulationIdentifier(k);
uint64_t stimulationDate = op_stimulationSet->getStimulationDate(k);
m_latestStimulusDate = std::max(m_latestStimulusDate, stimulationDate);
if (CTime(m_latestStimulusDate - stimulationDate).toSeconds() <= m_timeWindow)
{
// Stimulus is fresh, append
m_oStimulusDeque.push_back(std::pair<uint64_t, uint64_t>(stimulationId, stimulationDate));
newStimulus = true;
}
}
}
if (m_decoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedEnd)) { }
boxContext.markInputAsDeprecated(0, j);
}
if (m_oStimulusDeque.empty() || !newStimulus) { return true; }
// Always clear too old votes that have slipped off the time window. The time window is relative to the time of the latest stimulus received.
while (!m_oStimulusDeque.empty())
{
const uint64_t frontDate = m_oStimulusDeque.front().second;
if (CTime(m_latestStimulusDate - frontDate).toSeconds() > m_timeWindow)
{
// Drop it
m_oStimulusDeque.pop_front();
}
else
{
// Assume stimuli are received in time order. Since the stimulus at the head wasn't too old, the rest aren't either
break;
}
}
this->getLogManager() << Kernel::LogLevel_Debug << "Queue size is " << m_oStimulusDeque.size() << "\n";
if (m_oStimulusDeque.size() < m_minimumVotes)
{
// Not enough stimuli to vote
return true;
}
std::map<uint64_t, uint64_t> lastSeen; // The last occurrence of each type in time
std::map<uint64_t, size_t> votes; // Histogram of votes
// Make a histogram of the votes
for (const auto& stim : m_oStimulusDeque)
{
const uint64_t type = stim.first;
const uint64_t date = stim.second;
votes[type]++;
lastSeen[type] = std::max(lastSeen[type], date);
// Never pop here, only pop on expiration
}
// Find the winner
uint64_t resultClassLabel = m_rejectClassLabel;
size_t maxVotes = 0;
for (const auto& vote : votes)
{
const uint64_t type = vote.first;
const size_t nVotes = vote.second; // can not be zero by construction above
if (m_rejectClassCanWin == OVP_TypeId_Voting_RejectClass_CanWin_No && type == m_rejectClassLabel)
{
// Reject class never wins
continue;
}
if (nVotes > maxVotes)
{
resultClassLabel = type;
maxVotes = nVotes;
}
else if (nVotes == maxVotes)
{
// Break ties arbitrarily
if (System::Math::random0To1() > 0.5)
{
resultClassLabel = type;
maxVotes = nVotes;
}
}
}
if (m_lastTime == 0)
{
m_encoder->process(OVP_GD_Algorithm_StimulationEncoder_InputTriggerId_EncodeHeader);
boxContext.markOutputAsReadyToSend(0, m_lastTime, m_lastTime);
}
if (m_rejectClassCanWin == OVP_TypeId_Voting_RejectClass_CanWin_No && resultClassLabel == m_rejectClassLabel)
{
this->getLogManager() << Kernel::LogLevel_Debug << "Winning class " << resultClassLabel << " was 'rejected' with " << maxVotes << "votes. Dropped.\n";
}
else
{
const uint64_t currentTime = getPlayerContext().getCurrentTime();
uint64_t timeStamp;
if (m_outputDateMode == OVP_TypeId_Voting_OutputTime_Vote) { timeStamp = currentTime; }
else if (m_outputDateMode == OVP_TypeId_Voting_OutputTime_Winner) { timeStamp = lastSeen[resultClassLabel]; }
else { timeStamp = m_latestStimulusDate; }
this->getLogManager() << Kernel::LogLevel_Debug << "Appending winning stimulus " << resultClassLabel << " at " << timeStamp << " (" << maxVotes << " votes)\n";
ip_stimSet->setStimulationCount(0);
ip_stimSet->appendStimulation(resultClassLabel, timeStamp, 0);
m_encoder->process(OVP_GD_Algorithm_StimulationEncoder_InputTriggerId_EncodeBuffer);
boxContext.markOutputAsReadyToSend(0, m_lastTime, currentTime);
m_lastTime = currentTime;
if (m_clearVotes == OVP_TypeId_Voting_ClearVotes_AfterOutput) { m_oStimulusDeque.clear(); }
}
return true;
}
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,104 @@
#pragma once
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <map>
#include <deque>
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
class CBoxAlgorithmStimulationVoter 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_StimulationVoter)
protected:
uint64_t m_minimumVotes = 0;
double m_timeWindow = 0;
uint64_t m_rejectClassLabel = 0;
CIdentifier m_clearVotes = CIdentifier::undefined();
CIdentifier m_outputDateMode = CIdentifier::undefined();
CIdentifier m_rejectClassCanWin = CIdentifier::undefined();
private:
Kernel::IAlgorithmProxy* m_encoder = nullptr;
Kernel::IAlgorithmProxy* m_decoder = nullptr;
Kernel::TParameterHandler<const IMemoryBuffer*> ip_buffer;
Kernel::TParameterHandler<IStimulationSet*> op_stimulationSet;
std::deque<std::pair<uint64_t, uint64_t>> m_oStimulusDeque; // <label,time>
uint64_t m_latestStimulusDate = 0;
uint64_t m_lastTime = 0;
};
class CBoxAlgorithmStimulationVoterListener final : public Toolkit::TBoxListener<IBoxListener>
{
public:
CBoxAlgorithmStimulationVoterListener() : m_inputTypeID(OV_TypeId_Stimulations) { }
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
protected:
CIdentifier m_inputTypeID = CIdentifier::undefined();
};
class CBoxAlgorithmStimulationVoterDesc final : public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Stimulation Voter"); }
CString getAuthorName() const override { return CString("Jussi T. Lindgren"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("Performs majority vote on the input stimuli"); }
CString getDetailedDescription() const override
{
return CString(
"Votes the most frequent stimulus ID in a given time window. Outputs the winning stimulus type. Several options are possible. To process multiple inputs, use Stimulation Multiplexer first.");
}
CString getCategory() const override { return CString("Streaming"); }
CString getVersion() const override { return CString("1.0"); }
CString getSoftwareComponent() const override { return CString("openvibe-sdk"); }
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_StimulationVoter; }
IPluginObject* create() override { return new CBoxAlgorithmStimulationVoter; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Stimulus input", OV_TypeId_Stimulations);
prototype.addOutput("Selected stimulus", OV_TypeId_Stimulations);
prototype.addSetting("Number of stimuli required for vote", OV_TypeId_Integer, "4");
prototype.addSetting("Time window (secs)", OV_TypeId_Float, "2");
prototype.addSetting("Clear votes", OVP_TypeId_Voting_ClearVotes, "After output");
prototype.addSetting("Output timestamp", OVP_TypeId_Voting_OutputTime, "Time of last voting stimulus");
prototype.addSetting("Reject class label", OV_TypeId_Stimulation, "OVTK_StimulationId_Label_00");
prototype.addSetting("Reject class can win", OVP_TypeId_Voting_RejectClass_CanWin, "No");
return true;
}
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmStimulationVoterListener; }
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_StimulationVoterDesc)
};
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,100 @@
#include "ovpCBoxAlgorithmStreamEndDetector.h"
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
bool CBoxAlgorithmStreamEndDetector::initialize()
{
m_stimulationID = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), settingStimulationNameID());
OV_FATAL_UNLESS_K(this->getStaticBoxContext().getInterfacorIndex(Kernel::EBoxInterfacorType::Input, inputEBMLId(), m_inputEBMLIdx),
"Box does not have input with identifier " << inputEBMLId(), Kernel::ErrorType::Internal);
OV_FATAL_UNLESS_K(this->getStaticBoxContext().getInterfacorIndex(Kernel::EBoxInterfacorType::Output, outputStimulationsID(), m_outputStimulationsIdx),
"Box does not have output with identifier " << outputStimulationsID(), Kernel::ErrorType::Internal);
m_decoder.initialize(*this, m_inputEBMLIdx);
m_encoder.initialize(*this, m_outputStimulationsIdx);
m_isHeaderSent = false;
m_endDate = 0;
m_currentChunkEndDate = 0;
m_endState = EEndState::WaitingForEnd;
m_previousTime = 0;
return true;
}
bool CBoxAlgorithmStreamEndDetector::uninitialize()
{
m_decoder.uninitialize();
m_encoder.uninitialize();
return true;
}
bool CBoxAlgorithmStreamEndDetector::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CBoxAlgorithmStreamEndDetector::process()
{
Kernel::IBoxIO& dynamicBoxContext = this->getDynamicBoxContext();
for (size_t chunk = 0; chunk < dynamicBoxContext.getInputChunkCount(m_inputEBMLIdx); ++chunk)
{
OV_ERROR_UNLESS_KRF(m_decoder.decode(chunk), "Failed to decode chunk", Kernel::ErrorType::Internal);
// We can not receive anything before this date anymore, thus we can send an empty stream
m_currentChunkEndDate = dynamicBoxContext.getInputChunkStartTime(m_inputEBMLIdx, chunk);
if (m_decoder.isEndReceived())
{
m_endState = EEndState::EndReceived;
m_endDate = dynamicBoxContext.getInputChunkEndTime(m_inputEBMLIdx, chunk);
// As this is the last chunk, we make it so it ends at the same time as the received End chunk
m_currentChunkEndDate = dynamicBoxContext.getInputChunkEndTime(m_inputEBMLIdx, chunk);
}
}
if (!m_isHeaderSent)
{
m_encoder.encodeHeader();
this->getDynamicBoxContext().markOutputAsReadyToSend(0, 0, 0);
m_isHeaderSent = true;
}
IStimulationSet* stimulationSet = m_encoder.getInputStimulationSet();
stimulationSet->clear();
// If the timeout is reached we send the stimulation on the output 0
if (m_endState == EEndState::EndReceived)
{
stimulationSet->appendStimulation(m_stimulationID, m_endDate, 0);
m_endState = EEndState::StimulationSent;
}
if (m_endState != EEndState::Finished && (m_endState == EEndState::StimulationSent || m_previousTime != m_currentChunkEndDate))
{
// we need to send an empty chunk even if there's no stim
m_encoder.encodeBuffer();
this->getDynamicBoxContext().markOutputAsReadyToSend(0, m_previousTime, m_currentChunkEndDate);
}
m_previousTime = m_currentChunkEndDate;
if (m_endState == EEndState::StimulationSent)
{
m_encoder.encodeEnd();
this->getDynamicBoxContext().markOutputAsReadyToSend(0, m_previousTime, m_previousTime);
m_endState = EEndState::Finished;
}
return true;
}
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,81 @@
#pragma once
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
class CBoxAlgorithmStreamEndDetector final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
static CIdentifier inputEBMLId() { return CIdentifier(0x0, 0x1); }
static CIdentifier outputStimulationsID() { return CIdentifier(0x1, 0x1); }
static CIdentifier settingStimulationNameID() { return CIdentifier(0x2, 0x1); }
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_StreamEndDetector)
protected:
Toolkit::TStreamStructureDecoder<CBoxAlgorithmStreamEndDetector> m_decoder;
Toolkit::TStimulationEncoder<CBoxAlgorithmStreamEndDetector> m_encoder;
uint64_t m_stimulationID = 0;
uint64_t m_actionID = 0;
private:
enum class EEndState
{
WaitingForEnd,
EndReceived,
StimulationSent,
Finished
};
uint64_t m_endDate = 0;
uint64_t m_currentChunkEndDate = 0;
uint64_t m_previousTime = 0;
size_t m_inputEBMLIdx = 0;
size_t m_outputStimulationsIdx = 0;
bool m_isHeaderSent = false;
EEndState m_endState = EEndState::WaitingForEnd;
};
class CBoxAlgorithmStreamEndDetectorDesc final : public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Stream End Detector"); }
CString getAuthorName() const override { return CString("Jozef Legeny"); }
CString getAuthorCompanyName() const override { return CString("Mensia Technologies"); }
CString getShortDescription() const override { return CString("Sends a stimulation upon receiving an End chunk"); }
CString getDetailedDescription() const override { return CString("Sends a stimulation upon receiving an End chunk"); }
CString getCategory() const override { return CString("Stimulation"); }
CString getVersion() const override { return CString("1.0"); }
CString getSoftwareComponent() const override { return CString("openvibe-sdk"); }
CString getAddedSoftwareVersion() const override { return CString("2.0.0"); }
CString getUpdatedSoftwareVersion() const override { return CString("0.0.0"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_StreamEndDetector; }
IPluginObject* create() override { return new CBoxAlgorithmStreamEndDetector; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("EBML Stream", OV_TypeId_EBMLStream, CBoxAlgorithmStreamEndDetector::inputEBMLId());
prototype.addOutput("Output Stimulations", OV_TypeId_Stimulations, CBoxAlgorithmStreamEndDetector::outputStimulationsID());
prototype.addSetting("Stimulation name", OV_TypeId_Stimulation, "OVTK_StimulationId_Label_00", false,
CBoxAlgorithmStreamEndDetector::settingStimulationNameID());
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_StreamEndDetectorDesc)
};
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,106 @@
#include "ovpCBoxAlgorithmTimeout.h"
#include <cmath>
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
bool CBoxAlgorithmTimeout::initialize()
{
m_timeoutState = ETimeoutState::No;
m_encoder.initialize(*this, 0);
const double timeout = double(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0));
OV_ERROR_UNLESS_KRF(timeout > 0, "Timeout delay value must be positive and non-zero", Kernel::ErrorType::BadSetting);
OV_ERROR_UNLESS_KRF(timeout == std::floor(timeout), "Timeout delay value is not an integer", Kernel::ErrorType::BadSetting);
m_timeout = uint64_t(timeout) << 32;
m_stimulationToSend = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_lastTimePolled = 0;
m_previousTime = 0;
m_isHeaderSent = false;
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmTimeout::uninitialize()
{
m_encoder.uninitialize();
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmTimeout::processClock(Kernel::CMessageClock& /*msg*/)
{
// if there was nothing received on the input for a period of time we raise the
// timeout flag and let the box send a stimulation
if (m_timeoutState == ETimeoutState::No && getPlayerContext().getCurrentTime() > m_lastTimePolled + m_timeout)
{
this->getLogManager() << Kernel::LogLevel_Trace << "Timeout reached at time " << CTime(this->getPlayerContext().getCurrentTime()) << "\n";
m_timeoutState = ETimeoutState::Occurred;
}
this->getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
/*******************************************************************************/
uint64_t CBoxAlgorithmTimeout::getClockFrequency() { return 16LL << 32; } // the box clock frequency
/*******************************************************************************/
bool CBoxAlgorithmTimeout::processInput(const size_t /*index*/)
{
this->getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
// every time we receive input we store the last kernel time
m_lastTimePolled = this->getPlayerContext().getCurrentTime();
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmTimeout::process()
{
Kernel::IBoxIO& boxCtx = this->getDynamicBoxContext();
// Discard input data
for (size_t i = 0; i < boxCtx.getInputChunkCount(0); ++i) { boxCtx.markInputAsDeprecated(0, i); }
// Encoding the header
if (!m_isHeaderSent)
{
m_encoder.encodeHeader();
this->getDynamicBoxContext().markOutputAsReadyToSend(0, 0, 0);
m_isHeaderSent = true;
}
IStimulationSet* stimSet = m_encoder.getInputStimulationSet();
stimSet->clear();
const uint64_t date = this->getPlayerContext().getCurrentTime();
// If the timeout is reached we send the stimulation on the output 0
if (m_timeoutState == ETimeoutState::Occurred)
{
stimSet->appendStimulation(m_stimulationToSend, date, 0);
m_timeoutState = ETimeoutState::Sent;
}
// we need to send an empty chunk even if there's no stim
m_encoder.encodeBuffer();
this->getDynamicBoxContext().markOutputAsReadyToSend(0, m_previousTime, date);
m_previousTime = date;
return true;
}
} // namespace Stimulation
} // 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 Stimulation {
/**
* \class CBoxAlgorithmTimeout
* \author Jozef Legény (Inria)
* \date Thu Mar 21 14:40:23 2013
* \brief The class CBoxAlgorithmTimeout describes the box Timeout.
*
*/
class CBoxAlgorithmTimeout 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;
uint64_t getClockFrequency() override;
bool process() override;
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_Timeout)
protected:
Toolkit::TStimulationEncoder<CBoxAlgorithmTimeout> m_encoder;
private:
enum class ETimeoutState { No, Occurred, Sent };
ETimeoutState m_timeoutState = ETimeoutState::No;
bool m_isHeaderSent = false;
uint64_t m_timeout = 0;
uint64_t m_lastTimePolled = 0;
uint64_t m_previousTime = 0;
uint64_t m_stimulationToSend = 0;
};
/**
* \class CBoxAlgorithmTimeoutDesc
* \author Jozef Legény (Inria)
* \date Thu Mar 21 14:40:23 2013
* \brief Descriptor of the box Timeout.
*
*/
class CBoxAlgorithmTimeoutDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return "Timeout"; }
CString getAuthorName() const override { return "Jozef Legény"; }
CString getAuthorCompanyName() const override { return "Inria"; }
CString getShortDescription() const override { return "Sends a stimulation after a period of time without receiving signal"; }
CString getDetailedDescription() const override
{
return "Sends a stimulation after a period of time without receiving signal. Useful for stopping scenarios after hardware disconnection.";
}
CString getCategory() const override { return "Stimulation"; }
CString getVersion() const override { return "1.1"; }
CString getSoftwareComponent() const override { return "openvibe-sdk"; }
CString getAddedSoftwareVersion() const override { return "0.0.0"; }
CString getUpdatedSoftwareVersion() const override { return "0.0.0"; }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_Timeout; }
IPluginObject* create() override { return new CBoxAlgorithmTimeout; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Input Stream",OV_TypeId_StreamedMatrix);
prototype.addOutput("Output Stimulations",OV_TypeId_Stimulations);
prototype.addSetting("Timeout delay",OV_TypeId_Integer, "5");
prototype.addSetting("Output Stimulation",OV_TypeId_Stimulation, "OVTK_StimulationId_Label_00");
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_TimeoutDesc)
};
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,41 @@
#pragma once
// Boxes
//---------------------------------------------------------------------------------------------------
#define OVP_ClassId_BoxAlgorithm_ClockStimulator OpenViBE::CIdentifier(0x4F756D3F, 0x29FF0B96)
#define OVP_ClassId_BoxAlgorithm_ClockStimulatorDesc OpenViBE::CIdentifier(0x4FD067E9, 0x740D2AF0)
#define OVP_ClassId_BoxAlgorithm_PlayerController OpenViBE::CIdentifier(0x5F426DCE, 0x08456E13)
#define OVP_ClassId_BoxAlgorithm_PlayerControllerDesc OpenViBE::CIdentifier(0x2E4142D7, 0x3F957E25)
#define OVP_ClassId_BoxAlgorithm_StimulationMultiplexer OpenViBE::CIdentifier(0x07DB4EFA, 0x472B0938)
#define OVP_ClassId_BoxAlgorithm_StimulationMultiplexerDesc OpenViBE::CIdentifier(0x79EF4E4D, 0x178F09E6)
#define OVP_ClassId_BoxAlgorithm_StimulationVoter OpenViBE::CIdentifier(0x2BBD61FC, 0x041A4EDB)
#define OVP_ClassId_BoxAlgorithm_StimulationVoterDesc OpenViBE::CIdentifier(0x1C36287C, 0x6F143FBF)
#define OVP_ClassId_BoxAlgorithm_StreamEndDetector OpenViBE::CIdentifier(0x44F2725A, 0x8E922233)
#define OVP_ClassId_BoxAlgorithm_StreamEndDetectorDesc OpenViBE::CIdentifier(0x6DD8B6EA, 0xC581B3FC)
#define OVP_ClassId_BoxAlgorithm_Timeout OpenViBE::CIdentifier(0x24FCD292, 0x5C8F6AA8)
#define OVP_ClassId_BoxAlgorithm_TimeoutDesc OpenViBE::CIdentifier(0xB3D90844, 0x79A4CF6D)
// Type definitions
//---------------------------------------------------------------------------------------------------
#define OVP_TypeId_Voting_ClearVotes OpenViBE::CIdentifier(0x17AE30F8, 0x40B57661)
#define OVP_TypeId_Voting_ClearVotes_AfterOutput OpenViBE::CIdentifier(0x7FA81A20, 0x484023F9)
#define OVP_TypeId_Voting_ClearVotes_WhenExpires OpenViBE::CIdentifier(0x02766639, 0x00B155B4)
#define OVP_TypeId_Voting_OutputTime OpenViBE::CIdentifier(0x48583E8F, 0x47F22462)
#define OVP_TypeId_Voting_OutputTime_Vote OpenViBE::CIdentifier(0x2F37507F, 0x00C06761)
#define OVP_TypeId_Voting_OutputTime_Winner OpenViBE::CIdentifier(0x72416689, 0x17673658)
#define OVP_TypeId_Voting_OutputTime_Last OpenViBE::CIdentifier(0x4F2830DB, 0x716C2930)
#define OVP_TypeId_Voting_RejectClass_CanWin OpenViBE::CIdentifier(0x442F2F14, 0x7A17336C)
#define OVP_TypeId_Voting_RejectClass_CanWin_Yes OpenViBE::CIdentifier(0x40011974, 0x54BB3C71)
#define OVP_TypeId_Voting_RejectClass_CanWin_No OpenViBE::CIdentifier(0x275B746A, 0x480B302C)
#define OV_TypeId_PlayerAction OpenViBE::CIdentifier(0xCC14D8D6, 0xF27ECB73)
#define OV_TypeId_PlayerAction_Play OpenViBE::CIdentifier(0x6BD7E1B3, 0x85E75066)
#define OV_TypeId_PlayerAction_Stop OpenViBE::CIdentifier(0x8A72885E, 0xD537A9A4)
#define OV_TypeId_PlayerAction_Pause OpenViBE::CIdentifier(0xD2FA4573, 0xE7F1D11D)
#define OV_TypeId_PlayerAction_Forward OpenViBE::CIdentifier(0xE43E9888, 0x33A361ED)
// Global defines
//---------------------------------------------------------------------------------------------------
#ifdef TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
#include "ovp_global_defines.h"
#endif // TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
@@ -0,0 +1,46 @@
#include "ovp_defines.h"
#include "box-algorithms/ovpCBoxAlgorithmClockStimulator.h"
#include "box-algorithms/ovpCBoxAlgorithmPlayerController.h"
#include "box-algorithms/ovpCBoxAlgorithmStimulationMultiplexer.h"
#include "box-algorithms/ovpCBoxAlgorithmStimulationVoter.h"
#include "box-algorithms/ovpCBoxAlgorithmStreamEndDetector.h"
#include "box-algorithms/ovpCBoxAlgorithmTimeout.h"
namespace OpenViBE {
namespace Plugins {
namespace Stimulation {
OVP_Declare_Begin()
context.getTypeManager().registerEnumerationType(OV_TypeId_PlayerAction, "Player Action");
context.getTypeManager().registerEnumerationEntry(OV_TypeId_PlayerAction, "Play", OV_TypeId_PlayerAction_Play.id());
context.getTypeManager().registerEnumerationEntry(OV_TypeId_PlayerAction, "Stop", OV_TypeId_PlayerAction_Stop.id());
context.getTypeManager().registerEnumerationEntry(OV_TypeId_PlayerAction, "Pause", OV_TypeId_PlayerAction_Pause.id());
context.getTypeManager().registerEnumerationEntry(OV_TypeId_PlayerAction, "Forward", OV_TypeId_PlayerAction_Forward.id());
OVP_Declare_New(CBoxAlgorithmClockStimulatorDesc);
OVP_Declare_New(CBoxAlgorithmPlayerControllerDesc);
OVP_Declare_New(CBoxAlgorithmStimulationMultiplexerDesc);
OVP_Declare_New(CBoxAlgorithmStreamEndDetectorDesc);
OVP_Declare_New(CBoxAlgorithmTimeoutDesc);
OVP_Declare_New(CBoxAlgorithmStimulationVoterDesc);
context.getTypeManager().registerEnumerationType(OVP_TypeId_Voting_ClearVotes, "Clear votes");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_Voting_ClearVotes, "When expires", OVP_TypeId_Voting_ClearVotes_WhenExpires.id());
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_Voting_ClearVotes, "After output", OVP_TypeId_Voting_ClearVotes_AfterOutput.id());
context.getTypeManager().registerEnumerationType(OVP_TypeId_Voting_OutputTime, "Output time");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_Voting_OutputTime, "Time of voting", OVP_TypeId_Voting_OutputTime_Vote.id());
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_Voting_OutputTime, "Time of last winning stimulus", OVP_TypeId_Voting_OutputTime_Winner.id());
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_Voting_OutputTime, "Time of last voting stimulus", OVP_TypeId_Voting_OutputTime_Last.id());
context.getTypeManager().registerEnumerationType(OVP_TypeId_Voting_RejectClass_CanWin, "Reject can win");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_Voting_RejectClass_CanWin, "Yes", OVP_TypeId_Voting_RejectClass_CanWin_Yes.id());
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_Voting_RejectClass_CanWin, "No", OVP_TypeId_Voting_RejectClass_CanWin_No.id());
OVP_Declare_End()
} // namespace Stimulation
} // namespace Plugins
} // namespace OpenViBE