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,67 @@
#pragma once
#include "ovas_base.h"
#include "../ovasCSettingsHelper.h"
#include "boost/variant.hpp"
#include <deque>
/**
* \brief Interface for acquisition server plugins
*
* Contains an interface to the acquisition server plugins. Any plugin must inherit from this class in order to be able to register with the acquisition server.
*/
namespace OpenViBE {
namespace AcquisitionServer {
class CAcquisitionServer;
class IAcquisitionServerPlugin
{
public:
// Interface of the plugin. To develop a new plugin override any of the Hook functions in your implementation.
/// Hook called at the end of the AcquisitionServer constructor
virtual void createHook() {}
/// Hook called at the end of the start() function of AcquisitionServer. At this point the device has been connected to,
/// and signal properties should already be correct.
/// This function should return false if start failed.
virtual bool startHook(const std::vector<CString>& /*selectedChannelNames*/, const size_t /*sampling*/, const size_t /*nChannel*/,
const size_t /*nSamplePerSentBlock*/) { return true; }
/// Hook called at the end of the stop() function of AcquisitionServer
virtual void stopHook() {}
/** \brief Hook called in the loop() function of AcquisitionServer
*
* This hook is called before sending the stimulations or signal to the connected clients.
* It gets a reference to the current signal buffer and the stimulation set with its start and end dates.
*
* Note that the given input buffer may have more samples than what should be processed
* per iteration. All operations on vPendingBuffer done in the hook should only consider
* the first sampleCountSentPerBlock samples. The later samples should be left as-is
* and will be provided on the next call.
*/
virtual void loopHook(std::deque<std::vector<float>>& /*pendingBuffer*/, CStimulationSet& /*stimulationSet*/, const uint64_t /*start*/,
const uint64_t /*end*/, const uint64_t /*sampleTime*/) {}
/// Hook called at the end of the acceptNewConnection() function of AcquisitionServer
virtual void acceptNewConnectionHook() {}
IAcquisitionServerPlugin(const Kernel::IKernelContext& ctx, const CString& name)
: m_kernelCtx(ctx), m_settings(name, ctx.getConfigurationManager()) {}
virtual ~IAcquisitionServerPlugin() {}
const SettingsHelper& getSettingsHelper() const { return m_settings; }
SettingsHelper& getSettingsHelper() { return m_settings; }
protected:
const Kernel::IKernelContext& m_kernelCtx;
SettingsHelper m_settings;
};
} // namespace AcquisitionServer
} // namespace OpenViBE
@@ -0,0 +1,510 @@
#pragma once
#include "ovas_base.h"
namespace OpenViBE {
namespace AcquisitionServer {
class IHeader;
enum class EDriverFlag { IsUnstable, IsDeprecated };
/**
* \class IDriverContext
* \author Yann Renard (INRIA/IRISA)
* \date 2009-10-12
* \brief Base class for kernel functioanlities access from the driver classes
* \sa IDriver
*/
class IDriverContext
{
public:
/**
* \brief Destructor
*/
virtual ~IDriverContext() { }
/**
* \brief Gets the kernel Log Manager
* \return the kernel Log Manager
* \sa Kernel::ILogManager
*/
virtual Kernel::ILogManager& getLogManager() const = 0;
/**
* \brief Gets the kernel Configuration Manager
* \return the kernel Configuration Manager
* \sa Kernel::IConfigurationManager
*/
virtual Kernel::IConfigurationManager& getConfigurationManager() const = 0;
/**
* \brief Gets connection status
* \return \e true if the driver is connected
* \return \e false if the driver is not connected
* \sa isStarted
*/
virtual bool isConnected() const = 0;
/**
* \brief Gets acquisition status
* \return \e true if acquisition is started
* \return \e false if acquisition is stoped
* \sa isConnected
*/
virtual bool isStarted() const = 0;
/**
* \brief Checks if impedance check is required (when available)
* \return \e true if impedance check is required
* \return \e false if impedance check is not required
*
* It is up to the driver to check whether impedance check is required by
* the acquisition server or not. If this test is required, then the driver
* should perform impedance measures while initialized but not yet started.
*/
virtual bool isImpedanceCheckRequested() const = 0;
/**
* \brief Gets drift sample count
* \return \e the drift sample count
* \sa correctDriftSampleCount
*
* This function returns the difference between the theorical
* number of samples this driver should have sent so far and
* the number of samples it actually sent. This drift sample
* count is computed by the acquisition server and can be used
* to correct a drifting device behavior.
*
* \note If this number is less than 0 then samples are missing
* \note If this number if more than 0 then there are too much samples
* \note If this number is exactly 0 then the driver sent the exact
* number of samples it had to send
*/
virtual int64_t getDriftSampleCount() const = 0;
/**
* \brief Gets the drift sample count tolerance
* \return \e the drift sample count tolerance
*
* Gets the tolerance configured for the acquisition server. This
* tolerance is present to avoid numerous corrections on a drift
* value that would oscillate in a small range around 0. In such case,
* a correction in a way would probably turn in a correction in the
* opposite way a few seconds later, resulting in crap measurements
* because of irregular but valid source.
*
* If the actual drift is in the [-tolerance +tolerance] range,
* better don't correct it.
*/
virtual int64_t getDriftToleranceSampleCount() const = 0;
/**
* \brief Gets the suggested drift correction sample count
* \return \e the suggested drift correction sample count
*
* In case you don't want to manage how much samples should
* be used to correct the drift, you could simply use this function. The
* algorithm used to compute the returned value should be considered
* as undefined. This computation could change over time and versions
* of OpenViBE. That means the driver should not make any assumption
* on the way of computing the actual value returned by this function.
*/
virtual int64_t getSuggestedDriftCorrectionSampleCount() const = 0;
/**
* \brief Corrects a drifting device
* \return \e true in case of success
* \return \e false in case of error
* \sa getDriftSampleCount
* \sa setInnerLatencySampleCount
*
* Some devices don't sent the number of samples they promised to
* while requesting sampling rate. This can be for multiple reasons
* but the most probable one is that the device does not have its
* internal clock synchronized with the internal computer clock.
* OpenViBE data being dated with a start / end time, it is important
* for synchronisation purpose that all the theorical number of
* samples per second is preserved.
*
* In case the difference between the theorical number of samples
* this driver should have sent so far and the number of samples
* it actually sent becomes too big, this function helps to
* correct the drifting, removing or adding dummy samples.
* In a strict signal processing point of view those samples
* can't be considered as valid. However, this is the only way
* to guarantee that the timings are preserved.
*
* \note Passing a negative value removes samples
* \note Passing a positive value adds samples
* \note Passing 0 does nothing
* \note This function can be called several times if needed
* but does not change what \ref getDriftSampleCount
* returns until the next \ref IDriver::loop execution
* \warning Please be careful when calling this function.
* Consider the fact that there could be some drifting
* in the device and ths OS-level driver itself, or even
* in the communication pipeline to the prorprietary
* acquisition software. As an OpenViBE driver developer,
* you should allow an arbitrary small drifting (which
* range depends of the actual driver you are creating).
*/
virtual bool correctDriftSampleCount(const int64_t nSample) = 0;
/**
* \brief Sets a fixed latency due to the driver implementation and / or hardware
* \param nSample [in] : the number of samples for the inner latency
* \return \e true in case of success
* \return \e false in case of error
*
* Some drivers / hardware devices implement processes that delay the
* overall acquisition stream. Such processes include for instance
* sample buffering or temporal filtering. The delay induced by these
* processes can not be known by the acquisition server in a generic way
* and are usually not provided by the device manufacturer. An intelligent
* setup based on hardware tagging could however induce a fair estimate of this
* latency so that it can be injected in the drift correction process.
* Driver developers will generally not have to care about this feature.
* However, if it is important to have neurophysiologically relevant measures
* (more particularly on ERPs) and it is know that the driver and / or hardware
* has a latency, this latency compensation can be injected in the drift correction
* process using the aforementionned function.
*
* \note Passing a positive value supposes the driver / hardware induce a delay which shall be corrected
* \note Passing a negative value supposes the driver / hardware is able to predict and send future measures before they actually get measured (probably not recommended)
* \note Passing 0 supposes both the driver and hardware are ideals and send samples immediately to the acquisition server as they happen on the scalp
* \note Default configuration supposes both the driver and hardware are ideal, thus sets the inner latency to 0
*
* \sa getInnerLatencySampleCount
*/
virtual void setInnerLatencySampleCount(const int64_t nSample) = 0;
/**
* \brief Gets the fixed latency due to the driver implementation and / or hardware
* \return \e The inner latency of the driver in sample count
* \sa setInnerLatencySampleCount
*/
virtual int64_t getInnerLatencySampleCount() const = 0;
/**
* \brief Updates impedance for a specific channel
* \param index [in] : the index of the channel should be updated
* \param impedance [in] : the impedance of the specified channel (in ohm)
* \return \e true in case of success.
* \return \e false in case of error.
*
* This can be used during initialization phase to check
* if impedances are correct. This function should be connected
* while the driver is initialized and not started.
*
* If \c impedance is -1, then the impedance is considered as "unknown / measuring"
* If \c impedance is -2, then the impedance is considered as "unknown / not available"
* If \c impedance is any other negative value, then the impedance is considered as "unknown"
*/
virtual bool updateImpedance(const size_t index, const double impedance) = 0;
};
/**
* \class IDriverCallback
* \author Yann Renard (INRIA/IRISA)
* \date 2007-04-01
* \brief Base class for all the OpenViBE acquisition server driver callbacks
*
* Objects derived from this class are called by any driver to provide
* built sample buffers.
*
* \sa IDriver
* \sa IDriver::loop
*/
class IDriverCallback
{
public:
/**
* \brief Gives new sample buffer
* \param samples [in] : a buffer containing all the samples
*
* This is used by the acquisition server to be notified when the
* driver has finished to build the whole buffer of data to send.
* This function is called by the driver during the \e IDriver::loop
* and should give an array of \c nSamplesPerChannel x \c nChannel
* organised by channel first.
*
* The caller retains the ownership of the samples pointer.
*
* \code
* samples[0] is channel 0 sample 0
* samples[1] is channel 0 sample 1
* ...
* samples[nSamplesPerChannel-1] is channel 0 sample nSamplesPerChannel-1
* samples[nSamplesPerChannel ] is channel 1 sample 0
* samples[nSamplesPerChannel+1] is channel 1 sample 1
* ...
* samples[i*nSamplesPerChannel+j] is channel i sample j
* \endcode
*
* \sa IDriver::loop
*/
virtual void setSamples(const float* samples) = 0;
/**
* \brief Gives new sample buffer
* \param samples [in] : a buffer containing all the samples
* \param size : size of buffer
*
* This is used by the acquisition server to be notified when the
* driver has finished to build the whole buffer of data to send.
* This function is called by the driver during the \e IDriver::loop
* and should give an array of \c nSamplesPerChannel x \c nChannel
* organised by channel first.
*
* The caller retains the ownership of the samples pointer.
*
* \code
* samples[0] is channel 0 sample 0
* samples[1] is channel 0 sample 1
* ...
* samples[nSamplesPerChannel-1] is channel 0 sample nSamplesPerChannel-1
* samples[nSamplesPerChannel ] is channel 1 sample 0
* samples[nSamplesPerChannel+1] is channel 1 sample 1
* ...
* samples[i*nSamplesPerChannel+j] is channel i sample j
* \endcode
*
* \sa IDriver::loop
*/
virtual void setSamples(const float* samples, const size_t size) = 0;
/**
* \brief Gives a new stimulation set corresponding to the last sample buffer
* \param stimSet [in] : the stimulation set associated with the last sample buffer
*
* This is used by the acquisition server to be notified when the
* driver has finished to build the whole buffer of data to send.
* This function is called by the driver during the \e IDriver::loop
* and immediatly after the IDriverCallback::setSamples function, even
* if the stimulation set is empty.
*
* \warning The stimulation dates are relative to the
* last buffer start time.
*
* \sa IDriver::loop
*/
virtual void setStimulationSet(const IStimulationSet& stimSet) = 0;
/**
* \brief Destructor
*/
virtual ~IDriverCallback() { }
};
/**
* \class IDriver
* \author Yann Renard (INRIA/IRISA)
* \date 2007-04-01
* \brief Base class for all the OpenViBE acquisition server drivers
*
* This class should be used by hardware driver developers in order
* to add new peripherals to the OpenViBE acquisition server. This driver
* is then used by the server to get cerebral activity measurments and to
* send this measured activity to the platform so it can be processed.
*
* The behavior of the driver is splitted into 3 phases :
* - configuration
* - initialization / uninitialization
* - acquisition start / stop
*
* The implemented driver could either have direct access to the hardware
* or read the measurements from a proprietarry server, depending on the
* hardware manufacturer choice. Thus, the configuration phase of this driver
* should be able to provide the information OpenViBE needs that are
* not present from the hardware manufacturer'.
*
* Important job for the driver is to give the acquisition server fixed
* size measured buffers... This implies that if the hardware sends random
* size buffers, sample per sample buffers, fixed length buffer but not the
* size the acquisition server requested, it would be the driver's job to
* rebuild correct buffers.
*
* \sa CAcquisitionServer
*/
class IDriver
{
public:
/**
* \brief Constructor
* \param ctx [in] : the driver context
*/
explicit IDriver(IDriverContext& ctx) : m_driverCtx(ctx) { }
/**
* \brief Destructor
*/
virtual ~IDriver() { }
/** \name General purpose functions */
//@{
/**
* \brief Gets the driver name (usually the hardware name)
* \return the driver name.
*/
virtual const char* getName() = 0;
/**
* \brief Tests if a flag is set for this driver
* \param flag [in] : the flag to test
* \return \e true if the tested flag is set
* \return \e false if the tested flag is not set
* \note Default implementation always returns false, meaning that no flag is set
*/
virtual bool isFlagSet(const EDriverFlag flag) const { return false; }
//@}
/** \name Driver configuration */
//@{
/**
* \brief This function should tell whether the dirver is configurable or not
* \return \e true if this driver is configurable.
* \return \e false if this driver is not configurable.
* \sa configure
*/
virtual bool isConfigurable() = 0;
/**
* \brief Requests the driver to configure itself
* \return \e true if the configuration ended successfully
* \return \e false if the configuration ended with an error
*
* This function requests the driver to configure itself. The acquisition
* server never calls this function if \c isConfigurable returned \e false.
* However, calling this reflects a lack of information from the
* hardware itself or from the server that is provided by the hardware
* manufacturer. The configure function should then ask the user
* for missing information to be filled.
*
* Filling these information can be done any way you want... But
* if the driver developer wants to use a GUI for this, it is
* recommended to use Glade/GTK since the acquisition server
* already uses this API. If you use Glade/GTK, you won't have to
* perform API initialization ; this is done by the acquisition server
* already. It is the responsability of the driver developer to
* release any allocated GUI object after the configuration is done.
*
* \sa isConfigurable
*/
virtual bool configure() = 0;
//@}
/** \name Initialization / uninitialization */
//@{
/**
* \brief Initializes the driver
* \param nSamplePerSentBlock [in] : the number of samples to
* send per channel per driver send operation.
* \param callback [in] : the callback object to call when the buffer
* are filled correctly.
* \return \e true in case of success.
* \return \e false in case of error.
*
* When called, this function should prepare the driver to receive
* data from the hardware. This means doing everything from checking
* the hardware is present, checking its configuration, getting header
* information from it and so on. This function should return only when
* it has a valid header to return to the acquisition server... For
* some hardware, this could nead data sending request (so it gets basic
* information), and then request data sending to stop...
*
* \sa uninitialize
* \sa getHeader
* \sa IHeader
*/
virtual bool initialize(const uint32_t nSamplePerSentBlock, IDriverCallback& callback) = 0;
/**
* \brief Uninitializes the driver
* \return \e true in case of success.
* \return \e false in case of error.
*
* This function disconnects any link to the hardware and frees any
* allocated structures/objects related to the hardware. When this
* is called, the driver may be re-configured and re-initialized
* to start a new acquisition session.
*/
virtual bool uninitialize() = 0;
/**
* \brief Gets the header information for the session
* \return the header information for the session
*
* The returned header is used by the acquisition server to send
* encapsulated data to the platform at the beginning of the sending
* process. This header should be filled by the information collected
* from the hardware or the driver itself when configure is called.
*
* \sa IHeader
*/
virtual const IHeader* getHeader() = 0;
//@}
/** \name Starting / Stopping acquisition */
//@{
/**
* \brief Starts acquisition for this driver
* \return \e true in case of success.
* \return \e false in case of error.
*
* This function is called by the acquistion server to notify the driver
* that signal acquisiton should start... The driver should forward this
* instruction to the hardware... The loop function is then called
* repeatedly to receive data from the hardware and send it back to the
* server.
*
* \sa loop
* \sa stop
*/
virtual bool start() = 0;
/**
* \brief Stops acquisition for this driver
* \return \e true in case of success.
* \return \e false in case of error.
*
* This function is called by the acquistion server to notify the driver
* that signal acquisiton should stop... The driver should forward this
* instruction to the hardware... The loop function is then no more called
* and the driver may be uninitialized to be re-configured.
*
* \sa start
* \sa loop
*/
virtual bool stop() = 0;
/**
* \brief Requests data acquisition to be done
* \return \e true in case of success.
* \return \e false in case of error.
*
* This function is called repeatedly by the acquisition server when
* the driver is correctly initialized and started. The driver's job
* here is to receive measures from the hardware, build the buffers
* according to the requested sampling count per channel (see \c initialize)
* and send this built buffer to the provided callback object. The
* server will then send these informations to the platform.
*
* During this loop function, the object passed as IDriverCallback at
* the initialize phase should be ready to be notified of samples or
* stimulations.
*
* \warning When implementing the driver, one should take care
* of configuring stimulation dates so that they are relative
* to the last buffer start time.
*
* \sa IDriverCallback::setSamples
* \sa IDriverCallback::setStimulationSet
*/
virtual bool loop() = 0;
//@}
protected:
IDriverContext& m_driverCtx; ///< The driver context
private:
/**
* \brief Default constructor can not be used because a context is needed
*/
IDriver();
};
} // namespace AcquisitionServer
} // namespace OpenViBE
@@ -0,0 +1,325 @@
#pragma once
#include "ovas_base.h"
namespace OpenViBE {
namespace AcquisitionServer {
/**
* \class IHeader
* \author Yann Renard (INRIA/IRISA)
* \date 2007-04-01
* \brief Base class for an OpenViBE header container
*
* IHeader objects are used by IDriver objects to give all the header
* information to the acquisition server. The IDriver developer may
* implement his own IHeader derived class or use the one provided
* with the acquisition server. To get a standard header, refer to
* the \c CHeader class.
*
* The IHeader objects mainly consist in get/set/isSet functions
* that allow user code to modify, read back and check state of some
* single header information.
*
* \sa IDriver
* \sa IDriver::getHeader
* \sa CHeader
*/
class IHeader
{
public:
/** \name General purpose functions */
//@{
/**
* \brief Resets this header
*
* When called, this function resets all the header content to its
* default values. Most of the is*Set will return \e false after
* this call.
*/
virtual void reset() = 0;
//@}
/** \name Experiment information */
//@{
/**
* \brief Sets the experiment identifier
* \param experimentID [in] : the experiment identifier to send to
* the OpenViBE platform.
* \return \e true in case of success.
* \return \e false in case of error.
*
* The experiment identifier may be used by the platform
* to get details from a database, for example a description
* of the experiment, what is done, where etc...
*/
virtual bool setExperimentID(const size_t experimentID) = 0;
/**
* \brief Sets the subject age
* \param subjectAge [in] : the subject age in years
* \return \e true in case of success.
* \return \e false in case of error.
*/
virtual bool setSubjectAge(const size_t subjectAge) = 0;
/**
* \brief Sets the subject gender
* \param subjectGender [in] : the subject gender
* \return \e true in case of success.
* \return \e false in case of error.
*
* The subject gender is given as an integer and should
* be ISO 5218 conformant... Allowed values are :
* - 0 : unknown
* - 1 : male
* - 2 : female
* - 3 : not specified
*
* \note This values are defined in the OpenViBE toolkit.
*/
virtual bool setSubjectGender(const size_t subjectGender) = 0;
/**
* \brief Gets the experiment identifier
* \return the experiement identifier.
* \sa setExperimentID
*/
virtual size_t getExperimentID() const = 0;
/**
* \brief Gets the subject age
* \return the subject age.
* \sa setSubjectAge
*/
virtual size_t getSubjectAge() const = 0;
/**
* \brief Gets the subject gender
* \return the subject gender.
* \sa setSubjectGender
*/
virtual size_t getSubjectGender() const = 0;
/**
* \brief Tests if experiment identifier has been set
* \return \e true if experiment identifier has been set since last \c reset.
* \return \e false if experiment identifier has not been set.
* \sa setExperimentID
*/
virtual bool isExperimentIDSet() const = 0;
/**
* \brief Tests if subject age has been set
* \return \e true if the subject age has been set since last \c reset.
* \return \e false if the subject age has not been set.
* \sa setSubjectAge
*/
virtual bool isSubjectAgeSet() const = 0;
/**
* \brief Tests if subject gender has been set
* \return \e true if the subject gender has been set since last \c reset.
* \return \e false if the subject gender has not been set.
* \sa setSubjectGender
*/
virtual bool isSubjectGenderSet() const = 0;
virtual void setImpedanceCheckRequested(const bool active) = 0;
virtual bool isImpedanceCheckRequested() const = 0;
/**
* \brief Get impedance limit
* \return \e the chosen impedance limit (ohms)
*/
virtual size_t getImpedanceLimit() const = 0;
/**
* \brief Set impedance limit
* \param limit [in] : the new value for impedance limit (ohms)
*/
virtual void setImpedanceLimit(const size_t limit) = 0;
//@}
/** \name Chanel information */
//@{
/**
* \brief Sets channel count for the recorded signal
* \param nChannel [in] : the number of the channel for the recorder signal
* \return \e true in case of success.
* \return \e false in case of error.
*
* The number of channels will be used by the IDriver and the acquisition server
* to calculate the sample buffer size (that is \c nSamplesPerChannel x \c nChannel).
*/
virtual bool setChannelCount(const size_t nChannel) = 0;
/**
* \brief Sets a channel' name
* \param index [in] : the index of the channel which name should be set
* \param name [in] : the new name for this channel
* \return \e true in case of success.
* \return \e false in case of error.
* \note As soon as a channel name is set, all the yet-unset channel names are
* considered to be set to empty string.
*/
virtual bool setChannelName(const size_t index, const char* name) = 0;
/**
* \brief Sets a channel' gain
* \param index [in] : the index of the channel which gain should be set
* \param gain [in] : the gain value for this channel
* \return \e true in case of success.
* \return \e false in case of error.
* \note As soon as a channel gain is set, all the yet-unset channel gains are
* considered to be set to 1.
*
* Gains are multiplicator coefficients that are used by the OpenViBE platform to
* to transform measured values into physical dimension.
*/
virtual bool setChannelGain(const size_t index, const float gain) = 0;
/**
* \brief Sets a channel' measurement unit and its scaling factor
* \param index [in] : the index of the channel which gain should be set
* \param unit [in] : the unit
* \param factor [in] : the scaling factor
* \return \e true in case of success.
* \return \e false in case of error.
*
* Measurement units (e.g. Volts, Litres, ...) are specified by size_t enums defined in the openvibe toolkit.
* Scaling factors (megas, millis, ...) are specified similarly. To specify that the channel is in millivolts,
* you set unit to volts and factor to millis. You get the list of supported enums from toolkit/ovtk_defines.h.
*
* Default unit is 'Unspecified' and default factor is code translating 1e00.
*/
virtual bool setChannelUnits(const size_t index, const size_t unit, const size_t factor) = 0;
/// \todo setChannelLocation
// virtual bool setChannelLocation(const size_t index, const float channelLocationX, const float channelLocationY, const float channelLocationZ)=0;
/**
* \brief Gets the number of channels for this header
* \return the number of channels.
* \sa setChannelCount
*/
virtual size_t getChannelCount() const = 0;
/**
* \brief Gets the name of a channel
* \param index [in] : the index of the channel which name is wanted
* \return the name of the \c index th channel if in the correct range
* and name has been specified.
* \return an empty string if in the correct range but name has not been specified.
* \return an empty string when \c index is out of range.
* \sa setChannelName
*/
virtual const char* getChannelName(const size_t index) const = 0;
/**
* \brief Gets the gain of a channel
* \param index [in] : the index of the channel which gain is wanted
* \return the gain of the \c index th channel if in the correct range
* and gain has been specified.
* \return 1 if in the correct range but gain has not been specified.
* \return 0 when \c index is out of range.
* \sa setChannelGain
*/
virtual float getChannelGain(const size_t index) const = 0;
/**
* \brief Gets a channel' measurement unit and its scaling factor
* \param index [in] : the index of the channel which gain should be set
* \param channelUnit [in] : the unit
* \param channelFactor [in] : the scaling factor
* \return \e true in case of success.
* \return \e false in case of error. On false, the outputs will be set to default values.
*
* See setChannelUnits().
*/
virtual bool getChannelUnits(const size_t index, size_t& channelUnit, size_t& channelFactor) const = 0;
/// \todo getChannelLocation
// virtual getChannelLocation(const size_t index) const=0;
/**
* \brief Tests if channel count has been set
* \return \e true if channel count has been set since last \c reset.
* \return \e false if channel count has not been set.
* \sa setChannelCount
*/
virtual bool isChannelCountSet() const = 0;
/**
* \brief Tests if channel name has been set at least once
* \return \e true if channel name has been set at least once since last \c reset.
* \return \e false if channel name has not been set.
* \sa setChannelName
*/
virtual bool isChannelNameSet() const = 0;
/**
* \brief Tests if channel gain has been set at least once
* \return \e true if channel gain has been set at least once since last \c reset.
* \return \e false if channel gain has not been set.
* \sa setChannelGain
*/
virtual bool isChannelGainSet() const = 0;
/// \todo isChannelLocationSet
// virtual bool isChannelLocationSet() const=0;
/**
* \brief Tests if channel unit has been set at least once
* \return \e true if channel unit has been set at least once since last \c reset.
* \return \e false if channel unit has not been set.
* \sa setChannelGain
*/
virtual bool isChannelUnitSet() const = 0;
//@}
/** \name Samples information */
//@{
/**
* \brief Sets measured signal sampling rate
* \param sampling [in] : the sampling rate for the measured signal
* \return \e true in case of success.
* \return \e false in case of error.
* \note the sampling rate is a global value. It can not be specified per channel.
*/
virtual bool setSamplingFrequency(const size_t sampling) = 0;
/**
* \brief Gets the sampling rate of the measured signal
* \return the sampling rate of the measured signal
* \sa setSamplingFrequency
*/
virtual size_t getSamplingFrequency() const = 0;
/**
* \brief Tests if sampling frequency has been set
* \return \e true if sampling frequency has been set since last \c reset.
* \return \e false if sampling frequency has not been set.
* \sa setSamplingFrequency
*/
virtual bool isSamplingFrequencySet() const = 0;
//@}
/**
* \brief Destructor
*/
virtual ~IHeader() { }
static void copy(IHeader& dst, const IHeader& src)
{
// Make sure that nothing lingers, this is mainly for channel units: we have no way to restore dst to an 'unset' state unless we reset
dst.reset();
const size_t nChannel = src.getChannelCount();
dst.setExperimentID(src.getExperimentID());
dst.setSubjectAge(src.getSubjectAge());
dst.setSubjectGender(src.getSubjectGender());
dst.setChannelCount(src.getChannelCount());
dst.setSamplingFrequency(src.getSamplingFrequency());
dst.setChannelCount(src.getChannelCount());
for (size_t i = 0; i < nChannel; ++i)
{
dst.setChannelName(i, src.getChannelName(i));
dst.setChannelGain(i, src.getChannelGain(i));
}
if (src.isChannelUnitSet())
{
for (size_t i = 0; i < nChannel; ++i)
{
size_t unit = 0, factor = 0;
src.getChannelUnits(i, unit, factor); // No need to test for error, will set defaults on fail
dst.setChannelUnits(i, unit, factor);
}
}
}
};
} // namespace AcquisitionServer
} // namespace OpenViBE
@@ -0,0 +1,6 @@
#pragma once
#include "ovas_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
@@ -0,0 +1,16 @@
#pragma once
#define OVAS_Impedance_NotAvailable -2
#define OVAS_Impedance_Unknown -1
#define OVAS_Impedance_Zero 0
//___________________________________________________________________//
// //
// Global defines //
//___________________________________________________________________//
// //
#ifdef TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
#include "ovp_global_defines.h"
#endif // TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines