Files
amethyst/commons
Claude 076b301d84 fix(nests): close 4 audio-dropout sources across listener + speaker
1. Listener-side pre-roll + bigger playback buffer + audio-priority thread.
   - NestPlayer buffers 5 decoded frames (~100 ms) before starting
     the AudioPlayer, masking the first-frame underrun that fires
     whenever Compose / GC briefly stalls Main.
   - AudioTrackPlayer sizes the AudioTrack at max(minBuffer*16, 250 ms)
     instead of minBuffer*4 (~80 ms) and writes via a per-instance
     audio-priority single-thread executor (Process.THREAD_PRIORITY_AUDIO)
     instead of Dispatchers.IO, so WRITE_BLOCKING never contends with
     unrelated IO work.

2. MoqLiteSession.subscribe: hoist response typeCode out of the
   collect lambda. readVarint advances pos permanently while
   readSizePrefixed only rolls back its own length-varint, so a
   chunk-split between type and body would re-read the body's size
   prefix as the type code on the next chunk and misframe the
   response. Mirrors the same fix already in handleInboundBidi.

3. MoqLiteSession.subscribe: register the subscription in the map
   BEFORE writing the SUBSCRIBE bytes on the wire. The relay can
   open the first group's uni stream before our continuation
   re-enters [state] to register; if so, drainOneGroup looked the
   id up against an empty map and silently dropped the frame
   (~1 frame / 20 ms gap on first attach). Wrap the post-register
   writes so a transport-failure unwinds the orphan registration.

4. Hot-swap moq-lite publisher across JWT-refresh boundaries.
   - NestMoqLiteBroadcaster: publisher is now @Volatile + supports
     swapPublisher(); capture loop snapshots the reference per frame
     and resets framesInCurrentGroup on swap.
   - MoqLiteNestsSpeaker implements a new internal
     HotSwappablePublisherSource interface that exposes
     openPublisherForHotSwap(track) without spinning up a broadcaster.
   - ReissuingBroadcastHandle keeps a single long-lived broadcaster
     across session recycles when the speaker supports hot swap;
     legacy IETF / fake speakers fall back to close-then-restart.
   - connectReconnectingNestsSpeaker.orchestrator hoists the old-
     session close onto a sibling launch so the wrapper can swap
     the publisher into the broadcaster on the new session before
     the old session's WebTransport drops. Eliminates the previously-
     accepted 50–150 ms audible silence at every JWT refresh.
2026-05-05 03:06:40 +00:00
..