lasp/lasp/device/lasp_deviceinfo.cpp

140 lines
3.5 KiB
C++

#include "lasp_deviceinfo.h"
#include <algorithm>
#include <cassert>
#define MAX_DEV_COUNT_PER_API 20
#if LASP_HAS_ULDAQ == 1
#include "lasp_uldaq.h"
#endif
#if LASP_HAS_RTAUDIO == 1
#include "lasp_rtaudiodaq.h"
#endif
string DeviceInfo::serialize() const {
// Simple serializer for this object, used because we found a bit late
// that this object needs to be send over the wire. We do not want to make
// this implementation in Python, as these objects are created here, in
// the C++ code. The Python wrapper is just a readonly wrapper.
std::stringstream str;
str << api.apiname << "\t";
str << api.apicode << "\t";
str << api.api_specific_subcode << "\t";
str << device_name << "\t";
str << availableDataTypes.size() << "\t";
for (const auto &dtype : availableDataTypes) {
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
str << static_cast<int>(dtype) << "\t";
}
str << prefDataTypeIndex << "\t";
str << availableSampleRates.size() << "\t";
for (const double &fs : availableSampleRates) {
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
str << fs << "\t";
}
str << prefSampleRateIndex << "\t";
str << availableFramesPerBlock.size() << "\t";
for (const us &fb : availableFramesPerBlock) {
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
str << fb << "\t";
}
str << prefFramesPerBlockIndex << "\t";
str << availableInputRanges.size() << "\t";
for (const double &ir : availableInputRanges) {
// WARNING: THIS GOES COMPLETELY WRONG WHEN NAMES contain A TAB!!!
str << ir << "\t";
}
str << prefInputRangeIndex << "\t";
str << ninchannels << "\t";
str << noutchannels << "\t";
str << int(hasInputIEPE) << "\t";
str << int(hasInputACCouplingSwitch) << "\t";
str << int(hasInputTrigger) << "\t";
return str.str();
}
DeviceInfo DeviceInfo::deserialize(const string &dstr) {
DeviceInfo devinfo;
std::stringstream str(dstr);
string tmp;
us N;
// Lambda functions for deserializing
auto nexts = [&]() {
getline(str, tmp, '\t');
return tmp;
};
auto nexti = [&]() {
getline(str, tmp, '\t');
return std::atoi(tmp.c_str());
};
auto nextf = [&]() {
getline(str, tmp, '\t');
return std::atof(tmp.c_str());
};
// Api
string apiname = nexts();
auto apicode = nexti();
auto api_specific_subcode = nexti();
DaqApi api(apiname, apicode, api_specific_subcode);
devinfo.api = api;
devinfo.device_name = nexts();
N = us(nexti());
for (us i = 0; i < N; i++) {
devinfo.availableDataTypes.push_back(
static_cast<DataTypeDescriptor::DataType>(nexti()));
}
devinfo.prefDataTypeIndex = nexti();
N = us(nexti());
for (us i = 0; i < N; i++) {
devinfo.availableSampleRates.push_back(nextf());
}
devinfo.prefSampleRateIndex = nexti();
N = us(nexti());
for (us i = 0; i < N; i++) {
devinfo.availableFramesPerBlock.push_back(nexti());
}
devinfo.prefFramesPerBlockIndex = nexti();
N = us(nexti());
for (us i = 0; i < N; i++) {
devinfo.availableInputRanges.push_back(nexti());
}
devinfo.prefInputRangeIndex = nexti();
devinfo.ninchannels = nexti();
devinfo.noutchannels = nexti();
devinfo.hasInputIEPE = bool(nexti());
devinfo.hasInputACCouplingSwitch = bool(nexti());
devinfo.hasInputTrigger = bool(nexti());
return devinfo;
}
std::vector<DeviceInfo> DeviceInfo::getDeviceInfo() {
std::vector<DeviceInfo> devs;
#if LASP_HAS_ULDAQ ==1
fillUlDaqDeviceInfo(devs);
#endif
#if LASP_HAS_RTAUDIO == 1
fillRtAudioDeviceInfo(devs);
#endif
return devs;
}