From c0c2538c80022676ed8db6eb3234d6e1ec44957f Mon Sep 17 00:00:00 2001 From: Shawn Date: Thu, 18 Jun 2026 17:17:33 -0400 Subject: [PATCH] fix: verify JACK is operational before returning from start_jack() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit start_jack() only checked _jack_is_running() (pgrep -x jackd) which returns True even when jackd exists but failed to initialize the ALSA device — the process starts but hangs without creating SHM segments, making jack_lsp/jack_wait fail. The profile handler then continues as if JACK is running, jack_client.start() fails with server_error, the pi-multifx ports never get created, and NAM CPU drops to 0%. Fix: also verify /dev/shm/jack_default_0_0 (the JACK control socket) exists before declaring JACK started. This socket is only created after the ALSA device is successfully initialized, so a zombie jackd with a bad period/rate combination won't pass the check. --- src/system/audio.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/system/audio.py b/src/system/audio.py index d91d567..cbc3872 100644 --- a/src/system/audio.py +++ b/src/system/audio.py @@ -323,19 +323,29 @@ class AudioSystem: logger.error("jackd not found — install jackd2") return False - # Wait for readiness via jack_wait + # Wait for readiness — verify JACK is actually operational + # (process exists AND SHM socket is created), not just that + # the jackd process spawned. jackd can start but fail to + # initialize the audio device, leaving a zombie process that + # pgrep finds but jack_lsp can't connect to. deadline = time.monotonic() + timeout while time.monotonic() < deadline: time.sleep(0.3) if _jack_is_running(): - logger.info( - "JACK started: period=%d, nperiods=%d, rate=%d", - profile["period"], profile["nperiods"], profile["rate"], - ) - # Auto-connect ports if enabled - if self.config.auto_connect: - self.connect_fx_ports() - return True + # Double-check JACK is actually operational by testing + # the SHM socket — jack_default_0_0 is created only + # after the ALSA device is successfully initialized. + if Path("/dev/shm/jack_default_0_0").is_socket(): + logger.info( + "JACK started: period=%d, nperiods=%d, rate=%d", + profile["period"], profile["nperiods"], profile["rate"], + ) + # Auto-connect ports if enabled + if self.config.auto_connect: + self.connect_fx_ports() + return True + # JACK process exists but SHM not ready yet — keep waiting + continue # Timed out — check for common issues poll = proc.poll()