re: the voice decoder discards up to 87% of a bank — "multi-subwave" refuted

The record table gives a DIRECT binding hokyu_DS_s13A -> VOICE_D_452, where
the corpus records the movie as unbound and movie_manifest_disc.rs asserts
None, citing an in-game verdict that this exact value was "the wrong
recording". That is the only place on the disc where a runtime observation
disagrees with the record table, so it was worth settling.

First, shape: these banks are SHARED. Five slots bind VOICE_D_452, five bind
451, four 450, four 453, three 454 -- 21 hokyu slots over five banks, and the
movies repeat too. Generic resupply cutscenes, not per-stage recordings.

The recorded explanation for 453 decoding to 0.14 s and 454 to 0.43 s was
that the banks are "likely multi-subwave / not cleanly sliced". Refuted: the
count of RIFF magics EQUALS the number of sub-waves recovered in all five
banks, and the last data chunk ends exactly at EOF in four of them. Nothing
between or after sub-waves is being missed.

The real defect: slb::to_xma_riffs finds audio by searching for the RIFF
magic, and a large region PRECEDES it. 87% of VOICE_D_453 and 85% of
VOICE_D_454 sit in front of the first RIFF -- 21-27% zero over 256 distinct
byte values, i.e. content, not padding. VOICE_D_451 is the control: its
leading region is 100% zero, 1 distinct value, real padding.

So the in-game verdict listened to a decode that had discarded most of the
bank, for exactly this bank class. It is evidence about the decoder, not
about the mapping. Note also that what was rejected was a value INFERRED
from a shared demo id; the record table supplies the same value as a stored
field, and only the inference was ever tested.

This does NOT establish the binding is right -- it removes the only recorded
evidence against it. What the leading region actually holds is undecoded, and
confirming the binding needs a human listening.

Artifact: examples/voice_bank_shape.rs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
This commit is contained in:
Sylpheed RE agent
2026-08-25 23:03:33 +00:00
parent 75f0664bfe
commit 49c00e0955
4 changed files with 196 additions and 3 deletions

View File

@@ -1033,6 +1033,24 @@ premise was wrong.**
Candidates: the **7 `.embsec_` sections** (VAs 0x84D00000x86AC000, ~129 KB
total, executable) or a hashed record in `hidden/MiscBin.pak`. **Finding it
gives the actual per-phase clear condition for every stage.**
***(2026-08-25) The `.slb` "multi-subwave" guess is REFUTED, and the voice
decoder is discarding up to 87 % of a bank.** The record table gives a
**direct** binding `hokyu_DS_s13A -> VOICE_D_452` where the corpus records the
movie as unbound and a test asserts `None`, citing an in-game verdict that the
same value was "the wrong recording". Measured: the RIFF-magic count equals the
sub-wave count in all five hokyu banks, so nothing between or after sub-waves
is missed — the recorded "likely multi-subwave / not cleanly sliced" is wrong.
The audio is lost because a **large region precedes the first RIFF** and
`slb::to_xma_riffs` finds audio by searching for that magic: **87 % of
`VOICE_D_453` and 85 % of `VOICE_D_454`** sit in front of it, 2127 % zero over
256 distinct byte values — content, not padding. `VOICE_D_451` is the control,
its leading region being 100 % zero / 1 distinct value. 🟡 So the in-game
verdict tested a decode that had thrown away most of the bank and is **not**
evidence against the binding — though it does not confirm it either.
▶️ First step: decode the leading region (it is not padding and not a RIFF —
directory? seek table? raw stream?). Then a human has to listen; audio
judgement cannot be done in this container. See
[`voice-bank-leading-region.md`](voice-bank-leading-region.md).
***(2026-08-25) My own boot-nav diagnosis, MEASURED AND WITHDRAWN.** I said
the run died because `skip_intro.sh` gates the title test at `rmse <= 1500`
and the run logged 1503/1549, just above the cut. Measured over a clean

View File

@@ -98,9 +98,13 @@ the **correct join key is not yet known**:
was tried and is **WRONG** — it plays the wrong recording in-game. Do not use.
- Only `VOICE_D_450..454` exist (no 44x/45x neighbours). Decoded durations are
suspicious — `450`=2.8s, `451`=1.6s, `452`=2.2s, but `453`=**0.14s**,
`454`=**0.43s** — far too short for the spoken line, so these `.slb` banks are
likely **multi-subwave / not cleanly sliced** by the current extractor (same
class as the deferred B/C banks).
`454`=**0.43s** — far too short for the spoken line. ❌ The guess that follows
was **REFUTED 2026-08-25**: these banks are *not* multi-subwave-and-missed. The
RIFF-magic count equals the number of sub-waves recovered in all five banks, so
nothing between or after them is lost. The audio is missing because a large
region **precedes the first RIFF** and the decoder searches for that magic —
87 % of `453` and 85 % of `454` sit in front of it, high-entropy and not
padding. See [voice-bank-leading-region](../voice-bank-leading-region.md).
⇒ The unbound-hokyu voice mapping is **open** (needs either the real join key
from mission data, or a proper multi-subwave `.slb` decode + audio verification).

