re: the seek table's sample total is not the wave length -- durations corrected

Chasing w0 I decoded leading waves and the output matched neither trailer word.
Following that into RIFF waves, where the extent is certain, the decoded sample
count exceeds the seek table's last cumulative sample by a median 9.7%.

The tiebreak is the bank's own PsuedoBytesPerSec: over 14 banks it agrees with
an actual FFmpeg decode to a mean of 0.007 s and with the seek-table duration
only to 0.287 s. Two independent quantities agree with each other and both
disagree with the seek total, so that last entry is the last SEEK POINT, not the
sample count.

Both artifacts regenerated with data_bytes / PsuedoBytesPerSec. Total audio is
408.3 minutes, not the 390.9 I published -- 4.3% in aggregate. Dialogue timings
all rise, e.g. 'They got Leader!' from 1.78/2.46 s to 2.25/2.93 s.

What made this hard to catch is worth recording: the seek total gave BGM of 2.4
minutes, chatter of 2.8 seconds and cutscenes of 11 minutes, and I cited that as
the chain validating itself. It validated the structure, not the scale -- a
uniform 10% error preserves every ratio I checked.
This commit is contained in:
Sylpheed RE agent
2026-08-26 06:17:07 +00:00
parent 00e9a932ea
commit 640d860b23
5 changed files with 6587 additions and 6541 deletions

View File

@@ -601,3 +601,48 @@ That is the shape of a sparse table, and it is unidentified.
**A correction to how I described this block**: I called the region "zero
padding" after the seek chunk. It is not padding — it is a sparse structure that
is *mostly* zero. The distinction matters for anyone who tries to skip it.
## ❌ The `seek` table's sample total is NOT the wave's length — my durations were low
**2026-08-26.** I published two artifacts using `last cumulative sample ÷ sample
rate` as the duration. That is wrong, and this is the measurement that shows it.
Trying to pin down `w0`, I decoded leading waves and found the output matched
**neither** trailer word. Following that into the `RIFF` waves, where the extent
is certain, the decoded sample count exceeds the `seek` table's last cumulative
sample by a **median 9.7 %** — far too much to be rounding.
The tiebreak is the bank's own **`PsuedoBytesPerSec`** field, which gives a
duration as `data_bytes / PBPS` and is read, not decoded. Over 14 banks:
| comparison | mean absolute difference |
|---|---|
| `PBPS` vs the **seek-table** duration | **0.287 s** |
| `PBPS` vs the **decoded** duration | **0.007 s** |
Two independent quantities — the bank's declared byte rate and an actual FFmpeg
decode — agree with each other to seven milliseconds and both disagree with the
`seek` total. The `seek` table's last entry is therefore **not** the wave's
sample count; it is the last *seek point*, which stops short of the end.
**Corrected**, and both artifacts regenerated with `data_bytes / PsuedoBytesPerSec`:
* [`../data/voice-bank-manifest.txt`](../data/voice-bank-manifest.txt) — total
audio **408.3 minutes**, not the 390.9 I reported. A **4.3 %** understatement
in aggregate; the per-bank median error was 9.7 %, but long banks dominate the
total and are proportionally more accurate.
* [`../data/stage-dialogue-with-durations.txt`](../data/stage-dialogue-with-durations.txt)
— every line's timing rises, e.g. *"They got Leader!"* from 1.78/2.46 s to
**2.25/2.93 s**.
⚠️ **What made this hard to catch**: the `seek` total *looked* right. It gave
BGM tracks of 2.4 minutes, radio chatter of 2.8 seconds, cutscenes of 11
minutes — a set of numbers that sorted themselves into exactly the right shapes,
which I cited as the chain validating itself. It was validating the *structure*
and not the *scale*: a uniform 10 % error preserves every ratio I checked. A
self-consistency check cannot catch a systematic factor, and I should not have
read it as confirmation of the value.
🟡 `w0` remains unidentified. Neither trailer word matches the decoded length,
so the "usable length" reading of `w0` is now less likely, not more.