Added RtAudio and UlDAQ as subprojects that are compiled in. Fixed proper connection of UlDAQ. Set default sensitity to 1.0 for a new DaqChannel. Segfault bug fixed in DaqData::copyToRaw. Scan in background for devices when StreamMgr() is initialized. Fixed bug in storing of DaqConfigs to lasp_shelve. Set RtAudio to 5.2.0.

This commit is contained in:
Anne de Jong 2022-10-05 11:27:46 +02:00
parent e900a5ddad
commit 31ead60469
18 changed files with 862 additions and 98 deletions

3
.gitmodules vendored
View File

@ -28,3 +28,6 @@
[submodule "third_party/boost/core"] [submodule "third_party/boost/core"]
path = third_party/boost/core path = third_party/boost/core
url = https://github.com/boostorg/core url = https://github.com/boostorg/core
[submodule "third_party/uldaq"]
path = third_party/uldaq
url = https://github.com/mccdaq/uldaq

View File

@ -10,6 +10,7 @@ option(LASP_HAS_RTAUDIO "Compile with RtAudio Daq backend" ON)
option(LASP_HAS_ULDAQ "Compile with UlDaq backend" ON) option(LASP_HAS_ULDAQ "Compile with UlDaq backend" ON)
option(LASP_BUILD_TUNED "Tune build for current machine" OFF) option(LASP_BUILD_TUNED "Tune build for current machine" OFF)
option(LASP_WITH_OPENMP "Use OpenMP parallelization" ON) option(LASP_WITH_OPENMP "Use OpenMP parallelization" ON)
set(LASP_MAX_NFFT "33554432" CACHE STRING "Max FFT size")
# Use ccache if available # Use ccache if available
find_program(CCACHE_PROGRAM ccache) find_program(CCACHE_PROGRAM ccache)
@ -43,8 +44,10 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set(LASP_DEBUG True) set(LASP_DEBUG True)
# This does not work nicely with RtAudio # This does not work nicely with RtAudio. However, if we compile it
# add_definitions(-D_GLIBCXX_DEBUG) # ourselves as a third_party ref, this works nicely together.
add_definitions(-D_GLIBCXX_DEBUG)
else() else()
set(LASP_DEBUG False) set(LASP_DEBUG False)
endif() endif()
@ -58,34 +61,35 @@ if(LASP_BUILD_TUNED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mtune=native") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mtune=native")
endif() endif()
# link openblas # ###################################### Find and link to OpenBLAS
set(BLA_VENDOR OpenBLAS) set(BLA_VENDOR OpenBLAS)
find_package(BLAS REQUIRED) find_package(BLAS REQUIRED)
# Reasonable maximum to the nfft size, at 48kHz this is 700s of data... # ###################################### Find and link to FFTW
add_definitions(-DLASP_MAX_NFFT=33554432) # 2**25 if(LASP_FFT_BACKEND STREQUAL "FFTW")
find_library(fftw3 REQUIRED NAMES fftw fftw3)
set(LASP_FFT_LIBS "fftw3")
elseif(LASP_FFT_BACKEND STREQUAL "Armadillo")
endif()
# ####################################### End of user-adjustable variables section # ###################################### OpenMP related
include(OSSpecific)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-type-limits")
# Enable openmp, if set
if(LASP_WITH_OPENMP) if(LASP_WITH_OPENMP)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif() endif()
# ###################################### Compilation flags
set(CMAKE_C_FLAGS_RELEASE "-O3 -flto -mfpmath=sse -march=x86-64 -mtune=native \ set(CMAKE_C_FLAGS_RELEASE "-O3 -flto -mfpmath=sse -march=x86-64 -mtune=native \
-fdata-sections -ffunction-sections -fomit-frame-pointer -finline-functions") -fdata-sections -ffunction-sections -fomit-frame-pointer -finline-functions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-type-limits")
# ############################# End compilation flags # ############################# End compilation flags
include_directories(/usr/lib/python3.10/site-packages/numpy/core/include) include_directories(/usr/lib/python3.10/site-packages/numpy/core/include)
if(LASP_FFT_BACKEND STREQUAL "FFTW") # ####################################### End of user-adjustable variables section
find_library(fftw3 REQUIRED NAMES fftw fftw3) include(OSSpecific)
set(LASP_FFT_LIBS "fftw3") include(rtaudio)
include(uldaq)
elseif(LASP_FFT_BACKEND STREQUAL "Armadillo") #
endif()
add_subdirectory(src/lasp) add_subdirectory(src/lasp)

12
cmake/rtaudio.cmake Normal file
View File

@ -0,0 +1,12 @@
# ###################################### RtAudio
if(LASP_HAS_RTAUDIO)
message("Building RtAudio backend")
if(WIN32)
set(RTAUDIO_API_WASAPI TRUE CACHE BOOL "Build for WASAPI" FORCE)
else()
set(RTAUDIO_API_PULSE TRUE CACHE BOOL "Build with PulseAudio backend" FORCE)
set(RTAUDIO_API_ALSA OFF CACHE BOOL "Do not build with Alsa backend" FORCE)
endif()
set(RTAUDIO_BUILD_STATIC_LIBS ON CACHE BOOL "Build static libs for RtAudio" FORCE)
add_subdirectory(third_party/rtaudio)
endif()

28
cmake/uldaq.cmake Normal file
View File

