First work on moving RtAudio Api back to C++.
This commit is contained in:
parent
5c6838c7e4
commit
a73ef3d7a8
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,7 +1,6 @@
|
||||
*.a
|
||||
*.cxx
|
||||
*.pyc
|
||||
lasp_rtaudio.cxx
|
||||
lasp_uldaq.cxx
|
||||
dist
|
||||
CMakeFiles
|
||||
CMakeCache.txt
|
||||
@ -20,6 +19,7 @@ test/test_bf
|
||||
test/test_fft
|
||||
test/test_math
|
||||
test/test_workers
|
||||
test/test_uldaq
|
||||
doc
|
||||
LASP.egg-info
|
||||
lasp_octave_fir.*
|
||||
|
@ -1,5 +1,8 @@
|
||||
cmake_minimum_required (VERSION 3.0)
|
||||
|
||||
# To allow linking to static libs from other directories
|
||||
cmake_policy(SET CMP0079 NEW)
|
||||
|
||||
# This is used for code completion in vim
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS=ON)
|
||||
project(LASP)
|
||||
@ -72,6 +75,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
link_directories(C:\\mingw\\bin)
|
||||
link_directories(..\\rtaudio)
|
||||
link_directories(C:\\Users\\User\\Miniconda3)
|
||||
add_definitions(-DHAS_RTAUDIO_WIN_WASAPI_API)
|
||||
else()
|
||||
set(win32 false)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -std=c11 \
|
||||
@ -79,6 +83,14 @@ 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")
|
||||
|
||||
|
@ -1,21 +1,15 @@
|
||||
include_directories(/usr/include/rtaudio)
|
||||
|
||||
add_library(cpp_daq lasp_cppuldaq.cpp)
|
||||
add_library(cpp_daq lasp_cppdaq.cpp lasp_cppuldaq.cpp lasp_cpprtaudio.cpp)
|
||||
|
||||
set_source_files_properties(lasp_rtaudio.pyx PROPERTIES CYTHON_IS_CXX TRUE)
|
||||
set_source_files_properties(lasp_uldaq.pyx PROPERTIES CYTHON_IS_CXX TRUE)
|
||||
set_source_files_properties(lasp_rtaudio.cxx PROPERTIES COMPILE_FLAGS
|
||||
set_source_files_properties(lasp_daq.pyx PROPERTIES CYTHON_IS_CXX TRUE)
|
||||
set_source_files_properties(lasp_daq.cxx PROPERTIES COMPILE_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} ${CYTHON_EXTRA_CXX_FLAGS}")
|
||||
|
||||
cython_add_module(lasp_rtaudio lasp_rtaudio.pyx)
|
||||
cython_add_module(lasp_uldaq lasp_uldaq.pyx)
|
||||
cython_add_module(lasp_daq lasp_daq.pyx)
|
||||
|
||||
target_link_libraries(lasp_rtaudio pthread rtaudio)
|
||||
target_link_libraries(lasp_uldaq cpp_daq uldaq pthread)
|
||||
target_link_libraries(lasp_daq cpp_daq uldaq rtaudio pthread)
|
||||
if(win32)
|
||||
target_link_libraries(lasp_rtaudio python37)
|
||||
target_link_libraries(lasp_uldaq python37)
|
||||
target_link_libraries(lasp_daq python37)
|
||||
endif(win32)
|
||||
|
||||
add_executable(test_uldaq test_uldaq.cpp)
|
||||
target_link_libraries(test_uldaq cpp_daq uldaq pthread)
|
||||
|
@ -1,6 +1,5 @@
|
||||
#!/usr/bin/python3
|
||||
from .lasp_daqconfig import *
|
||||
from .lasp_avtype import *
|
||||
from .lasp_rtaudio import *
|
||||
from .lasp_uldaq import *
|
||||
from .lasp_daq import *
|
||||
|
||||
|
92
lasp/device/lasp_cppdaq.cpp
Normal file
92
lasp/device/lasp_cppdaq.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include "lasp_cppdaq.h"
|
||||
#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;
|
||||
unsigned deviceno;
|
||||
|
||||
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("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.name = name;
|
||||
|
||||
devinfo.devindex = i;
|
||||
devinfo.availableDataTypes.push_back(dtype_fl64);
|
||||
|
||||
devinfo.ninchannels = 4;
|
||||
devinfo.noutchannels = 1;
|
||||
|
||||
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.prefSampleRate = 48000;
|
||||
|
||||
devinfo.hasInputIEPE = true;
|
||||
devinfo.hasInputACCouplingSwitch = true;
|
||||
devinfo.hasInputTrigger = true;
|
||||
|
||||
devinfolist.push_back(devinfo);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vector<DeviceInfo> DaqDevices::getDeviceInfo() {
|
||||
vector<DeviceInfo> devs;
|
||||
#ifdef HAS_ULDAQ_LINUX_API
|
||||
fillUlDaqDeviceInfo(devs);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_RTAUDIO_ALSA_API
|
||||
#endif
|
||||
|
||||
#ifdef HAS_RTAUDIO_PULSEAUDIO_API
|
||||
#endif
|
||||
|
||||
#ifdef HAS_RTAUDIO_WIN_WASAPI_API
|
||||
#endif
|
||||
return devs;
|
||||
}
|
||||
|
||||
Daq* DaqDevices::createDevice(const DeviceInfo&) {
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
@ -1,18 +1,122 @@
|
||||
#ifndef LAP_CPPDAQ_H
|
||||
#define LAP_CPPDAQ_H
|
||||
#ifndef LASP_CPPDAQ_H
|
||||
#define LASP_CPPDAQ_H
|
||||
|
||||
#ifdef HAS_RTAUDIO
|
||||
#include <RtAudio.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_ULDAQ
|
||||
#include <uldaq.h>
|
||||
#endif
|
||||
|
||||
#include "lasp_cppqueue.h"
|
||||
#include "vector"
|
||||
#include "string"
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
class DataType {
|
||||
public:
|
||||
const string name;
|
||||
unsigned sw;
|
||||
bool is_floating;
|
||||
DataType(const char* name,unsigned sw,bool is_floating):
|
||||
name(name),
|
||||
sw(sw),
|
||||
is_floating(is_floating) {}
|
||||
|
||||
};
|
||||
|
||||
const DataType dtype_fl64("64-bits floating point",4,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);
|
||||
|
||||
const std::vector<DataType> dataTypes = {
|
||||
dtype_int8,
|
||||
dtype_int16,
|
||||
dtype_int32,
|
||||
dtype_fl64,
|
||||
};
|
||||
|
||||
class DaqApi {
|
||||
public:
|
||||
string apiname = "";
|
||||
unsigned apicode = 0;
|
||||
unsigned api_specific_subcode = 0;
|
||||
|
||||
DaqApi(string apiname,
|
||||
unsigned apicode,
|
||||
unsigned api_specific_subcode=0):
|
||||
apiname(apiname),
|
||||
apicode(apicode),
|
||||
api_specific_subcode(api_specific_subcode) {}
|
||||
DaqApi(){}
|
||||
};
|
||||
|
||||
#ifdef HAS_ULDAQ_LINUX_API
|
||||
const DaqApi uldaqapi = DaqApi("UlDaq", 0);
|
||||
#endif
|
||||
const vector<DaqApi> compiledApis = {
|
||||
#ifdef HAS_ULDAQ_LINUX_API
|
||||
uldaqapi,
|
||||
#endif
|
||||
#ifdef HAS_RTAUDIO_ALSA_API
|
||||
DaqApi("RtAudio Linux ALSA", 1, RtAudio::Api::LINUX_ALSA),
|
||||
#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 {
|
||||
public:
|
||||
DaqApi api;
|
||||
string name = "";
|
||||
unsigned devindex;
|
||||
|
||||
vector<DataType> availableDataTypes;
|
||||
vector<double> availableSampleRates;
|
||||
unsigned prefSampleRateIndex = 0;
|
||||
double prefSampleRate = 0;
|
||||
|
||||
unsigned ninchannels =0;
|
||||
unsigned noutchannels =0;
|
||||
|
||||
bool hasInputIEPE = false;
|
||||
bool hasInputACCouplingSwitch = false;
|
||||
bool hasInputTrigger = false;
|
||||
|
||||
};
|
||||
|
||||
class Daq;
|
||||
class DaqDevices {
|
||||
public:
|
||||
static vector<DeviceInfo> getDeviceInfo();
|
||||
static Daq* createDevice(const DeviceInfo&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
class Daq{
|
||||
|
||||
public:
|
||||
|
||||
virtual void start(
|
||||
SafeQueue<double*> *inqueue,
|
||||
SafeQueue<double*> *outqueue) = 0;
|
||||
SafeQueue<void*> *inqueue,
|
||||
SafeQueue<void*> *outqueue) = 0;
|
||||
|
||||
virtual void stop() = 0;
|
||||
virtual double samplerate() const = 0;
|
||||
virtual DataType getDataType() const = 0;
|
||||
|
||||
virtual ~Daq() {};
|
||||
|
||||
};
|
||||
|
||||
#endif // LAP_CPPDAQ_H
|
||||
#endif // LASP_CPPDAQ_H
|
||||
|
74
lasp/device/lasp_cpprtaudio.h
Normal file
74
lasp/device/lasp_cpprtaudio.h
Normal file
@ -0,0 +1,74 @@
|
||||
#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;
|
||||
|
||||
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*);
|
||||
};
|
||||
|
||||
#endif // RTAUDIO_H
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef ULDAQ_THREAD_H
|
||||
#define ULDAQ_THREAD_H
|
||||
#ifndef ULDAQ_H
|
||||
#define ULDAQ_H
|
||||
#include "lasp_cppqueue.h"
|
||||
#include "lasp_cppdaq.h"
|
||||
#include <uldaq.h>
|
||||
@ -59,8 +59,8 @@ class DT9837A: public Daq {
|
||||
bool isRunning() const { return bool(thread); }
|
||||
|
||||
virtual void start(
|
||||
SafeQueue<double*> *inqueue,
|
||||
SafeQueue<double*> *outqueue) final;
|
||||
SafeQueue<void*> *inqueue,
|
||||
SafeQueue<void*> *outqueue) final;
|
||||
|
||||
virtual void stop() final;
|
||||
|
||||
@ -68,6 +68,6 @@ class DT9837A: public Daq {
|
||||
friend void threadfcn(DT9837A*);
|
||||
};
|
||||
|
||||
#endif // ULDAQ_THREAD_H
|
||||
#endif // ULDAQ_H
|
||||
|
||||
|
||||
|
@ -9,10 +9,30 @@ Data Acquistiion (DAQ) device descriptors, and the DAQ devices themselves
|
||||
|
||||
"""
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses_json import dataclass_json
|
||||
from ..lasp_common import lasp_shelve, Qty, SIQtys
|
||||
from typing import List
|
||||
|
||||
from dataclasses_json import dataclass_json
|
||||
|
||||
from ..lasp_common import Qty, SIQtys, lasp_shelve
|
||||
|
||||
@dataclass
|
||||
class DAQApi:
|
||||
backendname: str
|
||||
apiname: str
|
||||
internal_nr: int
|
||||
|
||||
def description(self):
|
||||
return self.backendname + ' - ' + self.apiname
|
||||
|
||||
|
||||
class DAQApis:
|
||||
apis = []
|
||||
|
||||
@staticmethod
|
||||
def addApi(api):
|
||||
DAQApis.apis.append(api)
|
||||
|
||||
|
||||
|
||||
class InputMode:
|
||||
differential = 'Differential'
|
||||
@ -20,16 +40,19 @@ class InputMode:
|
||||
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
|
||||
class DeviceInfo:
|
||||
api: int
|
||||
|
@ -1,9 +1,14 @@
|
||||
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)
|
||||
add_executable(test_math test_math.c)
|
||||
|
||||
target_link_libraries(test_bf lasp_lib)
|
||||
target_link_libraries(test_fft lasp_lib pthread)
|
||||
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)
|
||||
|
@ -22,8 +22,8 @@ int main() {
|
||||
true // monitor Output
|
||||
);
|
||||
|
||||
SafeQueue<double*> inqueue;
|
||||
SafeQueue<double*> outqueue;
|
||||
SafeQueue<void*> inqueue;
|
||||
SafeQueue<void*> outqueue;
|
||||
|
||||
double totalTime = 5;
|
||||
double t = 0;
|
||||
@ -52,7 +52,7 @@ int main() {
|
||||
daq.stop();
|
||||
|
||||
while(!inqueue.empty()) {
|
||||
double* buf = inqueue.dequeue();
|
||||
double* buf = (double*) inqueue.dequeue();
|
||||
for(us i=0;i<samplesPerBlock;i++) {
|
||||
for(us ch=0;ch<daq.neninchannels();ch++) {
|
||||
cout << buf[ch*samplesPerBlock+i] << " ";
|
||||
@ -62,7 +62,7 @@ int main() {
|
||||
free(buf);
|
||||
}
|
||||
while(!outqueue.empty()){
|
||||
double* dat = outqueue.dequeue();
|
||||
void* dat = outqueue.dequeue();
|
||||
free(dat);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user