Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

notepat (native): keep audio-history ring frozen between reverse-replay gestures

Symptom: press space → reverse-play recent audio. Release. Press space
again with no notes played in between → expected the same buffer
content, instead the head of the loop is silent ("space is adding
time").

Cause: space-release was calling setCapturePaused(false), which
unfroze the ring write_pos. Between release and the next press, the
ring kept advancing — capturing real-time silence (no notes were
playing). The next reverse press played that silence back at the
front of the loop.

Fix: drop the setCapturePaused(false) from space-release entirely.
The ring stays frozen. Lazily unpause at the note-trigger site
(idempotent) so capture re-arms exactly when content the user actually
plays starts hitting the speakers — and not a moment before. Press →
release → press now reverses the same content as the first press,
and any notes played between releases are captured normally.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+15 -8
+15 -8
fedac/native/pieces/notepat.mjs
··· 2852 2852 // If this key is currently recording in per-key mode, suppress playback 2853 2853 if (perKeyRecording === key) return; 2854 2854 if (noteName && !sounds[key]) { 2855 + // Re-arm the audio-history ring before this note hits speakers. 2856 + // Capture stays paused after a space-release so the ring doesn't 2857 + // record the silent gap; unpausing here means the next reverse 2858 + // gesture replays exactly the audio the user generated, with 2859 + // none of the real-time silence between presses cluttering it. 2860 + // Idempotent — safe to call when capture is already running. 2861 + sound?.speaker?.setCapturePaused?.(false); 2855 2862 // NuPhy detection: analog pressure arrives as a float strictly between 2856 2863 // 0 and 1 (digital keys get the default 1.0 stamped on). Refresh the 2857 2864 // "last analog keypress" timestamp whenever we see one so the status ··· 2985 2992 if (key === "space") { 2986 2993 spaceHeld = false; 2987 2994 stopReversePlayback(sound); 2988 - // Unfreeze the output-history ring so live audio resumes being 2989 - // captured. sim() will animate waveViewOffsetSec back to 0 over 2990 - // ~20 frames (ease-out lerp) so the needle VISIBLY catches up to 2991 - // the present — which reads as a smooth "returning to live" sweep 2992 - // rather than a snap. The ring's write_pos didn't advance during 2993 - // the hold, so the catch-up target (offset=0) is still exactly the 2994 - // moment of press; recording picks up from there. 2995 - sound?.speaker?.setCapturePaused?.(false); 2995 + // KEEP capture paused on release. If we unpause here, the ring 2996 + // starts writing real-time silence between this release and the 2997 + // next note press — which the next reverse press would then play 2998 + // back as audible silence at the head of the loop ("space adds 2999 + // time"). Lazily unpaused at the first note-trigger site below 3000 + // (line ~2854) so the ring only captures content the user 3001 + // actually plays. Press → release → press again with no notes 3002 + // in between now reverses the same buffer content as press 1. 2996 3003 spacePressStartMs = 0; 2997 3004 return; 2998 3005 }