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 "ovpCBoxAlgorithmStreamedMatrixSwitch.h"
namespace OpenViBE {
namespace Plugins {
namespace Streaming {
bool CBoxAlgorithmStreamedMatrixSwitch::initialize()
{
// Getting the settings to build the map Stim code / output index
for (size_t i = 1; i < this->getStaticBoxContext().getSettingCount(); ++i)
{
const uint64_t stimCode = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), i);
const size_t idx = i - 1;
if (!m_stimOutputIndexes.insert(std::make_pair(stimCode, idx)).second)
{
this->getLogManager() << Kernel::LogLevel_Warning << "The stimulation code ["
<< this->getTypeManager().getEnumerationEntryNameFromValue(OV_TypeId_Stimulation, stimCode) << "] for the output ["
<< idx << "] is already used by a previous output.\n";
}
else
{
this->getLogManager() << Kernel::LogLevel_Trace << "The stimulation code ["
<< this->getTypeManager().getEnumerationEntryNameFromValue(OV_TypeId_Stimulation, stimCode) << "] is registered for the output ["
<< idx << "]\n";
}
}
const bool defaultToFirstOutput = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
if (defaultToFirstOutput) { m_activeOutputIdx = 0; }
else { m_activeOutputIdx = size_t(-1); } // At start, no output is active.
// Stimulation stream decoder
m_stimDecoder.initialize(*this, 0);
m_lastStimInputChunkEndTime = 0;
//initializing the decoder depending on the input type.
CIdentifier typeID;
this->getStaticBoxContext().getInputType(1, typeID);
m_streamDecoder = nullptr;
if (typeID == OV_TypeId_StreamedMatrix) { m_streamDecoder = new Toolkit::TStreamedMatrixDecoder<CBoxAlgorithmStreamedMatrixSwitch>(*this, 1); }
else if (typeID == OV_TypeId_Signal) { m_streamDecoder = new Toolkit::TSignalDecoder<CBoxAlgorithmStreamedMatrixSwitch>(*this, 1); }
else if (typeID == OV_TypeId_Spectrum) { m_streamDecoder = new Toolkit::TSpectrumDecoder<CBoxAlgorithmStreamedMatrixSwitch>(*this, 1); }
else if (typeID == OV_TypeId_FeatureVector) { m_streamDecoder = new Toolkit::TFeatureVectorDecoder<CBoxAlgorithmStreamedMatrixSwitch>(*this, 1); }
else if (typeID == OV_TypeId_ChannelLocalisation) { m_streamDecoder = new Toolkit::TChannelLocalisationDecoder<CBoxAlgorithmStreamedMatrixSwitch>(*this, 1); }
else if (typeID == OV_TypeId_Stimulations) { m_streamDecoder = new Toolkit::TStimulationDecoder<CBoxAlgorithmStreamedMatrixSwitch>(*this, 1); }
else if (typeID == OV_TypeId_ExperimentInfo) { m_streamDecoder = new Toolkit::TExperimentInfoDecoder<CBoxAlgorithmStreamedMatrixSwitch>(*this, 1); }
else if (typeID == OV_TypeId_ChannelUnits) { m_streamDecoder = new Toolkit::TChannelUnitsDecoder<CBoxAlgorithmStreamedMatrixSwitch>(*this, 1); }
else
{
this->getLogManager() << Kernel::LogLevel_Error << "Unsupported stream type " << this->getTypeManager().getTypeName(typeID) << " (" << typeID.str() << ")\n";
return false;
}
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmStreamedMatrixSwitch::uninitialize()
{
m_stimDecoder.uninitialize();
if (m_streamDecoder)
{
m_streamDecoder->uninitialize();
delete m_streamDecoder;
}
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmStreamedMatrixSwitch::processInput(const size_t /*index*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
/*******************************************************************************/
bool CBoxAlgorithmStreamedMatrixSwitch::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 nOutput = this->getStaticBoxContext().getOutputCount();
uint64_t start = 0;
uint64_t end = 0;
size_t chunkSize = 0;
bool gotStimulation = false;
const uint8_t* buffer = nullptr;
//iterate over all chunk on input 0 (Stimulation)
for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
m_stimDecoder.decode(i);
if (m_stimDecoder.isHeaderReceived() || m_stimDecoder.isEndReceived())
{
// nothing
}
if (m_stimDecoder.isBufferReceived())
{
// we update the active output index and time if needed
IStimulationSet* stimSet = m_stimDecoder.getOutputStimulationSet();
for (size_t j = 0; j < stimSet->getStimulationCount(); j++)
{
if (m_stimOutputIndexes.find(stimSet->getStimulationIdentifier(j)) != m_stimOutputIndexes.end())
{
m_activeOutputIdx = m_stimOutputIndexes[stimSet->getStimulationIdentifier(j)];
this->getLogManager() << Kernel::LogLevel_Trace << "Switching with ["
<< this->getTypeManager().getEnumerationEntryNameFromValue(OV_TypeId_Stimulation, stimSet->getStimulationIdentifier(j))
<< "] to output [" << m_activeOutputIdx << "].\n";
}
}
gotStimulation = true;
m_lastStimInputChunkEndTime = boxContext.getInputChunkEndTime(0, i);
}
}
for (size_t i = 0; i < boxContext.getInputChunkCount(1); ++i)
{
//We decode the chunk but we don't automatically mark it as deprecated, as we may need to keep it.
m_streamDecoder->decode(i, false);
{
boxContext.getInputChunk(1, i, start, end, chunkSize, buffer);
if (m_streamDecoder->isHeaderReceived() || m_streamDecoder->isEndReceived())
{
for (size_t j = 0; j < nOutput; ++j)
{
boxContext.appendOutputChunkData(j, buffer, chunkSize);
boxContext.markOutputAsReadyToSend(j, start, end);
}
boxContext.markInputAsDeprecated(1, i);
}
if (m_streamDecoder->isBufferReceived())
{
// we drop every chunk when no output is activated
if (m_activeOutputIdx == size_t(-1)) { boxContext.markInputAsDeprecated(1, i); }
else
{
if (!gotStimulation || (start < m_lastStimInputChunkEndTime))
{
// the input chunk is in the good time range (we are sure that no stim has been received to change the active output)
boxContext.appendOutputChunkData(m_activeOutputIdx, buffer, chunkSize);
boxContext.markOutputAsReadyToSend(m_activeOutputIdx, start, end);
boxContext.markInputAsDeprecated(1, i);
}
// else : we keep the input chunk, no mark as deprecated !
}
}
}
}
return true;
}
} // namespace Streaming
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,159 @@
#pragma once
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <stdio.h>
#include <map>
namespace OpenViBE {
namespace Plugins {
namespace Streaming {
/**
* \class CBoxAlgorithmStreamedMatrixSwitch
* \author Laurent Bonnet (INRIA)
* \date Thu May 12 18:02:05 2011
* \brief The class CBoxAlgorithmStreamedMatrixSwitch describes the box Streamed Matrix Switch.
*
*/
class CBoxAlgorithmStreamedMatrixSwitch 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_StreamedMatrixSwitch)
protected:
Toolkit::TStimulationDecoder<CBoxAlgorithmStreamedMatrixSwitch> m_stimDecoder;
Toolkit::TDecoder<CBoxAlgorithmStreamedMatrixSwitch>* m_streamDecoder = nullptr;
std::map<uint64_t, size_t> m_stimOutputIndexes;
size_t m_activeOutputIdx = 0;
uint64_t m_lastStimInputChunkEndTime = 0;
};
class CBoxAlgorithmStreamedMatrixSwitchListener final : public Toolkit::TBoxListener<IBoxListener>
{
public:
bool onInputTypeChanged(Kernel::IBox& box, const size_t index) override
{
if (index == 0)
{
box.setInputType(0,OV_TypeId_Stimulations);
return true;
}
CIdentifier id = CIdentifier::undefined();
box.getInputType(1, id);
// all output must have the input type
for (size_t i = 0; i < box.getOutputCount(); ++i) { box.setOutputType(i, id); }
return true;
}
bool onOutputAdded(Kernel::IBox& box, const size_t index) override
{
// the output must have the same type as the input
CIdentifier id = CIdentifier::undefined();
box.getInputType(1, id);
box.setOutputType(index, id);
const char* name = ("Switch stim for output " + std::to_string(index + 1)).c_str();
box.addSetting(name, OV_TypeId_Stimulation, "OVTK_StimulationId_Label_00");
return true;
}
bool onOutputRemoved(Kernel::IBox& box, const size_t index) override
{
box.removeSetting(1 + index); // +1 for the first setting which doesn't correspond to a stream
// Rename the rest to match the changed indexing
for (size_t i = (1 + index); i < box.getSettingCount(); ++i)
{
const char* name = ("Switch stim for output " + std::to_string(i)).c_str();
box.setSettingName(i, name);
}
return true;
}
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
};
/**
* \class CBoxAlgorithmStreamedMatrixSwitchDesc
* \author Laurent Bonnet (INRIA)
* \date Thu May 12 18:02:05 2011
* \brief Descriptor of the box Streamed Matrix Switch.
*
*/
class CBoxAlgorithmStreamedMatrixSwitchDesc final : virtual public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Stream Switch"); }
CString getAuthorName() const override { return CString("Laurent Bonnet"); }
CString getAuthorCompanyName() const override { return CString("INRIA"); }
CString getShortDescription() const override { return CString("Redirect its input on a particular output"); }
CString getDetailedDescription() const override
{
return CString(
"This box act as a switch between N possible outputs for its Streamed Matrix input. N Stimulation settings trigger the switch.");
}
CString getCategory() const override { return CString("Streaming"); }
CString getVersion() const override { return CString("1.1"); }
CString getStockItemName() const override { return CString("gtk-sort-ascending"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_StreamedMatrixSwitch; }
IPluginObject* create() override { return new CBoxAlgorithmStreamedMatrixSwitch; }
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmStreamedMatrixSwitchListener; }
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Triggers",OV_TypeId_Stimulations);
prototype.addInput("Matrix",OV_TypeId_StreamedMatrix);
prototype.addFlag(Kernel::BoxFlag_CanModifyInput);
//prototype.addFlag(Kernel::BoxFlag_CanAddInput);
prototype.addOutput("Output",OV_TypeId_StreamedMatrix);
prototype.addOutput("Output",OV_TypeId_StreamedMatrix);
//prototype.addFlag(Kernel::BoxFlag_CanModifyOutput);
prototype.addFlag(Kernel::BoxFlag_CanAddOutput);
prototype.addSetting("Default to output 1", OV_TypeId_Boolean, "false");
prototype.addSetting("Switch stim for output 1",OV_TypeId_Stimulation, "OVTK_StimulationId_Label_00");
prototype.addSetting("Switch stim for output 2",OV_TypeId_Stimulation, "OVTK_StimulationId_Label_01");
//prototype.addFlag(Kernel::BoxFlag_CanModifySetting);
//prototype.addFlag(Kernel::BoxFlag_CanAddSetting);
//prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_StreamedMatrixSwitchDesc)
};
} // namespace Streaming
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,14 @@
#pragma once
// Boxes
//---------------------------------------------------------------------------------------------------
#define OVP_ClassId_BoxAlgorithm_StreamedMatrixSwitch OpenViBE::CIdentifier(0x556A2C32, 0x61DF49FC)
#define OVP_ClassId_BoxAlgorithm_StreamedMatrixSwitchDesc OpenViBE::CIdentifier(0x556A2C32, 0x61DF49FC)
// Global defines
//---------------------------------------------------------------------------------------------------
#ifdef TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
#include "ovp_global_defines.h"
#endif // TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
#define OV_AttributeId_Box_FlagIsUnstable OpenViBE::CIdentifier(0x666FFFFF, 0x666FFFFF)
@@ -0,0 +1,19 @@
#include "ovp_defines.h"
#include "box-algorithms/ovpCBoxAlgorithmStreamedMatrixSwitch.h"
#include <vector>
namespace OpenViBE {
namespace Plugins {
namespace Streaming {
OVP_Declare_Begin()
context.getTypeManager().registerEnumerationEntry(OV_TypeId_BoxAlgorithmFlag, OV_AttributeId_Box_FlagIsUnstable.toString(),
OV_AttributeId_Box_FlagIsUnstable.id());
OVP_Declare_New(CBoxAlgorithmStreamedMatrixSwitchDesc);
OVP_Declare_End()
} // namespace Streaming
} // namespace Plugins
} // namespace OpenViBE