zebra-report/web
Russell Ballestrini 8fc5a4c1f8
zebra-spaces: smooth audio source pivot via worklet GainNode ramps
Single mechanism handling three audible-source transitions, all click-
free via Web Audio linearRampToValueAtTime (100ms by default):

1. SFU → mesh (auto, on mesh PC ontrack):
   - Previous: detachListenerStream → hard tear-down of the worklet
   - Now: rampWorkletGain(uuid, 0, 100) keeps the worklet decoding in
     the background; only the GainNode value moves. Free CPU cost (~3%
     on a phone), zero audible click.

2. mesh → SFU (auto, on mesh PC connectionState='failed'):
   - Previous: attachCachedSfuStreamFor re-attached the SFU stream
   - Now: rampWorkletGain(uuid, 1, 100) restores the path that was
     never disconnected. attachCachedSfuStreamFor kept as fallback
     for the <audio>-element case (when AudioContext failed at attach).

3. SFU → HTTP /stream (manual, per-speaker toggle button next to mic
   state); HTTP → SFU on toggle off:
   - Previous: existing mute logic only touched remoteAudio (mesh
     <audio> elements). Listeners use listenerAudioNodes (worklet),
     so toggle-on left the worklet playing AND started HTTP — double
     audio. Fox 2026-06-04: "it was breaking listeners."
   - Now: startStream calls rampWorkletGain(uuid, 0, 100) and mutes
     the mesh element. stopStream reverses both. Per-speaker toggle
     finally works for listeners.

The mesh and HTTP <audio> elements still hard-mute via .muted (cheap,
no Web Audio path for them). Only the SFU worklet path needs the
smooth ramp because it's the one that'd produce a click if cut
mid-sample.

Telemetry will show:
- "mesh audio attached for XXXX — SFU worklet faded out" on mesh ontrack
- existing "stream on for XXXX — DJ mode" on HTTP toggle ON
- no new event on toggle OFF / mesh fail (just the gain ramp)
2026-06-04 18:00:58 -04:00
..
blog phase 1: unfirehose reconstruction from session JSONL ingest 2026-05-27 13:51:14 -04:00
fonts phase 2: gap analysis — cat>> append + binary asset recovery 2026-05-27 13:54:19 -04:00
chat.html zebra-spaces: listener mute button doubles as audio-unlock gesture 2026-06-03 20:57:09 -04:00
host-your-own.html zebra-spaces: listener mute button doubles as audio-unlock gesture 2026-06-03 20:57:09 -04:00
how-it-works.html zebra-spaces: listener mute button doubles as audio-unlock gesture 2026-06-03 20:57:09 -04:00
index.html web: bump mobile body padding from 1rem to 1.25rem so the right edge has visible breathing room 2026-05-31 14:13:25 -04:00
kernel.html web: bump mobile body padding from 1rem to 1.25rem so the right edge has visible breathing room 2026-05-31 14:13:25 -04:00
stamp.js web: stamp each zebra-report page with build date + md5/sha256 2026-05-28 17:50:12 -04:00
zebra-audio.html zebra-spaces: listener mute button doubles as audio-unlock gesture 2026-06-03 20:57:09 -04:00
zebra-spaces.html zebra-spaces: smooth audio source pivot via worklet GainNode ramps 2026-06-04 18:00:58 -04:00