task-39: retract the HiFi-capture-is-dead finding
HiFi captures fine - 204136 nonzero, peak 32726 - once the channel map is clean. The zeros were stale SLIM map state, which PAF/audio.md already documents as the alternation law and the post-call unmapped-leg bug, and the TX7 poke used to "test the decimator" recreated that bug on all three AIFs. Device is back on HiFi; the Voice Call workaround is reverted.
This commit is contained in:
parent
05c03acbe7
commit
a711ce48cd
1 changed files with 34 additions and 75 deletions
|
|
@ -136,81 +136,40 @@ pipewire, pipewire-audio and wireplumber — while the device is in fact running
|
|||
pipewire, pipewire-pulse and wireplumber. Reconcile which is true before
|
||||
building policy on either.
|
||||
|
||||
## The HiFi profile captures pure silence (measured 2026-08-02)
|
||||
## RETRACTED — "HiFi capture is dead" was wrong (2026-08-02)
|
||||
|
||||
**`HiFi` capture is dead, and not subtly: 92133 frames, peak `0`.** Exactly
|
||||
zero, not a low level — the stream runs and the ADC delivers nothing. This is
|
||||
why STT on the keyboard has no microphone.
|
||||
**This section previously concluded that `HiFi` capture is structurally silent
|
||||
and that the DMIC needs the Q6 voice session. Both claims are false.** With the
|
||||
channel map cleaned up, HiFi capture reads **235520 frames, 204136 nonzero,
|
||||
peak 32726** through its normal `DMIC4 -> DEC5 -> TX5 -> SLIMBUS_0_TX ->
|
||||
hw:0,1` route. Speaker and mic both work on `HiFi`; the
|
||||
`Voice Call (Mic, Speaker)` workaround is not needed and was reverted.
|
||||
|
||||
The codec routing in `HiFi` is *correct*, which is what makes it a real bug
|
||||
rather than a missing mixer line:
|
||||
**What actually happened, and it is already documented in `PAF/audio.md`:**
|
||||
|
||||
DMIC MUX5 = DMIC4 CDC_IF TX5 MUX = DEC5 ADC MUX5 = DMIC
|
||||
DEC5 Volume = 84 AIF1_CAP Mixer SLIM TX5 = on
|
||||
MultiMedia2 Mixer SLIMBUS_0_TX = on (front end, on in both profiles)
|
||||
- The zeros were **stale SLIM channel-map state**, not a missing route. audio.md
|
||||
names both mechanisms: the *alternation law* ("a SLIM TX capture produces
|
||||
samples only when its channel map differs from the previous capture session's
|
||||
map; re-opening with the identical map always reads zeros") and the
|
||||
post-call leak where "TX5 and TX7 both stayed mapped into `AIF1_CAP`,
|
||||
SLIM_0_TX carried two channels into a mono front-end, and capture read exact
|
||||
zeros."
|
||||
- **The diagnosis then made it worse.** Enabling `AIF1_CAP Mixer SLIM TX7`
|
||||
alongside TX5 to "test the decimator" recreated that exact two-channel
|
||||
condition — on all three AIFs — and **no UCM DisableSequence ever unmaps
|
||||
TX7**, so it persisted. Clearing TX7 and cycling the verb restored capture.
|
||||
- The "11-control diff" reasoning was therefore measuring my own contamination,
|
||||
and the elimination of TX5/TX7 as a cause is void.
|
||||
|
||||
Forcing the capture onto the **TX7** decimator — the exact chain the call
|
||||
profile uses (`DMIC MUX7=5`, `CDC_IF TX7 MUX=2`, `DEC7 Volume=124`,
|
||||
`AIF1_CAP Mixer SLIM TX7=on`) — still yields peak `0`. So it is **not** the
|
||||
decimator, and not the front-end mixer.
|
||||
**Method lesson, which is the repo's own standing warning:** this was derived by
|
||||
diffing mixer state instead of reading `PAF/audio.md`, which had the answer
|
||||
written down since 2026-07-19. Read the doc first; a confident architecture
|
||||
built from `amixer` diffs is exactly the failure mode `CLAUDE.md` warns about.
|
||||
|
||||
Only **11** mixer controls differ between `HiFi` and `Voice Call (Mic, Speaker)`.
|
||||
After eliminating the TX5/TX7 pairs, what remains is
|
||||
`QUAT_TDM_RX_0 Voice Mixer VoiceMMode1` and
|
||||
`VoiceMMode1 Capture Mixer SLIMBUS_0_TX` — i.e. the DMIC only produces data
|
||||
while the **Q6 voice session** is up. That is the thing to chase; do not
|
||||
re-litigate the decimator, it is measured and ruled out.
|
||||
|
||||
**Working configuration today: `Voice Call (Mic, Speaker)`.** It carries the
|
||||
`Both CS35L36 amps, speakerphone` output *and* a live DMIC4 capture, and it
|
||||
survives a wireplumber restart. That is a workaround, not the answer — it holds
|
||||
the modem voice path open (`VoiceMMode1`) for ordinary media use, whose power
|
||||
and call-interaction cost is unmeasured.
|
||||
|
||||
**Capture gain belongs in the UCM.** The voice verb sets `DEC7 Volume=124`,
|
||||
which gives a flat noise floor at rms ~14000 with no speech variation at all;
|
||||
84 drops it to ~6200. A runtime `amixer cset` does **not** persist — activating
|
||||
the profile reapplies the UCM value, verified. Whatever gain STT wants has to
|
||||
land in `souveraine-ucm-blueline`.
|
||||
|
||||
## The in-call speaker button routes to a headset (root cause, 2026-08-02)
|
||||
|
||||
Casey, observed: an inbound call **defaulted to speakerphone**, and tapping the
|
||||
speaker button (to *turn on* speakerphone) **switched to headset mode**.
|
||||
|
||||
Not mysterious once the ownership is traced:
|
||||
|
||||
- `gnome-calls` is the dialer, and its speaker button calls the D-Bus name
|
||||
`org.mobian_project.CallAudio`.
|
||||
- That name is owned by upstream **`callaudiod`**
|
||||
(`/usr/share/dbus-1/services/org.mobian_project.CallAudio.service`,
|
||||
`Exec=/usr/bin/callaudiod`), which is D-Bus activated on demand.
|
||||
- **callaudiod cannot route this card.** It switches a sink *port* and needs a
|
||||
speaker port and an earpiece port on one sink; ACP models UCM devices as one
|
||||
profile per combination — `Voice Call (Earpiece, Mic)` and
|
||||
`Voice Call (Mic, Speaker)` — so no sink carries both. `blueline-callaudio-hook`
|
||||
already says this in a comment; the consequence was never written down.
|
||||
- So the button asks for a port that does not exist and lands on a headset
|
||||
route. **The working toggle already exists and nothing in the UI calls it:**
|
||||
`blueline-callaudio-hook speaker on|off` does direct mixer writes and is
|
||||
verified working (`speaker: on` / `speaker: off (earpiece)`).
|
||||
|
||||
`souveraine-callaudio` ships only the hook — it does **not** contest the D-Bus
|
||||
name, so callaudiod always wins.
|
||||
|
||||
**The fix is a shim that claims `org.mobian_project.CallAudio`** and translates
|
||||
`EnableSpeaker`/`SelectMode` into the hook's `speaker on|off`. It must be tested
|
||||
against a real inbound call before it is enabled: this path is phone calls, and
|
||||
a broken shim loses them entirely.
|
||||
|
||||
Until then the manual escape is `sudo blueline-callaudio-hook speaker on`.
|
||||
|
||||
Note the default-to-speakerphone half is a *separate* symptom: `apply()` forces
|
||||
Earpiece deliberately ("enabling Speaker here is what made every call come out
|
||||
of the loudspeaker with no way back"), and the hook is enabled, active and
|
||||
unshadowed (`FragmentPath=/usr/lib/systemd/system/...`). So something else put
|
||||
the card in a speaker profile before or during that call — unreproduced, and it
|
||||
needs a call to chase.
|
||||
**Still genuinely open** (unchanged by the above): capture gain lives in the UCM
|
||||
(`DEC5 Volume 84` for HiFi), runtime `amixer` does not survive profile
|
||||
activation, and nothing re-arms a stale map automatically — a verb switch that
|
||||
leaves a leg mapped still costs you the microphone.
|
||||
|
||||
### Prior art: this has been attacked before — read the branches first
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue