soundd/micd: retry getting stream (#30701)

retry soundd/micd
old-commit-hash: 4f3a186a6f
chrysler-long2
Justin Newberry 1 year ago committed by GitHub
parent 2a5bfd0bb3
commit b914f0a27f
  1. 20
      selfdrive/ui/soundd.py
  2. 25
      system/micd.py

@ -8,13 +8,12 @@ from typing import Dict, Optional, Tuple
from cereal import car, messaging from cereal import car, messaging
from openpilot.common.basedir import BASEDIR 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.hardware import TICI
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 import micd
SAMPLE_RATE = 48000 SAMPLE_RATE = 48000
SAMPLE_BUFFER = 4096 # (approx 100ms) SAMPLE_BUFFER = 4096 # (approx 100ms)
MAX_VOLUME = 1.0 MAX_VOLUME = 1.0
@ -127,16 +126,21 @@ class Soundd:
volume = ((weighted_db - AMBIENT_DB) / DB_SCALE) * (MAX_VOLUME - MIN_VOLUME) + MIN_VOLUME volume = ((weighted_db - AMBIENT_DB) / DB_SCALE) * (MAX_VOLUME - MIN_VOLUME) + MIN_VOLUME
return math.pow(10, (np.clip(volume, MIN_VOLUME, MAX_VOLUME) - 1)) return math.pow(10, (np.clip(volume, MIN_VOLUME, MAX_VOLUME) - 1))
@retry(attempts=7, delay=3)
def get_stream(self, sd):
# reload sounddevice to reinitialize portaudio
sd._terminate()
sd._initialize()
return sd.OutputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback, blocksize=SAMPLE_BUFFER)
def soundd_thread(self): def soundd_thread(self):
# sounddevice must be imported after forking processes # sounddevice must be imported after forking processes
import sounddevice as sd import sounddevice as sd
if TICI: sm = messaging.SubMaster(['controlsState', 'microphone'])
micd.wait_for_devices(sd) # wait for alsa to be initialized on device
with sd.OutputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback, blocksize=SAMPLE_BUFFER) as stream: with self.get_stream(sd) as stream:
rk = Ratekeeper(20) rk = Ratekeeper(20)
sm = messaging.SubMaster(['controlsState', 'microphone'])
cloudlog.info(f"soundd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}, {stream.blocksize=}") cloudlog.info(f"soundd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}, {stream.blocksize=}")
while True: while True:

@ -5,7 +5,6 @@ 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.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
@ -14,18 +13,6 @@ SAMPLE_RATE = 44100
SAMPLE_BUFFER = 4096 # (approx 100ms) SAMPLE_BUFFER = 4096 # (approx 100ms)
@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
@ -92,14 +79,18 @@ class Mic:
self.measurements = self.measurements[FFT_SAMPLES:] self.measurements = self.measurements[FFT_SAMPLES:]
@retry(attempts=7, delay=3)
def get_stream(self, sd):
# reload sounddevice to reinitialize portaudio
sd._terminate()
sd._initialize()
return sd.InputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback, blocksize=SAMPLE_BUFFER)
def micd_thread(self): def micd_thread(self):
# sounddevice must be imported after forking processes # sounddevice must be imported after forking processes
import sounddevice as sd import sounddevice as sd
if TICI: with self.get_stream(sd) as stream:
wait_for_devices(sd) # wait for alsa to be initialized on device
with sd.InputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback, blocksize=SAMPLE_BUFFER) as stream:
cloudlog.info(f"micd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}, {stream.blocksize=}") cloudlog.info(f"micd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}, {stream.blocksize=}")
while True: while True:
self.update() self.update()

Loading…
Cancel
Save