re: the voice region s leading chunk is the movie s OWN dialogue, and a guard puts it there
My own leading hypothesis -- that the leading chunk is an in-mission VOICE_D_* line -- is refuted, on the route the port suggested: widen the enumeration past the 95 manifest-bound movies and the byte-span test settles it without anyone listening. Scanning the stream for every trailer descriptor (the (id, 0x11) pair whose id repeats at +0x800) gives the complete cue partition, mission lines included: 287 descriptors in a 116.2 MB window, all 287 carrying an id the 4280-name registry names. Every one of the 17 leading spans is bracketed by desc(N-1)..desc(N) where desc(N) is that movie s OWN cue id. Zero mission lines. The mechanism is a guard in our own resolver. resolve_movie_voice_region takes the predecessor trailer as the region start, guards it with end - start < 1_500_000, and falls back to the .slb TOC anchor when that fails. Cues with a true span over the guard: 17, of which 17 are stream-opening. Cues under it: 78, of which 0. Perfect discrimination both ways. The anchor sits a constant 504464 B after the true predecessor trailer on all 17, which is unexplained. Not established, and stated as such: this does NOT mean the export truncates N seconds. The port s decode already has ADV s region at 359 s against a 137 s movie, so it over-covers and the byte-to-time mapping is not linear. No XMA1 decoder in this container to check. Also withdraws a claim this page had adopted from the port -- that chunks 1 and 2 are two stems of one performance. The port refuted its own claim by decoding: S00A chunk 2 is digital silence, ADV chunk 2 is 0.60x chunk 1 with the residual 26.8 dB down. Equal duration was a shape match and Q10 s music census should not have been carried across to voice on it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
|
||||
**Status:** ✅ the *structure* is decoded, disc-wide, 95/95 regions. 🟡 what the
|
||||
leading chunk **contains** is open, and this page states the reach of that
|
||||
negative rather than guessing.
|
||||
negative rather than guessing. 🔴 One claim this page carried — that chunks 1 and
|
||||
2 are two stems of one performance — is **withdrawn**; see
|
||||
[the bottom of the page](#what-a-consumer-should-do-meanwhile).
|
||||
|
||||
Raised by the port: `media::sound_bank_riffs("BGM_103.slb")` used to return three
|
||||
sub-waves where [`bgm-two-stems`](bgm-two-stems.md) says two, and
|
||||
@@ -75,36 +77,107 @@ where another region ends; **0 of 17** leading-stream regions do.
|
||||
|
||||
So the leading chunk is not another *movie's* voice.
|
||||
|
||||
## 🟡 What it is, is open — and here is the reach
|
||||
## ✅ RESOLVED 2026-08-29 — the leading chunk is the MOVIE'S OWN cue, and the mechanism is a guard
|
||||
|
||||
What is established: the leading chunk is a whole number of XMA1 packets at the
|
||||
disc's own derived data offset, inside this movie's region, claimed by no other
|
||||
movie-voice region. What is **not** established is what it sounds like.
|
||||
The section that stood here left this open and named an in-mission `VOICE_D_*`
|
||||
line as the leading hypothesis. **That hypothesis is refuted.** The port pointed
|
||||
out that the byte-span test already built settles it without anyone listening, if
|
||||
the enumeration is widened past the 95 manifest-bound movies — and it does.
|
||||
|
||||
The reach of the negative, stated plainly:
|
||||
Rather than resolving cues one at a time, scan the stream for **every** trailer
|
||||
descriptor: the `(id: u32be, 0x11, …)` pair whose id repeats at `+0x800`, which
|
||||
[`movie_voice`](../../crates/sylpheed-formats/src/movie_voice.rs) documents as
|
||||
the end of a cue's audio, with a false-match probability of ~2⁻⁶⁴. The full
|
||||
descriptor list **is** the stream's complete cue partition, movie and mission
|
||||
alike. Over a 116.2 MB window covering every region: **287 descriptors, and all
|
||||
287 carry an id the registry names** (4 280 cue names).
|
||||
|
||||
* The census enumerates the **95 movie-voice regions the manifest binds in
|
||||
English**. The same stream also carries the in-mission voice cues
|
||||
(`VOICE_D_*`), which are *not* enumerated here. The leading bytes could belong
|
||||
to one of those, and this test would not see it. **That is the leading
|
||||
hypothesis and it is untested.**
|
||||
* 🔴 **It could not be settled by listening in this container.** There is no XMA1
|
||||
decoder here — `sylpheed-cli audio info` reports `decode not supported (needs
|
||||
an XMA2 decoder + the sound-bank descriptor)`, and its header read of these
|
||||
chunks is visibly wrong (16 channels, 4310 Hz, 2-bit depth), so it cannot even
|
||||
be used for durations. Settling this needs a decoder run, which the port has
|
||||
and this container does not.
|
||||
Tool: `cargo run -p sylpheed-formats --example voice_stream_cue_map -- $SYLPHEED_DISC`,
|
||||
output at [`data/voice-stream-cue-map.txt`](../data/voice-stream-cue-map.txt).
|
||||
|
||||
### The leading span belongs to the movie itself — 17 of 17
|
||||
|
||||
Each leading span is bracketed by `desc(N-1) .. desc(N)`, and in every case
|
||||
`desc(N)` is **that movie's own cue id**:
|
||||
|
||||
| movie | leading span ends at descriptor | |
|
||||
|---|---|---|
|
||||
| `ADV` | id 1600 = `VOICE_ADV` | movie cue |
|
||||
| `S00A` | 1501 = `VOICE_S00A` | movie cue |
|
||||
| `S14A` | 1524 = `VOICE_S14A` | movie cue |
|
||||
| …all 17 | | **movie cue, 0 mission lines** |
|
||||
|
||||
By the stream's own rule — cue N's audio is `[desc(N-1) .. desc(N)]` — those
|
||||
bytes are **this movie's dialogue**. 🔴 So "it is an in-mission `VOICE_D_*` line"
|
||||
is dead, and so is any reading in which the leading chunk is foreign audio.
|
||||
|
||||
### ✅ And the mechanism is `resolve_movie_voice_region`'s own guard
|
||||
|
||||
`resolve_movie_voice_region` takes the predecessor trailer as the region start,
|
||||
but guards it with `end - start < 1_500_000` and falls back to the `.slb` TOC
|
||||
**anchor** when that fails. If the guard is the cause, the stream-opening regions
|
||||
should be exactly the cues whose true span exceeds it:
|
||||
|
||||
| | cues | of which stream-opening |
|
||||
|---|---|---|
|
||||
| true cue span **≥ 1.5 MB** | **17** | **17** |
|
||||
| true cue span **< 1.5 MB** | **78** | **0** |
|
||||
|
||||
**Perfect discrimination, both ways.** A long cue's region does not start at its
|
||||
cue boundary; it starts at the anchor, mid-cue, and everything from the anchor to
|
||||
the next `.slb` `RIFF` becomes the leading chunk. That is the whole phenomenon.
|
||||
|
||||
⚠️ **The anchor sits a constant `504 464 B` after the true predecessor trailer on
|
||||
all 17** — not an approximate constant, the same number every time. That
|
||||
regularity is unexplained and is worth someone's attention; it says the `.slb`
|
||||
chunk boundary is placed at a fixed distance from a trailer.
|
||||
|
||||
### ⚠️ What this does NOT establish — do not convert bytes into missing seconds
|
||||
|
||||
It is tempting to read "504 464 B of the cue's own audio lies outside the region"
|
||||
as *the export truncates 246 packets of dialogue*. **Do not.** The port's decode
|
||||
of `ADV`'s region already yields **359 s against a 137 s movie**, so the region
|
||||
over-covers rather than under-covers, and the byte↔time mapping is plainly not
|
||||
linear — consistent with more than one sub-stream being interleaved. Bytes are
|
||||
what was measured here; seconds are not, and this container has no XMA1 decoder
|
||||
to get them.
|
||||
|
||||
❔ **So what remains open is narrower and better posed than before:** not *whose
|
||||
audio is this* (answered: the movie's own), but *why one cue's byte span decodes
|
||||
to ~2.6× the movie's duration*, and what `ADV` chunk 2 — a 0.60 × scaled copy of
|
||||
chunk 1 — is doing in it.
|
||||
|
||||
## What a consumer should do meanwhile
|
||||
|
||||
🟡 Dropping the leading chunk is **defensible and should stay labelled**, which is
|
||||
what the port already does. It is not junk and it is not a header — it is
|
||||
undecoded audio — so the manifest note must not harden into "the bank had a
|
||||
spurious chunk". If it turns out to be an in-mission line, dropping it is
|
||||
correct; if it turns out to be part of the cutscene, it is a truncation.
|
||||
🔴 **Dropping the leading chunk is dropping the cutscene's own dialogue** — that
|
||||
is now measured, not suspected, and the manifest note must not say or imply that
|
||||
the bank had a spurious chunk. ⚠️ It does **not** follow that simply including it
|
||||
is right: the region already decodes to ~2.6× the movie's length, so inclusion is
|
||||
a decoding question that is still open, and this page has moved it rather than
|
||||
closed it. What is settled is the *provenance* of those bytes.
|
||||
|
||||
⚠️ **Do not "fix" it by concatenating.** The port measured a concatenated region
|
||||
at 359 s against a 137 s movie, and chunks 1 and 2 are the two-stem pattern
|
||||
[`bgm-two-stems`](bgm-two-stems.md) documents for music — equal duration, played
|
||||
together, not in sequence. Concatenation is wrong here for the same reason it is
|
||||
wrong there.
|
||||
at 359 s against a 137 s movie.
|
||||
|
||||
🔴 **But the REASON this page gave was wrong, and is withdrawn (2026-08-29).**
|
||||
It said chunks 1 and 2 are "the two-stem pattern [`bgm-two-stems`](bgm-two-stems.md)
|
||||
documents for music — equal duration, played together". That claim originated
|
||||
with the port, I adopted it here on the strength of equal duration, and the port
|
||||
then refuted its own claim by decoding the content:
|
||||
|
||||
* **`S00A` chunk 2 is digital silence** — 4 497 300 samples, peak −∞. Not a quiet
|
||||
stem. Nothing at all.
|
||||
* **`ADV` chunk 2 is `0.60 ×` chunk 1** — best-fit scalar, residual **26.8 dB
|
||||
below** the target. ~95 % of its energy is a −4.4 dB copy of chunk 1, not an
|
||||
independent performance.
|
||||
|
||||
Equal duration was a *shape* match and Q10's music census should not have been
|
||||
carried across to voice on it. ⚠️ **This is how a wrong belief hardens**: it was
|
||||
asserted in one place, adopted in a second, and the second citing the first would
|
||||
have made it look corroborated. It was caught because the port measured its own
|
||||
claim rather than the other agent's.
|
||||
|
||||
❔ **What `ADV`'s near-duplicate chunk 2 is remains open** — a decoding question,
|
||||
not a port one. What is *not* open is that summing a digitally silent chunk at
|
||||
`1/n` costs 6.02 dB for nothing; the port drops silent chunks before summing,
|
||||
which is arithmetic rather than a content judgement.
|
||||
|
||||
Reference in New Issue
Block a user