Inbetween state. Nothing is working
This commit is contained in:
parent
29662c82e3
commit
bc9639f10c
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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*);
|
||||
};
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
Daq* createUlDaqDevice(const DeviceInfo& devinfo,
|
||||
const DaqConfiguration& config);
|
||||
|
||||
void fillUlDaqDeviceInfo(vector<DeviceInfo> &devinfolist);
|
||||
|
||||
#endif // ULDAQ_H
|
||||
|
||||
|
||||
|
@ -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):
|
||||
# """
|
||||
|
@ -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):
|
||||
"""
|
||||
|
@ -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
|
||||
|
||||
|
@ -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})
|
||||
|
Loading…
Reference in New Issue
Block a user