// #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::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; }