diff --git a/isr.py b/isr.py index 01abfac..4b05ec0 100644 --- a/isr.py +++ b/isr.py @@ -186,13 +186,15 @@ class ALSAStream: self._process = subprocess.Popen( cmd, stdout=subprocess.PIPE, - stderr=subprocess.DEVNULL, + stderr=subprocess.PIPE, ) except FileNotFoundError: raise RuntimeError("arecord not found - install alsa-utils: sudo apt install alsa-utils") self._thread = threading.Thread(target=self._read_loop, daemon=True) + self._stderr_thread = threading.Thread(target=self._log_stderr, daemon=True) self._thread.start() + self._stderr_thread.start() return self def __exit__(self, *args): @@ -206,6 +208,12 @@ class ALSAStream: if self._thread: self._thread.join(timeout=1) + def _log_stderr(self): + for line in self._process.stderr: + line = line.decode('utf-8', errors='replace').rstrip() + if line: + self.logger.warning(f"arecord: {line}") + def _read_loop(self): chunk_size = self.sample_rate * self.channels * 2 // 10 # 100 ms chunks while self._running and self._process.poll() is None: @@ -306,6 +314,14 @@ class AudioSystem: if spec_lower in dev.name.lower(): return dev + # No hardware device matched. Treat spec as a direct ALSA PCM name so + # virtual devices defined in asound.conf (dsnoop, plug, etc.) work without + # appearing in `arecord -l`. + if 'alsa' in self._backends: + return AudioDevice( + id=spec, name=spec, channels=2, sample_rate=44100, backend='alsa' + ) + return None