port: add wait:<seconds>, observe the bed's loop, and measure the seam at 3.4 s of silence
The port could not be asked to run for a stated duration -- a bare step is a no-op that returns at settle -- so nothing after the settle point was observable. An 87.7 s bed on a harness whose longest menu run was 7 s. The bed loops at 87.8 s against the track's 87.7 (r=0.947 and 0.885 on a clean bed-only recording): loop: restart behaves exactly as authored. First end-to-end observation of P6 looping. The authored 'audibly wrong at the seam' is confirmed and quantified: 36 consecutive near-silent 50 ms windows, 84.40-87.80 s, about 3.4 s of silence after a fade from RMS 2057 to 431. Recorded in authored/audio.json. It does NOT license trimming, which would still invent a loop point. My first wait: used create_timer and ran 39% long (30 s requested, 41.7 s wall) because an idle scene throttles the delta it counts down on. Now polls Time.get_ticks_msec: +4.6%. Checked before generalising: over a boot the port's clock tracks wall clock within 4%, so animation timing is sound and the earlier splash-dwell agreement stands. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
@@ -5681,3 +5681,76 @@ first where I would have invented an *anomaly* rather than a defect.
|
||||
|
||||
Nothing in this section rests on that correlator. The finding is `stop_bed` having
|
||||
no caller, which is a fact about the source.
|
||||
|
||||
## `wait:<seconds>`, and the bed's loop seam is 3.4 seconds of silence
|
||||
|
||||
The port could not be asked to **run for a stated duration**. A bare `wait`
|
||||
script step is `pass` — it returns as soon as the screen settles — so nothing
|
||||
happening after the settle point was observable from a harness at all. The music
|
||||
bed made that concrete: an 87.7 s track whose restart nobody had watched, on a
|
||||
harness whose longest menu run was under seven seconds.
|
||||
|
||||
`--script=wait:105` fixes that, and the first thing it found was the answer.
|
||||
|
||||
### The bed loops, exactly where it should
|
||||
|
||||
Recording the Master bus over 132 s with nothing but the menu playing — no movie,
|
||||
no voice, a clean signal — the bed's `t=2…17 s` template matches twice:
|
||||
|
||||
| | r | pass begins |
|
||||
|---|---|---|
|
||||
| first pass | **0.947** | 0.0 s |
|
||||
| second pass | **0.885** | **87.8 s** |
|
||||
|
||||
The track is **87.7 s**. So `loop: "restart"` does what `authored/audio.json`
|
||||
says: replays from sample 0 at the track's end, no trimming, no loop point.
|
||||
✅ First end-to-end observation of P6's looping behaviour.
|
||||
|
||||
### And the seam is measurably as bad as it was authored to be
|
||||
|
||||
`loop_why` predicted *"the listener hears the track's own fade-out and the silence
|
||||
after it before the music comes back"*. Measured off the bus:
|
||||
|
||||
| window around the seam | RMS |
|
||||
|---|---|
|
||||
| −8 … −4 s | 2057 |
|
||||
| −4 … −2 s | 714 |
|
||||
| −2 … −0.3 s | 431 |
|
||||
| +0.3 … +2 s | 2164 |
|
||||
|
||||
and **36 consecutive 50 ms windows below peak 300, from 84.40 s to 87.80 s** —
|
||||
about **3.4 seconds of near-silence** before the music returns. That is long
|
||||
enough to read as *the music stopped*, not as a loop.
|
||||
|
||||
The claim was right and is now a number. ⚠️ It does **not** license trimming to
|
||||
the fade: that would still invent a loop point, and an invented one is
|
||||
indistinguishable from a decoded one a month later. The measurement is recorded
|
||||
to make the cost of the missing loop point concrete, in `authored/audio.json`.
|
||||
|
||||
### 🔴 My first `wait:` was wrong by 39 %, and the way it was wrong matters
|
||||
|
||||
It used `create_timer`, which counts down on the frame delta. In an **idle**
|
||||
scene this container throttles and the delta it reports is not the time that
|
||||
passed: a requested 30 s took **41.7 s** of wall clock while the port reported
|
||||
30. Measured against `date` either side of the process, with a no-wait control
|
||||
to subtract 1.21 s of startup.
|
||||
|
||||
Now polled on `Time.get_ticks_msec()`: 30 s requested, **31.38 s** wall, +4.6 %.
|
||||
|
||||
⚠️ **This is idle-specific and is not a general clock fault**, which I checked
|
||||
before writing any of it down. Over a whole boot, where things are animating, the
|
||||
port's clock tracks wall clock to **within 4 %** — 10.43 s wall against 10.82 s
|
||||
reported. So the port's *animation* timing is sound and the earlier splash-dwell
|
||||
agreement (4.400 s and 3.650 s against declared 255 and 210 units) **stands**; I
|
||||
had briefly believed it did not.
|
||||
|
||||
What is genuinely unsound is `_elapsed` **while idle**: it reported 23.21 s across
|
||||
30 real seconds of waiting. Every timing the port prints during animation is
|
||||
fine; a timing that spans a wait is not.
|
||||
|
||||
📌 The reason to care: the only reason to hold a screen is to observe something on
|
||||
a **real** clock — an audio loop, a timeout, an idle return. A timer that
|
||||
silently ran 39 % long would have put every such observation at the wrong instant,
|
||||
and the bed-loop result above would have been the first casualty. It survived only
|
||||
because the seam was read off the **recording's** clock, which the bed's own known
|
||||
length calibrates.
|
||||
|
||||
Reference in New Issue
Block a user