@ -0,0 +1,28 @@
# ###################################### UlDAQ
if(LASP_HAS_ULDAQ)
message("Building UlDAQ")
if(NOT WIN32)
find_package(PkgConfig REQUIRED)
pkg_check_modules(libusb-1.0 REQUIRED libusb-1.0)
endif()
# This is rather coarse!
file(GLOB ULDAQ_FILES1 third_party/uldaq/src/*.cpp)
file(GLOB ULDAQ_FILES2 third_party/uldaq/src/*/*.cpp)
file(GLOB ULDAQ_FILES3 third_party/uldaq/src/*/*/*.cpp)
file(GLOB ULDAQ_FILES4 third_party/uldaq/src/usb/fw/*c)
add_library(uldaq STATIC ${ULDAQ_FILES1} ${ULDAQ_FILES2}
${ULDAQ_FILES3} ${ULDAQ_FILES4})
if(NOT WIN32)
# message("libUSB libs: ${libusb-1.0_LIBRARIES}")
target_link_libraries(uldaq ${libusb-1.0_LIBRARIES})
# Rules to match UlDAQ Usb devices with libusb
install(FILES third_party/uldaq/rules/50-uldaq.rules DESTINATION
/etc/udev/rules.d PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ
GROUP_WRITE WORLD_READ)
endif()
endif()

619
examples/test_ppm.ipynb Normal file
View File

@ -0,0 +1,619 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "740b4091",
"metadata": {},
"source": [
"# Test PPM"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "ac06df04",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"make: Entering directory '/home/anne/wip/mycode/lasp'\n",
"make[1]: Entering directory '/home/anne/wip/mycode/lasp'\n",
"make[2]: Entering directory '/home/anne/wip/mycode/lasp'\n",
"make[2]: Leaving directory '/home/anne/wip/mycode/lasp'\n",
"[ 44%] Built target lasp_dsp_lib\n",
"make[2]: Entering directory '/home/anne/wip/mycode/lasp'\n",
"make[2]: Leaving directory '/home/anne/wip/mycode/lasp'\n",
"[ 68%] Built target lasp_device_lib\n",
"make[2]: Entering directory '/home/anne/wip/mycode/lasp'\n",
"make[2]: Leaving directory '/home/anne/wip/mycode/lasp'\n",
"[100%] Built target lasp_cpp\n",
"make[1]: Leaving directory '/home/anne/wip/mycode/lasp'\n",
"make: Leaving directory '/home/anne/wip/mycode/lasp'\n"
]
}
],
"source": [
"!make -j -C ~/wip/mycode/lasp"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "ce0dd691",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2022-10-03 13:39:03+0200 DebugTrace-cpp 2.0.0a2 (g++ 9.4.0)\n",
"2022-10-03 13:39:03+0200 \n",
"2022-10-03 13:39:03+0200 Enter getInstance (lasp_streammgr.cpp: 40)\n",
"2022-10-03 13:39:03+0200 | Enter StreamMgr (lasp_streammgr.cpp: 45)\n",
"2022-10-03 13:39:03+0200 | | Enter rescanDAQDevices (lasp_streammgr.cpp: 60)\n",
"2022-10-03 13:39:03+0200 | | | Enter rescanDAQDevices_impl (lasp_streammgr.cpp: 80)\n",
"2022-10-03 13:39:04+0200 | | | | Enter fillRtAudioDeviceInfo (lasp_rtaudiodaq.cpp: 20)\n",
"2022-10-03 13:39:04+0200 | | | | Leave fillRtAudioDeviceInfo (lasp_rtaudiodaq.cpp)\n",
"2022-10-03 13:39:04+0200 | | | Leave rescanDAQDevices_impl (lasp_streammgr.cpp)\n",
"2022-10-03 13:39:04+0200 | | Leave rescanDAQDevices (lasp_streammgr.cpp)\n",
"2022-10-03 13:39:04+0200 | Leave StreamMgr (lasp_streammgr.cpp)\n",
"2022-10-03 13:39:04+0200 Leave getInstance (lasp_streammgr.cpp)\n"
]
}
],
"source": [
"import lasp\n",
"# Get handle to stream manager\n",
"mgr = lasp.StreamMgr.getInstance()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "3cd242a8",
"metadata": {},
"outputs": [],
"source": [
"ds = mgr.getDeviceInfo()"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "a5d878e9",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0: Monitor of Starship/Matisse HD Audio Controller Analog Stereo\n",
"1: Starship/Matisse HD Audio Controller Analog Stereo\n",
"2: Baffin HDMI/DP Audio [Radeon RX 550 640SP / RX 560/560X] Digital Stereo (HDMI)\n",
"3: Monitor of Baffin HDMI/DP Audio [Radeon RX 550 640SP / RX 560/560X] Digital Stereo (HDMI)\n"
]
}
],
"source": [
"# Search for a device\n",
"for i, d in enumerate(ds):\n",
" print(f'{i}: ' + d.device_name)\n",
"d = ds[0]"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "6d5b281e",
"metadata": {},
"outputs": [],
"source": [
"# Create a configuration and enable some input channels\n",
"config = lasp.DaqConfiguration(d)\n",
"config.inchannel_config[0].enabled = True\n",
"config.inchannel_config[1].enabled = True\n",
"# Choose a different number of frames per block\n",
"config.framesPerBlockIndex = 4"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "1ead3995",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Out channels: 0\n",
"In channels: 2\n"
]
}
],
"source": [
"print('Out channels:',d.noutchannels)\n",
"print('In channels:',d.ninchannels)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "12db8306",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2022-10-03 13:39:06+0200 \n",
"2022-10-03 13:39:06+0200 Enter startStream (lasp_streammgr.cpp: 209)\n",
"2022-10-03 13:39:06+0200 | Enter createDaq (lasp_daq.cpp: 18)\n",
"2022-10-03 13:39:06+0200 | | Enter Daq (lasp_daq.cpp: 37)\n",
"2022-10-03 13:39:06+0200 | | Leave Daq (lasp_daq.cpp)\n",
"2022-10-03 13:39:06+0200 | | \n",
"2022-10-03 13:39:06+0200 | | Enter RtAudioDaq (lasp_rtaudiodaq.cpp: 135)\n",
"2022-10-03 13:39:06+0200 | | | Enter samplerate (lasp_daq.cpp: 58)\n",
"2022-10-03 13:39:06+0200 | | | Leave samplerate (lasp_daq.cpp)\n",
"2022-10-03 13:39:07+0200 | | Leave RtAudioDaq (lasp_rtaudiodaq.cpp)\n",
"2022-10-03 13:39:07+0200 | Leave createDaq (lasp_daq.cpp)\n",
"2022-10-03 13:39:07+0200 | isInput = true\n",
"2022-10-03 13:39:07+0200 | isOutput = false\n",
"2022-10-03 13:39:07+0200 | \n",
"2022-10-03 13:39:07+0200 | Enter start (lasp_rtaudiodaq.cpp: 215)\n",
"2022-10-03 13:39:07+0200 | Leave start (lasp_rtaudiodaq.cpp)\n",
"2022-10-03 13:39:07+0200 Leave startStream (lasp_streammgr.cpp)\n"
]
}
],
"source": [
"# Start a stream with a configuration\n",
"mgr.startStream(config)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "5323356f-4239-4f0b-ad58-0025501bf7a3",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2022-10-03 13:39:09+0200 \n",
"2022-10-03 13:39:09+0200 Enter InDataHandler (lasp_streammgr.cpp: 14)\n",
"2022-10-03 13:39:09+0200 Leave InDataHandler (lasp_streammgr.cpp)\n",
"2022-10-03 13:39:09+0200 \n",
"2022-10-03 13:39:09+0200 Enter ThreadedInDataHandler (lasp_threadedindatahandler.cpp: 13)\n",
"2022-10-03 13:39:09+0200 Leave ThreadedInDataHandler (lasp_threadedindatahandler.cpp)\n",
"2022-10-03 13:39:09+0200 \n",
"2022-10-03 13:39:09+0200 Enter PPMHandler (lasp_ppm.cpp: 14)\n",
"2022-10-03 13:39:09+0200 | Enter start (lasp_streammgr.cpp: 16)\n",
"2022-10-03 13:39:09+0200 | | Enter reset (lasp_ppm.cpp: 65)\n",
"2022-10-03 13:39:09+0200 | | | Enter samplerate (lasp_daq.cpp: 58)\n",
"2022-10-03 13:39:09+0200 | | | Leave samplerate (lasp_daq.cpp)\n",
"2022-10-03 13:39:09+0200 | | | fs = 44100.000000\n",
"2022-10-03 13:39:09+0200 | | Leave reset (lasp_ppm.cpp)\n",
"2022-10-03 13:39:09+0200 | Leave start (lasp_streammgr.cpp)\n",
"2022-10-03 13:39:09+0200 Leave PPMHandler (lasp_ppm.cpp)\n",
"2022-10-03 13:39:09+0200 \n",
"2022-10-03 13:39:09+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:09+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:09+0200 \n",
"2022-10-03 13:39:09+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:09+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:09+0200 \n",
"2022-10-03 13:39:09+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:09+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:10+0200 \n",
"2022-10-03 13:39:10+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:10+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:10+0200 \n",
"2022-10-03 13:39:10+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:10+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:10+0200 \n",
"2022-10-03 13:39:10+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:10+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:10+0200 \n",
"2022-10-03 13:39:10+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:10+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:11+0200 \n",
"2022-10-03 13:39:11+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:11+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:11+0200 \n",
"2022-10-03 13:39:11+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:11+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:11+0200 \n",
"2022-10-03 13:39:11+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:11+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:11+0200 \n",
"2022-10-03 13:39:11+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:11+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:11+0200 \n",
"2022-10-03 13:39:11+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:11+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:12+0200 \n",
"2022-10-03 13:39:12+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:12+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:12+0200 \n",
"2022-10-03 13:39:12+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:12+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:12+0200 \n",
"2022-10-03 13:39:12+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:12+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:12+0200 \n",
"2022-10-03 13:39:12+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:12+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:12+0200 \n",
"2022-10-03 13:39:12+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:12+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:13+0200 \n",
"2022-10-03 13:39:13+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:13+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:13+0200 \n",
"2022-10-03 13:39:13+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:13+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:13+0200 \n",
"2022-10-03 13:39:13+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:13+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:13+0200 \n",
"2022-10-03 13:39:13+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:13+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:14+0200 \n",
"2022-10-03 13:39:14+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:14+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:14+0200 \n",
"2022-10-03 13:39:14+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:14+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:14+0200 \n",
"2022-10-03 13:39:14+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:14+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:14+0200 \n",
"2022-10-03 13:39:14+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:14+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:14+0200 \n",
"2022-10-03 13:39:14+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:14+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:15+0200 \n",
"2022-10-03 13:39:15+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:15+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:15+0200 \n",
"2022-10-03 13:39:15+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:15+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n"
]
}
],
"source": [
"ppm = lasp.PPMHandler(mgr)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "169c52c4-687f-4371-af04-19a414feb73d",
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'a' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m/tmp/ipykernel_24491/2167009006.py\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: name 'a' is not defined"
]
}
],
"source": [
"a"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "688d41ae-a3b1-4a31-b1e3-278bb4eaae4c",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 12,
"id": "4d9f0103",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Monitor of Starship/Matisse HD Audio Controller Analog Stereo\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2022-10-03 13:39:15+0200 \n",
"2022-10-03 13:39:15+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:15+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:15+0200 \n",
"2022-10-03 13:39:15+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:15+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:15+0200 \n",
"2022-10-03 13:39:15+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:15+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:16+0200 \n",
"2022-10-03 13:39:16+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:16+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n"
]
}
],
"source": [
"daq = mgr.getDaq(lasp.StreamMgr.StreamType.input)\n",
"print(daq)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "26277ef0-3389-4581-9cc5-2c500e789dfa",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2022-10-03 13:39:16+0200 \n",
"2022-10-03 13:39:16+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:16+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n"
]
},
{
"ename": "RuntimeError",
"evalue": "Mat::init(): requested size is not compatible with column vector layout",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m/tmp/ipykernel_24664/1896157402.py\u001b[0m in \u001b[0;36m<cell line: 3>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0.1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mt\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m0.1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mlevel\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclip\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mppm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetCurrentValue\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;31m#print('\\r {\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mRuntimeError\u001b[0m: Mat::init(): requested size is not compatible with column vector layout"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2022-10-03 13:39:16+0200 \n",
"2022-10-03 13:39:16+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:16+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:17+0200 \n",
"2022-10-03 13:39:17+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:17+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:17+0200 \n",
"2022-10-03 13:39:17+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:17+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:17+0200 \n",
"2022-10-03 13:39:17+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:17+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:17+0200 \n",
"2022-10-03 13:39:17+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:17+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:17+0200 \n",
"2022-10-03 13:39:17+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:17+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:18+0200 \n",
"2022-10-03 13:39:18+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:18+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:18+0200 \n",
"2022-10-03 13:39:18+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:18+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:18+0200 \n",
"2022-10-03 13:39:18+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:18+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:18+0200 \n",
"2022-10-03 13:39:18+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:18+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:19+0200 \n",
"2022-10-03 13:39:19+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:19+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:19+0200 \n",
"2022-10-03 13:39:19+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:19+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:19+0200 \n",
"2022-10-03 13:39:19+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:19+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:19+0200 \n",
"2022-10-03 13:39:19+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:19+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:20+0200 \n",
"2022-10-03 13:39:20+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:20+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:20+0200 \n",
"2022-10-03 13:39:20+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:20+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:20+0200 \n",
"2022-10-03 13:39:20+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:20+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:20+0200 \n",
"2022-10-03 13:39:20+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:20+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:20+0200 \n",
"2022-10-03 13:39:20+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:20+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:20+0200 \n",
"2022-10-03 13:39:20+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:20+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:21+0200 \n",
"2022-10-03 13:39:21+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:21+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:21+0200 \n",
"2022-10-03 13:39:21+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:21+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:21+0200 \n",
"2022-10-03 13:39:21+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:21+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:21+0200 \n",
"2022-10-03 13:39:21+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:21+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:22+0200 \n",
"2022-10-03 13:39:22+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:22+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:22+0200 \n",
"2022-10-03 13:39:22+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:22+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:22+0200 \n",
"2022-10-03 13:39:22+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:22+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:22+0200 \n",
"2022-10-03 13:39:22+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:22+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:23+0200 \n",
"2022-10-03 13:39:23+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:23+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:23+0200 \n",
"2022-10-03 13:39:23+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:23+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:23+0200 \n",
"2022-10-03 13:39:23+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:23+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:23+0200 \n",
"2022-10-03 13:39:23+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:23+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:23+0200 \n",
"2022-10-03 13:39:23+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:23+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:23+0200 \n",
"2022-10-03 13:39:23+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:23+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:24+0200 \n",
"2022-10-03 13:39:24+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:24+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:24+0200 \n",
"2022-10-03 13:39:24+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:24+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:24+0200 \n",
"2022-10-03 13:39:24+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:24+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:24+0200 \n",
"2022-10-03 13:39:24+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:24+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:24+0200 \n",
"2022-10-03 13:39:24+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:24+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:25+0200 \n",
"2022-10-03 13:39:25+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:25+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:25+0200 \n",
"2022-10-03 13:39:25+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:25+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:25+0200 \n",
"2022-10-03 13:39:25+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:25+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:25+0200 \n",
"2022-10-03 13:39:25+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:25+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:25+0200 \n",
"2022-10-03 13:39:25+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:25+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:26+0200 \n",
"2022-10-03 13:39:26+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:26+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:26+0200 \n",
"2022-10-03 13:39:26+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:26+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:26+0200 \n",
"2022-10-03 13:39:26+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:26+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:26+0200 \n",
"2022-10-03 13:39:26+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:26+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:26+0200 \n",
"2022-10-03 13:39:26+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:26+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:26+0200 \n",
"2022-10-03 13:39:26+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:26+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:27+0200 \n",
"2022-10-03 13:39:27+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:27+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:27+0200 \n",
"2022-10-03 13:39:27+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:27+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:27+0200 \n",
"2022-10-03 13:39:27+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:27+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n",
"2022-10-03 13:39:27+0200 \n",
"2022-10-03 13:39:27+0200 Enter inCallback_threaded (lasp_ppm.cpp: 18)\n",
"2022-10-03 13:39:27+0200 Leave inCallback_threaded (lasp_ppm.cpp)\n"
]
}
],
"source": [
"import time\n",
"t=0\n",
"while t < 1:\n",
" time.sleep(0.1)\n",
" t += 0.1\n",
" level, clip = ppm.getCurrentValue()\n",
" #print('\\r {"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "30b77ce0-40ee-4b88-89fa-83b7a62e493c",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2022-10-03 13:39:27+0200 \n",
"2022-10-03 13:39:27+0200 Enter stopAllStreams (lasp_streammgr.cpp: 202)\n",
"2022-10-03 13:39:27+0200 | Enter ~Daq (lasp_daq.cpp: 14)\n",
"2022-10-03 13:39:27+0200 | Leave ~Daq (lasp_daq.cpp)\n",
"2022-10-03 13:39:27+0200 Leave stopAllStreams (lasp_streammgr.cpp)\n"
]
}
],
"source": [
"mgr.stopAllStreams()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "78cc8353-0e0b-4d96-a263-f4ad3fe4ee4c",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -18,6 +18,13 @@ include_directories(../../third_party/gsl-lite/include)
include_directories(../../third_party/tomlplusplus/include) include_directories(../../third_party/tomlplusplus/include)
include_directories(../../third_party/thread-pool) include_directories(../../third_party/thread-pool)
if(LASP_HAS_RTAUDIO)
include_directories(../../third_party/rtaudio)
endif()
if(LASP_HAS_ULDAQ)
include_directories(../../third_party/uldaq/src)
endif()
add_subdirectory(device) add_subdirectory(device)
add_subdirectory(dsp) add_subdirectory(dsp)

View File

@ -28,5 +28,4 @@ if(LASP_HAS_RTAUDIO)
endif() endif()
target_link_libraries(lasp_device_lib lasp_dsp_lib) target_link_libraries(lasp_device_lib lasp_dsp_lib)
target_link_libraries(lasp_device_lib PRIVATE )

View File

@ -113,12 +113,12 @@ public:
/** /**
* @brief Returns the number of enabled input channels * @brief Returns the number of enabled input channels
* *
* @param include_monitorchannel if true, all channels that are internally * @param include_monitorchannels if true, all channels that are internally
* monitored are added to the list. * monitored are added to the list.
* *
* @return number of enabled input channels * @return number of enabled input channels
*/ */
us neninchannels(bool include_monitorchannel = true) const; us neninchannels(bool include_monitorchannels = true) const;
/** /**
* @brief Returns the number of enabled output channels * @brief Returns the number of enabled output channels
@ -137,6 +137,7 @@ public:
* @return Boolean vector * @return Boolean vector
*/ */
boolvec eninchannels(bool include_monitor = true) const; boolvec eninchannels(bool include_monitor = true) const;
/** /**
* @brief Create an array of booleans for each enabled output channel. * @brief Create an array of booleans for each enabled output channel.
* *

View File

@ -88,6 +88,15 @@ int DaqConfiguration::getLowestOutChannel() const {
} }
vector<DaqChannel> DaqConfiguration::enabledInChannels() const { vector<DaqChannel> DaqConfiguration::enabledInChannels() const {
vector<DaqChannel> res; vector<DaqChannel> res;
if(monitorOutput) {
DaqChannel ch;
ch.name = "Internal output monitor (loopback)";
ch.enabled = true;
ch.sensitivity = 1;
ch.qty = DaqChannel::Qty::Number;
res.emplace_back(std::move(ch));
}
for(auto& ch: inchannel_config) { for(auto& ch: inchannel_config) {
if(ch.enabled) { res.push_back(ch);} if(ch.enabled) { res.push_back(ch);}
} }

View File

@ -134,7 +134,7 @@ const us LASP_ULDAQ_APICODE = 0;
const DaqApi uldaqapi("UlDaq", 0); const DaqApi uldaqapi("UlDaq", 0);
#endif #endif
#if LASP_HAS_RTAUDIO == 1 #if LASP_HAS_RTAUDIO == 1
#include <RtAudio.h> #include "RtAudio.h"
const us LASP_RTAUDIO_APICODE = 1; const us LASP_RTAUDIO_APICODE = 1;
const DaqApi rtaudioAlsaApi("RtAudio Linux ALSA", 1, RtAudio::Api::LINUX_ALSA); const DaqApi rtaudioAlsaApi("RtAudio Linux ALSA", 1, RtAudio::Api::LINUX_ALSA);
const DaqApi rtaudioPulseaudioApi("RtAudio Linux Pulseaudio", 1, const DaqApi rtaudioPulseaudioApi("RtAudio Linux Pulseaudio", 1,
@ -162,7 +162,7 @@ public:
*/ */
enum class Qty { Number, AcousticPressure, Voltage, UserDefined }; enum class Qty { Number, AcousticPressure, Voltage, UserDefined };
DaqChannel() = default; DaqChannel() {}
/** /**
* @brief Whether the channel is enabled. * @brief Whether the channel is enabled.
@ -175,7 +175,7 @@ public:
* outputed number, i.e. Number/Volt or Number/Pa. Converting stored numbers * outputed number, i.e. Number/Volt or Number/Pa. Converting stored numbers
* to physical qty, *divide* by the sensitivity. * to physical qty, *divide* by the sensitivity.
*/ */
double sensitivity = -1; double sensitivity = 1;
/** /**
* @brief For input-only: enable IEPE constant current power supply for * @brief For input-only: enable IEPE constant current power supply for
* this channel. Only for hardware that is capable of doing so. * this channel. Only for hardware that is capable of doing so.
@ -247,7 +247,6 @@ public:
*/ */
std::vector<DaqChannel> inchannel_config; std::vector<DaqChannel> inchannel_config;
/** /**
* @brief Return list of enabled input channels * @brief Return list of enabled input channels
* *

View File

@ -26,8 +26,8 @@ void DaqData::copyInFromRaw(const std::vector<uint8_t *> &ptrs) {
} }
void DaqData::copyToRaw(const us channel, uint8_t *ptr) { void DaqData::copyToRaw(const us channel, uint8_t *ptr) {
std::copy(&_data[sw * nframes * channel], std::copy(raw_ptr(0, channel),
&_data[sw * nframes * (channel + 1)], ptr); raw_ptr(nframes, channel), ptr);
} }
template <typename int_type> d convertToFloat(const int_type val) { template <typename int_type> d convertToFloat(const int_type val) {

View File

@ -4,7 +4,7 @@
#include "lasp_rtaudiodaq.h" #include "lasp_rtaudiodaq.h"
#if LASP_HAS_RTAUDIO == 1 #if LASP_HAS_RTAUDIO == 1
#include "lasp_daq.h" #include "lasp_daq.h"
#include <RtAudio.h> #include "RtAudio.h"
#include <atomic> #include <atomic>
#include <cassert> #include <cassert>

View File

@ -47,7 +47,7 @@ StreamMgr::StreamMgr() {
_main_thread_id = std::this_thread::get_id(); _main_thread_id = std::this_thread::get_id();
#endif #endif
// Trigger a scan for the available devices, in the background. // Trigger a scan for the available devices, in the background.
rescanDAQDevices(); rescanDAQDevices(true);
} }
#if LASP_DEBUG == 1 #if LASP_DEBUG == 1
void StreamMgr::checkRightThread() const { void StreamMgr::checkRightThread() const {

View File

@ -1,6 +1,10 @@
#include "lasp_uldaq.h" #define DEBUGTRACE_ENABLED
#include "debugtrace.hpp"
#include "lasp_config.h"
#if LASP_HAS_ULDAQ == 1 #if LASP_HAS_ULDAQ == 1
#include "lasp_daqconfig.h" #include "lasp_daqconfig.h"
#include "lasp_uldaq.h"
#include <algorithm> #include <algorithm>
#include <atomic> #include <atomic>
#include <cassert> #include <cassert>
@ -18,7 +22,7 @@ using namespace std::literals::chrono_literals;
using std::atomic; using std::atomic;
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using std::runtime_error; using rte = std::runtime_error;
#include "debugtrace.hpp" #include "debugtrace.hpp"
DEBUGTRACE_VARIABLES; DEBUGTRACE_VARIABLES;
@ -43,7 +47,10 @@ string showErr(UlError err) {
errstr = "UlDaq API Error: "; errstr = "UlDaq API Error: ";
ulGetErrMsg(err, errmsg); ulGetErrMsg(err, errmsg);
errstr += errmsg; errstr += errmsg;
std::cerr << "\b\n**************** UlDAQ backend error **********\n";
std::cerr << errstr << std::endl; std::cerr << errstr << std::endl;
std::cerr << "***********************************************\n\n";
return errstr; return errstr;
} }
return errstr; return errstr;
@ -80,7 +87,10 @@ public:
} }
} }
bool isRunning() const { return _thread.joinable(); } bool isRunning() const {
DEBUGTRACE_ENTER;
return _thread.joinable();
}
virtual void start(InDaqCallback inCallback, virtual void start(InDaqCallback inCallback,
OutDaqCallback outCallback) override final; OutDaqCallback outCallback) override final;
@ -92,7 +102,7 @@ public:
DEBUGTRACE_ENTER; DEBUGTRACE_ENTER;
StreamStatus status = _streamStatus; StreamStatus status = _streamStatus;
if (!isRunning()) { if (!isRunning()) {
throw runtime_error("No data acquisition running"); throw rte("No data acquisition running");
} }
_stopThread = true; _stopThread = true;
@ -111,15 +121,15 @@ public:
void DT9837A::start(InDaqCallback inCallback, OutDaqCallback outCallback) { void DT9837A::start(InDaqCallback inCallback, OutDaqCallback outCallback) {
DEBUGTRACE_ENTER; DEBUGTRACE_ENTER;
if (isRunning()) { if (isRunning()) {
throw runtime_error("DAQ is already running"); throw rte("DAQ is already running");
} }
if (neninchannels() > 0) { if (neninchannels() > 0) {
if (!inCallback) if (!inCallback)
throw runtime_error("DAQ requires a callback for input data"); throw rte("DAQ requires a callback for input data");
} }
if (nenoutchannels() > 0) { if (nenoutchannels() > 0) {
if (!outCallback) if (!outCallback)
throw runtime_error("DAQ requires a callback for output data"); throw rte("DAQ requires a callback for output data");
} }
assert(neninchannels() + nenoutchannels() > 0); assert(neninchannels() + nenoutchannels() > 0);
_thread = std::thread(&DT9837A::threadFcn, this, inCallback, outCallback); _thread = std::thread(&DT9837A::threadFcn, this, inCallback, outCallback);
@ -131,9 +141,11 @@ protected:
const DataTypeDescriptor dtype_descr; const DataTypeDescriptor dtype_descr;
us nchannels, nFramesPerBlock; us nchannels, nFramesPerBlock;
double samplerate; double samplerate;
dvec buf; std::vector<double> buf;
bool topenqueued, botenqueued; bool topenqueued, botenqueued;
us increment = 0; us increment = 0;
us totalFramesCount = 0; us totalFramesCount = 0;
long long buffer_mid_idx; long long buffer_mid_idx;
@ -158,7 +170,7 @@ public:
{ {
DEBUGTRACE_ENTER; DEBUGTRACE_ENTER;
assert(_handle != 0); assert(daq.getHandle() != 0);
monitorOutput = daq.monitorOutput; monitorOutput = daq.monitorOutput;
@ -167,12 +179,11 @@ public:
UlError err = ERR_NO_ERROR; UlError err = ERR_NO_ERROR;
std::vector<DaqInChanDescriptor> indescs; std::vector<DaqInChanDescriptor> indescs;
boolvec eninchannels_without_mon = daq.eninchannels(false);
boolvec eninchannels = daq.eninchannels();
// Initialize input, if any // Initialize input, if any
for (us chin = 0; chin < 4; chin++) { for (us chin = 0; chin < 4; chin++) {
if (eninchannels[chin] == true) { if (eninchannels_without_mon[chin] == true) {
DaqInChanDescriptor indesc; DaqInChanDescriptor indesc;
indesc.type = DAQI_ANALOG_SE; indesc.type = DAQI_ANALOG_SE;
indesc.channel = chin; indesc.channel = chin;
@ -191,50 +202,75 @@ public:
indescs.push_back(indesc); indescs.push_back(indesc);
} }
} }
// Overwrite last channel
// Add possibly last channel as monitor
if (monitorOutput) { if (monitorOutput) {
DaqInChanDescriptor indesc; DaqInChanDescriptor indesc;
indesc.type = DAQI_DAC; indesc.type = DAQI_DAC;
indesc.channel = 0; indesc.channel = 0;
/// The output only has a range of 10V, therefore the monitor of the
/// output also has to be set to this value.
indesc.range = BIP10VOLTS; indesc.range = BIP10VOLTS;
indescs.push_back(indesc); indescs.push_back(indesc);
} }
assert(indescs.size() == nchannels); assert(indescs.size() == nchannels);
DEBUGTRACE_MESSAGE("Starting input scan"); DEBUGTRACE_MESSAGE("Starting input scan");
err = ulDaqInScan(daq.getHandle(), indescs.data(), nchannels, err = ulDaqInScan(daq.getHandle(), indescs.data(), nchannels,
2 * nFramesPerBlock, // Watch the 2 here! 2 * nFramesPerBlock, // Watch the 2 here!
&samplerate, scanoptions, inscanflags, buf.data()); &samplerate, scanoptions, inscanflags, buf.data());
if (err != ERR_NO_ERROR) { if (err != ERR_NO_ERROR) {
showErr(err); showErr(err);
throw std::runtime_error("Could not start input DAQ"); throw rte("Could not start input DAQ");
}
}
void start() {
ScanStatus status;
TransferStatus transferStatus;
UlError err = ulDaqInScanStatus(daq.getHandle(), &status, &transferStatus);
if (err != ERR_NO_ERROR) {
showErr(err);
throw rte("Unable to start input on DAQ");
} }
botenqueued = false; totalFramesCount = transferStatus.currentTotalCount;
topenqueued = false; topenqueued = true;
botenqueued = true;
} }
/**
* @brief InBufHandler::operator()()
*
* @return true on success
*/
bool operator()() { bool operator()() {
/* DEBUGTRACE_ENTER; */
bool ret = true; bool ret = true;
auto runCallback = ([&](us totalOffset) { auto runCallback = ([&](us totalOffset) {
us monitoroffset = monitorOutput ? 1 : 0; /* DEBUGTRACE_ENTER; */
TypedDaqData<double> data(nchannels, nFramesPerBlock, TypedDaqData<double> data(nchannels, nFramesPerBlock,
DataTypeDescriptor::DataType::dtype_fl64); DataTypeDescriptor::DataType::dtype_fl64);
us monitorOffset = monitorOutput ? 1 : 0;
/* /// Put the output monitor in front */
if (monitorOutput) { if (monitorOutput) {
for (us sample = 0; sample < nFramesPerBlock; sample++) { for (us sample = 0; sample < nFramesPerBlock; sample++) {
data(0, sample) = data(sample, 0) =
buf[totalOffset + (sample * nchannels) + (nchannels - 1)]; buf[totalOffset + sample * nchannels + (nchannels - 1)];
} }
} }
for (us channel = monitoroffset; channel < (nchannels - monitoroffset); for (us channel = 0; channel < nchannels-monitorOffset; channel++) {
channel++) { /* DEBUGTRACE_PRINT(channel); */
for (us sample = 0; sample < nFramesPerBlock; sample++) { for (us frame = 0; frame < nFramesPerBlock; frame++) {
data(channel, sample) = data(frame, channel + monitorOffset) =
buf[totalOffset + (sample * nchannels) + channel]; buf[totalOffset + (frame * nchannels) + channel];
} }
} }
return cb(data); return cb(data);
@ -291,23 +327,46 @@ public:
: BufHandler(daq, daq.nenoutchannels()), cb(cb) { : BufHandler(daq, daq.nenoutchannels()), cb(cb) {
DEBUGTRACE_MESSAGE("Starting output scan"); DEBUGTRACE_MESSAGE("Starting output scan");
DEBUGTRACE_PRINT(nchannels);
AOutScanFlag outscanflags = AOUTSCAN_FF_DEFAULT; AOutScanFlag outscanflags = AOUTSCAN_FF_DEFAULT;
ScanOption scanoptions = SO_CONTINUOUS; ScanOption scanoptions = SO_CONTINUOUS;
UlError err = UlError err =
ulAOutScan(daq.getHandle(), 0, 0, BIP10VOLTS, ulAOutScan(daq.getHandle(), 0, 0, BIP10VOLTS,
2 * nFramesPerBlock, // Watch the 2 here! 2 * nFramesPerBlock, // Watch the 2 here!
&samplerate, scanoptions, outscanflags, buf.data()); &samplerate, scanoptions, outscanflags, buf.data());
if (err != ERR_NO_ERROR) { if (err != ERR_NO_ERROR) {
showErr(err); showErr(err);
throw runtime_error("Unable to start output on DAQ"); throw rte("Unable to start output on DAQ");
} }
}
void start() {
botenqueued = false, topenqueued = true; ScanStatus status;
TransferStatus transferStatus;
UlError err = ulAOutScanStatus(daq.getHandle(), &status, &transferStatus);
if (err != ERR_NO_ERROR) {
showErr(err);
throw rte("Unable to start output on DAQ");
} }
if (status != SS_RUNNING) {
throw rte("Unable to start output on DAQ");
}
totalFramesCount = transferStatus.currentTotalCount;
topenqueued = true;
botenqueued = true;
}
/**
* @brief OutBufHandler::operator()
*
* @return true on success
*/
bool operator()() { bool operator()() {
/* DEBUGTRACE_ENTER; */
bool res = true; bool res = true;
assert(_handle != 0); assert(daq.getHandle() != 0);
UlError err = ERR_NO_ERROR; UlError err = ERR_NO_ERROR;
@ -367,30 +426,39 @@ void DT9837A::threadFcn(InDaqCallback inCallback, OutDaqCallback outCallback) {
DEBUGTRACE_ENTER; DEBUGTRACE_ENTER;
cerr << "******************\n" /* cerr << "******************\n" */
"Todo: the current way of handling timing in this DAQ thread is not " /* "Todo: the current way of handling timing in this DAQ thread is not " */
"really robust, due " /* "really robust, due " */
"to input / output callbacks that can be too time-consuming. We have " /* "to input / output callbacks that can be too time-consuming. We have " */
"to fix the " /* "to fix the " */
"sleep_for to properly deal with longer callbacks." /* "sleep_for to properly deal with longer callbacks." */
"\n*****************" /* "\n*****************" */
<< endl; /* << endl; */
try { try {
std::unique_ptr<InBufHandler> ibh;
std::unique_ptr<OutBufHandler> obh;
if (neninchannels() > 0) { std::unique_ptr<OutBufHandler> obh;
assert(inCallback); std::unique_ptr<InBufHandler> ibh;
ibh = std::make_unique<InBufHandler>(*this, inCallback);
} StreamStatus status = _streamStatus;
status.isRunning = true;
_streamStatus = status;
if (nenoutchannels() > 0) { if (nenoutchannels() > 0) {
assert(outCallback); assert(outCallback);
obh = std::make_unique<OutBufHandler>(*this, outCallback); obh = std::make_unique<OutBufHandler>(*this, outCallback);
} }
if (neninchannels() > 0) {
assert(inCallback);
ibh = std::make_unique<InBufHandler>(*this, inCallback);
}
if (obh)
obh->start();
if (ibh)
ibh->start();
const double sleeptime = const double sleeptime_s =
static_cast<double>(_nFramesPerBlock) / (16 * samplerate()); static_cast<double>(_nFramesPerBlock) / (16 * samplerate());
const us sleeptime_us = static_cast<us>(sleeptime * 1e6); const us sleeptime_us = static_cast<us>(sleeptime_s * 1e6);
while (!_stopThread) { while (!_stopThread) {
if (ibh) { if (ibh) {
@ -402,13 +470,23 @@ void DT9837A::threadFcn(InDaqCallback inCallback, OutDaqCallback outCallback) {
if (!(*obh)()) { if (!(*obh)()) {
_stopThread = true; _stopThread = true;
} }
} } else {
std::this_thread::sleep_for(std::chrono::microseconds(sleeptime_us)); std::this_thread::sleep_for(std::chrono::microseconds(sleeptime_us));
} }
} catch (std::runtime_error &e) { }
} catch (rte &e) {
StreamStatus status = _streamStatus;
status.isRunning = false;
status.errorType = StreamStatus::StreamError::systemError;
_streamStatus = status;
cerr << "\n******************\n";
cerr << "Catched error in UlDAQ thread: " << e.what() << endl;
cerr << "\n******************\n";
} }
StreamStatus status = _streamStatus; StreamStatus status = _streamStatus;
;
status.isRunning = false; status.isRunning = false;
_streamStatus = status; _streamStatus = status;
_stopThread = false; _stopThread = false;
@ -425,19 +503,19 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config)
// Some sanity checks // Some sanity checks
if (inchannel_config.size() != 4) { if (inchannel_config.size() != 4) {
throw runtime_error("Invalid length of enabled inChannels vector"); throw rte("Invalid length of enabled inChannels vector");
} }
if (outchannel_config.size() != 1) { if (outchannel_config.size() != 1) {
throw runtime_error("Invalid length of enabled outChannels vector"); throw rte("Invalid length of enabled outChannels vector");
} }
if (_nFramesPerBlock < 24 || _nFramesPerBlock > 8192) { if (_nFramesPerBlock < 24 || _nFramesPerBlock > 8192) {
throw runtime_error("Unsensible number of samples per block chosen"); throw rte("Unsensible number of samples per block chosen");
} }
if (samplerate() < 10000 || samplerate() > 51000) { if (samplerate() < 10000 || samplerate() > 51000) {
throw runtime_error("Invalid sample rate"); throw rte("Invalid sample rate");
} }
DaqDeviceDescriptor devdescriptors[MAX_DEV_COUNT_PER_API]; DaqDeviceDescriptor devdescriptors[MAX_DEV_COUNT_PER_API];
@ -450,11 +528,11 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config)
err = ulGetDaqDeviceInventory(interfaceType, devdescriptors, err = ulGetDaqDeviceInventory(interfaceType, devdescriptors,
(unsigned *)&numdevs); (unsigned *)&numdevs);
if (err != ERR_NO_ERROR) { if (err != ERR_NO_ERROR) {
throw runtime_error("Device inventarization failed"); throw rte("Device inventarization failed");
} }
if ((us)api_specific_devindex >= numdevs) { if ((us)api_specific_devindex >= numdevs) {
throw runtime_error("Device number {deviceno} too high {err}. This could " throw rte("Device number {deviceno} too high {err}. This could "
"happen when the device is currently not connected"); "happen when the device is currently not connected");
} }
@ -464,8 +542,7 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config)
_handle = ulCreateDaqDevice(descriptor); _handle = ulCreateDaqDevice(descriptor);
if (_handle == 0) { if (_handle == 0) {
throw runtime_error( throw rte("Unable to create a handle to the specified DAQ "
"Unable to create a handle to the specified DAQ "
"device. Is the device currently in use? Please make sure to set " "device. Is the device currently in use? Please make sure to set "
"the DAQ configuration in duplex mode if simultaneous input and " "the DAQ configuration in duplex mode if simultaneous input and "
"output is required."); "output is required.");
@ -475,7 +552,7 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config)
if (err != ERR_NO_ERROR) { if (err != ERR_NO_ERROR) {
ulReleaseDaqDevice(_handle); ulReleaseDaqDevice(_handle);
_handle = 0; _handle = 0;
throw runtime_error(string("Unable to connect to device: " + showErr(err))); throw rte(string("Unable to connect to device: " + showErr(err)));
} }
for (us ch = 0; ch < 4; ch++) { for (us ch = 0; ch < 4; ch++) {
@ -483,14 +560,14 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config)
err = ulAISetConfigDbl(_handle, AI_CFG_CHAN_SENSOR_SENSITIVITY, ch, 1.0); err = ulAISetConfigDbl(_handle, AI_CFG_CHAN_SENSOR_SENSITIVITY, ch, 1.0);
showErr(err); showErr(err);
if (err != ERR_NO_ERROR) { if (err != ERR_NO_ERROR) {
throw runtime_error("Fatal: could normalize channel sensitivity"); throw rte("Fatal: could normalize channel sensitivity");
} }
CouplingMode cm = inchannel_config.at(ch).ACCouplingMode ? CM_AC : CM_DC; CouplingMode cm = inchannel_config.at(ch).ACCouplingMode ? CM_AC : CM_DC;
err = ulAISetConfig(_handle, AI_CFG_CHAN_COUPLING_MODE, ch, cm); err = ulAISetConfig(_handle, AI_CFG_CHAN_COUPLING_MODE, ch, cm);
if (err != ERR_NO_ERROR) { if (err != ERR_NO_ERROR) {
showErr(err); showErr(err);
throw runtime_error("Fatal: could not set AC/DC coupling mode"); throw rte("Fatal: could not set AC/DC coupling mode");
} }
IepeMode iepe = IepeMode iepe =
@ -498,7 +575,7 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config)
err = ulAISetConfig(_handle, AI_CFG_CHAN_IEPE_MODE, ch, iepe); err = ulAISetConfig(_handle, AI_CFG_CHAN_IEPE_MODE, ch, iepe);
if (err != ERR_NO_ERROR) { if (err != ERR_NO_ERROR) {
showErr(err); showErr(err);
throw runtime_error("Fatal: could not set IEPE mode"); throw rte("Fatal: could not set IEPE mode");
} }
} }
} }
@ -517,7 +594,7 @@ void fillUlDaqDeviceInfo(std::vector<DeviceInfo> &devinfolist) {
static_cast<unsigned *>(&numdevs)); static_cast<unsigned *>(&numdevs));
if (err != ERR_NO_ERROR) { if (err != ERR_NO_ERROR) {
throw runtime_error("UlDaq device inventarization failed"); throw rte("UlDaq device inventarization failed");
} }
for (unsigned i = 0; i < numdevs; i++) { for (unsigned i = 0; i < numdevs; i++) {
@ -528,7 +605,7 @@ void fillUlDaqDeviceInfo(std::vector<DeviceInfo> &devinfolist) {
devinfo.api = uldaqapi; devinfo.api = uldaqapi;
string name, interface; string name, interface;
if (string(descriptor.productName) != "DT9837A") { if (string(descriptor.productName) != "DT9837A") {
throw runtime_error("Unknown UlDAQ type"); throw rte("Unknown UlDAQ type");
} }
switch (descriptor.devInterface) { switch (descriptor.devInterface) {
@ -574,8 +651,10 @@ void fillUlDaqDeviceInfo(std::vector<DeviceInfo> &devinfolist) {
devinfo.hasInputACCouplingSwitch = true; devinfo.hasInputACCouplingSwitch = true;
devinfo.hasInputTrigger = true; devinfo.hasInputTrigger = true;
devinfo.hasInternalOutputMonitor = true;
// Finally, this devinfo is pushed back in list // Finally, this devinfo is pushed back in list
devinfolist.push_back(devinfo); devinfolist.push_back(devinfo);
} }
} }
#endif #endif // LASP_HAS_ULDAQ

View File

@ -52,6 +52,9 @@ const int LASP_VERSION_MINOR = @CMAKE_PROJECT_VERSION_MINOR@;
/* Audio-specific */ /* Audio-specific */
#cmakedefine LASP_MAX_NUM_CHANNELS @LASP_MAX_NUM_CHANNELS@ #cmakedefine LASP_MAX_NUM_CHANNELS @LASP_MAX_NUM_CHANNELS@
/* For FFT's */
#cmakedefine LASP_MAX_NFFT @LASP_MAX_NFFT@
/* Platform-specific */ /* Platform-specific */
#ifdef _WIN32 #ifdef _WIN32
#define MS_WIN64 #define MS_WIN64

View File

@ -116,6 +116,6 @@ class DaqConfigurations:
""" """
with lasp_shelve() as sh: with lasp_shelve() as sh:
configs = sh.load("daqconfigs", {}) configs_str = sh.load(f"daqconfigs_v{LASP_VERSION_MAJOR}", {})
del configs[name] del configs_str[name]
sh.store(f"daqconfigs_v{LASP_VERSION_MAJOR}", configs) sh.store(f"daqconfigs_v{LASP_VERSION_MAJOR}", configs_str)

2
third_party/rtaudio vendored

@ -1 +1 @@
Subproject commit a3e9aa621e65a0744f125e9740d057a4d088e0e9 Subproject commit 46b01b5b134f33d8ddc3dab76829d4b1350e0522

1
third_party/uldaq vendored Submodule

@ -0,0 +1 @@
Subproject commit 1d8404159c0fb6d2665461b80acca5bbef5c610a