lasp/cpp_src/device/lasp_daq.cpp
J.A. de Jong - Redu-Sone B.V., ASCEE V.O.F e973f14884
Some checks failed
Building, testing and releasing LASP if it has a tag / Build-Test-Ubuntu (push) Failing after 2m3s
Building, testing and releasing LASP if it has a tag / Release-Ubuntu (push) Has been skipped
Weak refs to Recording methods. Made the mutexes more simple for stream manager. Added extra guards and statements here and there. Code passes a sever stress test.
2024-03-13 12:19:24 +01:00

134 lines
3.6 KiB
C++

// #define DEBUGTRACE_ENABLED
#include "debugtrace.hpp"
#include "lasp_daqconfig.h"
#include "lasp_config.h"
#include "lasp_daq.h"
#if LASP_HAS_ULDAQ == 1
#include "lasp_uldaq.h"
#endif
#if LASP_HAS_RTAUDIO == 1
#include "lasp_rtaudiodaq.h"
#endif
#if LASP_HAS_PORTAUDIO == 1
#include "lasp_portaudiodaq.h"
#endif
using rte = std::runtime_error;
Daq::~Daq() { DEBUGTRACE_ENTER; }
std::unique_ptr<Daq> Daq::createDaq(const DeviceInfo &devinfo,
const DaqConfiguration &config) {
DEBUGTRACE_ENTER;
#if LASP_HAS_ULDAQ == 1
if (devinfo.api.apicode == LASP_ULDAQ_APICODE) {
return createUlDaqDevice(devinfo, config);
}
#endif
#if LASP_HAS_RTAUDIO == 1
// See lasp_daqconfig.h:114 ALSA, up to
if (devinfo.api.apicode == LASP_RTAUDIO_APICODE) {
return createRtAudioDevice(devinfo, config);
}
#endif
#if LASP_HAS_PORTAUDIO == 1
if (devinfo.api.apicode == LASP_PORTAUDIO_APICODE) {
return createPortAudioDevice(devinfo, config);
}
#endif
throw rte(string("Unable to match Device API: ") + devinfo.api.apiname);
}
Daq::Daq(const DeviceInfo &devinfo, const DaqConfiguration &config)
: DaqConfiguration(config), DeviceInfo(devinfo) {
DEBUGTRACE_ENTER;
if(!duplexMode() && monitorOutput) {
throw rte("Duplex mode requires enabling both input and output channels. Please make sure at least one output channel is enabled, or disable hardware output loopback in DAQ configuration.");
}
if (!hasInternalOutputMonitor && monitorOutput) {
throw rte(
"Output monitor flag set, but device does not have hardware output monitor.");
}
if (!config.match(devinfo)) {
throw rte("DaqConfiguration does not match device info");
}
{
const int hich = getHighestEnabledInChannel();
if (hich + 1 > devinfo.ninchannels)
{
throw rte(
string("Highest of enabled input channel: ") +
to_string(hich) +
string(" is higher than device capability, which is: ") +
to_string(ninchannels) + ".");
}
}
{
const int hoch = getHighestEnabledOutChannel();
if (hoch + 1 > devinfo.noutchannels)
{
throw rte(
string("Highest of enabled output channel: ") +
to_string(hoch) +
string(" is higher than device capability, which is: ") +
to_string(noutchannels) + ".");
}
}
}
double Daq::samplerate() const {
DEBUGTRACE_ENTER;
return availableSampleRates.at(sampleRateIndex);
}
DataTypeDescriptor::DataType Daq::dataType() const {
return availableDataTypes.at(dataTypeIndex);
}
const DataTypeDescriptor &Daq::dtypeDescr() const {
return dtype_map.at(dataType());
}
dvec Daq::inputRangeForEnabledChannels(const bool include_monitor) const {
dvec res;
auto chs = enabledInChannels(include_monitor);
for(auto& ch : chs) {
res.push_back(availableInputRanges.at(ch.rangeIndex));
}
return res;
}
us Daq::neninchannels(const bool include_monitorchannel) const {
boolvec eninchannels = this->eninchannels(include_monitorchannel);
return std::count(eninchannels.cbegin(), eninchannels.cend(), true);
}
us Daq::nenoutchannels() const {
boolvec enchannels = this->enoutchannels();
return std::count(enchannels.cbegin(), enchannels.cend(), true);
}
boolvec Daq::eninchannels(bool include_monitor) const {
boolvec res;
if (hasInternalOutputMonitor && include_monitor) {
res.push_back(monitorOutput);
}
for (auto &ch : inchannel_config) {
res.push_back(ch.enabled);
}
return res;
}
boolvec Daq::enoutchannels() const {
boolvec res;
for (auto &ch : outchannel_config) {
res.push_back(ch.enabled);
}
return res;
}