238 lines
6.5 KiB
C++
238 lines
6.5 KiB
C++
#pragma once
|
|
#include "lasp_daqconfig.h"
|
|
#include "lasp_types.h"
|
|
#include <armadillo>
|
|
#include <cassert>
|
|
#include <functional>
|
|
#include <gsl/gsl-lite.hpp>
|
|
#include <memory>
|
|
#include <type_traits>
|
|
|
|
/** \addtogroup device
|
|
* @{
|
|
*/
|
|
class Daq;
|
|
|
|
using byte_t = char;
|
|
|
|
/**
|
|
* @brief Data coming from / going to DAQ. **Non-interleaved format**, which
|
|
* means data in buffer is ordered by channel: _ptr[frame+channel*nframes]
|
|
*/
|
|
class DaqData {
|
|
protected:
|
|
/**
|
|
* @brief Storage for the actual data.
|
|
*/
|
|
byte_t *_data;
|
|
|
|
public:
|
|
/**
|
|
* @brief The number of frames in this block of data.
|
|
*/
|
|
us nframes;
|
|
|
|
/**
|
|
* @brief The number of channels
|
|
*/
|
|
us nchannels;
|
|
|
|
/**
|
|
* @brief The data type corresponding to a sample
|
|
*/
|
|
DataTypeDescriptor::DataType dtype;
|
|
|
|
/**
|
|
* @brief The data type description corresponding to a sample
|
|
*/
|
|
DataTypeDescriptor dtype_descr;
|
|
|
|
/**
|
|
* @brief The number of bytes per sample (sample width, sw)
|
|
*/
|
|
us sw;
|
|
|
|
/**
|
|
* @brief Initialize an empty frame of data
|
|
*
|
|
* @param nframes The number of frames
|
|
* @param nchannels The number of channels
|
|
* @param dtype The data type
|
|
*/
|
|
DaqData(const us nframes, const us nchannels,
|
|
const DataTypeDescriptor::DataType dtype);
|
|
/**
|
|
* @brief Initialize using no allocation
|
|
*/
|
|
DaqData(const DaqData &);
|
|
DaqData(DaqData &&);
|
|
DaqData &operator=(const DaqData &) = delete;
|
|
~DaqData();
|
|
|
|
/**
|
|
* @brief Return pointer to the raw data corresponding to a certain sample
|
|
* (frame, channel combo).
|
|
*
|
|
* @param frame The frame number
|
|
* @param channel The channel number
|
|
*
|
|
* @return Pointer to sample, not casted to final type
|
|
*/
|
|
byte_t *raw_ptr(const us frame = 0, const us channel = 0) {
|
|
assert(frame < nframes);
|
|
assert(channel < nchannels);
|
|
return &(_data[sw * (frame + channel * nframes)]);
|
|
}
|
|
const byte_t *raw_ptr(const us frame = 0, const us channel = 0) const {
|
|
assert(frame < nframes);
|
|
assert(channel < nchannels);
|
|
return &(_data[sw * (frame + channel * nframes)]);
|
|
}
|
|
|
|
/**
|
|
* @brief Return the total number of bytes
|
|
*
|
|
* @return Number of bytes of data.
|
|
*/
|
|
us size_bytes() const { return sw * nchannels * nframes; }
|
|
|
|
/**
|
|
* @brief Copy data from a set of raw pointers of *uninterleaved* data.
|
|
* Overwrites any existing available data.
|
|
*
|
|
* @param ptrs Pointers to data from channels
|
|
*/
|
|
void copyInFromRaw(const std::vector<byte_t *> &ptrs);
|
|
|
|
/**
|
|
* @brief Copy data from a set of raw pointers of *uninterleaved* data.
|
|
* Overwrites any existing available data.
|
|
*
|
|
* @param channel The channel to copy to
|
|
* @param ptr Pointers to data from channels
|
|
*/
|
|
void copyInFromRaw(const us channel, const byte_t *ptr);
|
|
|
|
/**
|
|
* @brief Copy contents of DaqData for a certain channel to a raw pointer.
|
|
*
|
|
* @param channel The channel to copy.
|
|
* @param ptr The pointer where data is copied to.
|
|
*/
|
|
void copyToRaw(const us channel, byte_t *ptr);
|
|
|
|
/**
|
|
* @brief Convert samples to floating point values and return a nframes x
|
|
* nchannels array of floats. For data that is not already floating-point,
|
|
* the data is scaled back from MAX_INT to +1.0.
|
|
*
|
|
* @return Array of floats
|
|
*/
|
|
arma::Mat<d> toFloat() const;
|
|
|
|
/**
|
|
* @brief Convert samples to floating point value; and return a nframes
|
|
* column vector of floats. For data that is not already floating-point,
|
|
* the data is scaled back from MAX_INT to +1.0.
|
|
*
|
|
* @param channel_no The channel number to convert
|
|
*
|
|
* @return Array of floats
|
|
*/
|
|
arma::Col<d> toFloat(const us channel_no) const;
|
|
|
|
/**
|
|
* @brief Convert single sample to floating point value; and return a nframes
|
|
* column vector of floats. For data that is not already floating-point,
|
|
* the data is scaled back from MAX_INT to +1.0.
|
|
*
|
|
* @param frame_no The frame number to convert
|
|
* @param channel_no The channel number to convert
|
|
*
|
|
* @return Float value
|
|
*/
|
|
d toFloat(const us frame_no, const us channel_no) const;
|
|
|
|
/**
|
|
* @brief Convert to channel data of native type from floating point values.
|
|
* Useful for 'changing' raw data in any way.
|
|
*
|
|
* @param frame_no The frame
|
|
* @param channel_no The channel
|
|
* @param data The value
|
|
*/
|
|
void fromFloat(const us frame_no, const us channel_no,
|
|
const d data);
|
|
|
|
/**
|
|
* @brief Convert to channel data of native type from floating point values.
|
|
* Useful for 'changing' raw data in any way.
|
|
*
|
|
* @param channel The channel to convert
|
|
* @param data Data to convert from float values
|
|
*/
|
|
void fromFloat(const us channel, const arma::Col<d> &data);
|
|
|
|
// Return value based on type
|
|
template <typename T> T &value(const us frame, const us channel) {
|
|
#if LASP_DEBUG == 1
|
|
check_type<T>();
|
|
#endif
|
|
return *reinterpret_cast<T *>(raw_ptr(frame, channel));
|
|
}
|
|
template <typename T> const T &value(const us frame, const us channel) const {
|
|
#if LASP_DEBUG == 1
|
|
check_type<T>();
|
|
#endif
|
|
return *reinterpret_cast<const T *>(raw_ptr(frame, channel));
|
|
}
|
|
|
|
/**
|
|
* @brief For debugging purposes: prints some stats
|
|
*/
|
|
void print() const;
|
|
|
|
protected:
|
|
template <typename T> void check_type() const {
|
|
using DataType = DataTypeDescriptor::DataType;
|
|
|
|
bool correct = false;
|
|
static_assert(std::is_arithmetic<T>::value);
|
|
|
|
if constexpr (std::is_floating_point<T>::value) {
|
|
correct |= sizeof(T) == 4 && dtype == DataType::dtype_fl32;
|
|
correct |= sizeof(T) == 8 && dtype == DataType::dtype_fl64;
|
|
|
|
} else {
|
|
correct |= sizeof(T) == 1 && dtype == DataType::dtype_int8;
|
|
correct |= sizeof(T) == 2 && dtype == DataType::dtype_int16;
|
|
correct |= sizeof(T) == 4 && dtype == DataType::dtype_int32;
|
|
}
|
|
if (!correct) {
|
|
throw std::runtime_error("Wrong datatype for template argument");
|
|
}
|
|
}
|
|
|
|
template <typename T> arma::Mat<d> toFloat() const;
|
|
template <typename T> arma::Col<d> toFloat(const us channel_no) const;
|
|
template <typename T> d toFloat(const us frame_no, const us channel_no) const;
|
|
|
|
/* template <typename T> void fromFloat(const dmat&); */
|
|
template <typename T>
|
|
void fromFloat(const us channel_no, const arma::Col<d> &vals);
|
|
template <typename T>
|
|
void fromFloat(const us frame_no, const us channel_no, const d val);
|
|
/**
|
|
* @brief Return a value as floating point. Does a conversion from integer to
|
|
* float, if the stored type is integer. Also scales by its maximum value.
|
|
*
|
|
* @tparam T The original type
|
|
* @param frame Frame number
|
|
* @param channel Channel number
|
|
*
|
|
* @return Value converted to floating point
|
|
*/
|
|
};
|
|
|
|
/** @} */
|