From bb9c835f9800f5f6a92c0c8a14650cb694eb47bc Mon Sep 17 00:00:00 2001 From: Shawn Date: Thu, 18 Jun 2026 18:32:55 -0400 Subject: [PATCH] fix: _jack_is_operational() now creates throwaway JACK client instead of jack_lsp; standard profile period=512 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _jack_is_operational(): jack_lsp is unreliable on JACK 1.9.22 (returns 0 exit even when dead, and socket path varies). Instead, try creating a real JACK.Client('_healthcheck') which is the definitive test — exactly what jack_client.start() does. If the client connects, JACK is truly operational. Standard profile: period changed from 256 to 512. The NAM engine takes 2-5ms per inference at 256/48k (5.33ms window = 93% CPU). Any jitter causes xruns (audible pops at ~1Hz). At 512/48k (10.67ms window), the same inference takes 40-50% CPU with 5ms headroom — far more stable. --- src/system/audio.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/system/audio.py b/src/system/audio.py index 9ab037f..fd0f91e 100644 --- a/src/system/audio.py +++ b/src/system/audio.py @@ -79,7 +79,7 @@ FOCUSRITE_PROFILES: dict[str, tuple[str, int, int]] = { # 48 kHz / 64 frames = 1.33 ms buffer → aggressive, may xrun on RPi 4B LATENCY_PROFILES: dict[str, dict] = { "standard": { - "period": 256, + "period": 512, "nperiods": 2, "rate": 48000, "rt_priority": 70, @@ -873,20 +873,20 @@ def _jack_is_running() -> bool: def _jack_is_operational() -> bool: """Check if JACK is actually accepting client connections. - Uses ``jack_lsp`` and checks stdout is non-empty (port names). - ``jack_lsp`` always exits 0 on JACK 1.9.22 even when dead — - only stdout content distinguishes 'JACK running' from - 'JACK inaccessible'. + Creates a temporary JACK client — this is the definitive test + since it's exactly what ``jack_client.start()`` does. ``jack_lsp`` + is unreliable on JACK 1.9.22 (returns 0 even when dead, and the + server socket path may differ between versions). + + The client is immediately deactivated and closed — it's throwaway. """ try: - result = subprocess.run( - ["jack_lsp"], - capture_output=True, timeout=3, - ) - # jack_lsp exits 0 even when dead on JACK 1.9.22 — - # only non-empty stdout means ports were actually listed - return bool(result.stdout.strip()) - except (FileNotFoundError, subprocess.TimeoutExpired): + import jack + client = jack.Client("_healthcheck") + client.deactivate() + client.close() + return True + except Exception: return False