diff --git a/tools/e2e/68-composition.mjs b/tools/e2e/68-composition.mjs index cb3a9c35..0b3b8093 100644 --- a/tools/e2e/68-composition.mjs +++ b/tools/e2e/68-composition.mjs @@ -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