Commit a74949b4 by PLN (Algolia)

gate: stop gating the painter probe on the audio engine

The one probe that asks whether the LCXL is actually being painted carried
needs=("scsynth",), so it SKIPPED for the whole of every cold run — which is
exactly the setup window, when the rig is cold by definition. The painter
translates hands to CCs and lights LEDs; it has nothing to do with SuperDirt.

It now also reports NRestarts, because a unit retrying forever is invisible
from outside. StartLimitIntervalSec=0 is deliberate (bind within 5s of a
replug) and the cost of it is that 1077 consecutive failures look exactly
like a healthy idle unit. The counter is the only place that shows.
parent 56fa3937
...@@ -380,3 +380,83 @@ than a wrong profile. ...@@ -380,3 +380,83 @@ than a wrong profile.
- Raw second-client `set_text` writes did not visibly render (A/B test, PLN half-watching) — - Raw second-client `set_text` writes did not visibly render (A/B test, PLN half-watching) —
consistent with H1 (bare set_text needs bring-up); probe will settle it. consistent with H1 (bare set_text needs bring-up); probe will settle it.
- LED rings update instantly; OLED glass ~2 Hz effective. Rings = fast channel, OLED = state. - LED rings update instantly; OLED glass ~2 Hz effective. Rings = fast channel, OLED = state.
## Wed 23 morning — the tripwire day (gig TOMORROW evening)
Three root causes found before 09:30, all evidenced, none of them what we thought.
### 1. The LCXL3 driver has failed 1077 times and nothing ever said so
`journalctl --user -u lcxl3-driver` — **one** distinct message, 1077 times:
`lcxl3: no LCXL3 DAW output port found.` Restart counter reached **497**.
`StartLimitIntervalSec=0` is doing its job (retry forever, bind on replug), so
this is not a systemd fault — it is the surface being absent, loudly, into a
journal nobody reads.
Right now the port IS there (`lcxl3.py ports` resolves
`DAW out='LCXL3 1:LCXL3 1 DAW In 24:1'`), and the unit is `inactive (dead)` —
a clean stop at Sep 22 19:55:31, not a start-limit hit. So it starts fine today.
- [ ] **YOU: `systemctl --user start lcxl3-driver`** (sandbox refuses unit starts).
Then `aconnect -l | grep ParVagues` and check C1/C2/C3 in midimon.
- [x] **The gate's hole** — `Probe("LCXL LEDs", ...)` does check
`is-active lcxl3-driver.service`, but carries `needs=("scsynth",)`, so it
**SKIPs whenever the rig is cold** — exactly when you are setting up. The
painter has nothing to do with SuperDirt. Fixed: the probe now runs cold.
- [x] **Crash-loop detector** — a unit that is retrying forever looks identical
to a unit that is fine, from outside. The gate now reads the restart
counter (`NRestarts`) and says so.
### 2. Audio is on the NVIDIA GPU because two hand-set pins say so
`~/.local/state/wireplumber/default-profile`:
```
alsa_card.pci-0000_00_1f.3-platform-sof_sdw=off <- the LAPTOP card. OFF.
alsa_card.pci-0000_01_00.1=pro-audio <- 01:00.1 = NVIDIA 22bc
```
So: Speaker / Headphones / HDMI 1-3 are missing because **the card that carries
them is pinned off**, and the four `pro-output-*` sinks are the **GPU's HDMI
audio** pinned into pro-audio. WirePlumber never chose either — its
`findBestProfile` skips `pro-audio` by name. A human set both.
The SOF card's profile list also lacks `HiFi` until a device re-probe
(`alsaucm -c sof-soundwire list _verbs` says `HiFi`; PipeWire offers only
`off`/`pro-audio`), so clearing the pin alone is not enough.
- [ ] **THE WINDOW IS NOW** — scsynth dead, Ardour closed, nothing to break. A
WirePlumber restart with the rig up kills every SC->Ardour link
(`project_travel-rig-headphones`). Do it cold, today, not tomorrow.
Five ordered steps in `docs/2026-09-22-audio-profile-stuck.md`.
- [ ] **OPEN QUESTION for you:** did you pin the laptop card `off` yourself? If
you set it *because* Speaker/Headphones had already vanished, then `off`
is a symptom and the profile disappearance is the disease.
### 3. WATCH_PREFERENCE: belt AND suspenders (his call, 2026-09-23)
"in my perspective, we would have always cell and rain?" — right. midiviz
prefers the driver's translated `ParVagues LCXL3` port and falls through to the
raw `LCXL3 1 DAW` port, where v3 numbering lands in the wrong cells. The viewer
should translate for itself when it is on the raw port, so the picture is
correct whether or not the driver runs.
- [x] The v3->v2 table is now canonical in `lcxl_grid.py`; midiviz translates
on the raw port. The driver's own copy is left untouched (it is the
nervous system, one day out) and a test asserts the two never drift.
### Still the actual gate: the 2h arc
- [ ] **YOU: perf regime has regressed** — `epp=power`, `gov=powersave`,
**PL1=15W**, and **457 xruns/hour**. `max_perf_pct` is 100 (you did that),
but EPP and the package power cap put the box at 854MHz. Every audio
measurement today is untrustworthy until this is fixed:
`sudo cpupower set --epp performance` +
`sudo /usr/local/sbin/thermal-mode-apply aggressive`
- [ ] **YOU: `systemctl --user restart parvagues-sc`** — loads `s.latency 0.1`
(still 0.2 in the running process, edit never went live) AND warms the
132-bank preload. ~15s of silence, safe while cold.
- [ ] **YOU: docker is running** — `sudo systemctl stop docker.service`.
- [ ] **YOU: the 2h run with Ardour recording.** Unmoved since Sunday. It is the
only check that has never been run, and the only one that can still
surprise you.
...@@ -280,17 +280,33 @@ print(" ".join(str(p) for p in m.setlist_tracks()))')"""), ...@@ -280,17 +280,33 @@ print(" ".join(str(p) for p in m.setlist_tracks()))')"""),
# visuel anymore" the day before a gig. Generation-aware: an LCXL3 is # visuel anymore" the day before a gig. Generation-aware: an LCXL3 is
# painted by lcxl3-driver, the original LCXL by lcxl-leds-watch. A v2-only # painted by lcxl3-driver, the original LCXL by lcxl-leds-watch. A v2-only
# grep made this probe pass by accident. # grep made this probe pass by accident.
# NOT gated on scsynth (it was until 2026-09-23, and that is how the board
# sat unpainted through every cold run). The painter has nothing to do with
# SuperDirt: it translates hands to CCs and lights LEDs. Gating it on the
# audio engine meant the one probe that would have caught a dead driver
# SKIPPED for the entire setup window, when the rig is cold by definition.
#
# It also reports NRestarts, because a unit retrying forever is invisible
# from outside: `StartLimitIntervalSec=0` is deliberate (bind within 5s of a
# replug) and its cost is that 1077 consecutive failures look exactly like
# a healthy idle unit. The counter is the only place that shows.
Probe("LCXL LEDs", shell(r""" Probe("LCXL LEDs", shell(r"""
n=$(systemctl --user show -p NRestarts --value lcxl3-driver.service 2>/dev/null)
if aseqdump -l 2>/dev/null | grep -qi "LCXL3"; then if aseqdump -l 2>/dev/null | grep -qi "LCXL3"; then
systemctl --user is-active --quiet lcxl3-driver.service if systemctl --user is-active --quiet lcxl3-driver.service; then
echo "lcxl3-driver up (NRestarts=${n:-?})"; exit 0
fi
echo "LCXL3 on the bus but lcxl3-driver is $(systemctl --user is-active lcxl3-driver.service 2>&1) (NRestarts=${n:-?})"
echo " the surface is a very nice-looking brick: no paint, no OLED, no faders to Ardour"
exit 1
elif aseqdump -l 2>/dev/null | grep -qi "Launch Control XL"; then elif aseqdump -l 2>/dev/null | grep -qi "Launch Control XL"; then
systemctl --user is-active --quiet lcxl-leds-watch.service systemctl --user is-active --quiet lcxl-leds-watch.service
else else
exit 0 echo "no surface on the bus"; exit 0
fi"""), fi"""),
fix="start the painter: LCXL3 -> systemctl --user start lcxl3-driver; " fix="start the painter: LCXL3 -> systemctl --user start lcxl3-driver; "
"original LCXL -> systemctl --user start lcxl-leds-watch", "original LCXL -> systemctl --user start lcxl-leds-watch",
kind=ADVISE, needs=("scsynth",)), kind=ADVISE),
# Asks whether THIS instance warmed, by keying to the unit's own start time # Asks whether THIS instance warmed, by keying to the unit's own start time
# — not "was there ever a PRELOAD line", which a previous boot would satisfy # — not "was there ever a PRELOAD line", which a previous boot would satisfy
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment