Inbetween state. Nothing is working

This commit is contained in:
Anne de Jong 2020-10-14 09:42:19 +02:00
parent 29662c82e3
commit bc9639f10c
12 changed files with 311 additions and 303 deletions

View File

@ -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)

View File

@ -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()

View File

@ -1,105 +1,26 @@
#include "lasp_cppdaq.h"
#include "lasp_cppuldaq.h"
#include <algorithm>
#include <cassert>
#include <iostream>
#include <strstream>
using std::cout;
using std::endl;
#define MAX_DEV_COUNT_PER_API 20
#ifdef HAS_ULDAQ_LINUX_API
void fillUlDaqDeviceInfo(vector<DeviceInfo> &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<DeviceInfo> Daq::getDeviceInfo() {
vector<DeviceInfo> 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<DeviceInfo> &devinfos) {
const vector<DeviceInfo> &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);

View File

@ -1,11 +1,11 @@
#ifndef LASP_CPPDAQ_H
#define LASP_CPPDAQ_H
#ifdef HAS_RTAUDIO
#ifdef HAS_RTAUDIO_API
#include <RtAudio.h>
#endif
#ifdef HAS_ULDAQ
#ifdef HAS_ULDAQ_API
#include <uldaq.h>
#endif
@ -13,6 +13,9 @@
#include "string"
#include "vector"
#include <mutex>
#include <iostream>
#include <sstream>
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<DataType> 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<DaqApi> 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 {

View File

@ -0,0 +1,97 @@
#include "lasp_cpprtaudio.h"
#include <RtAudio.h>
#include <atomic>
#include <thread>
using std::atomic;
void fillRtAudioDeviceInfo(vector<DeviceInfo> &devinfolist) {
vector<RtAudio::Api> 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<devinfo.sampleRates.size();j++){
us rate = devinfo.sampleRates[j];
d.availableSampleRates.push_back((double) rate);
if(devinfo.preferredSampleRate == rate) {
d.prefSampleRateIndex = j;
}
}
d.noutchannels = devinfo.outputChannels;
d.ninchannels = devinfo.inputChannels;
d.availableInputRanges = {1.0};
RtAudioFormat formats = devinfo.nativeFormats;
if(formats & RTAUDIO_SINT8) {
d.availableDataTypes.push_back(dtype_int8);
}
if(formats & RTAUDIO_SINT16) {
d.availableDataTypes.push_back(dtype_int16);
}
if(formats & RTAUDIO_SINT32) {
d.availableDataTypes.push_back(dtype_fl32);
}
if(formats & RTAUDIO_FLOAT64) {
d.availableDataTypes.push_back(dtype_fl64);
}
d.prefDataTypeIndex = d.availableDataTypes.size() - 1;
devinfolist.push_back(d);
}
}
}
class AudioDaq: public Daq {
atomic<bool> stopThread;
std::thread* thread = NULL;
SafeQueue<void*> *inqueue = NULL;
SafeQueue<void*> *outqueue = NULL;
void* inbuffer = NULL;
void* outbuffer = NULL;
public:
friend void threadfcn(AudioDaq*);
};

View File

@ -1,72 +1,11 @@
#ifndef RTAUDIO_H
#define RTAUDIO_H
#include "lasp_cppqueue.h"
#include "lasp_cppdaq.h"
#include <algorithm>
#include <vector>
#include <mutex>
#include <atomic>
#include <thread>
using std::vector;
using std::atomic;
typedef vector<bool> 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<bool> stopThread;
DaqDeviceHandle handle = 0;
std::thread* thread = NULL;
mutable std::mutex mutex;
SafeQueue<double*> *inqueue = NULL;
SafeQueue<double*> *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<double*> *inqueue,
SafeQueue<double*> *outqueue) final;
virtual void stop() final;
friend void threadfcn(DT9837A*);
};
void fillRtAudioDeviceInfo(vector<DeviceInfo> &devinfolist);
#endif // RTAUDIO_H

View File

@ -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<DeviceInfo> &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);
}
}
}

View File

@ -6,6 +6,8 @@
Daq* createUlDaqDevice(const DeviceInfo& devinfo,
const DaqConfiguration& config);
void fillUlDaqDeviceInfo(vector<DeviceInfo> &devinfolist);
#endif // ULDAQ_H

View File

@ -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 = <cppDeviceInfo> devinfos[i]
pydevinfo.append(d)
return pydevinfo
# @cython.nonecheck(True)
# def start(self, avstream):
# """

View File

@ -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):
"""

View File

@ -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

View File

@ -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})