Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

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

feat: notepat metronome F9, sonic awareness for 3x escape

- Metronome moved from F12 to F9 (no Fn key required)
- 3x escape now has rich sonic feedback:
- 1: low 220Hz tone + speak "one"
- 2: rising 330→440Hz + speak "two"
- 3: descending E5→C5→G4 chord + speak "exit"

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

+30 -10
+30 -10
fedac/native/pieces/notepat.mjs
··· 557 557 if (frame - escLastFrame > 90) escCount = 0; 558 558 escCount++; 559 559 escLastFrame = frame; 560 - if (escCount < 3) { 561 - // Beep feedback 562 - const beepFreq = escCount === 1 ? 440 : 660; 563 - const beep = sound?.synth?.("square", { frequency: beepFreq, duration: 0.08, volume: 0.15 }); 564 - if (beep) setTimeout(() => sound?.kill?.(beep, 0.02), 80); 560 + if (escCount === 1) { 561 + // First escape: low warning tone + spoken count 562 + const beep = sound?.synth?.("sine", { tone: 220, duration: 0.15, volume: 0.18, attack: 0.005, decay: 0.14 }); 563 + if (beep) setTimeout(() => sound?.kill?.(beep, 0.02), 150); 564 + sound?.speak?.("one"); 565 565 return; 566 566 } 567 - // Third escape — exit beep + jump 568 - const exitBeep = sound?.synth?.("square", { frequency: 880, duration: 0.12, volume: 0.2 }); 569 - if (exitBeep) setTimeout(() => sound?.kill?.(exitBeep, 0.02), 120); 567 + if (escCount === 2) { 568 + // Second escape: rising warning, two notes 569 + const a = sound?.synth?.("sine", { tone: 330, duration: 0.1, volume: 0.2, attack: 0.005, decay: 0.09 }); 570 + if (a) setTimeout(() => sound?.kill?.(a, 0.02), 100); 571 + setTimeout(() => { 572 + const b = sound?.synth?.("sine", { tone: 440, duration: 0.1, volume: 0.2, attack: 0.005, decay: 0.09 }); 573 + if (b) setTimeout(() => sound?.kill?.(b, 0.02), 100); 574 + }, 80); 575 + sound?.speak?.("two"); 576 + return; 577 + } 578 + // Third escape — descending exit chord + spoken "exit" 579 + const c1 = sound?.synth?.("sine", { tone: 660, duration: 0.12, volume: 0.22, attack: 0.005, decay: 0.11 }); 580 + if (c1) setTimeout(() => sound?.kill?.(c1, 0.02), 120); 581 + setTimeout(() => { 582 + const c2 = sound?.synth?.("sine", { tone: 523, duration: 0.12, volume: 0.22, attack: 0.005, decay: 0.11 }); 583 + if (c2) setTimeout(() => sound?.kill?.(c2, 0.02), 120); 584 + }, 80); 585 + setTimeout(() => { 586 + const c3 = sound?.synth?.("sine", { tone: 392, duration: 0.18, volume: 0.25, attack: 0.005, decay: 0.17 }); 587 + if (c3) setTimeout(() => sound?.kill?.(c3, 0.02), 180); 588 + }, 160); 589 + sound?.speak?.("exit"); 570 590 escCount = 0; 571 591 stopAllSounds(sound, system, 0.05); 572 592 system?.jump?.("prompt"); ··· 604 624 } 605 625 return; 606 626 } 607 - // F12: metronome toggle (moved from F10) 608 - if (key === "f12") { 627 + // F9: metronome toggle (no Fn key required) 628 + if (key === "f9") { 609 629 metronomeEnabled = !metronomeEnabled; 610 630 if (metronomeEnabled) { 611 631 metronomeBeatCount = Math.floor(syncedNow() / (60000 / metronomeBPM));