Commit af66a6df authored by Jussi Lindgren's avatar Jussi Lindgren

Merge remote-tracking branch 'origin/wip-jlindgre-noise-generator'

* origin/wip-jlindgre-noise-generator:
  Plugins: Added documentation for Noise Generator
  Plugins: Added uniform noise generator box
parents 600cd21b c75a1598
......@@ -25,6 +25,7 @@ namespace System
static System::int64 randomSInterger64(void);
static System::float32 randomFloat32(void);
static System::float32 randomFloat32BetweenZeroAndOne(void);
static System::float64 randomFloat64(void);
private:
......
......@@ -68,6 +68,11 @@ float32 Math::randomFloat32(void)
return fr;
}
float32 Math::randomFloat32BetweenZeroAndOne(void) {
float32 fr = static_cast<float32>(rand()) / static_cast<float32>(RAND_MAX);
return fr;
}
float64 Math::randomFloat64(void)
{
uint64 r=randomUInteger64();
......@@ -75,3 +80,5 @@ float64 Math::randomFloat64(void)
::memcpy(&fr, &r, sizeof(fr));
return fr;
}
/**
* \page BoxAlgorithm_NoiseGenerator Noise generator
__________________________________________________________________
Detailed description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_NoiseGenerator_Description|
The Noise Generator outputs random signals on a configurable number of channels. The sampling frequency and epoch size can be configured as well. The data is sampled from a pseudorandom uniform distribution.
* |OVP_DocEnd_BoxAlgorithm_NoiseGenerator_Description|
__________________________________________________________________
Outputs description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_NoiseGenerator_Outputs|
* |OVP_DocEnd_BoxAlgorithm_NoiseGenerator_Outputs|
* |OVP_DocBegin_BoxAlgorithm_NoiseGenerator_Output1|
Random signal generated.
* |OVP_DocEnd_BoxAlgorithm_NoiseGenerator_Output1|
__________________________________________________________________
Settings description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_NoiseGenerator_Settings|
* |OVP_DocEnd_BoxAlgorithm_NoiseGenerator_Settings|
* |OVP_DocBegin_BoxAlgorithm_NoiseGenerator_Setting1|
Number of channels generated.
* |OVP_DocEnd_BoxAlgorithm_NoiseGenerator_Setting1|
* |OVP_DocBegin_BoxAlgorithm_NoiseGenerator_Setting2|
Sampling frequency of generated signals.
* |OVP_DocEnd_BoxAlgorithm_NoiseGenerator_Setting2|
* |OVP_DocBegin_BoxAlgorithm_NoiseGenerator_Setting3|
Number of samples per epoch
* |OVP_DocEnd_BoxAlgorithm_NoiseGenerator_Setting3|
__________________________________________________________________
Miscellaneous description
__________________________________________________________________
* |OVP_DocBegin_BoxAlgorithm_NoiseGenerator_Miscellaneous|
* |OVP_DocEnd_BoxAlgorithm_NoiseGenerator_Miscellaneous|
*/
#include "ovpCBoxAlgorithmNoiseGenerator.h"
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <openvibe/ovITimeArithmetics.h>
#include <system/CMath.h>
using namespace OpenViBE;
using namespace OpenViBE::Kernel;
using namespace OpenViBE::Plugins;
using namespace OpenViBEPlugins;
using namespace OpenViBEPlugins::Samples;
using namespace OpenViBEToolkit;
using namespace std;
CNoiseGenerator::CNoiseGenerator(void)
:
m_bHeaderSent(false)
,m_ui64ChannelCount(0)
,m_ui64SamplingFrequency(0)
,m_ui64GeneratedEpochSampleCount(0)
,m_ui64SentSampleCount(0)
{
}
void CNoiseGenerator::release(void)
{
delete this;
}
boolean CNoiseGenerator::initialize(void)
{
m_pStreamEncoder=&getAlgorithmManager().getAlgorithm(getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SignalStreamEncoder));
if(!m_pStreamEncoder) {
this->getLogManager() << LogLevel_Error << "Unable to get stream encoder.\n";
return false;
}
m_pStreamEncoder->initialize();
m_ui64ChannelCount=FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_ui64SamplingFrequency=FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_ui64GeneratedEpochSampleCount=FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);
m_bHeaderSent=false;
if(m_ui64ChannelCount == 0)
{
this->getLogManager() << LogLevel_Error << "Channel count is 0. At least 1 channel required. Check box settings.\n";
return false;
}
if(m_ui64SamplingFrequency == 0)
{
this->getLogManager() << LogLevel_Error << "Sampling rate of 0 is not supported. Check box settings.\n";
return false;
}
if(m_ui64GeneratedEpochSampleCount == 0)
{
this->getLogManager() << LogLevel_Error << "Epoch sample count is 0. An epoch must have at least 1 sample. Check box settings.\n";
return false;
}
ip_ui64SignalSamplingRate.initialize(m_pStreamEncoder->getInputParameter(OVP_GD_Algorithm_SignalStreamEncoder_InputParameterId_SamplingRate));
ip_pSignalMatrix.initialize(m_pStreamEncoder->getInputParameter(OVP_GD_Algorithm_SignalStreamEncoder_InputParameterId_Matrix));
ip_ui64SignalSamplingRate = m_ui64SamplingFrequency;
IMatrix &l_rSampleMatrix = *ip_pSignalMatrix;
l_rSampleMatrix.setDimensionCount(2);
l_rSampleMatrix.setDimensionSize(0,(uint32)m_ui64ChannelCount);
l_rSampleMatrix.setDimensionSize(1,(uint32)m_ui64GeneratedEpochSampleCount);
return true;
}
boolean CNoiseGenerator::uninitialize(void)
{
m_pStreamEncoder->uninitialize();
getAlgorithmManager().releaseAlgorithm(*m_pStreamEncoder);
return true;
}
boolean CNoiseGenerator::processClock(CMessageClock& rMessageClock)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
boolean CNoiseGenerator::process(void)
{
IBoxIO* l_pDynamicBoxContext=getBoxAlgorithmContext()->getDynamicBoxContext();
TParameterHandler < IMemoryBuffer* > l_oOutputMemoryBufferHandle(m_pStreamEncoder->getOutputParameter(OVP_GD_Algorithm_StreamedMatrixStreamEncoder_OutputParameterId_EncodedMemoryBuffer));
l_oOutputMemoryBufferHandle=l_pDynamicBoxContext->getOutputChunk(0);
if(!m_bHeaderSent)
{
m_pStreamEncoder->process(OVP_GD_Algorithm_StreamedMatrixStreamEncoder_InputTriggerId_EncodeHeader);
uint64 l_ui64Time=ITimeArithmetics::sampleCountToTime(m_ui64SamplingFrequency, m_ui64SentSampleCount);
l_pDynamicBoxContext->markOutputAsReadyToSend(0, l_ui64Time, l_ui64Time);
m_bHeaderSent=true;
}
else
{
IMatrix &l_rSampleMatrix = *ip_pSignalMatrix;
float64* l_pSampleBuffer = l_rSampleMatrix.getBuffer();
uint32 l_ui32SentSampleCount=(uint32)m_ui64SentSampleCount;
for(uint32 i=0; i<(uint32)m_ui64ChannelCount; i++)
{
for(uint32 j=0; j<(uint32)m_ui64GeneratedEpochSampleCount; j++)
{
l_pSampleBuffer[i*m_ui64GeneratedEpochSampleCount+j]=(float64)System::Math::randomFloat32BetweenZeroAndOne();
}
}
m_ui64SentSampleCount+=m_ui64GeneratedEpochSampleCount;
uint64 l_ui64StartTime = ITimeArithmetics::sampleCountToTime(m_ui64SamplingFrequency, l_ui32SentSampleCount);
uint64 l_ui64EndTime = ITimeArithmetics::sampleCountToTime(m_ui64SamplingFrequency, m_ui64SentSampleCount);
m_pStreamEncoder->process(OVP_GD_Algorithm_StreamedMatrixStreamEncoder_InputTriggerId_EncodeBuffer);
l_pDynamicBoxContext->markOutputAsReadyToSend(0, l_ui64StartTime, l_ui64EndTime);
}
return true;
}
OpenViBE::uint64 CNoiseGenerator::getClockFrequency(void)
{
// Intentional parameter swap to get the frequency
return ITimeArithmetics::sampleCountToTime(m_ui64GeneratedEpochSampleCount, m_ui64SamplingFrequency);
}
#ifndef __SamplePlugin_CNoiseGenerator_H__
#define __SamplePlugin_CNoiseGenerator_H__
#include "../ovp_defines.h"
#include <toolkit/ovtk_all.h>
namespace OpenViBEPlugins
{
namespace Samples
{
class CNoiseGenerator : public OpenViBEToolkit::TBoxAlgorithm<OpenViBE::Plugins::IBoxAlgorithm>
{
public:
CNoiseGenerator(void);
virtual void release(void);
virtual OpenViBE::uint64 getClockFrequency(void);
virtual OpenViBE::boolean initialize(void);
virtual OpenViBE::boolean uninitialize(void);
virtual OpenViBE::boolean processClock(OpenViBE::Kernel::IMessageClock& rMessageClock);
virtual OpenViBE::boolean process(void);
_IsDerivedFromClass_Final_(OpenViBEToolkit::TBoxAlgorithm<OpenViBE::Plugins::IBoxAlgorithm>, OVP_ClassId_NoiseGenerator)
protected:
OpenViBE::Kernel::IAlgorithmProxy* m_pStreamEncoder;
OpenViBE::Kernel::TParameterHandler < OpenViBE::IMatrix* > ip_pSignalMatrix;
OpenViBE::Kernel::TParameterHandler < OpenViBE::uint64 > ip_ui64SignalSamplingRate;
OpenViBE::boolean m_bHeaderSent;
OpenViBE::uint64 m_ui64ChannelCount;
OpenViBE::uint64 m_ui64SamplingFrequency;
OpenViBE::uint64 m_ui64GeneratedEpochSampleCount;
OpenViBE::uint64 m_ui64SentSampleCount;
};
class CNoiseGeneratorDesc : public OpenViBE::Plugins::IBoxAlgorithmDesc
{
public:
virtual void release(void) { }
virtual OpenViBE::CString getName(void) const { return OpenViBE::CString("Noise generator"); }
virtual OpenViBE::CString getAuthorName(void) const { return OpenViBE::CString("Jussi T. Lindgren"); }
virtual OpenViBE::CString getAuthorCompanyName(void) const { return OpenViBE::CString("Inria"); }
virtual OpenViBE::CString getShortDescription(void) const { return OpenViBE::CString("Simple random noise generator"); }
virtual OpenViBE::CString getDetailedDescription(void) const { return OpenViBE::CString("Generates uniform random data in range [0,1]"); }
virtual OpenViBE::CString getCategory(void) const { return OpenViBE::CString("Data generation"); }
virtual OpenViBE::CString getVersion(void) const { return OpenViBE::CString("1.0"); }
virtual OpenViBE::CIdentifier getCreatedClass(void) const { return OVP_ClassId_NoiseGenerator; }
virtual OpenViBE::Plugins::IPluginObject* create(void) { return new OpenViBEPlugins::Samples::CNoiseGenerator(); }
virtual OpenViBE::CString getStockItemName(void) const { return OpenViBE::CString("gtk-execute"); }
virtual OpenViBE::boolean getBoxPrototype(
OpenViBE::Kernel::IBoxProto& rPrototype) const
{
rPrototype.addOutput("Generated signal", OV_TypeId_Signal);
rPrototype.addSetting("Channel count", OV_TypeId_Integer, "4");
rPrototype.addSetting("Sampling frequency", OV_TypeId_Integer, "512");
rPrototype.addSetting("Generated epoch sample count", OV_TypeId_Integer, "32");
return true;
}
_IsDerivedFromClass_Final_(OpenViBE::Plugins::IBoxAlgorithmDesc, OVP_ClassId_NoiseGeneratorDesc)
};
};
};
#endif // __SamplePlugin_CNoiseGenerator_H__
......@@ -40,6 +40,9 @@
#define OVP_ClassId_AlgorithmAdditionDesc OpenViBE::CIdentifier(0x842E0B85, 0xA59FABC1)
#define OVP_ClassId_BoxAlgorithmAdditionTestDesc OpenViBE::CIdentifier(0xB33EC315, 0xF63BC0C5)
#define OVP_ClassId_NoiseGeneratorDesc OpenViBE::CIdentifier(0x7237458A, 0x1F312C4A)
#define OVP_ClassId_NoiseGenerator OpenViBE::CIdentifier(0x0E3929F1, 0x15AF76B9)
//___________________________________________________________________//
// //
// Plugin Object Class Identifiers //
......
......@@ -5,6 +5,7 @@
#include "ovpCScenarioExporterSVG.h"
#include "box-algorithms/ovpCCrashingBox.h"
#include "box-algorithms/ovpCBoxAlgorithmNoiseGenerator.h"
#include "box-algorithms/ovpCSinusSignalGenerator.h"
#include "box-algorithms/ovpCTimeSignalGenerator.h"
#include "box-algorithms/ovpCIdentity.h"
......@@ -44,6 +45,7 @@ OVP_Declare_Begin();
// OVP_Declare_New(OpenViBEPlugins::Samples::CCrashingBoxDesc);
// OVP_Declare_New(OpenViBEPlugins::Samples::CBoxAlgorithmProducerDesc);
// OVP_Declare_New(OpenViBEPlugins::Samples::CBoxAlgorithmConsumerDesc);
OVP_Declare_New(OpenViBEPlugins::Samples::CNoiseGeneratorDesc);
OVP_Declare_New(OpenViBEPlugins::Samples::CSinusSignalGeneratorDesc);
OVP_Declare_New(OpenViBEPlugins::Samples::CTimeSignalGeneratorDesc);
OVP_Declare_New(OpenViBEPlugins::Samples::CIdentityDesc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment