From 31ead60469b695d2d07b05e22d898580e4e37730 Mon Sep 17 00:00:00 2001 From: "J.A. de Jong - Redu-Sone B.V., ASCEE V.O.F" Date: Wed, 5 Oct 2022 11:27:46 +0200 Subject: [PATCH] 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. --- .gitmodules | 3 + CMakeLists.txt | 38 +- cmake/rtaudio.cmake | 12 + cmake/uldaq.cmake | 28 ++ examples/test_ppm.ipynb | 619 ++++++++++++++++++++++++++++ src/lasp/CMakeLists.txt | 7 + src/lasp/device/CMakeLists.txt | 1 - src/lasp/device/lasp_daq.h | 5 +- src/lasp/device/lasp_daqconfig.cpp | 9 + src/lasp/device/lasp_daqconfig.h | 7 +- src/lasp/device/lasp_daqdata.cpp | 4 +- src/lasp/device/lasp_rtaudiodaq.cpp | 2 +- src/lasp/device/lasp_streammgr.cpp | 2 +- src/lasp/device/lasp_uldaq.cpp | 211 +++++++--- src/lasp/lasp_config.h.in | 3 + src/lasp/lasp_daqconfigs.py | 6 +- third_party/rtaudio | 2 +- third_party/uldaq | 1 + 18 files changed, 862 insertions(+), 98 deletions(-) create mode 100644 cmake/rtaudio.cmake create mode 100644 cmake/uldaq.cmake create mode 100644 examples/test_ppm.ipynb create mode 160000 third_party/uldaq diff --git a/.gitmodules b/.gitmodules index 8df0461..4844c33 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "third_party/boost/core"] path = third_party/boost/core url = https://github.com/boostorg/core +[submodule "third_party/uldaq"] + path = third_party/uldaq + url = https://github.com/mccdaq/uldaq diff --git a/CMakeLists.txt b/CMakeLists.txt index f1ff9fd..b846e6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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_BUILD_TUNED "Tune build for current machine" OFF) option(LASP_WITH_OPENMP "Use OpenMP parallelization" ON) +set(LASP_MAX_NFFT "33554432" CACHE STRING "Max FFT size") # Use ccache if available find_program(CCACHE_PROGRAM ccache) @@ -43,8 +44,10 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") set(LASP_DEBUG True) - # This does not work nicely with RtAudio - # add_definitions(-D_GLIBCXX_DEBUG) + # This does not work nicely with RtAudio. However, if we compile it + # ourselves as a third_party ref, this works nicely together. + add_definitions(-D_GLIBCXX_DEBUG) + else() set(LASP_DEBUG False) endif() @@ -58,34 +61,35 @@ if(LASP_BUILD_TUNED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mtune=native") endif() -# link openblas +# ###################################### Find and link to OpenBLAS set(BLA_VENDOR OpenBLAS) find_package(BLAS REQUIRED) -# Reasonable maximum to the nfft size, at 48kHz this is 700s of data... -add_definitions(-DLASP_MAX_NFFT=33554432) # 2**25 +# ###################################### Find and link to FFTW +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 -include(OSSpecific) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-type-limits") - -# Enable openmp, if set +# ###################################### OpenMP related if(LASP_WITH_OPENMP) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif() +# ###################################### Compilation flags set(CMAKE_C_FLAGS_RELEASE "-O3 -flto -mfpmath=sse -march=x86-64 -mtune=native \ -fdata-sections -ffunction-sections -fomit-frame-pointer -finline-functions") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-type-limits") + # ############################# End compilation flags include_directories(/usr/lib/python3.10/site-packages/numpy/core/include) -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 +include(OSSpecific) +include(rtaudio) +include(uldaq) +# add_subdirectory(src/lasp) diff --git a/cmake/rtaudio.cmake b/cmake/rtaudio.cmake new file mode 100644 index 0000000..ca36779 --- /dev/null +++ b/cmake/rtaudio.cmake @@ -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() diff --git a/cmake/uldaq.cmake b/cmake/uldaq.cmake new file mode 100644 index 0000000..ef538ba --- /dev/null +++ b/cmake/uldaq.cmake @@ -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() diff --git a/examples/test_ppm.ipynb b/examples/test_ppm.ipynb new file mode 100644 index 0000000..4cef664 --- /dev/null +++ b/examples/test_ppm.ipynb @@ -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\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\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 +} diff --git a/src/lasp/CMakeLists.txt b/src/lasp/CMakeLists.txt index a66c7c0..831094e 100644 --- a/src/lasp/CMakeLists.txt +++ b/src/lasp/CMakeLists.txt @@ -18,6 +18,13 @@ include_directories(../../third_party/gsl-lite/include) include_directories(../../third_party/tomlplusplus/include) 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(dsp) diff --git a/src/lasp/device/CMakeLists.txt b/src/lasp/device/CMakeLists.txt index 53d876b..052d997 100644 --- a/src/lasp/device/CMakeLists.txt +++ b/src/lasp/device/CMakeLists.txt @@ -28,5 +28,4 @@ if(LASP_HAS_RTAUDIO) endif() target_link_libraries(lasp_device_lib lasp_dsp_lib) -target_link_libraries(lasp_device_lib PRIVATE ) diff --git a/src/lasp/device/lasp_daq.h b/src/lasp/device/lasp_daq.h index 7e4ba35..fe57355 100644 --- a/src/lasp/device/lasp_daq.h +++ b/src/lasp/device/lasp_daq.h @@ -113,12 +113,12 @@ public: /** * @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. * * @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 @@ -137,6 +137,7 @@ public: * @return Boolean vector */ boolvec eninchannels(bool include_monitor = true) const; + /** * @brief Create an array of booleans for each enabled output channel. * diff --git a/src/lasp/device/lasp_daqconfig.cpp b/src/lasp/device/lasp_daqconfig.cpp index 7df5c97..bb6d33b 100644 --- a/src/lasp/device/lasp_daqconfig.cpp +++ b/src/lasp/device/lasp_daqconfig.cpp @@ -88,6 +88,15 @@ int DaqConfiguration::getLowestOutChannel() const { } vector DaqConfiguration::enabledInChannels() const { vector 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) { if(ch.enabled) { res.push_back(ch);} } diff --git a/src/lasp/device/lasp_daqconfig.h b/src/lasp/device/lasp_daqconfig.h index d43fc8c..dc5248d 100644 --- a/src/lasp/device/lasp_daqconfig.h +++ b/src/lasp/device/lasp_daqconfig.h @@ -134,7 +134,7 @@ const us LASP_ULDAQ_APICODE = 0; const DaqApi uldaqapi("UlDaq", 0); #endif #if LASP_HAS_RTAUDIO == 1 -#include +#include "RtAudio.h" const us LASP_RTAUDIO_APICODE = 1; const DaqApi rtaudioAlsaApi("RtAudio Linux ALSA", 1, RtAudio::Api::LINUX_ALSA); const DaqApi rtaudioPulseaudioApi("RtAudio Linux Pulseaudio", 1, @@ -162,7 +162,7 @@ public: */ enum class Qty { Number, AcousticPressure, Voltage, UserDefined }; - DaqChannel() = default; + DaqChannel() {} /** * @brief Whether the channel is enabled. @@ -175,7 +175,7 @@ public: * outputed number, i.e. Number/Volt or Number/Pa. Converting stored numbers * to physical qty, *divide* by the sensitivity. */ - double sensitivity = -1; + double sensitivity = 1; /** * @brief For input-only: enable IEPE constant current power supply for * this channel. Only for hardware that is capable of doing so. @@ -247,7 +247,6 @@ public: */ std::vector inchannel_config; - /** * @brief Return list of enabled input channels * diff --git a/src/lasp/device/lasp_daqdata.cpp b/src/lasp/device/lasp_daqdata.cpp index 8a4b34b..1e26091 100644 --- a/src/lasp/device/lasp_daqdata.cpp +++ b/src/lasp/device/lasp_daqdata.cpp @@ -26,8 +26,8 @@ void DaqData::copyInFromRaw(const std::vector &ptrs) { } void DaqData::copyToRaw(const us channel, uint8_t *ptr) { - std::copy(&_data[sw * nframes * channel], - &_data[sw * nframes * (channel + 1)], ptr); + std::copy(raw_ptr(0, channel), + raw_ptr(nframes, channel), ptr); } template d convertToFloat(const int_type val) { diff --git a/src/lasp/device/lasp_rtaudiodaq.cpp b/src/lasp/device/lasp_rtaudiodaq.cpp index 5a56f81..17cfe39 100644 --- a/src/lasp/device/lasp_rtaudiodaq.cpp +++ b/src/lasp/device/lasp_rtaudiodaq.cpp @@ -4,7 +4,7 @@ #include "lasp_rtaudiodaq.h" #if LASP_HAS_RTAUDIO == 1 #include "lasp_daq.h" -#include +#include "RtAudio.h" #include #include diff --git a/src/lasp/device/lasp_streammgr.cpp b/src/lasp/device/lasp_streammgr.cpp index 9e8156c..5677d22 100644 --- a/src/lasp/device/lasp_streammgr.cpp +++ b/src/lasp/device/lasp_streammgr.cpp @@ -47,7 +47,7 @@ StreamMgr::StreamMgr() { _main_thread_id = std::this_thread::get_id(); #endif // Trigger a scan for the available devices, in the background. - rescanDAQDevices(); + rescanDAQDevices(true); } #if LASP_DEBUG == 1 void StreamMgr::checkRightThread() const { diff --git a/src/lasp/device/lasp_uldaq.cpp b/src/lasp/device/lasp_uldaq.cpp index d4eb78e..2b2947a 100644 --- a/src/lasp/device/lasp_uldaq.cpp +++ b/src/lasp/device/lasp_uldaq.cpp @@ -1,6 +1,10 @@ -#include "lasp_uldaq.h" +#define DEBUGTRACE_ENABLED +#include "debugtrace.hpp" +#include "lasp_config.h" + #if LASP_HAS_ULDAQ == 1 #include "lasp_daqconfig.h" +#include "lasp_uldaq.h" #include #include #include @@ -18,7 +22,7 @@ using namespace std::literals::chrono_literals; using std::atomic; using std::cerr; using std::endl; -using std::runtime_error; +using rte = std::runtime_error; #include "debugtrace.hpp" DEBUGTRACE_VARIABLES; @@ -43,7 +47,10 @@ string showErr(UlError err) { errstr = "UlDaq API Error: "; ulGetErrMsg(err, errmsg); errstr += errmsg; + + std::cerr << "\b\n**************** UlDAQ backend error **********\n"; std::cerr << errstr << std::endl; + std::cerr << "***********************************************\n\n"; 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, OutDaqCallback outCallback) override final; @@ -92,7 +102,7 @@ public: DEBUGTRACE_ENTER; StreamStatus status = _streamStatus; if (!isRunning()) { - throw runtime_error("No data acquisition running"); + throw rte("No data acquisition running"); } _stopThread = true; @@ -111,15 +121,15 @@ public: void DT9837A::start(InDaqCallback inCallback, OutDaqCallback outCallback) { DEBUGTRACE_ENTER; if (isRunning()) { - throw runtime_error("DAQ is already running"); + throw rte("DAQ is already running"); } if (neninchannels() > 0) { 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 (!outCallback) - throw runtime_error("DAQ requires a callback for output data"); + throw rte("DAQ requires a callback for output data"); } assert(neninchannels() + nenoutchannels() > 0); _thread = std::thread(&DT9837A::threadFcn, this, inCallback, outCallback); @@ -131,9 +141,11 @@ protected: const DataTypeDescriptor dtype_descr; us nchannels, nFramesPerBlock; double samplerate; - dvec buf; + std::vector buf; bool topenqueued, botenqueued; + us increment = 0; + us totalFramesCount = 0; long long buffer_mid_idx; @@ -158,7 +170,7 @@ public: { DEBUGTRACE_ENTER; - assert(_handle != 0); + assert(daq.getHandle() != 0); monitorOutput = daq.monitorOutput; @@ -167,12 +179,11 @@ public: UlError err = ERR_NO_ERROR; std::vector indescs; - - boolvec eninchannels = daq.eninchannels(); + boolvec eninchannels_without_mon = daq.eninchannels(false); // Initialize input, if any for (us chin = 0; chin < 4; chin++) { - if (eninchannels[chin] == true) { + if (eninchannels_without_mon[chin] == true) { DaqInChanDescriptor indesc; indesc.type = DAQI_ANALOG_SE; indesc.channel = chin; @@ -191,50 +202,75 @@ public: indescs.push_back(indesc); } } - // Overwrite last channel + + // Add possibly last channel as monitor if (monitorOutput) { DaqInChanDescriptor indesc; indesc.type = DAQI_DAC; 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; indescs.push_back(indesc); } assert(indescs.size() == nchannels); + DEBUGTRACE_MESSAGE("Starting input scan"); + err = ulDaqInScan(daq.getHandle(), indescs.data(), nchannels, 2 * nFramesPerBlock, // Watch the 2 here! &samplerate, scanoptions, inscanflags, buf.data()); if (err != ERR_NO_ERROR) { 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; - topenqueued = false; + totalFramesCount = transferStatus.currentTotalCount; + topenqueued = true; + botenqueued = true; } + /** + * @brief InBufHandler::operator()() + * + * @return true on success + */ bool operator()() { + /* DEBUGTRACE_ENTER; */ + bool ret = true; auto runCallback = ([&](us totalOffset) { - us monitoroffset = monitorOutput ? 1 : 0; + /* DEBUGTRACE_ENTER; */ TypedDaqData data(nchannels, nFramesPerBlock, DataTypeDescriptor::DataType::dtype_fl64); + us monitorOffset = monitorOutput ? 1 : 0; + /* /// Put the output monitor in front */ if (monitorOutput) { for (us sample = 0; sample < nFramesPerBlock; sample++) { - data(0, sample) = - buf[totalOffset + (sample * nchannels) + (nchannels - 1)]; + data(sample, 0) = + buf[totalOffset + sample * nchannels + (nchannels - 1)]; } } - for (us channel = monitoroffset; channel < (nchannels - monitoroffset); - channel++) { - for (us sample = 0; sample < nFramesPerBlock; sample++) { - data(channel, sample) = - buf[totalOffset + (sample * nchannels) + channel]; + for (us channel = 0; channel < nchannels-monitorOffset; channel++) { + /* DEBUGTRACE_PRINT(channel); */ + for (us frame = 0; frame < nFramesPerBlock; frame++) { + data(frame, channel + monitorOffset) = + buf[totalOffset + (frame * nchannels) + channel]; } } return cb(data); @@ -291,23 +327,46 @@ public: : BufHandler(daq, daq.nenoutchannels()), cb(cb) { DEBUGTRACE_MESSAGE("Starting output scan"); + DEBUGTRACE_PRINT(nchannels); AOutScanFlag outscanflags = AOUTSCAN_FF_DEFAULT; ScanOption scanoptions = SO_CONTINUOUS; UlError err = ulAOutScan(daq.getHandle(), 0, 0, BIP10VOLTS, 2 * nFramesPerBlock, // Watch the 2 here! &samplerate, scanoptions, outscanflags, buf.data()); + if (err != ERR_NO_ERROR) { showErr(err); - throw runtime_error("Unable to start output on DAQ"); + throw rte("Unable to start output on DAQ"); } - - botenqueued = false, topenqueued = true; } + void start() { + + 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()() { + /* DEBUGTRACE_ENTER; */ bool res = true; - assert(_handle != 0); + assert(daq.getHandle() != 0); UlError err = ERR_NO_ERROR; @@ -367,30 +426,39 @@ void DT9837A::threadFcn(InDaqCallback inCallback, OutDaqCallback outCallback) { DEBUGTRACE_ENTER; - cerr << "******************\n" - "Todo: the current way of handling timing in this DAQ thread is not " - "really robust, due " - "to input / output callbacks that can be too time-consuming. We have " - "to fix the " - "sleep_for to properly deal with longer callbacks." - "\n*****************" - << endl; + /* cerr << "******************\n" */ + /* "Todo: the current way of handling timing in this DAQ thread is not " */ + /* "really robust, due " */ + /* "to input / output callbacks that can be too time-consuming. We have " */ + /* "to fix the " */ + /* "sleep_for to properly deal with longer callbacks." */ + /* "\n*****************" */ + /* << endl; */ try { - std::unique_ptr ibh; - std::unique_ptr obh; - if (neninchannels() > 0) { - assert(inCallback); - ibh = std::make_unique(*this, inCallback); - } + std::unique_ptr obh; + std::unique_ptr ibh; + + StreamStatus status = _streamStatus; + status.isRunning = true; + _streamStatus = status; + if (nenoutchannels() > 0) { assert(outCallback); obh = std::make_unique(*this, outCallback); } + if (neninchannels() > 0) { + assert(inCallback); + ibh = std::make_unique(*this, inCallback); + } + if (obh) + obh->start(); + if (ibh) + ibh->start(); - const double sleeptime = + const double sleeptime_s = static_cast(_nFramesPerBlock) / (16 * samplerate()); - const us sleeptime_us = static_cast(sleeptime * 1e6); + const us sleeptime_us = static_cast(sleeptime_s * 1e6); while (!_stopThread) { if (ibh) { @@ -402,13 +470,23 @@ void DT9837A::threadFcn(InDaqCallback inCallback, OutDaqCallback outCallback) { if (!(*obh)()) { _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; - ; + status.isRunning = false; _streamStatus = status; _stopThread = false; @@ -425,19 +503,19 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config) // Some sanity checks 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) { - throw runtime_error("Invalid length of enabled outChannels vector"); + throw rte("Invalid length of enabled outChannels vector"); } 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) { - throw runtime_error("Invalid sample rate"); + throw rte("Invalid sample rate"); } DaqDeviceDescriptor devdescriptors[MAX_DEV_COUNT_PER_API]; @@ -450,12 +528,12 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config) err = ulGetDaqDeviceInventory(interfaceType, devdescriptors, (unsigned *)&numdevs); if (err != ERR_NO_ERROR) { - throw runtime_error("Device inventarization failed"); + throw rte("Device inventarization failed"); } if ((us)api_specific_devindex >= numdevs) { - throw runtime_error("Device number {deviceno} too high {err}. This could " - "happen when the device is currently not connected"); + throw rte("Device number {deviceno} too high {err}. This could " + "happen when the device is currently not connected"); } descriptor = devdescriptors[api_specific_devindex]; @@ -464,18 +542,17 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config) _handle = ulCreateDaqDevice(descriptor); if (_handle == 0) { - throw runtime_error( - "Unable to create a handle to the specified DAQ " - "device. Is the device currently in use? Please make sure to set " - "the DAQ configuration in duplex mode if simultaneous input and " - "output is required."); + throw rte("Unable to create a handle to the specified DAQ " + "device. Is the device currently in use? Please make sure to set " + "the DAQ configuration in duplex mode if simultaneous input and " + "output is required."); } err = ulConnectDaqDevice(_handle); if (err != ERR_NO_ERROR) { ulReleaseDaqDevice(_handle); _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++) { @@ -483,14 +560,14 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config) err = ulAISetConfigDbl(_handle, AI_CFG_CHAN_SENSOR_SENSITIVITY, ch, 1.0); showErr(err); 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; err = ulAISetConfig(_handle, AI_CFG_CHAN_COUPLING_MODE, ch, cm); if (err != ERR_NO_ERROR) { 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 = @@ -498,7 +575,7 @@ DT9837A::DT9837A(const DeviceInfo &devinfo, const DaqConfiguration &config) err = ulAISetConfig(_handle, AI_CFG_CHAN_IEPE_MODE, ch, iepe); if (err != ERR_NO_ERROR) { 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 &devinfolist) { static_cast(&numdevs)); 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++) { @@ -528,7 +605,7 @@ void fillUlDaqDeviceInfo(std::vector &devinfolist) { devinfo.api = uldaqapi; string name, interface; if (string(descriptor.productName) != "DT9837A") { - throw runtime_error("Unknown UlDAQ type"); + throw rte("Unknown UlDAQ type"); } switch (descriptor.devInterface) { @@ -574,8 +651,10 @@ void fillUlDaqDeviceInfo(std::vector &devinfolist) { devinfo.hasInputACCouplingSwitch = true; devinfo.hasInputTrigger = true; + devinfo.hasInternalOutputMonitor = true; + // Finally, this devinfo is pushed back in list devinfolist.push_back(devinfo); } } -#endif +#endif // LASP_HAS_ULDAQ diff --git a/src/lasp/lasp_config.h.in b/src/lasp/lasp_config.h.in index f89947c..5a0f28e 100644 --- a/src/lasp/lasp_config.h.in +++ b/src/lasp/lasp_config.h.in @@ -52,6 +52,9 @@ const int LASP_VERSION_MINOR = @CMAKE_PROJECT_VERSION_MINOR@; /* Audio-specific */ #cmakedefine LASP_MAX_NUM_CHANNELS @LASP_MAX_NUM_CHANNELS@ +/* For FFT's */ +#cmakedefine LASP_MAX_NFFT @LASP_MAX_NFFT@ + /* Platform-specific */ #ifdef _WIN32 #define MS_WIN64 diff --git a/src/lasp/lasp_daqconfigs.py b/src/lasp/lasp_daqconfigs.py index adae5d7..fe80f4f 100644 --- a/src/lasp/lasp_daqconfigs.py +++ b/src/lasp/lasp_daqconfigs.py @@ -116,6 +116,6 @@ class DaqConfigurations: """ with lasp_shelve() as sh: - configs = sh.load("daqconfigs", {}) - del configs[name] - sh.store(f"daqconfigs_v{LASP_VERSION_MAJOR}", configs) + configs_str = sh.load(f"daqconfigs_v{LASP_VERSION_MAJOR}", {}) + del configs_str[name] + sh.store(f"daqconfigs_v{LASP_VERSION_MAJOR}", configs_str) diff --git a/third_party/rtaudio b/third_party/rtaudio index a3e9aa6..46b01b5 160000 --- a/third_party/rtaudio +++ b/third_party/rtaudio @@ -1 +1 @@ -Subproject commit a3e9aa621e65a0744f125e9740d057a4d088e0e9 +Subproject commit 46b01b5b134f33d8ddc3dab76829d4b1350e0522 diff --git a/third_party/uldaq b/third_party/uldaq new file mode 160000 index 0000000..1d84041 --- /dev/null +++ b/third_party/uldaq @@ -0,0 +1 @@ +Subproject commit 1d8404159c0fb6d2665461b80acca5bbef5c610a