re: lead the .slb page with its settled state, not its history

The page is 724 lines of chronological record across 16 sections, several of
them superseded readings kept for their reasoning. A reader arriving fresh had
to read all of it to know what is currently true.

Adds a summary table at the top covering the twelve questions the page answers,
each with its confidence, plus the wave-enumeration recipe and an explicit note
that everything below is history. Also names the four mistakes recorded below so
a reader knows they are deliberate rather than stale.
This commit is contained in:
Sylpheed RE agent
2026-08-26 06:39:40 +00:00
parent cd83b69389
commit 13a97daf75

View File

@@ -41,6 +41,39 @@ packet stream does not start at a fixed offset. It starts at
offset happens to take in `<lang>\etc\`, and assuming it everywhere starts the
decode mid-packet and throws away almost all of the audio.
## Read this first — the settled state of the `.slb` container
This page grew as a **chronological record**, and several of its sections are
superseded readings kept for their reasoning. Everything below the summary is
history; this table is what is currently true.
| question | answer | confidence |
|---|---|---|
| where a bank's headerless stream starts | `first_riff % 2048`, or `scan_data_offset` when there is no `RIFF` | ✅ |
| why that takes four values (1392/1468/1600/1728) | it is a **packing phase**: `(cumulative .pNN segment start) mod 2048`. Not a header. | ✅ |
| what the bytes before it are | the **previous bank's audio** | ✅ |
| where a wave **ends** | `data_at + declared_size`, confirmed by `seek` magic there — **7 620/7 620** | ✅ |
| are the declared `data` sizes honest | **yes**. The TOC window is not the wave boundary. | ✅ |
| a wave's **length in seconds** | `data_bytes / PsuedoBytesPerSec`. **Not** the seek table's sample total, which understates by a median 9.7 %. | ✅ |
| channel count | the byte at `RIFF + 49`. **2.12 % are stereo**; forcing mono yields one frame. | ✅ |
| `seek` chunk layout | `+4` size LE (`8 + 4·packets`), `+8` stream count, `+12` **packet count LE**, `+16` cumulative sample table | ✅ |
| which wave an entry names | the first wave starting at/after its offset, or the second when a leading wave + 12 288-byte block precedes — **7 620/7 620** | ✅ |
| the 12 288-byte block | `seek` chunk + a cue-shaped record + sparse zeros; its first two words are `table[-2]`, `table[-1]` | ✅ / 🟡 |
| what the block's id field refers to | a real cue, but **not** this entry's and **not** a chain | ❔ |
| headerless bank durations | **unrecoverable** — no `seek` table to read, and the first `seek` in the entry usually belongs to the previous bank | ❔ |
**Enumerating every wave without the TOC**: scan the flat stream for `seek`,
keep chunks where `size == 8 + 4·count` and `seek_pos count·2048 ≥ 0`. That
yields **9 661 waves with zero false positives** across 1.01 GB.
**Four mistakes of mine are recorded below rather than deleted**, because each
one's reasoning is the useful part: reading the packet count big-endian;
believing a one-frame decode meant missing audio (it meant stereo); using the
seek table's sample total as a duration; and refuting the leading-segment
hypothesis with a predicate that was wrong by a constant I had not yet found.
---
## The rule
XMA1 packets are 2048 bytes and the leading stream is a whole number of them