diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index 5ac503aadf..01148ec199 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -8,13 +8,12 @@ from typing import Dict, Optional, Tuple from cereal import car, messaging from openpilot.common.basedir import BASEDIR 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.retry import retry from openpilot.common.swaglog import cloudlog +from openpilot.system import micd + SAMPLE_RATE = 48000 SAMPLE_BUFFER = 4096 # (approx 100ms) MAX_VOLUME = 1.0 @@ -127,16 +126,21 @@ class Soundd: 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)) + @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): # sounddevice must be imported after forking processes import sounddevice as sd - 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, blocksize=SAMPLE_BUFFER) as stream: + with self.get_stream(sd) as stream: rk = Ratekeeper(20) - sm = messaging.SubMaster(['controlsState', 'microphone']) cloudlog.info(f"soundd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}, {stream.blocksize=}") while True: diff --git a/system/micd.py b/system/micd.py index baf75c17b9..8b738ebe93 100755 --- a/system/micd.py +++ b/system/micd.py @@ -5,7 +5,6 @@ from cereal import messaging from openpilot.common.realtime import Ratekeeper from openpilot.common.retry import retry from openpilot.common.swaglog import cloudlog -from openpilot.system.hardware import TICI RATE = 10 FFT_SAMPLES = 4096 @@ -14,18 +13,6 @@ SAMPLE_RATE = 44100 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): # https://www.engineeringtoolbox.com/sound-pressure-d_711.html sound_pressure = np.sqrt(np.mean(measurements ** 2)) # RMS of amplitudes @@ -92,14 +79,18 @@ class Mic: 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): # sounddevice must be imported after forking processes import sounddevice as sd - 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, blocksize=SAMPLE_BUFFER) as stream: + with self.get_stream(sd) as stream: cloudlog.info(f"micd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}, {stream.blocksize=}") while True: self.update()