soundd/micd: more robust setup procedure (#30640)

* just use the default device :/

* Ruff

* this seems like the most reliable way

* Ruff

* move comments too

* wait for devices

* fix that

* and that

* ruff

* add logging for avaliable devices

---------

Co-authored-by: Comma Device <device@comma.ai>
pull/30660/head
Justin Newberry 1 year ago committed by GitHub
parent e909f634f5
commit bc70c94f75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      selfdrive/ui/soundd.py
  2. 19
      system/micd.py

@ -10,9 +10,9 @@ from openpilot.common.basedir import BASEDIR
from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.filter_simple import FirstOrderFilter
from openpilot.system import micd from openpilot.system import micd
from openpilot.system.hardware import TICI
from openpilot.common.realtime import Ratekeeper from openpilot.common.realtime import Ratekeeper
from openpilot.system.hardware import PC
from openpilot.common.swaglog import cloudlog from openpilot.common.swaglog import cloudlog
SAMPLE_RATE = 48000 SAMPLE_RATE = 48000
@ -130,16 +130,13 @@ class Soundd:
# sounddevice must be imported after forking processes # sounddevice must be imported after forking processes
import sounddevice as sd import sounddevice as sd
rk = Ratekeeper(20) if TICI:
micd.wait_for_devices(sd) # wait for alsa to be initialized on device
sm = messaging.SubMaster(['controlsState', 'microphone']) with sd.OutputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback) as stream:
rk = Ratekeeper(20)
sm = messaging.SubMaster(['controlsState', 'microphone'])
if PC:
device = None
else:
device = "sdm845-tavil-snd-card: - (hw:0,0)"
with sd.OutputStream(device=device, channels=1, samplerate=SAMPLE_RATE, callback=self.callback) as stream:
cloudlog.info(f"soundd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}") cloudlog.info(f"soundd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}")
while True: while True:
sm.update(0) sm.update(0)

@ -3,7 +3,9 @@ import numpy as np
from cereal import messaging from cereal import messaging
from openpilot.common.realtime import Ratekeeper from openpilot.common.realtime import Ratekeeper
from openpilot.common.retry import retry
from openpilot.common.swaglog import cloudlog from openpilot.common.swaglog import cloudlog
from openpilot.system.hardware import TICI
RATE = 10 RATE = 10
FFT_SAMPLES = 4096 FFT_SAMPLES = 4096
@ -11,6 +13,18 @@ REFERENCE_SPL = 2e-5 # newtons/m^2
SAMPLE_RATE = 44100 SAMPLE_RATE = 44100
@retry(attempts=7, delay=3)
def wait_for_devices(sd):
# reload sounddevice to reinitialize portaudio
sd._terminate()
sd._initialize()
devices = sd.query_devices()
cloudlog.info(f"sounddevice available devices: {list(devices)}")
assert len(devices) > 0
def calculate_spl(measurements): def calculate_spl(measurements):
# https://www.engineeringtoolbox.com/sound-pressure-d_711.html # https://www.engineeringtoolbox.com/sound-pressure-d_711.html
sound_pressure = np.sqrt(np.mean(measurements ** 2)) # RMS of amplitudes sound_pressure = np.sqrt(np.mean(measurements ** 2)) # RMS of amplitudes
@ -81,7 +95,10 @@ class Mic:
# sounddevice must be imported after forking processes # sounddevice must be imported after forking processes
import sounddevice as sd import sounddevice as sd
with sd.InputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback) as stream: if TICI:
wait_for_devices(sd) # wait for alsa to be initialized on device
with sd.InputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback) as stream:
cloudlog.info(f"micd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}") cloudlog.info(f"micd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}")
while True: while True:
self.update() self.update()

Loading…
Cancel
Save