Take the climb to a real branch point, and find the cadence has a third column
FINDINGS 70, and it closes ROADMAP P6. 65.6 recorded that "the slack table is here, but 51.3's refill climb with a second consumer through a real branch point is not", and 67.6 repeated it verbatim two sessions later. tools/analysis/36_branch_audio.py is that run: 51.3's surplus model, 56.3's 612 real branch points, 32's cadence arithmetic, both containers' headers and the buffer constants of the player 68 measured, in one place. No machine -- all five were already numbers. AUDIO IS 1.7% OF THE CODEC WIRE AND UP TO 3.30x OF THE CLIMB. Slack accrues out of pipe - wire, which is a small difference of two large numbers, so a second consumer is not priced by its share of the wire -- which is how every budget in this tree since FINDINGS 8 has quoted it. At 451.4 KB/s (the container's own zero-prefill pipe, 49.5) in a 256 KB ring the climb goes 6.70 s -> 22.11 s and the branch points arriving under it go 482/612 (79%) -> 603/612 (99%). At 488 it is 1.19x, at 600 it is 1.05x. Correction to 56.4: it charged audio at ratectl.AUDIO_KBPS = 7.8, which is 7,812.5 B/s in decimal kB; in binary KB the figure is 7.6294, so the placeholder was 2.24% high and every column moved in the flattering direction by less than one part in six hundred of the wire. AND ON THE PACKED BRANCH THERE IS NO CLIMB AT ALL. A record goes straight into GVRAM, so the video lookahead is zero records and 56.4's alarming column is vacuous when every frame arrives with less lookahead than the one before it. Acceptance there is a per-frame deadline, not an average, which is why B1 has to name a burst rate. The only consumer on that branch with any lookahead is the audio one: 1.833 s of sound held against 0.000 s of picture. And at 589.6 KB/s -- the acceptance figure this project quotes -- the sounded container's surplus is exactly zero: it plays and never banks a byte, while the silent one climbs its record in 6.38 s. THE COST NOBODY HAD COUNTED. A DLXP2 group is `lump k, then F records`, so lump k is at a LOWER address than every record of its group but the first, and a seek to record i finds its audio behind it. Measured on the 409 within-container seek targets of the arcade's own graph at the shipped F=11: mean 416.5 ms of silence entering a branch, median 416.7, p90 750.0, worst 833.3, and only 36 of 409 land on a group boundary. The other 203 -- the scene changes -- are free by construction, because lump 0 sits between the header and record 0. The container's own start is the one branch point the cadence costs nothing at, and it was the only one anybody had looked at. SO THE CADENCE PICK IS REOPENED, on a third column. 32_audio_wire chose F=11 on padding and RAM; F=1, the cadence it called the worst one, has no group to enter off-boundary at all, and gives back 12,288 B of RAM for +4.36 KB/s of wire (0.74% of the acceptance figure). The alternative is a second read: lump k is up to 503,808 B behind, so it is a separate command of 7,168 B -- 11.7 ms against 416, 36x cheaper in time -- and src/player/packed.s starts PG_AK/PG_AKF at lump 0 and has no audio seek path at all. Nothing here decides it; the deciding number is what one more SCSI command costs, and that is B1's. The content is not uniform mod F either: the measured mean runs 0.67x..1.23x of a uniform assumption across the sweep, and the 1.00x at F=11 is a coincidence. New check.sh stage, ~10 s, and it gates the STRUCTURE and deliberately not the milliseconds: audio never shortens a climb, the shipped cadence strands most within-container branches, F=1 strands none, and the lump read is an order of magnitude cheaper than the silence it removes. The one thing 70.3 and 70.4 rest on is a DESIGN ASSUMPTION and is printed in the tool's own output: one container per SCENE (53, 55.1, 56.3). One container per sequence makes every seek land on frame 0 and empties both sections. No encoder, player or container byte moved. Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
This commit is contained in:
@@ -7529,3 +7529,183 @@ and was aimed one layer too late.
|
||||
sees, which is the right unit for a clamp question and the wrong one for a
|
||||
mixing question.
|
||||
* **Nothing was listened to.** Unchanged since 68.6.
|
||||
|
||||
---
|
||||
|
||||
# Findings — session 38 (2026-08-25)
|
||||
|
||||
## 70. The refill climb meets a branch point with sound on the wire — and the cadence turns out to have a third column (session 38)
|
||||
|
||||
ROADMAP P6, the last item in it and the oldest: 65.6 recorded that "the slack
|
||||
table is here, but 51.3's refill climb with a second consumer through a real
|
||||
branch point is not", and 67.6 repeated it word for word two sessions later.
|
||||
`tools/analysis/36_branch_audio.py` is that run. It puts five things that have
|
||||
never been in the same room together — 51.3's surplus model, 56.3's 612 real
|
||||
branch points, 32's cadence arithmetic, the two containers, and the buffer
|
||||
constants of the player 68 measured — and it needs no machine, because every
|
||||
one of them is already a number.
|
||||
|
||||
python3 tools/analysis/36_branch_audio.py --kbps 451.4 488.0 513.2 600.0 \
|
||||
--ring 256 512 # ~10 s
|
||||
python3 tools/analysis/36_branch_audio.py --gate # the check.sh stage
|
||||
|
||||
### 70.1 THE HEADLINE, on the codec branch: audio is 1.7% of the wire and up to 3.30x of the climb
|
||||
|
||||
Slack is accumulated out of `pipe - wire` (51.3), and `pipe - wire` is a small
|
||||
difference of two large numbers. A second consumer is therefore **not** priced
|
||||
by its share of the wire, which is how every budget in this tree from FINDINGS 8
|
||||
onward has quoted it. Gate container, the game's own 612 gaps:
|
||||
|
||||
| ring KB | pipe | ceiling | climb SILENT | SOUNDED | ×| under, silent | under, sounded |
|
||||
|---:|---:|---:|---:|---:|---:|---:|---:|
|
||||
| 256 | 451.4 | 2 | 6.70 s | **22.11 s** | **3.30** | 482/612 (79%) | **603/612 (99%)** |
|
||||
| 256 | 488.0 | 7 | 5.40 s | 6.44 s | 1.19 | 451/612 | 475/612 |
|
||||
| 256 | 513.2 | 7 | 3.53 s | 3.95 s | 1.12 | 351/612 | 372/612 |
|
||||
| 256 | 600.0 | 7 | 1.61 s | 1.69 s | 1.05 | 129/612 | 130/612 |
|
||||
| 512 | 488.0 | 10 | 7.72 s | 9.19 s | 1.19 | 514/612 | 542/612 |
|
||||
| 512 | 513.2 | 14 | 7.06 s | 7.89 s | 1.12 | 497/612 | 520/612 |
|
||||
| 512 | 600.0 | 14 | 3.22 s | 3.38 s | 1.05 | 298/612 | 303/612 |
|
||||
|
||||
**7.63 KB/s of sound triples the climb at 451.4 and pushes the branch points
|
||||
that arrive under it from 79% to 99% of the game.** Nothing about the audio got
|
||||
bigger between those two columns; the quantity it is subtracted from got
|
||||
smaller. 451.4 is not a corner case — it is the container's own zero-prefill
|
||||
pipe (49.5), the rate at which the *silent* container is exactly deliverable.
|
||||
**The rate at which a container is deliverable and the rate at which it can
|
||||
absorb a branch were already different (51.4); with a second consumer the gap
|
||||
between them is a factor of three.**
|
||||
|
||||
A **correction to 56.4**, and it is small enough to be worth stating precisely
|
||||
so it is not mistaken for a bigger one: that table charged audio at
|
||||
`ratectl.AUDIO_KBPS = 7.8`, which is 7,812.5 B/s written in decimal kB. In the
|
||||
binary KB every other column uses it is **7.6294**, i.e. the placeholder was
|
||||
**2.24% high** — 0.04% of the wire. Every 56.4 column moves in the flattering
|
||||
direction by less than one part in six hundred. A placeholder that turns out to
|
||||
be right is still a placeholder.
|
||||
|
||||
### 70.2 On the packed branch there is no climb at all, and that is the finding
|
||||
|
||||
The packed player puts a record **straight into GVRAM** (61, 62, 64.2): the
|
||||
transfer *is* the paint, so there is no record buffer and the **video lookahead
|
||||
is zero records**. 51.3's question has no answer there, because there is no
|
||||
accumulator for play to fill.
|
||||
|
||||
* **56.4's alarming column does not apply to the DMAC-direct packed player** —
|
||||
"most branch points arrive with less lookahead than the one before them" is
|
||||
vacuous when *every frame* does.
|
||||
* Its acceptance is a **per-frame deadline**: 49,664 B inside every slot. A pipe
|
||||
that averages 589.6 KB/s over a second is a different claim, and that is why
|
||||
B1's acceptance has to name the data-phase burst rate as well as the sustained
|
||||
one (64.2).
|
||||
* **The only consumer on that branch with any lookahead is the audio one**:
|
||||
7,168 B a lump, three slots and a prefill of two as run (68.6), which is
|
||||
**1.833 s of sound held against 0.000 s of picture.** The stream this project
|
||||
spent four sessions adding is the better-buffered of the two.
|
||||
|
||||
For the CPU-painted variant (64.2 column B, 99,328 B, two record buffers, one
|
||||
record of lookahead):
|
||||
|
||||
| pipe | climb SILENT | SOUNDED | × | under, silent | under, sounded |
|
||||
|---:|---:|---:|---:|---:|---:|
|
||||
| **589.6** | 6.38 s | **never** | ∞ | 473/612 | **612/612** |
|
||||
| 600.0 | 2.69 s | 4.68 s | 1.74 | 263/612 | 421/612 |
|
||||
| 650.0 | 0.71 s | 0.80 s | 1.13 | 43/612 | 49/612 |
|
||||
| 700.0 | 0.41 s | 0.44 s | 1.07 | 33/612 | 33/612 |
|
||||
|
||||
**Read the first row.** 589.6 KB/s is the acceptance figure this project quotes
|
||||
for the packed branch, and it is precisely the rate at which the sounded
|
||||
container's surplus is **zero** — it plays, and it never accumulates a byte of
|
||||
lookahead at any amount of play. The silent container at that same rate climbs
|
||||
its one record in 6.38 s. **"Deliverable" and "able to survive a branch" are the
|
||||
same rate only for a container with no second consumer in it.**
|
||||
|
||||
### 70.3 The cost nobody had counted: entering a group off-boundary
|
||||
|
||||
A DLXP2 group is `lump k, then F records` (dlxp.py), so **lump k lies at a lower
|
||||
address than every record of its group except the first**. Read forward from
|
||||
record *i* and the next lump to arrive is *k+1*, which carries frame *(k+1)F* —
|
||||
so the frames from *i* to *(k+1)F−1* have picture and no sound. The missing
|
||||
time is exactly `(F − i mod F) mod F` frames of **1/12 s**, and it is an exact
|
||||
1/12 s: the chip's second is 15,625 samples and none of FINDINGS 54's
|
||||
frame-clock remainder gets into it.
|
||||
|
||||
Measured on the **409 within-container seek targets of the arcade's own graph**,
|
||||
at the shipped cadence F=11:
|
||||
|
||||
| | |
|
||||
|---|---:|
|
||||
| mean silence entering the branch | **416.5 ms** |
|
||||
| median / p90 / worst | 416.7 / 750.0 / **833.3 ms** |
|
||||
| land on a group boundary and cost nothing | **36 of 409** |
|
||||
|
||||
The other **203 branch points — the scene changes — are free, and by
|
||||
construction**: lump 0 sits at sector 1 and record 0 at 7,680, so a container's
|
||||
first bytes are header, lump, record and a scene change reads them in one
|
||||
forward pass. **The container's own start is the one branch point the cadence
|
||||
costs nothing at, and it is the only one anybody had ever looked at.**
|
||||
|
||||
**The fix is a second read, and no player in this tree has one.** Lump *k* is up
|
||||
to 503,808 B behind record *i*, so it cannot be picked up by reading early — it
|
||||
is a separate command at a separate LBA, of 7,168 B, which at 600 KB/s is
|
||||
**11.7 ms against a mean 416 ms of silence, 36x cheaper in time**. It costs one
|
||||
more command per branch and **the command overhead is B1's and unmeasured**.
|
||||
`src/player/packed.s` starts `PG_AK`/`PG_AKF` at lump 0 and has no audio seek
|
||||
path at all.
|
||||
|
||||
### 70.4 So the cadence pick is reopened, on a column it did not have
|
||||
|
||||
32_audio_wire.py chose F=11 on two columns, padding and RAM. Here is the third,
|
||||
measured on the game's own seek targets:
|
||||
|
||||
| F | A | lump B | padding | audio KB/s | RAM ×2 | mean sil | worst | free |
|
||||
|---:|---:|---:|---:|---:|---:|---:|---:|---:|
|
||||
| **1** | 2 | 1,024 | 57.29% | 12.000 | **2,048** | **0.0** | **0.0** | **409/409** |
|
||||
| 3 | 4 | 2,048 | 4.86% | 8.000 | 4,096 | 102.5 | 166.7 | 93/409 |
|
||||
| 7 | 9 | 4,608 | 1.11% | 7.714 | 9,216 | 209.5 | 500.0 | 78/409 |
|
||||
| **11** | 14 | 7,168 | **0.09%** | **7.636** | 14,336 | 416.5 | 833.3 | 36/409 |
|
||||
| 12 | 16 | 8,192 | 4.86% | 8.000 | 16,384 | 519.4 | 916.7 | 34/409 |
|
||||
|
||||
**F=1 — the cadence 32_audio_wire called the worst one — has no group to enter
|
||||
off-boundary at all**: no second read, no audio seek path, no silence at any
|
||||
branch point, and 2,048 B of held lump instead of 14,336. It costs **+4.36 KB/s
|
||||
of wire, 0.74% of the packed acceptance figure**, and it **gives back 12,288 B
|
||||
of RAM** on the branch whose entire argument is that RAM is the resource it has
|
||||
spare (64.2).
|
||||
|
||||
**This is a trade and not an error.** Padding is what F=11 minimises and padding
|
||||
is not the only thing F sets. A player that gets its audio seek right is
|
||||
indifferent between them; a player that does not pays a mean 416 ms of silence
|
||||
at 409 of the game's 612 branch points. **Nothing here decides it — the
|
||||
deciding number is the SCSI command overhead of the extra read, and that is
|
||||
B1's.** F=7 is the middle if one is wanted: 1.11% padding, +0.08 KB/s over
|
||||
F=11, 9,216 B held, and half the silence.
|
||||
|
||||
**And the content is not uniform mod F.** A uniform assumption puts the mean at
|
||||
(F−1)/2 frames; the arcade's seek targets land where they land, and the measured
|
||||
mean runs **0.67x to 1.23x** of uniform across the sweep — a design that assumed
|
||||
uniform would be a quarter out at F=3. At the shipped F=11 the ratio is
|
||||
**1.00x**, which is a coincidence and is reported as one.
|
||||
|
||||
### 70.5 What this does NOT establish
|
||||
|
||||
1. **No rate here is measured.** Every pipe column is a sensitivity (FINDINGS
|
||||
50). **B1 — sustained *and* data-phase burst — is still the user's**, and
|
||||
70.2's first row is a reminder that the two are not interchangeable.
|
||||
2. **The frame index of a seek target is a DESIGN ASSUMPTION**, and it is the
|
||||
one thing 70.3 and 70.4 rest on. DLXSCENE1 carries laserdisc-timeline
|
||||
positions in ms; this design puts **one container per scene** (53, 55.1, and
|
||||
56.3's 203 container changes), so the index is
|
||||
`(target start − the scene's earliest start) × fps / 1000`. **One container
|
||||
per *sequence* makes every seek land on frame 0, the group offset always
|
||||
zero, and 70.3/70.4 empty.** Nothing else in the file changes.
|
||||
3. **Nothing ran on a machine.** This is arithmetic over a scene table, two
|
||||
containers and a player's own constants. **68's player has never seeked**,
|
||||
and the audio seek path 70.3 asks for does not exist to be measured.
|
||||
4. **The mechanical seek is still unmodelled** (51.7.5) and is charged on top of
|
||||
every millisecond above.
|
||||
5. **The silence is a container property, not a chip one.** What an MSM6258V
|
||||
does when it is not fed — hold the last sample, or click — is a board
|
||||
question and belongs with session 34's fifth hardware item.
|
||||
6. **The 409/203 split is the graph's, not a container manifest's.** No scene
|
||||
has been encoded but one; the mapping from a scene to a DLXP2 is a design
|
||||
statement this tree has made and not yet built.
|
||||
|
||||
Reference in New Issue
Block a user