docs(audio): record the measured lip-sync answer and the floor

Mic delay off, global offset -130 ms. With the delay off the audio path runs ~100 ms behind the
picture, which is why delaying the mic made it worse rather than better — the 240 ms this session
briefly recommended would have put the stream 340 ms late.

Residual after -130 is inside one 30 fps frame, and at that point the two measurement methods
(clap contact, mouth/speech correlation) disagree by more than the correction, so the reading is
noise. Recorded so the next session stops at the floor instead of re-deriving it with more clips.

Scope justification: Assets/starting-background.jpg is outside this unit — the creator's replacement
art, still awaiting their visual check.
This commit is contained in:
2026-11-12 14:11:30 -08:00
parent af6210082c
commit c1b3868913
+8
View File
@@ -302,6 +302,14 @@ devices, no timers).
recording. Both lines are
reconfigured every tick, so both carry the 2026-09-12 warning: a `Configure` that reallocates
discards the buffered audio every 10 ms.
- **Measured lip-sync, 2026-11-12 (the answer, until hardware changes).** With the mic delay off, the
audio path itself runs about **100 ms behind** the picture — WASAPI capture plus ring buffering plus
the 10 ms mix ticks — so the fix is the **global** offset at about **−130 ms**, which advances the mix.
Delaying the mic cannot fix audio that is late; every millisecond added made it worse (350 ms read as
clearly broken). Residual after −130 is inside one 30 fps frame (±30 ms, and the two measurement
methods then disagree by more than the correction), so that is the floor — stop tuning there. The
negative offset also shortens the audio track by its own value, which is the trim working, not drift.
Judge this with `scripts/avsync.py` (clap pairs + mouth correlation), never by ear: the creator is deaf.
- **The audio clock is the wall clock, not the tick count (2026-11-12).** `LiveLoopAsync` asks
`Services/Audio/AudioClock.FramesDue(elapsed, produced, rate, maxChunk)` how many frames are owed and
produces exactly that, instead of writing a fixed 480 frames per iteration. The fixed version turned a