From bc9639f10ca7bff204a0125971700546e01f7a27 Mon Sep 17 00:00:00 2001 From: "J.A. de Jong - Redu-Sone B.V., ASCEE V.O.F" Date: Wed, 14 Oct 2020 09:42:19 +0200 Subject: [PATCH] Inbetween state. Nothing is working --- CMakeLists.txt | 48 +++++++----- lasp/device/CMakeLists.txt | 57 +++++++------- lasp/device/lasp_cppdaq.cpp | 133 +++++++------------------------- lasp/device/lasp_cppdaq.h | 36 ++++----- lasp/device/lasp_cpprtaudio.cpp | 97 +++++++++++++++++++++++ lasp/device/lasp_cpprtaudio.h | 67 +--------------- lasp/device/lasp_cppuldaq.cpp | 81 ++++++++++++++++++- lasp/device/lasp_cppuldaq.h | 2 + lasp/device/lasp_daq.pyx | 14 ++++ lasp/device/lasp_daqconfig.pyx | 72 ++--------------- lasp/device/lasp_deviceinfo.pyx | 4 + test/CMakeLists.txt | 3 +- 12 files changed, 311 insertions(+), 303 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 07cc4a4..1e11533 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_policy(SET CMP0079 NEW) # This is used for code completion in vim set(CMAKE_EXPORT_COMPILE_COMMANDS=ON) -project(LASP) +project(LASP LANGUAGES C CXX) # Whether we want to use blas yes or no set(LASP_USE_BLAS TRUE) @@ -14,28 +14,44 @@ set(LASP_USE_BLAS TRUE) set(LASP_FLOAT double) # set(LASP_FLOAT float) -add_definitions(-DLASP_PARALLEL) +option(LASP_PARALLEL "Parallel processing" ON) +option(LASP_RTAUDIO "Compile with RtAudio Daq backend" ON) +option(LASP_ULDAQ "Compile with UlDaq backend" ON) +option(LASP_DEBUG "Compile in debug mode" ON) +option(LASP_FFTW_BACKEND "Compile with FFTW fft backend" ON) +option(LAS_FFTPACK_BACKEND "Compile with Fftpack fft backend" OFF) + +if(LASP_PARALLEL) add_definitions(-DLASP_MAX_NUM_THREADS=30) +add_definitions(-D_REENTRANT) +endif() + +if(LASP_RTAUDIO) + add_definitions(-DHAS_RTAUDIO_API) +endif() +if(LASP_ULDAQ) + add_definitions(-DHAS_ULDAQ_API) +endif() add_definitions(-DLASP_MAX_NUM_CHANNELS=80) -# Reasonable maximum to the nfft size, at 48kHz this is 700s of data.. +# Reasonable maximum to the nfft size, at 48kHz this is 700s of data... add_definitions(-DLASP_MAX_NFFT=33554432) # 2**25 # ####################################### End of user-adjustable variables section -add_definitions(-D_REENTRANT) # ############### Choose an fft backend here -set(LASP_FFT_BACKEND fftpack) -#set(LASP_FFT_BACKEND "fftw") +if(LASP_FFTW_BACKEND AND LASP_FFTPACK_BACKEND) + message(FATAL_ERROR "Either FFTW or Fftpack backend should be chosen. Please disable one of them") +endif() -if(LASP_FFT_BACKEND STREQUAL "fftw") +if(LASP_FFTW_BACKEND) find_library(FFTW_LIBRARY NAMES fftw3 fftw) set(FFTW_LIBRARIES "${FFTW_LIBRARY}") set(LASP_FFT_LIBRARY "${FFTW_LIBRARIES}") add_definitions(-DLASP_FFT_BACKEND_FFTW) -elseif(LASP_FFT_BACKEND STREQUAL "fftpack") +elseif(LASP_FFTPACK_BACKEND) add_definitions(-DLASP_FFT_BACKEND_FFTPACK) set(LASP_FFT_LIBRARY "fftpack") endif() @@ -49,10 +65,6 @@ else() add_definitions(-DLASP_SINGLE_PRECISION) endif(LASP_FLOAT STREQUAL "double") -if(NOT DEFINED LASP_DEBUG) - message(FATAL_ERROR "LASP_DEBUG flag not defined. Please set -DLASP_DEBUG=TRUE - or -DLASP_DEBUG=FALSE") -endif(NOT DEFINED LASP_DEBUG) # ##################### END Cmake variables converted to a macro set(Python_ADDITIONAL_VERSIONS "3.8") @@ -83,14 +95,8 @@ else() include_directories(/usr/local/include/rtaudio) link_directories(/usr/local/lib) - add_definitions(-DHAS_RTAUDIO) - add_definitions(-DHAS_RTAUDIO_PULSEAUDIO_API) - add_definitions(-DHAS_RTAUDIO_ALSA_API) # This should become optional later on, and be added to the windows list as # well. - add_definitions(-DHAS_ULDAQ) - add_definitions(-DHAS_ULDAQ_LINUX_API) - endif(CMAKE_SYSTEM_NAME STREQUAL "Windows") @@ -152,12 +158,18 @@ endif(LASP_USE_BLAS) find_package(PythonLibs REQUIRED ) find_package(PythonInterp REQUIRED) +if(LASP_FFTPACK_BACKEND) add_subdirectory(fftpack) include_directories( fftpack + ) +endif() + +include_directories( lasp/c ) +set(cpp_daq_linklibs pthread) add_subdirectory(lasp) add_subdirectory(test) diff --git a/lasp/device/CMakeLists.txt b/lasp/device/CMakeLists.txt index b7d7dc5..7b026bc 100644 --- a/lasp/device/CMakeLists.txt +++ b/lasp/device/CMakeLists.txt @@ -1,31 +1,34 @@ -include_directories(/usr/include/rtaudio) +set(cpp_daq_files lasp_cppdaq.cpp) +# set(cpp_daq_linklibs pthread) +# set(cpp_daq_linklibs PARENT_SCOPE) -# add_library(cpp_daq lasp_cppdaq.cpp lasp_cppuldaq.cpp lasp_cpprtaudio.cpp) -add_library(cpp_daq lasp_cppdaq.cpp lasp_cppuldaq.cpp ) - -set_source_files_properties(lasp_daq.pyx PROPERTIES CYTHON_IS_CXX TRUE) -set_source_files_properties(lasp_deviceinfo.pyx PROPERTIES CYTHON_IS_CXX TRUE) -set_source_files_properties(lasp_daqconfig.pyx PROPERTIES CYTHON_IS_CXX TRUE) - -set_source_files_properties(lasp_daq.cxx PROPERTIES COMPILE_FLAGS - "${CMAKE_CXX_FLAGS} ${CYTHON_EXTRA_CXX_FLAGS}") - -set_source_files_properties(lasp_deviceinfo.cxx PROPERTIES COMPILE_FLAGS - "${CMAKE_CXX_FLAGS} ${CYTHON_EXTRA_CXX_FLAGS}") - -set_source_files_properties(lasp_daqconfig.cxx PROPERTIES COMPILE_FLAGS - "${CMAKE_CXX_FLAGS} ${CYTHON_EXTRA_CXX_FLAGS}") - -cython_add_module(lasp_daq lasp_daq.pyx) -cython_add_module(lasp_deviceinfo lasp_deviceinfo.pyx) -cython_add_module(lasp_daqconfig lasp_daqconfig.pyx) - -target_link_libraries(lasp_daq cpp_daq uldaq rtaudio pthread) -target_link_libraries(lasp_deviceinfo cpp_daq uldaq rtaudio pthread) -target_link_libraries(lasp_daqconfig cpp_daq uldaq rtaudio pthread) +if(LASP_RTAUDIO) + include_directories(/usr/include/rtaudio) + list(APPEND cpp_daq_files lasp_cpprtaudio.cpp) + list(PREPEND cpp_daq_linklibs rtaudio) +endif() +if(LASP_ULDAQ) + list(APPEND cpp_daq_files lasp_cppuldaq.cpp) + list(PREPEND cpp_daq_linklibs uldaq) +endif() if(win32) -target_link_libraries(lasp_daq python37) -target_link_libraries(lasp_deviceinfo python37) -target_link_libraries(lasp_daqconfig python37) + list(APPEND cpp_daq_linklibs python) endif(win32) +message("Linklibs: ${cpp_daq_linklibs}") +add_library(cpp_daq ${cpp_daq_files}) + +foreach(cython_file lasp_daq lasp_deviceinfo lasp_daqconfig) + + set_source_files_properties(${cython_file}.pyx PROPERTIES + CYTHON_IS_CXX TRUE) + + set_source_files_properties(${cython_file}.cxx PROPERTIES + COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${CYTHON_EXTRA_CXX_FLAGS}") + + cython_add_module(${cython_file} ${cython_file}.pyx) + + target_link_libraries(${cython_file} ${cpp_daq_linklibs}) + +endforeach() + diff --git a/lasp/device/lasp_cppdaq.cpp b/lasp/device/lasp_cppdaq.cpp index 796effd..00787de 100644 --- a/lasp/device/lasp_cppdaq.cpp +++ b/lasp/device/lasp_cppdaq.cpp @@ -1,105 +1,26 @@ #include "lasp_cppdaq.h" -#include "lasp_cppuldaq.h" #include #include -#include -#include -using std::cout; -using std::endl; #define MAX_DEV_COUNT_PER_API 20 -#ifdef HAS_ULDAQ_LINUX_API -void fillUlDaqDeviceInfo(vector &devinfolist) { - - UlError err; - unsigned int numdevs = MAX_DEV_COUNT_PER_API; - - DaqDeviceDescriptor devdescriptors[MAX_DEV_COUNT_PER_API]; - DaqDeviceDescriptor descriptor; - DaqDeviceInterface interfaceType = ANY_IFC; - - err = ulGetDaqDeviceInventory(interfaceType, devdescriptors, &numdevs); - - if (err != ERR_NO_ERROR) - throw std::runtime_error("UlDaq device inventarization failed"); - - for (unsigned i = 0; i < numdevs; i++) { - - descriptor = devdescriptors[i]; - - DeviceInfo devinfo; - devinfo.api = uldaqapi; - string name, interface; - - if (string(descriptor.productName) == "DT9837A") { - if (descriptor.devInterface == USB_IFC) { - name = "USB - "; - } else if (descriptor.devInterface == BLUETOOTH_IFC) { - /* devinfo. */ - name = "Bluetooth - "; - } else if (descriptor.devInterface == ETHERNET_IFC) { - /* devinfo. */ - name = "Ethernet - "; - } - - name += string(descriptor.productName) + " "; - name += string(descriptor.uniqueId); - devinfo.device_name = name; - - devinfo.api_specific_devindex = i; - devinfo.availableDataTypes.push_back(dtype_fl64); - devinfo.prefDataTypeIndex = 0; - - devinfo.availableSampleRates.push_back(10000); - devinfo.availableSampleRates.push_back(12000); - devinfo.availableSampleRates.push_back(20000); - devinfo.availableSampleRates.push_back(24000); - devinfo.availableSampleRates.push_back(32000); - devinfo.availableSampleRates.push_back(48000); - devinfo.availableSampleRates.push_back(51000); - - devinfo.prefSampleRateIndex = 5; - - devinfo.availableFramesPerBlock.push_back(512); - devinfo.availableFramesPerBlock.push_back(1024); - devinfo.availableFramesPerBlock.push_back(2048); - devinfo.availableFramesPerBlock.push_back(4096); - devinfo.availableFramesPerBlock.push_back(8192); - devinfo.prefFramesPerBlockIndex = 1; - - devinfo.availableInputRanges = {1.0, 10.0}; - devinfo.prefInputRangeIndex = 0; - - devinfo.ninchannels = 4; - devinfo.noutchannels = 1; - - devinfo.hasInputIEPE = true; - devinfo.hasInputACCouplingSwitch = true; - devinfo.hasInputTrigger = true; - - // Finally, this devinfo is pushed back in list - devinfolist.push_back(devinfo); - } - } -} +#ifdef HAS_ULDAQ_API +#include "lasp_cppuldaq.h" +#endif +#ifdef HAS_RTAUDIO_API +#include "lasp_cpprtaudio.h" #endif vector Daq::getDeviceInfo() { vector devs; -#ifdef HAS_ULDAQ_LINUX_API +#ifdef HAS_ULDAQ_API fillUlDaqDeviceInfo(devs); #endif -#ifdef HAS_RTAUDIO_ALSA_API - +#ifdef HAS_RTAUDIO_API + fillRtAudioDeviceInfo(devs); #endif -#ifdef HAS_RTAUDIO_PULSEAUDIO_API -#endif - -#ifdef HAS_RTAUDIO_WIN_WASAPI_API -#endif return devs; } @@ -113,13 +34,13 @@ DaqConfiguration::DaqConfiguration(const DeviceInfo &device) { inchannel_sensitivities.resize(device.ninchannels, 1.0); for (us i = 0; i < eninchannels.size(); i++) { - std::strstream chname; + std::stringstream chname; chname << "Unnamed input channel " << i; inchannel_names.push_back(chname.str()); } for (us i = 0; i < enoutchannels.size(); i++) { - std::strstream chname; + std::stringstream chname; chname << "Unnamed output channel " << i; outchannel_names.push_back(chname.str()); } @@ -141,7 +62,7 @@ bool DaqConfiguration::match(const DeviceInfo& dev) const { } Daq *Daq::createDevice(const DaqConfiguration &config, - const vector &devinfos) { + const vector &devinfos) { bool match; DeviceInfo devinfo; @@ -167,27 +88,27 @@ Daq *Daq::createDevice(const DaqConfiguration &config, return createUlDaqDevice(devinfo, config); } else { throw std::runtime_error(string("Unable to match API: ") + - devinfo.api.apiname); + devinfo.api.apiname); } } Daq::Daq(const DeviceInfo &devinfo, const DaqConfiguration &config) - : DaqConfiguration(config), DeviceInfo(devinfo) { + : DaqConfiguration(config), DeviceInfo(devinfo) { - if (monitorOutput && !(nenoutchannels() > 0)) { - throw runtime_error( - "Output monitoring only possible when output is enabled"); - } - // Some sanity checks - if (eninchannels.size() != 4) { - throw runtime_error("Invalid length of enabled inChannels vector"); - } + if (monitorOutput && !(nenoutchannels() > 0)) { + throw runtime_error( + "Output monitoring only possible when output is enabled"); + } + // Some sanity checks + if (eninchannels.size() != 4) { + throw runtime_error("Invalid length of enabled inChannels vector"); + } - if (enoutchannels.size() != 1) { - throw runtime_error("Invalid length of enabled outChannels vector"); + if (enoutchannels.size() != 1) { + throw runtime_error("Invalid length of enabled outChannels vector"); + } } -} double Daq::samplerate() const { @@ -201,6 +122,8 @@ DataType Daq::dataType() const { assert((us)dataTypeIndex < availableDataTypes.size()); return availableDataTypes[dataTypeIndex]; } + + double Daq::inputRangeForChannel(us ch) const { if (!(ch < ninchannels)) { throw runtime_error("Invalid channel number"); @@ -208,6 +131,8 @@ double Daq::inputRangeForChannel(us ch) const { assert(inputRangeIndices.size() == eninchannels.size()); return availableInputRanges[inputRangeIndices[ch]]; } + + us Daq::neninchannels() const { mutexlock lock(mutex); us inch = std::count(eninchannels.begin(), eninchannels.end(), true); @@ -215,6 +140,8 @@ us Daq::neninchannels() const { inch++; return inch; } + + us Daq::nenoutchannels() const { mutexlock lock(mutex); return std::count(enoutchannels.begin(), enoutchannels.end(), true); diff --git a/lasp/device/lasp_cppdaq.h b/lasp/device/lasp_cppdaq.h index 36349ad..19d3ad3 100644 --- a/lasp/device/lasp_cppdaq.h +++ b/lasp/device/lasp_cppdaq.h @@ -1,11 +1,11 @@ #ifndef LASP_CPPDAQ_H #define LASP_CPPDAQ_H -#ifdef HAS_RTAUDIO +#ifdef HAS_RTAUDIO_API #include #endif -#ifdef HAS_ULDAQ +#ifdef HAS_ULDAQ_API #include #endif @@ -13,6 +13,9 @@ #include "string" #include "vector" #include +#include +#include + using std::cerr; using std::cout; using std::endl; @@ -38,7 +41,8 @@ class DataType { }; const DataType dtype_invalid; -const DataType dtype_fl64("64-bits floating point", 4, true); +const DataType dtype_fl32("32-bits floating point", 4, true); +const DataType dtype_fl64("64-bits floating point", 8, true); const DataType dtype_int8("8-bits integers", 1, false); const DataType dtype_int16("16-bits integers", 2, false); const DataType dtype_int32("32-bits integers", 4, false); @@ -47,6 +51,7 @@ const std::vector dataTypes = { dtype_int8, dtype_int16, dtype_int32, + dtype_fl32, dtype_fl64, }; @@ -66,28 +71,17 @@ class DaqApi { } }; -#ifdef HAS_ULDAQ_LINUX_API +#ifdef HAS_ULDAQ_API const DaqApi uldaqapi("UlDaq", 0); #endif -#ifdef HAS_RTAUDIO_ALSA_API -const DaqApi rtaudioalsaapi("RtAudio Linux ALSA", 1, RtAudio::Api::LINUX_ALSA); +#ifdef HAS_RTAUDIO_API +const DaqApi rtaudioAlsaApi("RtAudio Linux ALSA", 1, RtAudio::Api::LINUX_ALSA); +const DaqApi rtaudioPulseaudioApi("RtAudio Linux Pulseaudio", 2, RtAudio::Api::LINUX_PULSE); +const DaqApi rtaudioWasapiApi("RtAudio Windows Wasapi", 3, RtAudio::Api::WINDOWS_WASAPI); +const DaqApi rtaudioDsApi("RtAudio Windows DirectSound", 4, RtAudio::Api::WINDOWS_DS); +const DaqApi rtaudioAsioApi("RtAudio Windows ASIO", 4, RtAudio::Api::WINDOWS_ASIO); #endif -const vector compiledApis = { -#ifdef HAS_ULDAQ_LINUX_API - uldaqapi, -#endif -#ifdef HAS_RTAUDIO_ALSA_API - rtaudioalsaapi, -#endif -#ifdef HAS_RTAUDIO_PULSEAUDIO_API - DaqApi("RtAudio Linux Pulseaudio", 2, RtAudio::Api::LINUX_PULSE), -#endif -#ifdef HAS_RTAUDIO_WIN_WASAPI_API - DaqApi("RtAudio Windows Wasapi", 3, RtAudio::Api::WINDOWS_WASAPI), -#endif - -}; // Structure containing device info parameters class DeviceInfo { diff --git a/lasp/device/lasp_cpprtaudio.cpp b/lasp/device/lasp_cpprtaudio.cpp index e69de29..705c19e 100644 --- a/lasp/device/lasp_cpprtaudio.cpp +++ b/lasp/device/lasp_cpprtaudio.cpp @@ -0,0 +1,97 @@ +#include "lasp_cpprtaudio.h" +#include +#include +#include +using std::atomic; + +void fillRtAudioDeviceInfo(vector &devinfolist) { + + vector apis; + RtAudio::getCompiledApi(apis); + + for(auto api: apis) { + RtAudio rtaudio(api); + us count = rtaudio.getDeviceCount(); + for(us devno = 0; devno< count;devno++) { + + RtAudio::DeviceInfo devinfo = rtaudio.getDeviceInfo(devno); + + DeviceInfo d; + switch(api){ + case RtAudio::LINUX_ALSA: + d.api = rtaudioAlsaApi; + break; + case RtAudio::LINUX_PULSE: + d.api = rtaudioPulseaudioApi; + break; + case RtAudio::WINDOWS_WASAPI: + d.api = rtaudioWasapiApi; + break; + case RtAudio::WINDOWS_DS: + d.api = rtaudioDsApi; + break; + case RtAudio::WINDOWS_ASIO: + d.api = rtaudioAsioApi; + break; + default: + cerr << "Not implemented RtAudio API, skipping." << endl; + continue; + break; + } + + d.device_name = devinfo.name; + d.api_specific_devindex = devno; + + for(us j=0; j stopThread; + + std::thread* thread = NULL; + + SafeQueue *inqueue = NULL; + SafeQueue *outqueue = NULL; + + void* inbuffer = NULL; + void* outbuffer = NULL; + + public: + friend void threadfcn(AudioDaq*); +}; + diff --git a/lasp/device/lasp_cpprtaudio.h b/lasp/device/lasp_cpprtaudio.h index 83beae8..cbe7dca 100644 --- a/lasp/device/lasp_cpprtaudio.h +++ b/lasp/device/lasp_cpprtaudio.h @@ -1,72 +1,11 @@ #ifndef RTAUDIO_H #define RTAUDIO_H -#include "lasp_cppqueue.h" #include "lasp_cppdaq.h" -#include -#include -#include -#include -#include -using std::vector; -using std::atomic; -typedef vector boolvec; +Daq* createRtAudioDevice(const DeviceInfo& devinfo, + const DaqConfiguration& config); -typedef unsigned int us; - -class RtA: public Daq {h - us samplesPerBlock; - double _samplerate; - boolvec inChannels; - boolvec high_range; - boolvec outChannels; - bool monitorOutput; - atomic stopThread; - DaqDeviceHandle handle = 0; - - std::thread* thread = NULL; - mutable std::mutex mutex; - SafeQueue *inqueue = NULL; - SafeQueue *outqueue = NULL; - - double* inbuffer = NULL; - double* outbuffer = NULL; - - public: - double samplerate() const {return this->_samplerate;} - DT9837A( - us samplesPerBlock, - boolvec& inChannels, - boolvec& outChannels, - double samplerate, - bool monitorOutput, - us device_no = 0 - ); - DT9837A(const DT9837A&) = delete; - - ~DT9837A(); - - void setIEPEEnabled(boolvec& config); - - // Coupling_ac: true, means AC coupling, false means DC coupling - void setACCouplingMode(boolvec& coupling_ac); - - void setInputRange(boolvec& high_range); - - us neninchannels() const; - us nenoutchannels() const; - - bool isRunning() const { return bool(thread); } - - virtual void start( - SafeQueue *inqueue, - SafeQueue *outqueue) final; - - virtual void stop() final; - - - friend void threadfcn(DT9837A*); -}; +void fillRtAudioDeviceInfo(vector &devinfolist); #endif // RTAUDIO_H diff --git a/lasp/device/lasp_cppuldaq.cpp b/lasp/device/lasp_cppuldaq.cpp index aae8240..e7fd83e 100644 --- a/lasp/device/lasp_cppuldaq.cpp +++ b/lasp/device/lasp_cppuldaq.cpp @@ -10,7 +10,7 @@ using std::atomic; /* using std::this_thread; */ -const us MAX_DEF_COUNT = 100; +const us MAX_DEV_COUNT_PER_API = 100; const us UL_ERR_MSG_LEN = 512; inline void showErr(UlError err) { @@ -54,13 +54,13 @@ public: throw runtime_error("Invalid sample rate"); } - DaqDeviceDescriptor devdescriptors[MAX_DEF_COUNT]; + DaqDeviceDescriptor devdescriptors[MAX_DEV_COUNT_PER_API]; DaqDeviceDescriptor descriptor; DaqDeviceInterface interfaceType = ANY_IFC; UlError err; - us numdevs = MAX_DEF_COUNT; + us numdevs = MAX_DEV_COUNT_PER_API; err = ulGetDaqDeviceInventory(interfaceType, devdescriptors, &numdevs); if (err != ERR_NO_ERROR) { throw runtime_error("Device inventarization failed"); @@ -515,3 +515,78 @@ Daq *createUlDaqDevice(const DeviceInfo &devinfo, } return daq; } + + +void fillUlDaqDeviceInfo(vector &devinfolist) { + + UlError err; + unsigned int numdevs = MAX_DEV_COUNT_PER_API; + + DaqDeviceDescriptor devdescriptors[MAX_DEV_COUNT_PER_API]; + DaqDeviceDescriptor descriptor; + DaqDeviceInterface interfaceType = ANY_IFC; + + err = ulGetDaqDeviceInventory(interfaceType, devdescriptors, &numdevs); + + if (err != ERR_NO_ERROR) + throw std::runtime_error("UlDaq device inventarization failed"); + + for (unsigned i = 0; i < numdevs; i++) { + + descriptor = devdescriptors[i]; + + DeviceInfo devinfo; + devinfo.api = uldaqapi; + string name, interface; + + if (string(descriptor.productName) == "DT9837A") { + if (descriptor.devInterface == USB_IFC) { + name = "USB - "; + } else if (descriptor.devInterface == BLUETOOTH_IFC) { + /* devinfo. */ + name = "Bluetooth - "; + } else if (descriptor.devInterface == ETHERNET_IFC) { + /* devinfo. */ + name = "Ethernet - "; + } + + name += string(descriptor.productName) + " "; + name += string(descriptor.uniqueId); + devinfo.device_name = name; + + devinfo.api_specific_devindex = i; + devinfo.availableDataTypes.push_back(dtype_fl64); + devinfo.prefDataTypeIndex = 0; + + devinfo.availableSampleRates.push_back(10000); + devinfo.availableSampleRates.push_back(12000); + devinfo.availableSampleRates.push_back(20000); + devinfo.availableSampleRates.push_back(24000); + devinfo.availableSampleRates.push_back(32000); + devinfo.availableSampleRates.push_back(48000); + devinfo.availableSampleRates.push_back(51000); + + devinfo.prefSampleRateIndex = 5; + + devinfo.availableFramesPerBlock.push_back(512); + devinfo.availableFramesPerBlock.push_back(1024); + devinfo.availableFramesPerBlock.push_back(2048); + devinfo.availableFramesPerBlock.push_back(4096); + devinfo.availableFramesPerBlock.push_back(8192); + devinfo.prefFramesPerBlockIndex = 1; + + devinfo.availableInputRanges = {1.0, 10.0}; + devinfo.prefInputRangeIndex = 0; + + devinfo.ninchannels = 4; + devinfo.noutchannels = 1; + + devinfo.hasInputIEPE = true; + devinfo.hasInputACCouplingSwitch = true; + devinfo.hasInputTrigger = true; + + // Finally, this devinfo is pushed back in list + devinfolist.push_back(devinfo); + } + } +} diff --git a/lasp/device/lasp_cppuldaq.h b/lasp/device/lasp_cppuldaq.h index c82dba6..59f8cea 100644 --- a/lasp/device/lasp_cppuldaq.h +++ b/lasp/device/lasp_cppuldaq.h @@ -6,6 +6,8 @@ Daq* createUlDaqDevice(const DeviceInfo& devinfo, const DaqConfiguration& config); +void fillUlDaqDeviceInfo(vector &devinfolist); + #endif // ULDAQ_H diff --git a/lasp/device/lasp_daq.pyx b/lasp/device/lasp_daq.pyx index 8546b2b..08e747a 100644 --- a/lasp/device/lasp_daq.pyx +++ b/lasp/device/lasp_daq.pyx @@ -1,4 +1,6 @@ cimport cython +from .lasp_deviceinfo cimport DeviceInfo + from cpython.ref cimport PyObject,Py_INCREF, Py_DECREF from .lasp_device_common import AvType @@ -138,6 +140,18 @@ cdef class Daq: def isRunning(self): return self.sd is not NULL + @staticmethod + def getDeviceInfo(): + cdef: + vector[cppDeviceInfo] devinfos = cppDaq.getDeviceInfo() + pydevinfo = [] + for i in range(devinfos.size()): + d = DeviceInfo() + d.devinfo = devinfos[i] + pydevinfo.append(d) + + return pydevinfo + # @cython.nonecheck(True) # def start(self, avstream): # """ diff --git a/lasp/device/lasp_daqconfig.pyx b/lasp/device/lasp_daqconfig.pyx index 571d2a9..6e2047d 100644 --- a/lasp/device/lasp_daqconfig.pyx +++ b/lasp/device/lasp_daqconfig.pyx @@ -10,28 +10,21 @@ Data Acquistiion (DAQ) device descriptors, and the DAQ devices themselves """ from dataclasses import dataclass, field from typing import List - from dataclasses_json import dataclass_json -from ..lasp_common import Qty, SIQtys, lasp_shelve +from ..lasp_common import lasp_shelve, SIQtys, Qty + -# class InputMode: -# differential = 'Differential' -# single_ended = 'Single-ended' -# pseudo_differential = 'Pseudo-differential' -# undefined = 'Undefined' class CouplingMode: ac = 'AC' dc = 'DC' undefined = 'Undefined' - class Range: oneV = '+/- 1 V' tenV = '+/- 10 V' undefined = 'Undefined' - @dataclass_json @dataclass class DAQChannel: @@ -40,60 +33,16 @@ class DAQChannel: sensitivity: float = 1.0 qty: Qty = SIQtys.default range_: str = 'Undefined' + ACCoupling_enabled: bool = False IEPE_enabled: bool = False -@dataclass_json -@dataclass -class DAQConfiguration: + +cdef class DAQConfiguration: """ Initialize a device descriptor - - Args: - duplex_mode: Set device to duplex mode, if possible - monitor_gen: If set to true, add monitor channel to recording. - outputDelayBlocks: number of blocks to delay output stream when added - to input for monitoring the output synchronously with input. - - input_device_name: ASCII name with which to open the device when connected - outut_device_name: ASCII name with which to open the device when connected - - ============================== - en_format: index of the format in the list of sample formats - en_input_rate: index of enabled input sampling frequency [Hz] - in the list of frequencies. - input_channel_configs: list of channel indices which are used to - acquire data from. - input_sensitivity: List of sensitivity values, in units of [Pa^-1] - input_gain_settings: If a DAQ supports it, list of indices which - corresponds to a position in the possible input - gains for each channel. Should only be not equal - to None when the hardware supports changing the - input gain. - en_output_rate: index in the list of possible output sampling - frequencies. - en_output_channels: list of enabled output channels - =============================== - - """ - api: int - duplex_mode: bool - - input_device_name: str - output_device_name: str - - en_input_sample_format: str - en_output_sample_format: str - en_input_rate: int - en_output_rate: int - - input_channel_configs: List[DAQChannel] = field(default_factory=list) - output_channel_configs: List[DAQChannel] = field(default_factory=list) - monitor_gen: bool = False - - outputDelayBlocks: int = 0 - nFramesPerBlock: int = 1024 + # DaqConfiguration config def getInputChannels(self): return self.input_channel_configs @@ -101,15 +50,6 @@ class DAQConfiguration: def getOutputChannels(self): return self.output_channel_configs - def firstEnabledInputChannelNumber(self): - """ - Returns the channel number of the first enabled channel. Returns -1 if - no channels are enabled. - """ - for i, ch in enumerate(self.input_channel_configs): - if ch.channel_enabled: - return i - return -1 def firstEnabledOutputChannelNumber(self): """ diff --git a/lasp/device/lasp_deviceinfo.pyx b/lasp/device/lasp_deviceinfo.pyx index 123d9c0..469c93d 100644 --- a/lasp/device/lasp_deviceinfo.pyx +++ b/lasp/device/lasp_deviceinfo.pyx @@ -1,5 +1,6 @@ __all__ = ['DeviceInfo'] + cdef class DeviceInfo: def __cinit__(self): pass @@ -10,6 +11,9 @@ cdef class DeviceInfo: @property def name(self): return self.devinfo.device_name.decode('utf-8') + def __repr__(self): + return self.api + ': ' + self.name + @property def ninchannels(self): return self.devinfo.ninchannels diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 660b093..12219f5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,6 @@ include_directories(${CMAKE_SOURCE_DIR}/lasp/c) include_directories(${CMAKE_SOURCE_DIR}/lasp/device) + add_executable(test_bf test_bf.c) add_executable(test_workers test_workers.c) add_executable(test_fft test_fft.c) @@ -11,4 +12,4 @@ target_link_libraries(test_workers lasp_lib pthread) target_link_libraries(test_math lasp_lib pthread) add_executable(test_uldaq test_uldaq.cpp) -target_link_libraries(test_uldaq cpp_daq uldaq pthread) +target_link_libraries(test_uldaq cpp_daq ${cpp_daq_linklibs})