Almost working on multiple apis
This commit is contained in:
parent
c1f713c8fb
commit
4e0c09d356
@ -29,14 +29,14 @@ vector<DaqApi> DaqApi::getAvailableApis() {
|
|||||||
vector<DaqApi> apis;
|
vector<DaqApi> apis;
|
||||||
apis.resize(6);
|
apis.resize(6);
|
||||||
#ifdef HAS_ULDAQ_API
|
#ifdef HAS_ULDAQ_API
|
||||||
apis[uldaqapi.apicode] = uldaqapi;
|
apis.at(uldaqapi.apicode) = uldaqapi;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_RTAUDIO_API
|
#ifdef HAS_RTAUDIO_API
|
||||||
apis[rtaudioAlsaApi.apicode] = rtaudioAlsaApi;
|
apis.at(rtaudioAlsaApi.apicode) = rtaudioAlsaApi;
|
||||||
apis[rtaudioPulseaudioApi.apicode] = rtaudioPulseaudioApi;
|
apis.at(rtaudioPulseaudioApi.apicode) = rtaudioPulseaudioApi;
|
||||||
apis[rtaudioWasapiApi.apicode] = rtaudioWasapiApi;
|
apis.at(rtaudioWasapiApi.apicode) = rtaudioWasapiApi;
|
||||||
apis[rtaudioDsApi.apicode] = rtaudioDsApi;
|
apis.at(rtaudioDsApi.apicode) = rtaudioDsApi;
|
||||||
apis[rtaudioAsioApi.apicode] = rtaudioAsioApi;
|
apis.at(rtaudioAsioApi.apicode) = rtaudioAsioApi;
|
||||||
#endif
|
#endif
|
||||||
return apis;
|
return apis;
|
||||||
}
|
}
|
||||||
@ -85,26 +85,26 @@ bool DaqConfiguration::match(const DeviceInfo& dev) const {
|
|||||||
|
|
||||||
int DaqConfiguration::getHighestInChannel() const {
|
int DaqConfiguration::getHighestInChannel() const {
|
||||||
for(int i=eninchannels.size()-1; i>-1;i--) {
|
for(int i=eninchannels.size()-1; i>-1;i--) {
|
||||||
if(eninchannels[i]) return i;
|
if(eninchannels.at(i)) return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DaqConfiguration::getHighestOutChannel() const {
|
int DaqConfiguration::getHighestOutChannel() const {
|
||||||
for(us i=enoutchannels.size()-1; i>=0;i--) {
|
for(us i=enoutchannels.size()-1; i>=0;i--) {
|
||||||
if(enoutchannels[i]) return i;
|
if(enoutchannels.at(i)) return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int DaqConfiguration::getLowestInChannel() const {
|
int DaqConfiguration::getLowestInChannel() const {
|
||||||
for(us i=0; i<eninchannels.size();i++) {
|
for(us i=0; i<eninchannels.size();i++) {
|
||||||
if(eninchannels[i]) return i;
|
if(eninchannels.at(i)) return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int DaqConfiguration::getLowestOutChannel() const {
|
int DaqConfiguration::getLowestOutChannel() const {
|
||||||
for(us i=0; i<enoutchannels.size();i++) {
|
for(us i=0; i<enoutchannels.size();i++) {
|
||||||
if(enoutchannels[i]) return i;
|
if(enoutchannels.at(i)) return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -118,15 +118,29 @@ Daq *Daq::createDaq(const DeviceInfo& devinfo,
|
|||||||
|
|
||||||
// Some basic sanity checks
|
// Some basic sanity checks
|
||||||
if ((devinfo.ninchannels != config.eninchannels.size())) {
|
if ((devinfo.ninchannels != config.eninchannels.size())) {
|
||||||
|
/* cerr << "devinfo.ninchannels: " << devinfo.ninchannels << endl; */
|
||||||
|
/* cerr << "config.eninchannels.size(): " << config.eninchannels.size() << endl; */
|
||||||
throw runtime_error("Invalid length of enabled input channels specified");
|
throw runtime_error("Invalid length of enabled input channels specified");
|
||||||
}
|
}
|
||||||
if ((devinfo.noutchannels != config.enoutchannels.size())) {
|
if ((devinfo.noutchannels != config.enoutchannels.size())) {
|
||||||
throw runtime_error("outvalid length of enabled output channels specified");
|
throw runtime_error("outvalid length of enabled output channels specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (devinfo.api == uldaqapi) {
|
int apicode = devinfo.api.apicode;
|
||||||
|
if(devinfo.api == DaqApi()) {
|
||||||
|
throw std::runtime_error(string("Unable to match API: ") + devinfo.api.apiname);
|
||||||
|
}
|
||||||
|
#ifdef HAS_ULDAQ_API
|
||||||
|
else if (devinfo.api == uldaqapi) {
|
||||||
return createUlDaqDevice(devinfo, config);
|
return createUlDaqDevice(devinfo, config);
|
||||||
} else {
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_RTAUDIO_API
|
||||||
|
else if(apicode >= 1 && apicode <= 5) {
|
||||||
|
return createRtAudioDevice(devinfo, config);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
throw std::runtime_error(string("Unable to match API: ") +
|
throw std::runtime_error(string("Unable to match API: ") +
|
||||||
devinfo.api.apiname);
|
devinfo.api.apiname);
|
||||||
}
|
}
|
||||||
@ -154,14 +168,14 @@ Daq::Daq(const DeviceInfo &devinfo, const DaqConfiguration &config)
|
|||||||
double Daq::samplerate() const {
|
double Daq::samplerate() const {
|
||||||
mutexlock lock(mutex);
|
mutexlock lock(mutex);
|
||||||
assert(sampleRateIndex < availableSampleRates.size());
|
assert(sampleRateIndex < availableSampleRates.size());
|
||||||
return availableSampleRates[sampleRateIndex];
|
return availableSampleRates.at(sampleRateIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DataType Daq::dataType() const {
|
DataType Daq::dataType() const {
|
||||||
mutexlock lock(mutex);
|
mutexlock lock(mutex);
|
||||||
assert((us)dataTypeIndex < availableDataTypes.size());
|
assert((us)dataTypeIndex < availableDataTypes.size());
|
||||||
return availableDataTypes[dataTypeIndex];
|
return availableDataTypes.at(dataTypeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -171,7 +185,7 @@ double Daq::inputRangeForChannel(us ch) const {
|
|||||||
}
|
}
|
||||||
mutexlock lock(mutex);
|
mutexlock lock(mutex);
|
||||||
assert(inputRangeIndices.size() == eninchannels.size());
|
assert(inputRangeIndices.size() == eninchannels.size());
|
||||||
return availableInputRanges[inputRangeIndices[ch]];
|
return availableInputRanges.at(inputRangeIndices.at(ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ public:
|
|||||||
double prefSampleRate() const {
|
double prefSampleRate() const {
|
||||||
if (((us)prefSampleRateIndex < availableSampleRates.size()) &&
|
if (((us)prefSampleRateIndex < availableSampleRates.size()) &&
|
||||||
(prefSampleRateIndex >= 0)) {
|
(prefSampleRateIndex >= 0)) {
|
||||||
return availableSampleRates[prefSampleRateIndex];
|
return availableSampleRates.at(prefSampleRateIndex);
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("No prefered sample rate available");
|
throw std::runtime_error("No prefered sample rate available");
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ public:
|
|||||||
|
|
||||||
us framesPerBlock() const {
|
us framesPerBlock() const {
|
||||||
mutexlock lock(mutex);
|
mutexlock lock(mutex);
|
||||||
return availableFramesPerBlock[framesPerBlockIndex];
|
return availableFramesPerBlock.at(framesPerBlockIndex);
|
||||||
}
|
}
|
||||||
bool duplexMode() const {
|
bool duplexMode() const {
|
||||||
return (neninchannels(false) > 0 && nenoutchannels() > 0);
|
return (neninchannels(false) > 0 && nenoutchannels() > 0);
|
||||||
|
@ -116,17 +116,22 @@ class AudioDaq: public Daq {
|
|||||||
|
|
||||||
nFramesPerBlock = this->framesPerBlock();
|
nFramesPerBlock = this->framesPerBlock();
|
||||||
|
|
||||||
|
|
||||||
if(neninchannels(false) > 0) {
|
if(neninchannels(false) > 0) {
|
||||||
instreamparams = new RtAudio::StreamParameters();
|
instreamparams = new RtAudio::StreamParameters();
|
||||||
instreamparams->nChannels = getHighestInChannel();
|
instreamparams->nChannels = getHighestInChannel() + 1;
|
||||||
|
if(instreamparams->nChannels < 1) {
|
||||||
|
throw runtime_error("Invalid input number of channels");
|
||||||
|
}
|
||||||
instreamparams->firstChannel = 0;
|
instreamparams->firstChannel = 0;
|
||||||
instreamparams->deviceId = devinfo.api_specific_devindex;
|
instreamparams->deviceId = devinfo.api_specific_devindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nenoutchannels() > 0) {
|
if(nenoutchannels() > 0) {
|
||||||
outstreamparams = new RtAudio::StreamParameters();
|
outstreamparams = new RtAudio::StreamParameters();
|
||||||
outstreamparams->nChannels = getHighestOutChannel();
|
outstreamparams->nChannels = getHighestOutChannel() + 1;
|
||||||
|
if(outstreamparams->nChannels < 1) {
|
||||||
|
throw runtime_error("Invalid output number of channels");
|
||||||
|
}
|
||||||
outstreamparams->firstChannel = 0;
|
outstreamparams->firstChannel = 0;
|
||||||
outstreamparams->deviceId = devinfo.api_specific_devindex;
|
outstreamparams->deviceId = devinfo.api_specific_devindex;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,15 @@ public:
|
|||||||
DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config)
|
DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config)
|
||||||
: Daq(devinfo, config) {
|
: Daq(devinfo, config) {
|
||||||
|
|
||||||
|
// 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");
|
||||||
|
}
|
||||||
|
|
||||||
stopThread = false;
|
stopThread = false;
|
||||||
|
|
||||||
nFramesPerBlock = availableFramesPerBlock[framesPerBlockIndex];
|
nFramesPerBlock = availableFramesPerBlock[framesPerBlockIndex];
|
||||||
|
@ -6,5 +6,8 @@ cdef class Daq:
|
|||||||
cdef:
|
cdef:
|
||||||
PyStreamData *sd
|
PyStreamData *sd
|
||||||
cppDaq* daq_device
|
cppDaq* daq_device
|
||||||
|
cdef public:
|
||||||
|
double samplerate
|
||||||
|
unsigned int nFramesPerBlock
|
||||||
|
|
||||||
cdef cleanupStream(self, PyStreamData* sd)
|
cdef cleanupStream(self, PyStreamData* sd)
|
||||||
|
@ -7,7 +7,7 @@ from .lasp_device_common import AvType
|
|||||||
|
|
||||||
__all__ = ['Daq']
|
__all__ = ['Daq']
|
||||||
|
|
||||||
cdef cnp.NPY_TYPES getNumpyDataType(DataType& dt):
|
cdef cnp.NPY_TYPES getCNumpyDataType(DataType& dt):
|
||||||
if(dt == dtype_fl32):
|
if(dt == dtype_fl32):
|
||||||
return cnp.NPY_FLOAT32
|
return cnp.NPY_FLOAT32
|
||||||
elif(dt == dtype_fl64):
|
elif(dt == dtype_fl64):
|
||||||
@ -21,6 +21,19 @@ cdef cnp.NPY_TYPES getNumpyDataType(DataType& dt):
|
|||||||
else:
|
else:
|
||||||
raise ValueError('Unknown data type')
|
raise ValueError('Unknown data type')
|
||||||
|
|
||||||
|
cdef getNumpyDataType(DataType& dt):
|
||||||
|
if(dt == dtype_fl32):
|
||||||
|
return np.float32
|
||||||
|
elif(dt == dtype_fl64):
|
||||||
|
return np.float64
|
||||||
|
elif(dt == dtype_int8):
|
||||||
|
return np.int8
|
||||||
|
elif(dt == dtype_int16):
|
||||||
|
return np.int16
|
||||||
|
elif(dt == dtype_int32):
|
||||||
|
return np.int32
|
||||||
|
else:
|
||||||
|
raise ValueError('Unknown data type')
|
||||||
|
|
||||||
|
|
||||||
ctypedef struct PyStreamData:
|
ctypedef struct PyStreamData:
|
||||||
@ -132,21 +145,47 @@ cdef void audioCallbackPythonThreadFunction(void* voidsd) nogil:
|
|||||||
|
|
||||||
cdef class Daq:
|
cdef class Daq:
|
||||||
|
|
||||||
def __cinit__(self):
|
def __cinit__(self, DeviceInfo pydevinfo, DaqConfiguration pydaqconfig):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Acquires a daq handle, and opens the device
|
Acquires a daq handle, and opens the device
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
cdef:
|
||||||
|
cppDaqConfiguration* daqconfig
|
||||||
|
cppDeviceInfo* devinfo
|
||||||
|
vector[cppDeviceInfo] devinfos
|
||||||
|
|
||||||
self.daq_device = NULL
|
self.daq_device = NULL
|
||||||
self.sd = NULL
|
self.sd = NULL
|
||||||
|
|
||||||
|
daqconfig = &(pydaqconfig.config)
|
||||||
|
devinfo = &(pydevinfo.devinfo)
|
||||||
|
|
||||||
|
self.daq_device = cppDaq.createDaq(devinfo[0], daqconfig[0])
|
||||||
|
self.nFramesPerBlock = self.daq_device.framesPerBlock()
|
||||||
|
self.samplerate = self.daq_device.samplerate()
|
||||||
|
|
||||||
|
if self.nFramesPerBlock > 8192 or self.nFramesPerBlock < 512:
|
||||||
|
del self.daq_device
|
||||||
|
raise ValueError('Invalid number of nFramesPerBlock')
|
||||||
|
|
||||||
def __dealloc__(self):
|
def __dealloc__(self):
|
||||||
# fprintf(stderr, "UlDaq.__dealloc__\n")
|
# fprintf(stderr, "UlDaq.__dealloc__\n")
|
||||||
if self.sd is not NULL:
|
if self.sd is not NULL:
|
||||||
fprintf(stderr, "UlDaq.__dealloc__: stopping stream.\n")
|
fprintf(stderr, "UlDaq.__dealloc__: stopping stream.\n")
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
|
if self.daq_device is not NULL:
|
||||||
|
del self.daq_device
|
||||||
|
self.daq_device = NULL
|
||||||
|
|
||||||
|
def getNumpyDataType(self):
|
||||||
|
cdef:
|
||||||
|
DataType dt = self.daq_device.dataType()
|
||||||
|
return getNumpyDataType(dt)
|
||||||
|
|
||||||
|
|
||||||
def isRunning(self):
|
def isRunning(self):
|
||||||
return self.sd is not NULL
|
return self.sd is not NULL
|
||||||
|
|
||||||
@ -166,7 +205,7 @@ cdef class Daq:
|
|||||||
return pydevinfo
|
return pydevinfo
|
||||||
|
|
||||||
@cython.nonecheck(True)
|
@cython.nonecheck(True)
|
||||||
def start(self, avstream):
|
def start(self, audiocallback):
|
||||||
"""
|
"""
|
||||||
Opens a stream with specified parameters
|
Opens a stream with specified parameters
|
||||||
|
|
||||||
@ -175,36 +214,15 @@ cdef class Daq:
|
|||||||
|
|
||||||
Returns: None
|
Returns: None
|
||||||
"""
|
"""
|
||||||
cdef:
|
|
||||||
DaqConfiguration pydaqconfig
|
|
||||||
DeviceInfo pydevinfo
|
|
||||||
cppDaqConfiguration* daqconfig
|
|
||||||
cppDeviceInfo* devinfo
|
|
||||||
vector[cppDeviceInfo] devinfos
|
|
||||||
|
|
||||||
if self.sd is not NULL:
|
if self.sd is not NULL:
|
||||||
assert self.daq_device is not NULL
|
assert self.daq_device is not NULL
|
||||||
raise RuntimeError('Stream is already opened.')
|
raise RuntimeError('Stream is already opened.')
|
||||||
|
|
||||||
pydaqconfig = avstream.daqconfig
|
|
||||||
avtype = avstream.avtype
|
|
||||||
pydevinfo = avstream.deviceinfo
|
|
||||||
|
|
||||||
daqconfig = &(pydaqconfig.config)
|
|
||||||
devinfo = &(pydevinfo.devinfo)
|
|
||||||
|
|
||||||
self.daq_device = cppDaq.createDaq(devinfo[0], daqconfig[0])
|
|
||||||
cdef:
|
cdef:
|
||||||
cppDaq* daq = self.daq_device
|
cppDaq* daq = self.daq_device
|
||||||
|
unsigned nFramesPerBlock = self.nFramesPerBlock
|
||||||
cdef:
|
DataType dtype = self.daq_device.dataType()
|
||||||
unsigned int nFramesPerBlock = daq.framesPerBlock()
|
double samplerate = self.samplerate
|
||||||
double samplerate = daq.samplerate()
|
|
||||||
DataType dtype = daq.dataType()
|
|
||||||
|
|
||||||
if nFramesPerBlock > 8192 or nFramesPerBlock < 512:
|
|
||||||
del self.daq_device
|
|
||||||
raise ValueError('Invalid number of nFramesPerBlock')
|
|
||||||
|
|
||||||
|
|
||||||
# All set, allocate the stream!
|
# All set, allocate the stream!
|
||||||
@ -225,17 +243,17 @@ cdef class Daq:
|
|||||||
self.sd.noutchannels = daq.nenoutchannels()
|
self.sd.noutchannels = daq.nenoutchannels()
|
||||||
self.sd.nBytesPerChan = nFramesPerBlock*dtype.sw
|
self.sd.nBytesPerChan = nFramesPerBlock*dtype.sw
|
||||||
self.sd.nFramesPerBlock = nFramesPerBlock
|
self.sd.nFramesPerBlock = nFramesPerBlock
|
||||||
self.sd.npy_format = getNumpyDataType(dtype)
|
self.sd.npy_format = getCNumpyDataType(dtype)
|
||||||
|
|
||||||
if daq.neninchannels() > 0:
|
if daq.neninchannels() > 0:
|
||||||
self.sd.inQueue = new SafeQueue[void*]()
|
self.sd.inQueue = new SafeQueue[void*]()
|
||||||
if daq.nenoutchannels() > 0:
|
if daq.nenoutchannels() > 0:
|
||||||
self.sd.inQueue = new SafeQueue[void*]()
|
self.sd.inQueue = new SafeQueue[void*]()
|
||||||
|
|
||||||
self.sd.pyCallback = <PyObject*> avstream._audioCallback
|
self.sd.pyCallback = <PyObject*> audiocallback
|
||||||
|
|
||||||
# Increase reference count to the callback
|
# Increase reference count to the callback
|
||||||
Py_INCREF(<object> avstream._audioCallback)
|
Py_INCREF(<object> audiocallback)
|
||||||
|
|
||||||
with nogil:
|
with nogil:
|
||||||
self.sd.thread = new CPPThread[void*, void (*)(void*)](audioCallbackPythonThreadFunction,
|
self.sd.thread = new CPPThread[void*, void (*)(void*)](audioCallbackPythonThreadFunction,
|
||||||
@ -248,15 +266,11 @@ cdef class Daq:
|
|||||||
self.sd.inQueue,
|
self.sd.inQueue,
|
||||||
self.sd.outQueue)
|
self.sd.outQueue)
|
||||||
|
|
||||||
return nFramesPerBlock, self.daq_device.samplerate()
|
return self.daq_device.samplerate()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
if self.sd is NULL:
|
if self.sd is NULL:
|
||||||
raise RuntimeError('Stream is not opened')
|
raise RuntimeError('Stream is not opened')
|
||||||
if self.daq_device is not NULL:
|
|
||||||
self.daq_device.stop()
|
|
||||||
del self.daq_device
|
|
||||||
self.daq_device = NULL
|
|
||||||
|
|
||||||
self.cleanupStream(self.sd)
|
self.cleanupStream(self.sd)
|
||||||
self.sd = NULL
|
self.sd = NULL
|
||||||
|
@ -107,6 +107,9 @@ cdef class DaqConfiguration:
|
|||||||
config.outchannel_names = [outchname.encode('utf-8') for outchname in
|
config.outchannel_names = [outchname.encode('utf-8') for outchname in
|
||||||
pydict['outchannel_names']]
|
pydict['outchannel_names']]
|
||||||
|
|
||||||
|
config.inchannel_sensitivities = pydict['inchannel_sensitivities']
|
||||||
|
config.outchannel_sensitivities = pydict['outchannel_sensitivities']
|
||||||
|
|
||||||
config.sampleRateIndex = pydict['sampleRateIndex']
|
config.sampleRateIndex = pydict['sampleRateIndex']
|
||||||
config.framesPerBlockIndex = pydict['framesPerBlockIndex']
|
config.framesPerBlockIndex = pydict['framesPerBlockIndex']
|
||||||
config.dataTypeIndex = pydict['dataTypeIndex']
|
config.dataTypeIndex = pydict['dataTypeIndex']
|
||||||
@ -138,6 +141,16 @@ cdef class DaqConfiguration:
|
|||||||
outchannel_names = [name.decode('utf-8') for name in
|
outchannel_names = [name.decode('utf-8') for name in
|
||||||
self.config.outchannel_names],
|
self.config.outchannel_names],
|
||||||
|
|
||||||
|
inchannel_sensitivities = [sens for sens in
|
||||||
|
self.config.inchannel_sensitivities],
|
||||||
|
outchannel_sensitivities = [sens for sens in
|
||||||
|
self.config.outchannel_sensitivities],
|
||||||
|
|
||||||
|
inchannel_metadata = [inchmeta.decode('utf-8') for inchmeta in
|
||||||
|
self.config.inchannel_metadata],
|
||||||
|
outchannel_metadata = [outchmeta.decode('utf-8') for outchmeta in
|
||||||
|
self.config.outchannel_metadata],
|
||||||
|
|
||||||
sampleRateIndex = self.config.sampleRateIndex,
|
sampleRateIndex = self.config.sampleRateIndex,
|
||||||
dataTypeIndex = self.config.dataTypeIndex,
|
dataTypeIndex = self.config.dataTypeIndex,
|
||||||
framesPerBlockIndex = self.config.framesPerBlockIndex,
|
framesPerBlockIndex = self.config.framesPerBlockIndex,
|
||||||
@ -147,27 +160,23 @@ cdef class DaqConfiguration:
|
|||||||
inputACCouplingMode = self.config.inputACCouplingMode,
|
inputACCouplingMode = self.config.inputACCouplingMode,
|
||||||
inputRangeIndices = self.config.inputRangeIndices,
|
inputRangeIndices = self.config.inputRangeIndices,
|
||||||
|
|
||||||
inchannel_metadata = [inchmeta.decode('utf-8') for inchmeta in
|
|
||||||
self.config.inchannel_metadata],
|
|
||||||
outchannel_metadata = [outchmeta.decode('utf-8') for outchmeta in
|
|
||||||
self.config.outchannel_metadata]
|
|
||||||
))
|
))
|
||||||
|
|
||||||
def getInChannel(self, i:int):
|
def getInChannel(self, i:int):
|
||||||
return DaqChannel(
|
return DaqChannel(
|
||||||
channel_enabled=self.config.eninchannels[i],
|
channel_enabled=self.config.eninchannels.at(i),
|
||||||
channel_name=self.config.inchannel_names[i].decode('utf-8'),
|
channel_name=self.config.inchannel_names.at(i).decode('utf-8'),
|
||||||
sensitivity=self.config.inchannel_sensitivities[i],
|
sensitivity=self.config.inchannel_sensitivities.at(i),
|
||||||
range_index=self.config.inputRangeIndices[i],
|
range_index=self.config.inputRangeIndices.at(i),
|
||||||
ACCoupling_enabled=self.config.inputACCouplingMode[i],
|
ACCoupling_enabled=self.config.inputACCouplingMode.at(i),
|
||||||
IEPE_enabled=self.config.inputIEPEEnabled[i],
|
IEPE_enabled=self.config.inputIEPEEnabled.at(i),
|
||||||
channel_metadata=self.config.inchannel_metadata[i].decode('utf-8'),
|
channel_metadata=self.config.inchannel_metadata.at(i).decode('utf-8'),
|
||||||
)
|
)
|
||||||
def getOutChannel(self, i:int):
|
def getOutChannel(self, i:int):
|
||||||
return DaqChannel(
|
return DaqChannel(
|
||||||
channel_enabled=self.config.enoutchannels[i],
|
channel_enabled=self.config.enoutchannels.at(i),
|
||||||
channel_name=self.config.outchannel_names[i].decode('utf-8'),
|
channel_name=self.config.outchannel_names.at(i).decode('utf-8'),
|
||||||
channel_metadata=self.config.outchannel_metadata[i].decode('utf-8'),
|
channel_metadata=self.config.outchannel_metadata.at(i).decode('utf-8'),
|
||||||
)
|
)
|
||||||
|
|
||||||
def setInChannel(self, i:int, ch: DaqChannel):
|
def setInChannel(self, i:int, ch: DaqChannel):
|
||||||
@ -184,6 +193,25 @@ cdef class DaqConfiguration:
|
|||||||
self.config.outchannel_names[i] = ch.channel_name.encode('utf-8')
|
self.config.outchannel_names[i] = ch.channel_name.encode('utf-8')
|
||||||
self.config.outchannel_metadata[i] = ch.channel_metadata.encode('utf-8')
|
self.config.outchannel_metadata[i] = ch.channel_metadata.encode('utf-8')
|
||||||
|
|
||||||
|
def getEnabledInChannels(self, include_monitor=True):
|
||||||
|
inch = []
|
||||||
|
for i, enabled in enumerate(self.config.eninchannels):
|
||||||
|
if enabled:
|
||||||
|
inch.append(self.getInChannel(i))
|
||||||
|
if include_monitor:
|
||||||
|
outch = self.getEnabledOutChannels()
|
||||||
|
if len(outch) > 0:
|
||||||
|
inch.insert(0, outch[0])
|
||||||
|
|
||||||
|
return inch
|
||||||
|
|
||||||
|
def getEnabledOutChannels(self):
|
||||||
|
outch = []
|
||||||
|
for i, enabled in enumerate(self.config.enoutchannels):
|
||||||
|
if enabled:
|
||||||
|
outch.append(self.getOutChannel(i))
|
||||||
|
return outch
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def api(self):
|
def api(self):
|
||||||
return self.config.api.apiname.decode('utf-8')
|
return self.config.api.apiname.decode('utf-8')
|
||||||
|
@ -13,8 +13,6 @@ class DAQConfiguration:
|
|||||||
|
|
||||||
import time
|
import time
|
||||||
from .device import (Daq, DeviceInfo,
|
from .device import (Daq, DeviceInfo,
|
||||||
# get_numpy_dtype_from_format_string,
|
|
||||||
# get_sampwidth_from_format_string,
|
|
||||||
AvType,
|
AvType,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,8 +27,8 @@ class AvStream:
|
|||||||
processing the data."""
|
processing the data."""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
device: DeviceInfo,
|
|
||||||
avtype: AvType,
|
avtype: AvType,
|
||||||
|
device: DeviceInfo,
|
||||||
daqconfig: DAQConfiguration,
|
daqconfig: DAQConfiguration,
|
||||||
video=None):
|
video=None):
|
||||||
"""Open a stream for audio in/output and video input. For audio output,
|
"""Open a stream for audio in/output and video input. For audio output,
|
||||||
@ -49,46 +47,20 @@ class AvStream:
|
|||||||
self.daqconfig = daqconfig
|
self.daqconfig = daqconfig
|
||||||
self.device = device
|
self.device = device
|
||||||
self.avtype = avtype
|
self.avtype = avtype
|
||||||
self.duplex_mode = daqconfig.duplex_mode
|
|
||||||
|
|
||||||
self.output_channel_names = [ch.channel_name for ch in daqconfig.getEnabledOutputChannels()]
|
en_out_ch = daqconfig.getEnabledOutChannels()
|
||||||
|
en_in_ch = daqconfig.getEnabledInChannels(include_monitor=True)
|
||||||
|
|
||||||
if daqconfig.monitor_gen:
|
self.output_channel_names = [ch.channel_name for ch in en_out_ch]
|
||||||
self.input_channel_names = self.output_channel_names
|
self.input_channel_names = [ch.channel_name for ch in en_in_ch]
|
||||||
self.input_sensitivity = daqconfig.getEnabledOutputChannelSensitivities()
|
|
||||||
self.input_qtys = daqconfig.getEnabledOutputChannelQtys()
|
self.input_sensitivity = [ch.sensitivity for ch in en_in_ch]
|
||||||
else:
|
self.input_qtys = [ch.qty for ch in en_in_ch]
|
||||||
self.input_channel_names = []
|
|
||||||
self.input_sensitivity = []
|
|
||||||
self.input_qtys = []
|
|
||||||
|
|
||||||
self.input_sensitivity += daqconfig.getEnabledInputChannelSensitivities()
|
|
||||||
self.input_sensitivity = np.asarray(self.input_sensitivity)
|
self.input_sensitivity = np.asarray(self.input_sensitivity)
|
||||||
self.input_qtys += daqconfig.getEnabledInputChannelQtys()
|
|
||||||
|
|
||||||
# Fill in numpy data type, and sample width
|
# Fill in numpy data type, and sample width
|
||||||
self.input_numpy_dtype = get_numpy_dtype_from_format_string(
|
datatype = daqconfig.dataTypeIndex
|
||||||
daqconfig.en_input_sample_format)
|
|
||||||
|
|
||||||
self.input_sampwidth = get_sampwidth_from_format_string(
|
|
||||||
daqconfig.en_input_sample_format)
|
|
||||||
|
|
||||||
self.input_channel_names += [
|
|
||||||
ch.channel_name for ch in daqconfig.getEnabledInputChannels()]
|
|
||||||
|
|
||||||
self.input_samplerate = float(daqconfig.en_input_rate)
|
|
||||||
if self.duplex_mode:
|
|
||||||
self.output_samplerate = float(daqconfig.en_input_rate)
|
|
||||||
self.output_sampwidth = self.input_sampwidth
|
|
||||||
self.output_numpy_dtype = self.input_numpy_dtype
|
|
||||||
else:
|
|
||||||
self.output_samplerate = float(daqconfig.en_output_rate)
|
|
||||||
|
|
||||||
self.output_sampwidth = get_sampwidth_from_format_string(
|
|
||||||
daqconfig.en_output_sample_format)
|
|
||||||
|
|
||||||
self.output_numpy_dtype = get_numpy_dtype_from_format_string(
|
|
||||||
daqconfig.en_output_sample_format)
|
|
||||||
|
|
||||||
# Counters for the number of frames that have been coming in
|
# Counters for the number of frames that have been coming in
|
||||||
self._aframectr = Atomic(0)
|
self._aframectr = Atomic(0)
|
||||||
@ -113,8 +85,9 @@ class AvStream:
|
|||||||
self._videothread = None
|
self._videothread = None
|
||||||
|
|
||||||
# self._audiobackend = RtAudio(daqconfig.api)
|
# self._audiobackend = RtAudio(daqconfig.api)
|
||||||
self._audiobackend = UlDaq()
|
self._daq = Daq(device, daqconfig)
|
||||||
self.blocksize = daqconfig.nFramesPerBlock
|
self.blocksize = self._daq.nFramesPerBlock
|
||||||
|
self.samplerate = self._daq.samplerate
|
||||||
|
|
||||||
def nCallbacks(self):
|
def nCallbacks(self):
|
||||||
"""Returns the current number of installed callbacks."""
|
"""Returns the current number of installed callbacks."""
|
||||||
@ -154,7 +127,7 @@ class AvStream:
|
|||||||
else:
|
else:
|
||||||
self._video_started <<= True
|
self._video_started <<= True
|
||||||
|
|
||||||
self.blocksize, self.samplerate = self._audiobackend.start(self)
|
self.samplerate = self._daq.start(self._audioCallback)
|
||||||
|
|
||||||
def _videoThread(self):
|
def _videoThread(self):
|
||||||
cap = cv.VideoCapture(self._video)
|
cap = cv.VideoCapture(self._video)
|
||||||
|
Loading…
Reference in New Issue
Block a user