init
This commit is contained in:
+159
@@ -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
|
||||
+159
@@ -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
|
||||
+14
@@ -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)
|
||||
+19
@@ -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
|
||||
Reference in New Issue
Block a user