View File

@@ -0,0 +1,95 @@
# The resupply voice banks — the decoder discards up to 87 % of them
Status: ❌ the recorded "multi-subwave / not cleanly sliced" explanation is
**REFUTED**. ✅ the real defect is measured. 🟡 the in-game verdict that rejected
the `hokyu_DS_s13A` voice binding is therefore **not** evidence against it. ❔ the
binding still needs audio verification, which needs a human.
Artifact: `crates/sylpheed-formats/examples/voice_bank_shape.rs`.
## Why this was worth chasing
The [record-table decode](structures/idxd-container.md) gives a **direct**
binding for a movie the corpus records as unbound:
```
S13_SUPPLY_ACROPOLIS MOVIE = hokyu_DS_s13A.wmv VOICETRACK = VOICE_D_452
```
`crates/sylpheed-formats/tests/movie_manifest_disc.rs` asserts the opposite —
`voice_token == None` — with the note that extending unbound movies *by shared
demo line* was "verified WRONG against the running game". That inference
predicted the same value the disc actually stores, so the two are in direct
conflict, and it is the only place on the disc where a runtime observation
disagrees with the record table.
First, the shape of the data. The resupply banks are **shared**: five slots bind
`VOICE_D_452` (S04, S07, S08, S12, S13), five bind `VOICE_D_451`, four bind
`VOICE_D_450`, four `VOICE_D_453`, three `VOICE_D_454` — 21 hokyu slots over five
banks. The movies repeat too (`hokyu_DS_s07A.wmv` serves S07 and S12). These are
generic resupply cutscenes, not per-stage recordings.
## ❌ What was recorded, and why it is wrong
`structures/movie-subtitles.md` notes that `450`=2.8 s, `451`=1.6 s, `452`=2.2 s
but `453`=**0.14 s** and `454`=**0.43 s** — "far too short for the spoken line, so
these `.slb` banks are likely **multi-subwave / not cleanly sliced**".
Measured, that is not it. **Every RIFF present in every bank is found and
parsed** — the count of `RIFF` magics equals the number of sub-waves recovered,
in all five banks:
| bank | bytes | RIFF magics | sub-waves recovered | bytes covered |
|---|---|---|---|---|
| `VOICE_D_450` | 65 652 | 1 | 1 | 56.2 % |
| `VOICE_D_451` | 67 704 | 2 | 2 | 64.8 % |
| `VOICE_D_452` | 67 704 | 2 | 2 | 46.7 % |
| `VOICE_D_453` | 53 340 | 1 | 1 | **5.4 %** |
| `VOICE_D_454` | 71 808 | 1 | 1 | **9.7 %** |
Nothing is being missed *between* sub-waves, and nothing is lost *after* them:
the last `data` chunk ends exactly at EOF in four of the five banks.
## ✅ The real defect: a leading region before the first RIFF
`slb::to_xma_riffs` locates audio by **searching for the `RIFF` magic**. In these
banks a large region *precedes* it, and the search skips the lot:
| bank | first RIFF at | share of file before it | that region |
|---|---|---|---|
| `VOICE_D_451` | 3 440 | 5 % | **100.0 % zero, 1 distinct byte** — real padding |
| `VOICE_D_452` | 15 728 | 23 % | 78.3 % zero, **256 distinct** |
| `VOICE_D_450` | 17 776 | 27 % | 69.1 % zero, **256 distinct** |
| `VOICE_D_453` | 46 448 | **87 %** | 27.4 % zero, **256 distinct** |
| `VOICE_D_454` | 60 784 | **85 %** | 21.1 % zero, **256 distinct** |
`VOICE_D_451` is the control: its leading region really is padding, and its
coverage is unremarkable. The other four have high-entropy content there — 46 KB
in `453`, 60 KB in `454` — which the decoder throws away. That is exactly the
size needed to explain a "line" that decodes to 0.14 s.
## 🟡 What this does to the conflict
The in-game test that rejected this binding listened to a decode that had
discarded **most of the bank**, for precisely the two-bank class involved. A
correct bank played from the wrong region sounds exactly like "the wrong line",
so the verdict does not refute the disc's binding — it is evidence about the
decoder, not about the mapping.
Note also what was actually rejected: a value derived *by inference* from a
shared demo id. The record table supplies the same value as a **stored field**.
Those are different kinds of evidence for the same claim, and only the first was
tested.
⚠️ This does **not** establish that the binding is right. It removes the only
recorded evidence against it.
## What this does not settle
***What the leading region is.** It is not padding and not a RIFF. Whether it
is a directory, a seek table, an alternate codec stream, or the audio itself is
unestablished — I did not decode it.
* ❔ Whether `hokyu_DS_s13A` really plays `VOICE_D_452`. That needs the leading
region decoded *and* a human listening; audio judgement cannot be done here.
* ❔ Whether the same leading region exists across the other ~9 500 `sound.pak`
entries, or is peculiar to these banks. Only five were measured.