diff --git a/docs/agents/CONTAINER-NOTES.md b/docs/agents/CONTAINER-NOTES.md index 583dddd7..7d8dae19 100644 --- a/docs/agents/CONTAINER-NOTES.md +++ b/docs/agents/CONTAINER-NOTES.md @@ -84,8 +84,18 @@ python3 tools/re-capture/gmem.py find hex:820af844 400 ✅ **The working route is `--apu=alsa` with an ALSA `file` tee in front of a paced slave** — full recipe, controls and three configuration traps in [`audio-capture-alsa-file-tee.md`](../re/audio-capture-alsa-file-tee.md). - ⚠️ A *bare* file tee free-runs at ~250× real time and wrote **7.3 GB in 50 s**; - the slave must pace. Always run with a size guard. +* 🔴 **A BARE ALSA `file` tee WILL FILL THE DISK — always run a size guard.** + Xenia's ALSA writer thread pads silence whenever its ring is empty + (`alsa_audio_driver.cc:359`), so against a device that never blocks it + free-runs: measured at **~250× real time, 7.34 GB in 50 seconds**. The slave + must pace — `slave.pcm { type pulse }` — and the capture loop should abort + above ~3× real time. The next person to try a bare tee hits this in the first + minute. +* ✅ **And use `--gpu=null` for an audio capture.** It is what takes the guest + from 0.70× to **0.96×** real time, which stops Xenia padding at all: 0.31 % + silence and 0.01 gaps/s, against 9.98 % / 8.37 rendered. ⚠️ No video, so + screen-based provenance is unavailable (use the XMA probe), and `--gpu=null` + runs here die at ~70 s with `PM4_DRAW_INDX: Failed in backend`. ⚠️ **Do not read Canary's 6-channel PulseAudio stream as evidence the GAME is 5.1.** `pactl` will show `float32le 6ch 48000Hz`, channel-mapped to a full 5.1 diff --git a/docs/re/audio-capture-alsa-file-tee.md b/docs/re/audio-capture-alsa-file-tee.md index 64842ef1..7a0d0355 100644 --- a/docs/re/audio-capture-alsa-file-tee.md +++ b/docs/re/audio-capture-alsa-file-tee.md @@ -170,6 +170,32 @@ ffmpeg -f f32le -ar 48000 -ac 6 -i capture.raw out.wav # float32, not s16 use the XMA probe instead. And it is only appropriate when the question is about audio; it changes what the guest is doing. +## ✅ The distinction that makes even an imperfect tee capture usable + +Contributed by the port, and it is sharper than the framing this page had: + +* **PulseAudio's monitor SUBSTITUTES.** Audio that existed is *replaced* by + silence to keep the wall clock. Information is destroyed, and deleting the + holes cannot recover it — it only compresses time unevenly. +* **Xenia's padding is ADDITIVE.** The silence is *inserted between* samples the + guest emitted. **Nothing is lost.** Every real sample is present and in order. + +So **stripping all-channel-zero runs from an ALSA-tee capture is exact, not a +repair** — it returns a contiguous stream of everything the guest produced. That +means even the 0.70×-real-time rendered capture (9.98 % padded) is usable for +correlation, where none of the PulseAudio-monitor captures ever were, however +they were tuned. + +⚠️ **Unverified as of writing** — the port is controlling it before relying on +it, by padding a known source to match and checking the stripped result +correlates back. The mechanism says it should; the control is what will settle +it. + +⚠️ **Consequence for `check-capture`:** its silence/gap-rate rule was built when +only *damage* existed, and **cannot distinguish genuine emulator padding from +capture damage.** A FAIL on an ALSA-tee capture is a statement about the +recording path, not about the file's usability. + ## Consequences for verification 🔴 **Short file becomes the failure mode**, so a capture check needs an