port: withdraw my own "two stems" reading of a voice region, and stop summing silence
The Decoder asked me to decode a voice region's leading chunk -- it has no XMA1
decoder in its container -- and the decoder run refuted a claim of mine that it
had already adopted into `docs/re/structures/voice-region-leading-chunk.md`.
I wrote that a region's two equal-length chunks are HANDOFF Q10's decoded
two-stem shape. Equal duration was a SHAPE match and I carried the music census
across on the strength of it. The content does not support it:
S00A chunk 2 is DIGITAL SILENCE -- 4497300 samples, peak -inf.
ADV chunk 2 is 0.60x chunk 1, best-fit scalar, residual 26.8 dB below the
target: about 95% of its energy is a -4.4 dB copy of the first chunk.
That cost real level. Summing chunk 1 with silence at 1/n put S00A's dialogue
6.02 dB down for nothing -- the exported file peaked at -16.2 dBFS against a
source chunk peaking at -4.2. `export_voice` now drops a digitally silent chunk
before the sum, which is arithmetic and not a judgement about content.
WHAT ADV'S NEAR-DUPLICATE SECOND CHUNK IS REMAINS OPEN AND IT IS STILL SUMMED.
Whether the game plays both is a decoding question, 26.8 dB of residual is not
nothing, and dropping a chunk because it correlates with another would be
answering it.
The leading chunk, answered as far as a measurement goes: ADV region + 1392, 394
packets, 84.553 s, stereo 48 kHz, peak -2.48 dBFS, 6 silent gaps over 0.4 s
totalling 45.3 s -- 54% silence, the same duty cycle as the full-length chunks.
Speech-structured, so not a header and not padding. "Cutscene or mission" is an
identification and this agent has no ears and no oracle; envelope correlation
peaks at 0.768 at the last lag in the search range, which is where a statistic
lands when it has found nothing, and it is not an answer.
Not taken yet, and said so in BLOCKED: the discriminator should be
`bank_header_len`, not a duration tie. This exporter never used `riffs.len()`, so
it already handles both of the Decoder's cases, but a tie is an observation and
`bank_header_len` is decoded. It switches when `c1f3608` reaches `main`;
`sylpheed-formats` is a path dependency and merging another agent's topic branch
is not the port's to do.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
@@ -98,6 +98,7 @@ HANDOFF.
|
||||
|---|---|---|---|
|
||||
| P4/P7 — the intro's dialogue | ~~why the intro has no voices~~ | Q9 | ✅ **answered and TAKEN 2026-08-29, and the obvious diagnosis was wrong.** Not a transcode fault: `ADV.wmv` carries music and effects only, and a cutscene's voice is a *separate* continuous XMA stream in `sound.pak` bound by the movie manifest. `audio::export_voice` now resolves it with `media::resolve_movie_voice_region` — never by filename, because `RT01A`'s voice lives inside `VOICE_ADV.slb` and a name match is right on exactly the two movies this port would have spot-checked. Region chunks are **concatenated** (one continuous stream), not summed. This is **decoded, nothing authored**. |
|
||||
| P4/P7 — the movie downmix | **is the exporter allowed to ship a matrix MISSION §6 did not pin?** | — | 🔴 **with the HUMAN, not the Decoder, and now visible for the first time.** §6 pins the 5.1 fold as a human decision of 2026-08-29; `video.rs` has shipped that matrix scaled by **0.4142** since P4 — same weighting, **7.65 dB quieter** — and said so nowhere. Re-measured this iteration with the right instrument (float decode, whole file, count the samples that would clamp, not a peak reading): under the **pinned** matrix `ADV` peaks at **+4.26 dBFS** with **4 406** samples at or over full scale and 1 874 more than 1 dB over, while `S00A` peaks at −1.34 dBFS and **never clips**. So the pin overloads one movie and the exporter's constant is over-broad for the other. Smallest single scalar under which neither clamps: **0.612**, +3.39 dB on today. **Not changed** — the level of a mix is what §6 reserves. The export now carries a manifest warning with these numbers. |
|
||||
| P4/P7 — a voice region's chunks | **what is the leading chunk, and is `ADV`'s near-duplicate second chunk played?** | — | 🟡 **half answered by the Decoder, half by my decoder run, and one of my own claims withdrawn.** Structure is decoded disc-wide, 95/95 regions (`auto/no-disc-and-menu-captures` at `7e12a3b`, `docs/re/structures/voice-region-leading-chunk.md`): 78 regions open with a bank header, 17 with a leading headerless stream at the disc's own `1392 mod 2048` data offset, 0 at a `RIFF` — and **the chunk count discriminates nothing**, 8 header regions also yield three. What the leading chunk *contains* is 🟡, and the Decoder cannot settle it: no XMA1 decoder in that container. I decoded it — `ADV`, 84.553 s, speech-structured, 54 % silence — which says it is dialogue-shaped and says **nothing about whose dialogue**. 🔴 **And it refuted my own "two stems" reading**: `S00A`'s second chunk is digital silence and `ADV`'s is 0.60 × the first with 26.8 dB of residual. The silent one is now dropped (arithmetic — it cost `S00A` 6.02 dB); `ADV`'s near-duplicate is **still summed and still open**. What settles the leading chunk: enumerating the `VOICE_D_*` regions and re-running the Decoder's own byte-span coverage test. |
|
||||
| P4 — is an attract movie skippable at all? | **does the real game let Ⓐ end `ADV`, or does it play through?** | Q9 | 🔴 **a human play-test reports Ⓐ does not skip the port's intro, and the port could not tell which bug that is.** It is *implemented*, not assumed: `authored/flow.json` carries `skippable: true` with a `why` citing Q9 as measured (title at 57 s against a 193 s baseline), and `boot.gd` `_unhandled_input` acts on it. What did not exist was any way to **test** it: `--script` structurally cannot press during a movie, because `_script_settled` waits while `_player != null`. `--skip-at=SECONDS` was added this iteration to close that hole. ⚠️ Two different questions sit behind the one symptom, and only the first is mine: (a) does the synthetic press reach `_unhandled_input` — measurable here; (b) does the **game** permit skipping an attract movie — `INDEX.md` still marks skippability 🟡 and only a capture settles it. If (b) is no, the port's skip path is deleted rather than debugged. Asked 2026-08-29. |
|
||||
| ~~P5 — a real submenu cycle~~ | ~~is any submenu reachable without a new archive?~~ | Q2/Q4 | ✅ **already shipped at P5, and one premise of the ask is refuted by this repo.** `ptbtn05` (EXTRAS) → screen `extras` (entries 6/9), and `extras`' `on_cancel` returns to `main_menu` with focus restored — a full main-menu → submenu → back cycle, in `GP_TITLE`, live since P5. ⚠️ **Build 8 is not a submenu.** It is `main_menu_jp`, the Japanese five-button main menu; `authored/screen_names.json` records that an earlier reading called 8 a submenu and that HANDOFF Q2 **withdrew it** against a capture. That coordinates identical to build 5 mean a language twin rather than a second menu is exactly the inference the port is not allowed to make on layout similarity — in either direction. The other four main-menu items really are blocked: `GP_SAVE_LOAD`, `GP_OPTIONS`, `GP_MISSION_SELECT` and the `DIFFICULTY`/`TUTORIAL_MENU` builds are not in this archive. |
|
||||
|
||||
|
||||
@@ -2592,3 +2592,67 @@ to skip is live**. What that does not cover is a real key event from a focused
|
||||
window, which is the difference between this run and the human's — and, separately,
|
||||
**whether the game permits skipping an attract movie at all** is HANDOFF Q9 and
|
||||
still 🟡. If the answer is no, this path is deleted rather than debugged.
|
||||
|
||||
|
||||
## Refutation of my own two-stem reading — and it had already been adopted elsewhere
|
||||
|
||||
Two hours after writing that a voice region's equal-length chunks are *"HANDOFF
|
||||
Q10's decoded two-stem shape"*, the Decoder asked me to decode the leading chunk
|
||||
— it has no XMA1 decoder in its container — and the decoder run refuted the
|
||||
claim I had made.
|
||||
|
||||
**Equal duration was a shape match, and I carried Q10's *music* census across to
|
||||
voice on the strength of it.** The content does not support it:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| `S00A` chunk 2 | **digital silence** — 4 497 300 samples, peak −inf |
|
||||
| `ADV` chunk 2 | **0.60 × chunk 1** (best-fit scalar), residual **26.8 dB** below the target |
|
||||
|
||||
About 95 % of `ADV`'s second chunk is a −4.4 dB copy of the first. Two chunks of
|
||||
equal length, one silence and the other a scaled near-duplicate, are not two
|
||||
stems of one performance. ⚠️ **The claim had already travelled** — it is quoted in
|
||||
the Decoder's `voice-region-leading-chunk.md` — which is the failure PROTOCOL
|
||||
names: a wrong belief moving faster than its correction, through two documents
|
||||
that share a source.
|
||||
|
||||
### What it cost, and what changed
|
||||
|
||||
Summing chunk 1 with silence at `1/n` put `S00A`'s dialogue **6.02 dB down for
|
||||
nothing**: the exported file peaked at −16.2 dBFS against a source chunk peaking
|
||||
at −4.2. `export_voice` now drops a **digitally silent** chunk before the sum.
|
||||
That is arithmetic, not a content judgement — a silent input contributes nothing
|
||||
to a mix and counting it in the normalisation is simply my error.
|
||||
|
||||
**What `ADV`'s near-duplicate chunk 2 is remains open and it is still summed.**
|
||||
Whether the game plays both is a decoding question; 26.8 dB of residual is not
|
||||
nothing, and dropping a chunk because it correlates with another would be
|
||||
answering it.
|
||||
|
||||
### The leading chunk, decoded — structure, and not one word about content
|
||||
|
||||
The Decoder's ask was *"cutscene dialogue or mission dialogue"*. `ADV` region
|
||||
+ 1392, 394 packets: **84.553 s, stereo, 48 kHz, peak −2.48 dBFS, RMS −24.80**,
|
||||
with **6 silent gaps over 0.4 s below −50 dB totalling 45.3 s** — 54 % silence,
|
||||
the same duty cycle as the two full-length chunks (54 %, 55 %). So it is
|
||||
**speech-structured audio**: not a header, not padding, not noise.
|
||||
|
||||
🔴 **Which is as far as a measurement goes.** *Cutscene or mission* is an
|
||||
identification and this agent has no ears and no oracle. Envelope
|
||||
cross-correlation against the full-length chunks peaks at 0.768 **at the last lag
|
||||
in the search range**, which is where a statistic lands when it has found
|
||||
nothing, and it is not evidence. The Decoder's 🟡 stands, and its own leading
|
||||
hypothesis — an in-mission `VOICE_D_*` line — is untouched by any of this. The
|
||||
byte-span test it already built settles it the moment those regions are
|
||||
enumerated; nobody has to listen.
|
||||
|
||||
### Taken from the same message: `bank_header_len`, not `riffs.len()`
|
||||
|
||||
The Decoder's census warns that eight bank-header regions also yield three
|
||||
chunks, so the chunk count cannot say which structure you are in. **This exporter
|
||||
never used the count** — it selects on decoded duration, which is why it already
|
||||
handles both cases: `RT01A`'s 10 300 B leading chunk decodes to 9 ms and falls
|
||||
out on its own. But a duration tie is an *observation* and `bank_header_len` is
|
||||
*decoded*, so the rule switches the day `c1f3608` reaches `main`.
|
||||
`sylpheed-formats` is a path dependency and merging another agent's topic branch
|
||||
is not the port's to do.
|
||||
|
||||
Reference in New Issue
Block a user