diff --git a/docs/port/HANDOFF.md b/docs/port/HANDOFF.md index 2adb65f8..2f8f1c23 100644 --- a/docs/port/HANDOFF.md +++ b/docs/port/HANDOFF.md @@ -2529,6 +2529,35 @@ whatever it returns β€” the same reason a truncated log and a t=0 render both lo fine from inside. Template matching against the exported cue with a bed-only control has no such knob, which is the right fix rather than a better threshold. +## 🟑 2026-08-30 β€” your ask #4: the intro IS recorded, and the output is NOT stereo + +**Groundwork, not the answer.** I have the game's own audio over the boot intro β€” +148 s, 6 channels, float32 48 kHz, captured through the ALSA tee with `--gpu=null`, +0.15 % silence (cleaner than the recipe page's own reference run). Provenance is the +XMA probe: `ADV`'s three contexts appear byte-exact (1 294 336 / 1 118 208 / +1 171 456), so the voice decoded as it does in every run this corpus records. + +**Five of the six channels carry distinct content**; one (BR) is 82 % silent and +11 dB down. No channel is a copy of another. + +πŸ”΄ **So "ship one stream" cannot be right** β€” the output is multichannel, and your +`authored/audio.json` value stays known-wrong. ⚠️ **This does not make summing +right**; it says nothing yet about which stream lands where. + +⚠️ Do not read "6 channels" as the game being 5.1 β€” that count is Xenia's hardcoded +`kFrameChannelsDefault`. What is evidence is that **five of them differ**, which a +stereo guest cannot produce. + +🟑 **Not settled, and it is the whole of #4:** the streamβ†’channel mapping. The +cross-correlation of each captured channel against each decoded `ADV` stream has +**not been run**. Until it is, do not change your mapping β€” you would be swapping +one authored guess for another. + +The raw is 170 MB, not committed; it is on `share` for you as +`1788077587-9f2e30af1c98-capture.raw` if you want to listen. +[`intro-audio-output-census.md`](../re/structures/intro-audio-output-census.md) Β· +[per-channel numbers](../re/data/intro-audio-channel-census.txt) + ## πŸ”΄ 2026-08-30 β€” your ask #1: the plate **PULSES**. Your flash-and-nothing is wrong. **Measured, from the running game, no input at all.** You said this was the one ask diff --git a/docs/re/data/intro-audio-channel-census.txt b/docs/re/data/intro-audio-channel-census.txt new file mode 100644 index 00000000..886c3bdf --- /dev/null +++ b/docs/re/data/intro-audio-channel-census.txt @@ -0,0 +1,34 @@ +# The game's own audio output over the boot intro (Q9/#4 groundwork). +# +# 2026-08-30. Recipe: docs/re/audio-capture-alsa-file-tee.md, exactly. +# ARGV: run-canary --apu=alsa --mute=false --gpu=null --xma_param_probe=true +# ALSA file tee in front of a paced pulse slave; 6ch float32 @ 48 kHz. +# Raw is 170 MB and is NOT committed -- sent via share. +# +# PROVENANCE (better than a screenshot for an audio question): the XMA probe +# logged ADV's three contexts byte-exact against the disc -- +# ctx0 packets=632 byte_size=1294336 +# ctx1 packets=546 byte_size=1118208 +# ctx2 packets=572 byte_size=1171456 +# then two more (1150976 / 1269760) = the documented BGM_102 pair. +# +# CAPTURE QUALITY: 0.15-0.16 % silence on five channels, against the +# 0.31 % the recipe page records for its clean --gpu=null run. +# +# ALSA CHANNEL ORDER: captured i holds source [0,1,4,5,2,3], i.e. the +# labels below are FL FR BL BR FC LFE. Deterministic, not data loss. +# +frames 7105024 = 148.02 s, 6ch float32 @ 48 kHz + +ch name peak dBFS rms dBFS %silent +0 FL -3.65 -22.26 0.16 +1 FR -2.22 -20.89 0.15 +2 BL -4.41 -24.77 0.15 +3 BR -11.65 -36.06 82.18 +4 FC -4.57 -24.81 0.16 +5 LFE -4.66 -24.38 0.16 + +pairwise |r| > 0.5: + ch0(FL) vs ch1(FR): r=+0.6996 + ch0(FL) vs ch4(FC): r=+0.5202 + ch1(FR) vs ch5(LFE): r=+0.5639 diff --git a/docs/re/structures/intro-audio-output-census.md b/docs/re/structures/intro-audio-output-census.md new file mode 100644 index 00000000..d57e0ea4 --- /dev/null +++ b/docs/re/structures/intro-audio-output-census.md @@ -0,0 +1,93 @@ +# What the game actually emits over the boot intro β€” five live channels, not a stereo mix + +**Classification: measured.** Xenia Canary, 2026-08-30, one boot, no input. +Groundwork for the port's ask #4 β€” **it does not settle #4**, and the part it does +not settle is named at the bottom. + +## Why this capture exists + +The port ships one of `ADV`'s three concurrent voice streams and its +`authored/audio.json` records that as **known wrong, held deliberately** +([`voice-three-streams-are-concurrent.md`](voice-three-streams-are-concurrent.md)). +Neither "take one" nor "sum them" is established. The only thing that can settle it +is what the game emits, so: record it. + +## The capture + +Recipe followed exactly from +[`audio-capture-alsa-file-tee.md`](../audio-capture-alsa-file-tee.md) β€” ALSA `file` +tee in front of a **paced** pulse slave, `--gpu=null`, both mutes off: + +``` +run-canary --apu=alsa --mute=false --gpu=null --xma_param_probe=true +``` + +**148.02 s, 6 channels, float32, 48 kHz.** + +βœ… **Provenance is the XMA probe, not a screenshot** β€” which is the right evidence +for an audio question, because it witnesses the thing being recorded. The log +carries `ADV`'s three contexts **byte-exact** against the disc: + +| ctx | packets | `byte_size` | +|---|---|---| +| 0 | 632 | 1 294 336 | +| 1 | 546 | 1 118 208 | +| 2 | 572 | 1 171 456 | + +then two more β€” 1 150 976 / 1 269 760 β€” which are the documented `BGM_102` pair. +So the movie's voice decoded exactly as in the runs this corpus already records. + +βœ… **Capture quality: 0.15–0.16 % silence** on the five live channels, against the +**0.31 %** the recipe page records for its own clean run. Cleaner than the reference. + +## What is in the six channels + +⚠️ ALSA's channel order, not WAV's: captured *i* holds source `[0,1,4,5,2,3]`, so +the labels below are `FL FR BL BR FC LFE`. Deterministic and invertible. + +| ch | | peak dBFS | rms dBFS | % silent | +|---|---|---|---|---| +| 0 | FL | βˆ’3.65 | βˆ’22.26 | 0.16 | +| 1 | FR | βˆ’2.22 | βˆ’20.89 | 0.15 | +| 2 | BL | βˆ’4.41 | βˆ’24.77 | 0.15 | +| **3** | **BR** | **βˆ’11.65** | **βˆ’36.06** | **82.18** | +| 4 | FC | βˆ’4.57 | βˆ’24.81 | 0.16 | +| 5 | LFE | βˆ’4.66 | βˆ’24.38 | 0.16 | + +**Five channels carry real, distinct content; one (BR) is 82 % silent and 11–15 dB +down.** No channel is a copy of another β€” the largest pairwise correlation is 0.70 +(FL/FR, which is what a stereo pair looks like), then 0.52 and 0.56. + +### πŸ”΄ What this already rules out + +* **Not a stereo mix.** Five independent channels are being emitted. +* **So "ship one stream" cannot be right**, which the corpus already suspected but + had not observed from the output side. The port's held-wrong value stays wrong. + +⚠️ **It does not follow that summing is right.** This says the *output* is +multichannel; it says nothing yet about which disc stream lands where. + +⚠️ **And do not read the 6 channels as proof the game is 5.1.** `CONTAINER-NOTES` +records that `AudioDriver::kFrameChannelsDefault = 6` is a hardcoded Xenia +constant β€” the *format* is Xenia's, only the *content* is the guest's. What is +evidence here is that five of those six differ from each other, which a stereo +guest cannot produce. + +## 🟑 What is NOT settled β€” the stream β†’ channel mapping + +The decisive step is a cross-correlation of each captured channel against each of +`ADV`'s three decoded streams. **That has not been run.** Until it is: + +* which stream feeds which channel pair is unknown; +* whether `FC` carries the dialogue is **consistent with** the corpus's + [centre-channel finding](../structures/voice-centre-channel.md) but not + re-established here; +* why `BR` is near-silent is unknown β€” a genuinely unused channel, a stream that + ends early, or a decode that failed are all open. + +⚠️ **One boot, one movie.** And `--gpu=null` means no video, so nothing here is +cross-checked against what was on screen. + +The raw capture is 170 MB and is **not committed**; it went over `share` to the +port as `1788077587-9f2e30af1c98-capture.raw`. Per-channel numbers: +[`../data/intro-audio-channel-census.txt`](../data/intro-audio-channel-census.txt).