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,66 @@
/*
* Generates a channel units stream with user-specified unit and factor
*/
#include "ovpCBoxAlgorithmChannelUnitsGenerator.h"
namespace OpenViBE {
namespace Plugins {
namespace DataGeneration {
bool CChannelUnitsGenerator::initialize()
{
m_headerSent = false;
m_nChannel = size_t(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0)));
m_unit = size_t(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1)));
m_factor = size_t(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2)));
m_encoder.initialize(*this, 0);
return true;
}
bool CChannelUnitsGenerator::uninitialize()
{
m_encoder.uninitialize();
return true;
}
bool CChannelUnitsGenerator::processClock(Kernel::CMessageClock& /*msg*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CChannelUnitsGenerator::process()
{
Kernel::IBoxIO* boxContext = getBoxAlgorithmContext()->getDynamicBoxContext();
if (!m_headerSent)
{
CMatrix* units = m_encoder.getInputMatrix();
units->resize(m_nChannel, 2);
units->setDimensionLabel(1, 0, "Unit");
units->setDimensionLabel(1, 1, "Factor");
for (size_t i = 0; i < m_nChannel; ++i)
{
units->getBuffer()[i * 2 + 0] = double(m_unit);
units->getBuffer()[i * 2 + 1] = double(m_factor);
units->setDimensionLabel(0, i, ("Channel " + std::to_string(i + 1)).c_str());
}
m_encoder.encodeHeader();
boxContext->markOutputAsReadyToSend(0, 0, 0);
m_encoder.encodeBuffer();
boxContext->markOutputAsReadyToSend(0, 0, 0);
m_headerSent = true;
}
return true;
}
} // namespace DataGeneration
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,70 @@
#pragma once
#include "../ovp_defines.h"
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace DataGeneration {
class CChannelUnitsGenerator final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
void release() override { delete this; }
uint64_t getClockFrequency() override { return 1LL << 32; }
bool initialize() override;
bool uninitialize() override;
bool processClock(Kernel::CMessageClock& /*msg*/) override;
bool process() override;
_IsDerivedFromClass_Final_(IBoxAlgorithm, OVP_ClassId_ChannelUnitsGenerator)
protected:
bool m_headerSent = false;
size_t m_nChannel = 0;
size_t m_unit = 0;
size_t m_factor = 0;
Toolkit::TChannelUnitsEncoder<CChannelUnitsGenerator> m_encoder;
};
class CChannelUnitsGeneratorDesc final : public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Channel units generator"); }
CString getAuthorName() const override { return CString("Jussi T. Lindgren"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("Generates channel units"); }
CString getDetailedDescription() const override
{
return CString(
"This box can generate a channel unit stream if specific measurement units are needed. The box is mainly provided for completeness.");
}
CString getCategory() const override { return CString("Data generation"); }
CString getVersion() const override { return CString("1.0"); }
CString getStockItemName() const override { return CString("gtk-execute"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_ChannelUnitsGenerator; }
IPluginObject* create() override { return new CChannelUnitsGenerator(); }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addSetting("Number of channels", OV_TypeId_Integer, "4");
prototype.addSetting("Unit", OV_TypeId_MeasurementUnit, "V");
prototype.addSetting("Factor", OV_TypeId_Factor, "1e-06");
prototype.addOutput("Channel units", OV_TypeId_ChannelUnits);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_ChannelUnitsGeneratorDesc)
};
} // namespace DataGeneration
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,111 @@
#include "ovpCBoxAlgorithmNoiseGenerator.h"
#include <system/ovCMath.h>
#include <iostream>
#include <sstream>
namespace OpenViBE {
namespace Plugins {
namespace DataGeneration {
CNoiseGenerator::CNoiseGenerator()
{
// Use the OV random seed (if specified) to get dictate the sequence here
std::random_device device;
m_engine = std::default_random_engine(device());
}
bool CNoiseGenerator::initialize()
{
m_encoder.initialize(*this, 0);
m_nChannel = size_t(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0)));
m_sampling = size_t(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1)));
m_nGeneratedEpochSample = size_t(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2)));
m_noiseType = size_t(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3)));
m_headerSent = false;
if (m_nChannel == 0)
{
this->getLogManager() << Kernel::LogLevel_Error << "Channel count is 0. At least 1 channel is required. Check box settings.\n";
return false;
}
if (m_sampling == 0)
{
this->getLogManager() << Kernel::LogLevel_Error << "Sampling rate of 0 is not supported. Check box settings.\n";
return false;
}
if (m_nGeneratedEpochSample == 0)
{
this->getLogManager() << Kernel::LogLevel_Error << "Epoch sample count is 0. An epoch must have at least 1 sample. Check box settings.\n";
return false;
}
// Set parameters of the encoder
m_encoder.getInputSamplingRate() = m_sampling;
CMatrix* sample = m_encoder.getInputMatrix();
sample->resize(m_nChannel, m_nGeneratedEpochSample);
for (size_t i = 0; i < m_nChannel; ++i) { sample->setDimensionLabel(0, i, ("Noise " + std::to_string(i + 1)).c_str()); }
return true;
}
bool CNoiseGenerator::uninitialize()
{
m_encoder.uninitialize();
return true;
}
bool CNoiseGenerator::processClock(Kernel::CMessageClock& /*msg*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CNoiseGenerator::process()
{
Kernel::IBoxIO* boxContext = getBoxAlgorithmContext()->getDynamicBoxContext();
// Send header?
if (!m_headerSent)
{
m_encoder.encodeHeader();
boxContext->markOutputAsReadyToSend(0, 0, 0);
m_headerSent = true;
}
else
{
// Send buffer
double* sample = m_encoder.getInputMatrix()->getBuffer();
const size_t n = m_encoder.getInputMatrix()->getBufferElementCount();
if (m_noiseType == OVP_TypeId_NoiseType_Uniform) { for (size_t i = 0; i < n; ++i) { sample[i] = double(m_uniformDistrib(m_engine)); } }
else { for (size_t i = 0; i < n; ++i) { sample[i] = double(m_normalDistrib(m_engine)); } }
const size_t prevNSamples = m_nSentSample;
m_nSentSample = prevNSamples + m_nGeneratedEpochSample;
const uint64_t start = CTime(m_sampling, prevNSamples).time();
const uint64_t end = CTime(m_sampling, m_nSentSample).time();
m_encoder.encodeBuffer();
boxContext->markOutputAsReadyToSend(0, start, end);
}
return true;
}
uint64_t CNoiseGenerator::getClockFrequency()
{
// Intentional parameter swap to get the frequency
return CTime(m_nGeneratedEpochSample, m_sampling).time();
}
} // namespace DataGeneration
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,77 @@
#pragma once
#include "../ovp_defines.h"
#include <toolkit/ovtk_all.h>
#include <random>
namespace OpenViBE {
namespace Plugins {
namespace DataGeneration {
class CNoiseGenerator final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
CNoiseGenerator();
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_NoiseGenerator)
protected:
Toolkit::TSignalEncoder<CNoiseGenerator> m_encoder;
bool m_headerSent = false;
size_t m_nChannel = 0;
size_t m_sampling = 0;
size_t m_nGeneratedEpochSample = 0;
size_t m_nSentSample = 0;
size_t m_noiseType = 0;
std::default_random_engine m_engine;
std::normal_distribution<> m_normalDistrib{ 0.0, 1.0 }; // Mean=0, Var=1
std::uniform_real_distribution<> m_uniformDistrib{ 0.0, 1.0 }; // Min=0, Max=1
};
class CNoiseGeneratorDesc final : public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Noise generator"); }
CString getAuthorName() const override { return CString("Jussi T. Lindgren"); }
CString getAuthorCompanyName() const override { return CString("Inria"); }
CString getShortDescription() const override { return CString("Simple random noise generator"); }
CString getDetailedDescription() const override { return CString("Generates uniform or Gaussian random data"); }
CString getCategory() const override { return CString("Data generation"); }
CString getVersion() const override { return CString("1.1"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_NoiseGenerator; }
IPluginObject* create() override { return new CNoiseGenerator(); }
CString getStockItemName() const override { return CString("gtk-execute"); }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addOutput("Generated signal", OV_TypeId_Signal);
prototype.addSetting("Channel count", OV_TypeId_Integer, "4");
prototype.addSetting("Sampling frequency", OV_TypeId_Integer, "512");
prototype.addSetting("Generated epoch sample count", OV_TypeId_Integer, "32");
prototype.addSetting("Noise type", OVP_TypeId_NoiseType, std::to_string(OVP_TypeId_NoiseType_Uniform).c_str());
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_NoiseGeneratorDesc)
};
} // namespace DataGeneration
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,107 @@
#include "ovpCSinusSignalGenerator.h"
#include <cmath>
#include <cstdio>
namespace OpenViBE {
namespace Plugins {
namespace DataGeneration {
bool CSinusSignalGenerator::initialize()
{
m_encoder.initialize(*this, 0);
// Parses box settings to try connecting to server
m_nChannel = size_t(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0)));
m_sampling = size_t(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1)));
m_nGeneratedEpochSample = size_t(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2)));
m_headerSent = false;
if (m_nChannel == 0)
{
this->getLogManager() << Kernel::LogLevel_Error << "Channel count is 0. At least 1 channel required. Check box settings.\n";
return false;
}
if (m_sampling == 0)
{
this->getLogManager() << Kernel::LogLevel_Error << "Sampling rate of 0 is not supported. Check box settings.\n";
return false;
}
if (m_nGeneratedEpochSample == 0)
{
this->getLogManager() << Kernel::LogLevel_Error << "Epoch sample count is 0. An epoch must have at least 1 sample. Check box settings.\n";
return false;
}
return true;
}
bool CSinusSignalGenerator::uninitialize()
{
m_encoder.uninitialize();
return true;
}
bool CSinusSignalGenerator::processClock(Kernel::CMessageClock& /*msg*/)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
bool CSinusSignalGenerator::process()
{
Kernel::IBoxIO* boxContext = getBoxAlgorithmContext()->getDynamicBoxContext();
if (!m_headerSent)
{
m_encoder.getInputSamplingRate() = m_sampling;
CMatrix* matrix = m_encoder.getInputMatrix();
matrix->resize(m_nChannel, m_nGeneratedEpochSample);
for (size_t i = 0; i < m_nChannel; ++i)
{
// Convention: channel shown as users go as 1,2,...
matrix->setDimensionLabel(0, i, ("sinusOsc " + std::to_string(i + 1)).c_str());
}
m_encoder.encodeHeader();
m_headerSent = true;
const uint64_t time = CTime(m_sampling, m_nSentSample).time();
boxContext->markOutputAsReadyToSend(0, time, time);
}
else
{
double* buffer = m_encoder.getInputMatrix()->getBuffer();
const size_t nSentSample = m_nSentSample;
for (size_t i = 0; i < m_nChannel; ++i)
{
for (size_t j = 0; j < m_nGeneratedEpochSample; ++j)
{
buffer[i * m_nGeneratedEpochSample + j] = sin(((j + m_nSentSample) * (i + 1) * 12.3) / m_sampling)
+ sin(((j + m_nSentSample) * (i + 1) * 4.5) / m_sampling)
+ sin(((j + m_nSentSample) * (i + 1) * 67.8) / m_sampling);
}
}
m_encoder.encodeBuffer();
m_nSentSample += m_nGeneratedEpochSample;
const uint64_t start = CTime(m_sampling, nSentSample).time();
const uint64_t end = CTime(m_sampling, m_nSentSample).time();
boxContext->markOutputAsReadyToSend(0, start, end);
}
return true;
}
} // namespace DataGeneration
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,69 @@
#pragma once
#include "../ovp_defines.h"
#include <toolkit/ovtk_all.h>
namespace OpenViBE {
namespace Plugins {
namespace DataGeneration {
class CSinusSignalGenerator final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
CSinusSignalGenerator() {}
void release() override { delete this; }
uint64_t getClockFrequency() override { return CTime(m_nGeneratedEpochSample, m_sampling).time(); } // Intentional parameter swap to get the frequency
bool initialize() override;
bool uninitialize() override;
bool processClock(Kernel::CMessageClock& msg) override;
bool process() override;
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_SinusSignalGenerator)
protected:
Toolkit::TSignalEncoder<CSinusSignalGenerator> m_encoder;
bool m_headerSent = false;
size_t m_nChannel = 0;
size_t m_sampling = 0;
size_t m_nGeneratedEpochSample = 0;
size_t m_nSentSample = 0;
};
class CSinusSignalGeneratorDesc final : public IBoxAlgorithmDesc
{
public:
void release() override { }
CString getName() const override { return CString("Sinus oscillator"); }
CString getAuthorName() const override { return CString("Yann Renard"); }
CString getAuthorCompanyName() const override { return CString("INRIA/IRISA"); }
CString getShortDescription() const override { return CString("Simple sinus signal generator"); }
CString getDetailedDescription() const override { return CString(""); }
CString getCategory() const override { return CString("Data generation"); }
CString getVersion() const override { return CString("1.0"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_SinusSignalGenerator; }
IPluginObject* create() override { return new CSinusSignalGenerator(); }
CString getStockItemName() const override { return CString("gtk-execute"); }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addOutput("Generated signal", OV_TypeId_Signal);
prototype.addSetting("Channel count", OV_TypeId_Integer, "4");
prototype.addSetting("Sampling frequency", OV_TypeId_Integer, "512");
prototype.addSetting("Generated epoch sample count", OV_TypeId_Integer, "32");
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_SinusSignalGeneratorDesc)
};
} // namespace DataGeneration
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,23 @@
#pragma once
// Boxes
//---------------------------------------------------------------------------------------------------
#define OVP_ClassId_SinusSignalGenerator OpenViBE::CIdentifier(0x7E33BDB8, 0x68194A4A)
#define OVP_ClassId_SinusSignalGeneratorDesc OpenViBE::CIdentifier(0x2633AFA2, 0x6974E32F)
#define OVP_ClassId_TimeSignalGenerator OpenViBE::CIdentifier(0x28A5E7FF, 0x530095DE)
#define OVP_ClassId_TimeSignalGeneratorDesc OpenViBE::CIdentifier(0x57AD8655, 0x1966B4DC)
#define OVP_ClassId_NoiseGenerator OpenViBE::CIdentifier(0x0E3929F1, 0x15AF76B9)
#define OVP_ClassId_NoiseGeneratorDesc OpenViBE::CIdentifier(0x7237458A, 0x1F312C4A)
#define OVP_ClassId_ChannelUnitsGenerator OpenViBE::CIdentifier(0x42B09186, 0x582C8422)
#define OVP_ClassId_ChannelUnitsGeneratorDesc OpenViBE::CIdentifier(0x4901A752, 0xD8578577)
// Global defines
//---------------------------------------------------------------------------------------------------
#ifdef TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
#include "ovp_global_defines.h"
#endif // TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
#define OVP_TypeId_NoiseType OpenViBE::CIdentifier(0x2E85E95E, 0x8A1A8365)
#define OVP_TypeId_NoiseType_Uniform 1
#define OVP_TypeId_NoiseType_Gaussian 2
@@ -0,0 +1,25 @@
#include "ovp_defines.h"
#include "box-algorithms/ovpCBoxAlgorithmNoiseGenerator.h"
#include "box-algorithms/ovpCSinusSignalGenerator.h"
#include "box-algorithms/ovpCBoxAlgorithmChannelUnitsGenerator.h"
namespace OpenViBE {
namespace Plugins {
namespace DataGeneration {
OVP_Declare_Begin()
OVP_Declare_New(CNoiseGeneratorDesc);
context.getTypeManager().registerEnumerationType(OVP_TypeId_NoiseType, "Noise type");
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_NoiseType, "Uniform", OVP_TypeId_NoiseType_Uniform);
context.getTypeManager().registerEnumerationEntry(OVP_TypeId_NoiseType, "Gaussian", OVP_TypeId_NoiseType_Gaussian);
OVP_Declare_New(CSinusSignalGeneratorDesc);
OVP_Declare_New(CChannelUnitsGeneratorDesc);
OVP_Declare_End()
} // namespace DataGeneration
} // namespace Plugins
} // namespace OpenViBE