diff --git a/docs/re/structures/slb-data-offset.md b/docs/re/structures/slb-data-offset.md index 7123db12..3e667faa 100644 --- a/docs/re/structures/slb-data-offset.md +++ b/docs/re/structures/slb-data-offset.md @@ -41,6 +41,39 @@ packet stream does not start at a fixed offset. It starts at offset happens to take in `\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