/* #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()) { if (neninchannels() == 0) { throw rte("Duplex mode enabled, but no input channels enabled"); } if (nenoutchannels() == 0) { throw rte("Duplex mode enabled, but no output channels enabled"); } } if(!duplexMode() && monitorOutput) { throw rte("Output monitoring only allowed when running in duplex mode"); } if (!hasInternalOutputMonitor && monitorOutput) { throw rte( "Output monitor flag set, but device does not have output monitor"); } if (!config.match(devinfo)) { throw rte("DaqConfiguration does not match device info"); } if (neninchannels(false) > devinfo.ninchannels) { throw rte( "Number of enabled input channels is higher than device capability"); } if (nenoutchannels() > devinfo.noutchannels) { throw rte( "Number of enabled output channels is higher than device capability"); } } 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; }