diff --git a/docs/re/audio-capture-alsa-file-tee.md b/docs/re/audio-capture-alsa-file-tee.md index 4ddfb2a4..f41ef21a 100644 --- a/docs/re/audio-capture-alsa-file-tee.md +++ b/docs/re/audio-capture-alsa-file-tee.md @@ -94,6 +94,43 @@ ffmpeg -f s16le -ar 48000 -ac 6 -i capture.raw out.wav `--apu=nop` stalls the guest in the intro movie still stands and is why `--mute=true` was there; it says nothing about the ALSA backend. +## ✅ Measured on Canary — and the residual silence changes meaning + +150 s boot, `--apu=alsa --mute=false`, tee in front of the paced pulse slave. +⚠️ **Xenia's ALSA driver is `SND_PCM_FORMAT_FLOAT_LE`** (`alsa_audio_driver.cc:173`) +and its log confirms `ALSA initialized: 48000 Hz, 6 channels (output: 6), +period: 512, buffer: 2048`. The raw tee is therefore **float32, 6 channels** — +reading it as `s16` produces a plausible-looking file with a giveaway signature: +peaks alternating exactly `−0.00 / −4.82 / −0.00 / −4.82 / −0.00 / −4.82`, which +is the two halves of each float landing in alternate "channels". + +| capture route | silence | gaps/s | notes | +|---|---|---|---| +| PulseAudio monitor, xenia default (~5.3 ms) | 39.3 % | 30.5 | | +| PulseAudio monitor, `PULSE_LATENCY_MSEC=200` | 15.6 % | 3.5 | | +| PulseAudio monitor, `PULSE_LATENCY_MSEC=500` | 50.1 % | 1.3 | | +| **ALSA tee → paced pulse slave** | **9.98 %** | 8.37 | 106.2 s captured over ~151 s wall = **0.70× real time** | + +**The file is short rather than gap-riddled, which is the intended trade** — and +six distinct channels, no duplicates, sensible peaks (−4.41 / −3.96 / −4.41 / +−11.65 / −8.09 / −6.53 dBFS). + +🔴 **But the residual ~10 % silence is NOT removed, and its meaning has changed.** +It is no longer invented by PulseAudio's monitor — the tee records exactly what +Xenia wrote, and **Xenia wrote silence**, because its writer thread pads whenever +the guest has not filled the ring (`alsa_audio_driver.cc:359`). So: + +* ✅ the capture is now **faithful** — every sample in it is a sample the + emulator emitted; +* ❔ the emulator is still emitting padding, because the guest runs at ~0.7× real + time here, and **no capture method can remove that**. Fixing it needs the guest + to keep up, or a change to the driver's padding behaviour. + +⚠️ **So this is a 3.9× improvement in silence and a change of attribution, not a +clean capture.** At 9.98 % / 8.37 gaps/s it sits right on the port's "≥10 % +silent *and* ≥1 gap/s" fail bar. **Do not treat it as an oracle without saying +which side of that line it fell on.** + ## Consequences for verification 🔴 **Short file becomes the failure mode**, so a capture check needs an