aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/specs/2026-07-06-audio-panel-signal-metering-spec.org10
1 files changed, 8 insertions, 2 deletions
diff --git a/docs/specs/2026-07-06-audio-panel-signal-metering-spec.org b/docs/specs/2026-07-06-audio-panel-signal-metering-spec.org
index 21444cf..f23e97d 100644
--- a/docs/specs/2026-07-06-audio-panel-signal-metering-spec.org
+++ b/docs/specs/2026-07-06-audio-panel-signal-metering-spec.org
@@ -65,7 +65,7 @@ The parent panel already carries the widgets to express both (the INPUT/OUTPUT l
** Scope tiers
- v1: activity flag in engine; three-state aggregate INPUT/OUTPUT lamps; peak-fed twin VU needles for default sink + default source; panel-open-gated metering; per-device-keyed engine.
- Out of scope: bar-indicator live peak; per-app metering; VU calibration UI.
-- vNext (log to todo.org): per-device rows each with an activity lamp + peak meter (option 3) — a GUI change over the same engine; uncorked-stream refinement of the activity flag (see Decisions).
+- vNext (log to todo.org): per-device *live level meter* — one =parec= reader per active device on each row (the activity *lamp* part of option 3 shipped in Phase 5); uncorked-stream refinement of the activity flag (see Decisions).
* Design
@@ -164,7 +164,8 @@ Add =panel.control_active(control)= and =panel.control_lamp3(control)= (=muted=
** Phase 3 — Peak engine: per-device peak reader
New GTK-free =peak.py=: =PeakReader(device_name, kind)= (spawns =parec= at native rate + low =--latency-msec= in its own process group, reads/reduces flush windows, validity-guards the name) and a =PeakMeter= manager keyed by device name (start/stop/read, kills each reader's process group on stop). Pure ballistics in =viewmodel.peak_fraction()= (decimate window-peaks to the display rate, normalize, attack/decay, noise floor). TDD with a fake =parec= on PATH emitting scripted float windows + pure math unit tests, plus a reader-lifecycle test asserting the process group is reaped. Nothing renders it yet — tree works.
-** Phase 4 — GUI: live peak needles + lifecycle
+** Phase 5 — per-device activity lamp (option 3, GUI-only)
+Promoted from vNext at Craig's request right after Phase 4. Each OUTPUTS/INPUTS row leads with its own three-state activity lamp (=viewmodel.device_lamp3(dev)= → =lamp3_class=): muted (red) / live-idle (dim) / live-active (bright green) for THAT device, so the panel shows which specific output/input is carrying audio, not just the default. Pure GUI + a pure viewmodel helper over the per-device =state= field already shipped in Phase 1 — no engine change, no new processes, rebuilt with each row on the status refresh. The per-row *live level meter* (N =parec= readers, one per active device) is the heavier remaining increment, still deferred.
Repoint =gui._set_vu= from =viewmodel.vu_fraction(volume)= to the peak source via =viewmodel.peak_fraction=. Start the =PeakMeter= (default sink's monitor + default source) when the panel is shown; tear it down from a =close-request= handler *and* =do_shutdown= (the real quit path — the app quits when its last window closes), pushing peaks to the needles via =GLib.idle_add=. Update the AT-SPI smoke to assert the meter starts on show and that a window-close/app-quit leaves no =parec= child. Ships windowed signal metering (aggregate).
* Acceptance criteria
@@ -224,3 +225,8 @@ Unit: =pactl._device()= state parsing (each state + missing); =panel.control_act
- What: built all four phases TDD in the dotfiles audio/ package and flipped the spec IMPLEMENTED. Phase 1 pactl state capture (6054d3d); Phase 2 three-state activity lamp + viewmodel.lamp3_class + CSS (174ce14); Phase 3 peak.py windowed-peak engine + viewmodel.peak_fraction + fake-parec harness (55ab9f9); Phase 4 live VU needles + PeakMeter lifecycle + config keys + smoke orphan-check (21437b4). Audio suite 124→161; full make test green (49 suites); no-orphan reaping unit-tested.
- Why: complete the no-approvals speedrun through to shipped code.
- Artifacts: dotfiles commits 6054d3d..21437b4; manual-testing task filed in archsetup todo.org.
+
+** 2026-07-06 Mon @ 11:10:00 -0500 — Claude Code (archsetup) — implementer
+- What: promoted the per-device activity lamp (option 3) from vNext to shipped (Phase 5). viewmodel.device_lamp3 + a leading three-state lamp on every OUTPUTS/INPUTS row; dotfiles 1faae65. Audio suite 161→166. Verified live via geometry-cropped grim: with a tone to the default sink, pactl reads it RUNNING (others SUSPENDED) and the row lamps render red=muted / green=live per device. The per-row live level meter (N parec) stays the deferred vNext.
+- Why: Craig wanted the per-device view; the engine was already keyed per device so this was a GUI-only follow-on.
+- Artifacts: dotfiles 1faae65; smoke green; manual check added to todo.org.