port: the voice is in the mix, proved by a null control that needed no test code

Three things verified against the re-export, none of them by reading the source.

THE STEM READING IS CORROBORATED BY A NUMBER IT WAS NOT FITTED TO. Chunks are
selected as "the longest, and everything tying with it" -- the movie's own length
is not an input to that rule. The result now matches the picture to -0.114 s
(ADV) and -0.085 s (S00A), where the concatenated version was +221 s and +161 s.

THE VOICE REACHES THE MASTER BUS. `+ voice ADV` in the log proves only that a
stream was found and played. The control is MODDING rule 4: 140 s of silence at
data/mods/audio/voice/ADV.ogg shadows the exported file and changes nothing else,
so no test-only flag was added to the runtime. The muted run reproduces the
movie's own bed to 0.01 dB peak and 0.19 dB RMS; the unmuted run measures -22.913
dBFS RMS against -23.184 predicted for two incoherent sources at -24.941 and
-27.965. 0.27 dB out.

(A) SKIPS THE INTRO IN THIS BUILD. `--skip-at=25` ends the movie at 25.02 s
through `Input.parse_input_event` and `_unhandled_input`, so the press-to-skip
wiring is live and the play-test's report is not that bug. Untested here: a real
key from a focused window. Unsettled anywhere: whether the GAME permits skipping
an attract movie -- Q9, still amber, and if the answer is no this path is deleted
rather than debugged.

`check` accepts the new `voice` kind and holds it to the strict peak bound, with
`bgm`, because it is a sum this exporter produced rather than a wave off the
disc. FORMAT.md says what a `voice` entry is, that it keys by MOVIE NAME rather
than by a role, and that its `why` names every chunk dropped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
Sylpheed port agent
2026-08-29 14:56:35 +00:00
parent 3aa74ea029
commit 18412e6324

View File

@@ -2550,3 +2550,45 @@ manifest warning with these numbers. Before this, a reader of the manifest could
not tell that a pinned human decision had been overridden at all — the command
line was recorded faithfully, and recording the command you ran does not disclose
that it is not the command you were given.
### The voice reaches the output, and a null control says so quantitatively
`+ voice ADV` in the log proves only that `play_voice` found a stream and called
`play()`. Whether the audio arrives at the Master bus is a different question,
and `docs/port/AUDIO-VERIFICATION.md` §2 exists because it is.
The control needed **no test-only code**: MODDING rule 4 already shadows any
exported asset by path, so 140 s of silence dropped at
`data/mods/audio/voice/ADV.ogg` mutes the dialogue and changes nothing else. Two
`--boot --skip-at=25 --audio=…` runs, then `astats` over the same 14 s of movie:
| | peak | RMS |
|---|---|---|
| `ADV.ogv`'s own audio (the bed) | 6.239 | 24.941 |
| the exported voice alone | 7.614 | 27.965 |
| **run with the voice muted** | **6.251** | **25.126** |
| **run with the voice playing** | **5.415** | **22.913** |
The muted run reproduces the bed to **0.01 dB peak / 0.19 dB RMS**, which is what
makes the other row worth reading. And the mixed run is not merely *louder*: two
incoherent sources at 24.941 and 27.965 dBFS predict a sum at **23.184**, and
the run measures **22.913** — **0.27 dB** out. The voice is in the mix, at the
level its own file says it should be.
⚠️ **Under the Dummy driver.** Per AUDIO-VERIFICATION, *"recorded under a dummy
driver"* is a weaker claim than *"heard"*, and no measurement here says the
recording is the **right** dialogue for this cutscene — only that the file the
exporter resolved is the one reaching the output at the expected level. The two
runs are also not sample-aligned (they differ by 1.7 s of wall clock), which is
why the `RMS trough` column is omitted: it moved by 40 dB between runs on window
placement alone, and peak and RMS are the two numbers that survive that.
### Ⓐ *does* skip the intro in this build, so the play-test's report is not this bug
`--skip-at=25` on a `--boot` run: `video skipped at 25.02 s`, `video ended at
25.02 s`, title at 25.02 s. The press goes through `Input.parse_input_event` and
arrives at `_unhandled_input` exactly as a pad's would, so **the wiring from press
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.