Tracer level in dmat_to_ndarray lower. set only one input channel default in default_device. Bugfix nogil on data read in daqdevice. Lots of improved comments. Real time power spectra functionality working again
This commit is contained in:
parent
473de073a6
commit
889a1898f5
@ -20,7 +20,7 @@ include_directories(
|
||||
# DEPENDS MakeTable
|
||||
# )
|
||||
|
||||
set(ui_files ui_apsrt ui_mainwindow ui_figure ui_about ui_apswidget ui_revtime ui_slmwidget ui_daq)
|
||||
set(ui_files ui_apsrtsettings ui_mainwindow ui_figure ui_about ui_apswidget ui_revtime ui_slmwidget ui_daq ui_apssettings)
|
||||
foreach(fn ${ui_files})
|
||||
add_custom_command(
|
||||
OUTPUT "${fn}.py"
|
||||
|
@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
#ifndef LASP_PYTHON_H
|
||||
#define LASP_PYTHON_H
|
||||
#define TRACERPLUS (-10)
|
||||
#include <numpy/ndarrayobject.h>
|
||||
#ifdef LASP_DOUBLE_PRECISION
|
||||
#define LASP_NUMPY_FLOAT_TYPE NPY_FLOAT64
|
||||
|
@ -115,7 +115,7 @@ roga_plugndaq = DAQConfiguration(name='Roga-instruments Plug.n.DAQ USB',
|
||||
en_format=0,
|
||||
en_input_rate=2,
|
||||
en_input_channels=[0],
|
||||
input_sensitivity=[1., 1.],
|
||||
input_sensitivity=[46.92e-3, 46.92e-3],
|
||||
input_gain_settings=[-20, 0, 20],
|
||||
en_input_gain_setting=[1, 1],
|
||||
en_output_rate=1,
|
||||
@ -128,8 +128,8 @@ default_soundcard = DAQConfiguration(name="Default device",
|
||||
device_name='default',
|
||||
en_format=0,
|
||||
en_input_rate=2,
|
||||
en_input_channels=[0, 1],
|
||||
input_sensitivity=[1., 1.],
|
||||
en_input_channels=[0],
|
||||
input_sensitivity=[1.0, 1.0],
|
||||
input_gain_settings=[0],
|
||||
en_input_gain_setting=[0, 0],
|
||||
en_output_rate=1,
|
||||
|
@ -66,7 +66,7 @@ cdef extern from "alsa/asoundlib.h":
|
||||
int snd_pcm_info_get_card(snd_pcm_info_t*)
|
||||
|
||||
int snd_pcm_drain(snd_pcm_t*)
|
||||
int snd_pcm_readi(snd_pcm_t*,void* buf,snd_pcm_uframes_t nframes)
|
||||
int snd_pcm_readi(snd_pcm_t*,void* buf,snd_pcm_uframes_t nframes) nogil
|
||||
int snd_pcm_hw_params(snd_pcm_t*,snd_pcm_hw_params_t*)
|
||||
int snd_pcm_hw_params_test_rate(snd_pcm_t*, snd_pcm_hw_params_t*,
|
||||
unsigned int val,int dir)
|
||||
@ -444,7 +444,8 @@ cdef class DAQDevice:
|
||||
buf = self._getEmptyBuffer()
|
||||
# buf2 = self._getEmptyBuffer()
|
||||
cdef cnp.int16_t[:, ::1] bufv = buf
|
||||
rval = snd_pcm_readi(self.pcm,<void*> &bufv[0, 0], self.blocksize)
|
||||
with nogil:
|
||||
rval = snd_pcm_readi(self.pcm,<void*> &bufv[0, 0], self.blocksize)
|
||||
# rval = 2048
|
||||
if rval > 0:
|
||||
# print('Samples obtained:' , rval)
|
||||
|
@ -1,15 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Sat Mar 10 08:28:03 2018
|
||||
|
||||
@author: Read data from image stream and record sound at the same time
|
||||
Description: Read data from image stream and record sound at the same time
|
||||
"""
|
||||
import cv2 as cv
|
||||
from .lasp_atomic import Atomic
|
||||
from threading import Thread, Condition, Lock
|
||||
import time
|
||||
from .device import DAQDevice, roga_plugndaq
|
||||
import numpy as np
|
||||
__all__ = ['AvType', 'AvStream']
|
||||
|
||||
video_x, video_y = 640, 480
|
||||
@ -30,6 +29,7 @@ class AvStream:
|
||||
self.nchannels = len(daq.channels_en)
|
||||
self.samplerate = daq.input_rate
|
||||
self.blocksize = daq.blocksize
|
||||
self.sensitivity = np.asarray(daqconfig.input_sensitivity)[daq.channels_en]
|
||||
except Exception as e:
|
||||
raise RuntimeError(f'Could not initialize DAQ device: {str(e)}')
|
||||
|
||||
@ -92,6 +92,7 @@ class AvStream:
|
||||
# contains quite some rubbish.
|
||||
data = daq.read()
|
||||
while self._running:
|
||||
# print('read data...')
|
||||
data = daq.read()
|
||||
self._audioCallback(data)
|
||||
except RuntimeError as e:
|
||||
|
@ -35,7 +35,7 @@ The video dataset can possibly be not present in the data.
|
||||
|
||||
|
||||
"""
|
||||
__all__ = ['Measurement']
|
||||
__all__ = ['Measurement', 'scaleBlockSens']
|
||||
from contextlib import contextmanager
|
||||
import h5py as h5
|
||||
import numpy as np
|
||||
@ -93,6 +93,24 @@ def getSampWidth(dtype):
|
||||
raise ValueError('Invalid data type: %s' % dtype)
|
||||
|
||||
|
||||
def scaleBlockSens(block, sens):
|
||||
"""
|
||||
Scale a block of raw data to return raw acoustic
|
||||
pressure data.
|
||||
|
||||
Args:
|
||||
block: block of raw data with integer data type
|
||||
sensitivity: array of sensitivity coeficients for
|
||||
each channel
|
||||
|
||||
"""
|
||||
assert sens.ndim == 1
|
||||
assert sens.size == block.shape[1]
|
||||
sw = getSampWidth(block.dtype)
|
||||
fac = 2**(8*sw - 1) - 1
|
||||
return block.astype(LASP_NUMPY_FLOAT_TYPE)/fac/sens[np.newaxis, :]
|
||||
|
||||
|
||||
def exportAsWave(fn, fs, data, force=False):
|
||||
if '.wav' not in fn[-4:]:
|
||||
fn += '.wav'
|
||||
@ -154,7 +172,8 @@ class Measurement:
|
||||
|
||||
# Sensitivity
|
||||
try:
|
||||
self._sens = f.attrs['sensitivity']
|
||||
sens = f.attrs['sensitivity']
|
||||
self._sens = sens*np.ones(self.nchannels) if isinstance(sens, float) else sens
|
||||
except KeyError:
|
||||
self._sens = np.ones(self.nchannels)
|
||||
|
||||
@ -201,17 +220,7 @@ class Measurement:
|
||||
# When the data is stored as integers, we assume dB full-scale scaling.
|
||||
# Hence, when we convert the data to floats, we divide by the maximum
|
||||
# possible value.
|
||||
if block.dtype == np.int32:
|
||||
fac = 2**31
|
||||
elif block.dtype == np.int16:
|
||||
fac = 2**15
|
||||
elif block.dtype == np.float64:
|
||||
fac = 1.0
|
||||
else:
|
||||
raise RuntimeError(
|
||||
f'Unimplemented data type from recording: {block.dtype}.')
|
||||
sens = self._sens
|
||||
return block.astype(LASP_NUMPY_FLOAT_TYPE)/fac/sens[np.newaxis, :]
|
||||
return scaleBlockSens(block, self.sensitivity)
|
||||
|
||||
@property
|
||||
def prms(self):
|
||||
|
@ -104,7 +104,6 @@ class Recording:
|
||||
self._vCallback(data)
|
||||
|
||||
def _aCallback(self, frames, aframe):
|
||||
# print(self._aframeno())
|
||||
print('.', end='')
|
||||
curT = self._aframeno()*self.blocksize/self.samplerate
|
||||
if self.rectime is not None and curT > self.rectime:
|
||||
|
41
scripts/lasp_apsrt
Executable file
41
scripts/lasp_apsrt
Executable file
@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
from lasp.lasp_rtapsdialog import RealTimeAPSDialog
|
||||
from lasp.lasp_avstream import AvStream
|
||||
from lasp.device.lasp_daqconfig import default_soundcard, roga_plugndaq
|
||||
from lasp.lasp_gui_tools import Branding, ASCEEColors, warningdialog
|
||||
from PySide import QtGui
|
||||
|
||||
|
||||
def main():
|
||||
app = QtGui.QApplication(sys.argv) # A new instance of QApplication
|
||||
app.setFont(Branding.font())
|
||||
|
||||
stream = AvStream(default_soundcard)
|
||||
# stream = AvStream(roga_plugndaq)
|
||||
mw = RealTimeAPSDialog(None, stream)
|
||||
|
||||
mw.show() # Show the form
|
||||
|
||||
# Install exception hook to catch exceptions
|
||||
def excepthook(cls, exception, traceback):
|
||||
"""
|
||||
This exception hook is installed as the global exception hook. Shows a
|
||||
simple QMessageBox in case of an exception that is not caught.
|
||||
"""
|
||||
if __debug__:
|
||||
import traceback as tb
|
||||
tbtxt = ''.join(tb.format_tb(sys.last_traceback))
|
||||
warningdialog(mw, str(exception), tbtxt)
|
||||
else:
|
||||
warningdialog(mw, str(exception))
|
||||
|
||||
# Set custom exception hook that catches all exceptions
|
||||
sys.excepthook = excepthook
|
||||
stream.start()
|
||||
app.exec_() # and execute the app
|
||||
stream.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main() # run the main function
|
0
scripts/lasp_record
Normal file → Executable file
0
scripts/lasp_record
Normal file → Executable file
Loading…
Reference in New Issue
Block a user