140 lines
3.5 KiB
C++
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;
|
|
}
|
|
|