lasp/src/lasp/device/lasp_daqdata.cpp

299 lines
7.7 KiB
C++

/* #define DEBUGTRACE_ENABLED */
#include "lasp_daqdata.h"
#include "debugtrace.hpp"
#include "lasp_mathtypes.h"
#include <armadillo>
#include <cassert>
#include <memory>
using std::cerr;
using std::cout;
using std::endl;
using rte = std::runtime_error;
static_assert(sizeof(byte_t) == 1, "Invalid char size");
DEBUGTRACE_VARIABLES;
/// Constructors and destructors
DaqData::DaqData(const us nframes, const us nchannels,
const DataTypeDescriptor::DataType dtype)
: nframes(nframes), nchannels(nchannels), dtype(dtype),
dtype_descr(dtype_map.at(dtype)), sw(dtype_descr.sw) {
DEBUGTRACE_ENTER;
DEBUGTRACE_PRINT(sw);
assert(sw > 0 && sw <= 8);
_data = reinterpret_cast<byte_t*>(new double[(sw * nchannels * nframes)/8 + 1]);
if (!_data) {
throw rte("Could not allocate memory for DaqData!");
}
}
DaqData::DaqData(const DaqData &o) : DaqData(o.nframes, o.nchannels, o.dtype) {
DEBUGTRACE_ENTER;
memcpy(_data, o._data, sw * nchannels * nframes);
}
DaqData::DaqData(DaqData &&o)
: nframes(o.nframes), nchannels(o.nchannels), dtype(o.dtype),
dtype_descr(std::move(o.dtype_descr)), sw(o.sw) {
/// Steal from other one
DEBUGTRACE_ENTER;
_data = o._data;
/// Nullptrs do not get deleted
o._data = nullptr;
}
DaqData::~DaqData() {
DEBUGTRACE_ENTER;
if (_data)
delete[] (reinterpret_cast<double*>(_data));
}
void DaqData::copyInFromRaw(const std::vector<byte_t *> &ptrs) {
DEBUGTRACE_ENTER;
us ch = 0;
assert(ptrs.size() == nchannels);
for (auto &ptr : ptrs) {
copyInFromRaw(ch, ptr);
ch++;
}
}
void DaqData::copyInFromRaw(const us channel, const byte_t *ptr) {
DEBUGTRACE_ENTER;
assert(ptr);
memcpy(&_data[sw * channel * nframes], ptr, sw * nframes);
}
void DaqData::copyToRaw(const us channel, byte_t *ptr) {
/* std::copy(raw_ptr(0, channel), raw_ptr(nframes, channel), ptr); */
assert(channel < nchannels);
assert(ptr);
memcpy(ptr, raw_ptr(0, channel), sw * nframes);
}
template <typename T>
d DaqData::toFloat(const us frame, const us channel) const {
/* DEBUGTRACE_ENTER; */
if constexpr (std::is_integral<T>::value) {
return static_cast<d>(value<T>(frame, channel)) /
std::numeric_limits<T>::max();
} else {
return static_cast<d>(value<T>(frame, channel));
}
}
template <typename T> vd DaqData::toFloat(const us channel) const {
DEBUGTRACE_ENTER;
#if LASP_DEBUG == 1
check_type<T>();
#endif
vd res(nframes);
for (us i = 0; i < nframes; i++) {
res(i) = toFloat<T>(i, channel);
}
return res;
}
template <typename T> dmat DaqData::toFloat() const {
DEBUGTRACE_ENTER;
#if LASP_DEBUG == 1
check_type<T>();
#endif
dmat res(nframes, nchannels);
for (us i = 0; i < nframes; i++) {
for (us j = 0; j < nchannels; j++) {
res(i, j) = toFloat<T>(i, j);
}
}
return res;
}
d DaqData::toFloat(const us frame, const us channel) const {
DEBUGTRACE_ENTER;
using DataType = DataTypeDescriptor::DataType;
switch (dtype) {
case (DataType::dtype_int8):
return toFloat<int8_t>(frame, channel);
break;
case (DataType::dtype_int16):
return toFloat<int16_t>(frame, channel);
break;
case (DataType::dtype_int32):
return toFloat<int32_t>(frame, channel);
break;
case (DataType::dtype_fl32):
return toFloat<float>(frame, channel);
break;
case (DataType::dtype_fl64):
return toFloat<double>(frame, channel);
break;
default:
throw std::runtime_error("BUG");
} // End of switch
// Never arrives her
return 0;
}
vd DaqData::toFloat(const us channel_no) const {
DEBUGTRACE_ENTER;
using DataType = DataTypeDescriptor::DataType;
/* cerr << (int)dtype << endl; */
switch (dtype) {
case (DataType::dtype_int8): {
return toFloat<int8_t>(channel_no);
} break;
case (DataType::dtype_int16): {
return toFloat<int16_t>(channel_no);
} break;
case (DataType::dtype_int32): {
return toFloat<int32_t>(channel_no);
} break;
case (DataType::dtype_fl32): {
return toFloat<float>(channel_no);
} break;
case (DataType::dtype_fl64): {
return toFloat<double>(channel_no);
} break;
default:
throw std::runtime_error("BUG");
} // End of switch
// Never arrives here
return vd();
}
dmat DaqData::toFloat() const {
DEBUGTRACE_ENTER;
/* DEBUGTRACE_PRINT(nframes); */
/* DEBUGTRACE_PRINT(nchannels); */
using DataType = DataTypeDescriptor::DataType;
/* cerr << "DataType: " << (int) dtype << endl; */
switch (dtype) {
case (DataType::dtype_int8):
return toFloat<int8_t>();
break;
case (DataType::dtype_int16):
DEBUGTRACE_PRINT("Dtype = int16");
return toFloat<int16_t>();
break;
case (DataType::dtype_int32):
return toFloat<int32_t>();
break;
case (DataType::dtype_fl32):
DEBUGTRACE_PRINT("Dtype = float32");
return toFloat<float>();
break;
case (DataType::dtype_fl64):
DEBUGTRACE_PRINT("Dtype = float64");
return toFloat<double>();
break;
default:
throw std::runtime_error("BUG");
} // End of switch
// Never reached
return dmat();
}
template <typename T>
void DaqData::fromFloat(const us frame, const us channel, const d val) {
DEBUGTRACE_ENTER;
#if LASP_DEBUG == 1
check_type<T>();
#endif
if constexpr (std::is_integral<T>::value) {
value<T>(frame, channel) =
static_cast<T>(val * std::numeric_limits<T>::max());
} else {
value<T>(frame, channel) = static_cast<T>(val);
}
}
void DaqData::fromFloat(const us frame, const us channel, const d val) {
using DataType = DataTypeDescriptor::DataType;
switch (dtype) {
case (DataType::dtype_int8):
return fromFloat<int8_t>(frame, channel, val);
break;
case (DataType::dtype_int16):
return fromFloat<int16_t>(frame, channel, val);
break;
case (DataType::dtype_int32):
return fromFloat<int32_t>(frame, channel, val);
break;
case (DataType::dtype_fl32):
return fromFloat<float>(frame, channel, val);
break;
case (DataType::dtype_fl64):
return fromFloat<float>(frame, channel, val);
break;
default:
throw std::runtime_error("BUG");
} // End of switch
}
void DaqData::fromFloat(const us channel, const vd &vals) {
if (vals.size() != nframes) {
throw rte("Invalid number of frames in channel data");
}
using DataType = DataTypeDescriptor::DataType;
switch (dtype) {
case (DataType::dtype_int8):
for (us frame = 0; frame < nframes; frame++) {
fromFloat<int8_t>(frame, channel, vals(frame));
}
break;
case (DataType::dtype_int16):
for (us frame = 0; frame < nframes; frame++) {
fromFloat<int16_t>(frame, channel, vals(frame));
}
break;
case (DataType::dtype_int32):
for (us frame = 0; frame < nframes; frame++) {
fromFloat<int32_t>(frame, channel, vals(frame));
}
break;
case (DataType::dtype_fl32):
for (us frame = 0; frame < nframes; frame++) {
fromFloat<float>(frame, channel, vals(frame));
}
break;
case (DataType::dtype_fl64):
for (us frame = 0; frame < nframes; frame++) {
fromFloat<double>(frame, channel, vals(frame));
}
break;
default:
throw std::runtime_error("BUG");
} // End of switch
}
void DaqData::print() const {
cout << "Number of frames: " << nframes << endl;
cout << "Number of channels: " << nchannels << endl;
cout << "DataType: " << dtype_map.at(dtype).name << endl;
cout << "First sample of first channel (as float)" << toFloat(0, 0) << endl;
cout << "Last sample of first channel (as float)" << toFloat(nframes - 1, 0)
<< endl;
cout << "Last sample of last channel (as float)"
<< toFloat(nframes - 1, nchannels - 1) << endl;
dmat data = toFloat();
vrd max = arma::max(data, 0);
vrd min = arma::min(data, 0);
cout << "Maximum value in buf: " << max << endl;
cout << "Minumum value in buf: " << min << endl;
}