Measure e2e 68h against what the sound is held to (#418)

The check failed in CI twice in a row (tasks 740 and 741) with the
sound 61 and 52 ms ahead of the picture, against a fixed limit of
50 ms. Neither commit touched the sound timing. The limit was tighter
than what the composition promises.

- The sound follows the unrounded `player.time` and is started again
  once it lies more than `SLIP` (40 ms) off.
- The check reads the picture from `videoTime`, which counts in whole
  frames of the cut. It can lie up to one frame (1/60 s) behind.
- The first frame at 0.5 s may also come past it (0.5167 s in 740).
  That overshoot is now taken off.
- The limit is SLIP plus one frame plus 5 ms for the audio clock
  moving on between the game's frame and the test's.

Recomputed, the two red runs give 44.5 and 52.1 ms, under the new
limit of 61.7 ms.

Tests:
- e2e 68 (atx): ALL PASSED, 21 checks, 68h at 16 ms.
- Counter-probe: sound planned 100 ms early, 68h red at 116 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-10-18 20:39:14 +02:00
1 parent 24cd9fdeaa
commit e4b0419a53
1 file changed
+8 -2
+8 -2
View File
@@ -432,7 +432,13 @@ export async function composition(t) {
const ran = toneRows.findIndex((row) => row.time > 0);
const reached = toneRows.find((row) => row.time >= 0.5);
const toneClip = toneRows.at(-1)?.clip;
const early = reached && toneClip ? reached.clock - toneClip.at : null;
// How far the sound runs ahead of the picture in that frame: the frame may come past 0.5, and the
// sound is held to the picture only within SLIP (40 ms, compositionSound.ts). `videoTime` counts
// in whole frames of the cut while the sound follows the unrounded time, so the picture read here
// can lie up to one frame (1/60 s) behind what the sound is held to; 5 ms more for the audio clock
// moving on between the game's frame and this one. A fixed 50 ms failed at 52 and 61 ms in CI
// (tasks 740, 741) with the sound inside all of that.
const early = reached && toneClip ? reached.clock - toneClip.at - (reached.time - 0.5) : null;
check(
'a sound item is planned only once the cut’s clock runs, for when the cut reaches it, to its end',
ran > 0 &&
@@ -442,7 +448,7 @@ export async function composition(t) {
Math.abs(toneClip.duration - 0.5) < 0.002 &&
early !== null &&
early > -0.02 &&
early < 0.05,
early < 0.04 + 1 / 60 + 0.005,
JSON.stringify({ waited: ran, early, reached, toneClip }),
);
// 68i. The sound item picked the composition's bus, the video item picked none: both go into the