LASP 1.0
Library for Acoustic Signal Processing
Loading...
Searching...
No Matches
lasp_daqdata.cpp
Go to the documentation of this file.
1/* #define DEBUGTRACE_ENABLED */
2#include "lasp_daqdata.h"
3#include "debugtrace.hpp"
4#include "lasp_mathtypes.h"
5#include <armadillo>
6#include <cassert>
7#include <memory>
8
9using std::cerr;
10using std::cout;
11using std::endl;
12using rte = std::runtime_error;
13
14static_assert(sizeof(byte_t) == 1, "Invalid char size");
15
17
19DaqData::DaqData(const us nframes, const us nchannels,
21
22 : nframes(nframes), nchannels(nchannels), dtype(dtype),
23 dtype_descr(dtype_map.at(dtype)), sw(dtype_descr.sw) {
24
25 DEBUGTRACE_ENTER;
26 DEBUGTRACE_PRINT(sw);
27
28 assert(sw > 0 && sw <= 8);
29 _data = reinterpret_cast<byte_t *>(
30 new double[(sw * nchannels * nframes) / sizeof(double) + 1]);
31
32 if (!_data) {
33 throw rte("Could not allocate memory for DaqData!");
34 }
35}
36DaqData::DaqData(const DaqData &o) : DaqData(o.nframes, o.nchannels, o.dtype) {
37
38 DEBUGTRACE_ENTER;
39 memcpy(_data, o._data, sw * nchannels * nframes);
40}
41
43 : nframes(o.nframes), nchannels(o.nchannels), dtype(o.dtype),
44 dtype_descr(std::move(o.dtype_descr)), sw(o.sw) {
45
47
48 DEBUGTRACE_ENTER;
49 _data = o._data;
51 o._data = nullptr;
52}
53
55 DEBUGTRACE_ENTER;
56 if (_data)
57 delete[](reinterpret_cast<double *>(_data));
58}
59
60void DaqData::copyInFromRaw(const std::vector<byte_t *> &ptrs) {
61 DEBUGTRACE_ENTER;
62 us ch = 0;
63 assert(ptrs.size() == nchannels);
64 for (auto &ptr : ptrs) {
65 copyInFromRaw(ch, ptr);
66 ch++;
67 }
68}
69void DaqData::copyInFromRaw(const us channel, const byte_t *ptr) {
70 DEBUGTRACE_ENTER;
71 assert(ptr);
72 memcpy(&_data[sw * channel * nframes], ptr, sw * nframes);
73}
74
75void DaqData::copyToRaw(const us channel, byte_t *ptr) {
76 /* std::copy(raw_ptr(0, channel), raw_ptr(nframes, channel), ptr); */
77 assert(channel < nchannels);
78 assert(ptr);
79 memcpy(ptr, raw_ptr(0, channel), sw * nframes);
80}
81
82template <typename T>
83d DaqData::toFloat(const us frame, const us channel) const {
84 /* DEBUGTRACE_ENTER; */
85 if constexpr (std::is_integral<T>::value) {
86 return static_cast<d>(value<T>(frame, channel)) /
87 std::numeric_limits<T>::max();
88 } else {
89 return static_cast<d>(value<T>(frame, channel));
90 }
91}
92
93template <typename T> vd DaqData::toFloat(const us channel) const {
94 DEBUGTRACE_ENTER;
95#if LASP_DEBUG == 1
96 check_type<T>();
97#endif
98 vd res(nframes);
99 for (us i = 0; i < nframes; i++) {
100 res(i) = toFloat<T>(i, channel);
101 }
102 return res;
103}
104template <typename T> dmat DaqData::toFloat() const {
105
106 DEBUGTRACE_ENTER;
107#if LASP_DEBUG == 1
108 check_type<T>();
109#endif
110 dmat res(nframes, nchannels);
111
112 for (us i = 0; i < nframes; i++) {
113 for (us j = 0; j < nchannels; j++) {
114 res(i, j) = toFloat<T>(i, j);
115 }
116 }
117 return res;
118}
119
120d DaqData::toFloat(const us frame, const us channel) const {
121 DEBUGTRACE_ENTER;
122 using DataType = DataTypeDescriptor::DataType;
123 switch (dtype) {
124 case (DataType::dtype_int8):
125 return toFloat<int8_t>(frame, channel);
126 break;
127 case (DataType::dtype_int16):
128 return toFloat<int16_t>(frame, channel);
129 break;
130 case (DataType::dtype_int32):
131 return toFloat<int32_t>(frame, channel);
132 break;
133 case (DataType::dtype_fl32):
134 return toFloat<float>(frame, channel);
135 break;
136 case (DataType::dtype_fl64):
137 return toFloat<double>(frame, channel);
138 break;
139 default:
140 throw std::runtime_error("BUG");
141 } // End of switch
142
143 // Never arrives her
144 return 0;
145}
146
147vd DaqData::toFloat(const us channel_no) const {
148 DEBUGTRACE_ENTER;
149 using DataType = DataTypeDescriptor::DataType;
150 /* cerr << (int)dtype << endl; */
151 switch (dtype) {
152 case (DataType::dtype_int8): {
153 return toFloat<int8_t>(channel_no);
154 } break;
155 case (DataType::dtype_int16): {
156 return toFloat<int16_t>(channel_no);
157 } break;
158 case (DataType::dtype_int32): {
159 return toFloat<int32_t>(channel_no);
160 } break;
161 case (DataType::dtype_fl32): {
162 return toFloat<float>(channel_no);
163 } break;
164 case (DataType::dtype_fl64): {
165 return toFloat<double>(channel_no);
166 } break;
167 default:
168 throw std::runtime_error("BUG");
169 } // End of switch
170
171 // Never arrives here
172 return vd();
173}
174
176
177 DEBUGTRACE_ENTER;
178 /* DEBUGTRACE_PRINT(nframes); */
179 /* DEBUGTRACE_PRINT(nchannels); */
180
181 using DataType = DataTypeDescriptor::DataType;
182
183 /* cerr << "DataType: " << (int) dtype << endl; */
184
185 switch (dtype) {
186 case (DataType::dtype_int8):
187 return toFloat<int8_t>();
188 break;
189 case (DataType::dtype_int16):
190 DEBUGTRACE_PRINT("Dtype = int16");
191 return toFloat<int16_t>();
192 break;
193 case (DataType::dtype_int32):
194 return toFloat<int32_t>();
195 break;
196 case (DataType::dtype_fl32):
197 DEBUGTRACE_PRINT("Dtype = float32");
198 return toFloat<float>();
199 break;
200 case (DataType::dtype_fl64):
201 DEBUGTRACE_PRINT("Dtype = float64");
202 return toFloat<double>();
203 break;
204 default:
205 throw std::runtime_error("BUG");
206 } // End of switch
207
208 // Never reached
209 return dmat();
210}
211
212template <typename T>
213void DaqData::fromFloat(const us frame, const us channel, const d val) {
214 DEBUGTRACE_ENTER;
215#if LASP_DEBUG == 1
216 check_type<T>();
217#endif
218 if constexpr (std::is_integral<T>::value) {
219 value<T>(frame, channel) =
220 static_cast<T>(val * std::numeric_limits<T>::max());
221 } else {
222 value<T>(frame, channel) = static_cast<T>(val);
223 }
224}
225
226void DaqData::fromFloat(const us frame, const us channel, const d val) {
227
228 using DataType = DataTypeDescriptor::DataType;
229
230 switch (dtype) {
231 case (DataType::dtype_int8):
232 return fromFloat<int8_t>(frame, channel, val);
233 break;
234 case (DataType::dtype_int16):
235 return fromFloat<int16_t>(frame, channel, val);
236 break;
237 case (DataType::dtype_int32):
238 return fromFloat<int32_t>(frame, channel, val);
239 break;
240 case (DataType::dtype_fl32):
241 return fromFloat<float>(frame, channel, val);
242 break;
243 case (DataType::dtype_fl64):
244 return fromFloat<float>(frame, channel, val);
245 break;
246 default:
247 throw std::runtime_error("BUG");
248 } // End of switch
249}
250void DaqData::fromFloat(const us channel, const vd &vals) {
251 if (vals.size() != nframes) {
252 throw rte("Invalid number of frames in channel data");
253 }
254 using DataType = DataTypeDescriptor::DataType;
255 switch (dtype) {
256 case (DataType::dtype_int8):
257 for (us frame = 0; frame < nframes; frame++) {
258 fromFloat<int8_t>(frame, channel, vals(frame));
259 }
260 break;
261 case (DataType::dtype_int16):
262 for (us frame = 0; frame < nframes; frame++) {
263 fromFloat<int16_t>(frame, channel, vals(frame));
264 }
265 break;
266 case (DataType::dtype_int32):
267 for (us frame = 0; frame < nframes; frame++) {
268 fromFloat<int32_t>(frame, channel, vals(frame));
269 }
270 break;
271 case (DataType::dtype_fl32):
272 for (us frame = 0; frame < nframes; frame++) {
273 fromFloat<float>(frame, channel, vals(frame));
274 }
275 break;
276 case (DataType::dtype_fl64):
277 for (us frame = 0; frame < nframes; frame++) {
278 fromFloat<double>(frame, channel, vals(frame));
279 }
280 break;
281 default:
282 throw std::runtime_error("BUG");
283 } // End of switch
284}
285
286void DaqData::print() const {
287 cout << "Number of frames: " << nframes << endl;
288 cout << "Number of channels: " << nchannels << endl;
289 cout << "DataType: " << dtype_map.at(dtype).name << endl;
290 cout << "First sample of first channel (as float)" << toFloat(0, 0) << endl;
291 cout << "Last sample of first channel (as float)" << toFloat(nframes - 1, 0)
292 << endl;
293 cout << "Last sample of last channel (as float)"
294 << toFloat(nframes - 1, nchannels - 1) << endl;
295 dmat data = toFloat();
296 vrd max = arma::max(data, 0);
297 vrd min = arma::min(data, 0);
298 cout << "Maximum value in buf: " << max << endl;
299 cout << "Minumum value in buf: " << min << endl;
300}
Data coming from / going to DAQ. Non-interleaved format, which means data in buffer is ordered by cha...
void copyInFromRaw(const std::vector< byte_t * > &ptrs)
Copy data from a set of raw pointers of uninterleaved data. Overwrites any existing available data.
arma::Mat< d > toFloat() const
Convert samples to floating point values and return a nframes x nchannels array of floats....
DataTypeDescriptor::DataType dtype
The data type corresponding to a sample.
byte_t * raw_ptr(const us frame=0, const us channel=0)
Return pointer to the raw data corresponding to a certain sample (frame, channel combo).
void print() const
For debugging purposes: prints some stats.
void copyToRaw(const us channel, byte_t *ptr)
Copy contents of DaqData for a certain channel to a raw pointer.
void fromFloat(const us frame_no, const us channel_no, const d data)
Convert to channel data of native type from floating point values. Useful for 'changing' raw data in ...
us nchannels
The number of channels.
us sw
The number of bytes per sample (sample width, sw)
byte_t * _data
Storage for the actual data.
DaqData(const us nframes, const us nchannels, const DataTypeDescriptor::DataType dtype)
Initialize an empty frame of data.
us nframes
The number of frames in this block of data.
DataType
Basic data types coming from a DAQ that we can deal with. The naming will be self-explainging.
std::runtime_error rte
Definition lasp_daq.cpp:16
const std::map< DataTypeDescriptor::DataType, const DataTypeDescriptor > dtype_map
char byte_t
DEBUGTRACE_VARIABLES
arma::Row< d > vrd
arma::Col< d > vd
arma::Mat< d > dmat
size_t us
We often use boolean values.
Definition lasp_types.h:29