lasp/src/lasp/device/lasp_daqdata.h

124 lines
3.1 KiB
C++

#pragma once
#include "lasp_daqconfig.h"
#include "lasp_types.h"
#include <functional>
#include <gsl/gsl-lite.hpp>
#include <memory>
/**
* @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.
*/
std::vector<int8_t> _data;
public:
/**
* @brief The number of channels
*/
const us nchannels;
/**
* @brief The number of frames in this block of data.
*/
const us nframes;
/**
* @brief The data type corresponding to a sample
*/
const DataTypeDescriptor::DataType dtype;
/**
* @brief The data type description corresponding to a sample
*/
const DataTypeDescriptor &dtype_descr;
/**
* @brief The number of bytes per sample (sample width, sw)
*/
const us sw;
/**
* @brief Initialize an empty frame of data
*
* @param nchannels The number of channels
* @param nframes The number of frames
* @param dtype The data type
*/
DaqData(const us nchannels, const us nframes,
const DataTypeDescriptor::DataType dtype);
virtual ~DaqData() = default;
/**
* @brief Return pointer to the raw data corresponding to a certain sample.
*
* @param frame The frame number
* @param channel The channel number
*
* @return Pointer to sample, not casted to final type
*/
int8_t *raw_ptr(const us frame = 0, const us channel = 0) {
return &(_data.data()[sw * (frame + channel * nframes)]);
}
/**
* @brief Return the total number of bytes
*
* @return Number of bytes of data.
*/
us size_bytes() const { return _data.size(); }
/**
* @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<uint8_t *> &ptrs);
/**
* @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, uint8_t *ptr);
};
template <typename T> class TypedDaqData : public DaqData {
public:
TypedDaqData(const us nchannels, const us nframes,
const DataTypeDescriptor::DataType dtype_descr)
: DaqData(nchannels, nframes, dtype_descr) {}
T &operator[](const us i) { return _data[sw * i]; }
/**
* @brief Reference of sample, casted to the right type. Same as raw_ptr(),
* but then as reference, and corresponding to right type.
*
* @param frame Frame number
* @param channel Channel number
*
* @return
*/
T &operator()(const us frame = 0, const us channel = 0) {
return reinterpret_cast<T &>(*raw_ptr(frame, channel));
}
/**
* @brief Copy out the data for a certain channel to a buffer
*
* @param channel The channel to copy
* @param buffer The buffer to copy to. *Make sure* it is allocated with at
* least `sw*nframes` bytes.
*/
void copyToRaw(const us channel, T *buffer) {
DaqData::copyToRaw(channel, reinterpret_cast<uint8_t *>(buffer));
}
};