Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

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

notepat: fix z/x side keys + drop sampler noise voice

Two related fixes both rooted in "pf is not defined" ReferenceError
cleanup + offset routing:

1. activeKitForOffset routes z/x (offset=-1) to the LEFT kit
The grid split in hitTestGrid + the note trigger block treats
offset <= 0 as left-side notes (z=-a#, x=-b, plus all the 0-offset
c..b letters). activeKitForOffset was comparing `offset === 0`, so
a non-zero offset (like -1 for z/x) fell into the `else` branch and
picked kitRight. With a drum kit armed on the upper octave only,
pressing z suddenly played a drum mapped to the letter "a#" from
the RIGHT kit instead of its proper A#3 tone on the LEFT instrument.
Changed the comparison to `offset <= 0` so both in-octave and below-
octave left-side keys pick kitLeft.

2. Drop the noise voice from the sample-delete confirmation
Line 2557 was `sound.synth({ type: "noise", tone: 200 * pf, ... })`
with `pf` undefined outside playPercussion scope — every Delete in
sample mode threw a ReferenceError (silently swallowed by QuickJS's
top-level handler, so the confirmation sound just never played).
Replaced with a clean descending triangle pair (440 → 220 Hz) that
matches the rest of the sample-mode palette and doesn't rely on an
out-of-scope pitch factor variable.

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

+16 -2
+16 -2
fedac/native/pieces/notepat.mjs
··· 1428 1428 // (letter, gridOffset) so render code doesn't need to branch on 1429 1429 // kitLeft/kitRight everywhere. 1430 1430 function activeKitForOffset(offset) { 1431 - return offset === 0 ? kitLeft : kitRight; 1431 + // Side routing matches the grid split in hitTestGrid / the note-trigger 1432 + // block: offset <= 0 belongs to the LEFT grid (includes z/x which are 1433 + // offset=-1, the below-octave A#/B keys), offset >= 1 is the RIGHT grid 1434 + // (+c upward). Previously only offset===0 mapped to kitLeft, so z/x 1435 + // reached into whatever kit was loaded on the RIGHT side — meaning if 1436 + // you armed a drum kit on the upper octave, `z` suddenly played a drum 1437 + // instead of its tied A#3 tone on the left instrument. 1438 + return offset <= 0 ? kitLeft : kitRight; 1432 1439 } 1433 1440 function kitNamesFor(kit) { 1434 1441 if (isWarKit(kit)) return WAR_NAMES; ··· 2554 2561 sound.sample.loadData(globalSample.data, globalSample.rate); 2555 2562 sampleLoaded = true; 2556 2563 } 2557 - sound.synth({ type: "noise", tone: 200 * pf, duration: 0.1, volume: 0.15, attack: 0.001, decay: 0.08 }); 2564 + // Clean descending triangle blip for the clear confirmation. The 2565 + // previous "noise" voice here referenced `pf` (pitch factor, only 2566 + // defined inside playZoo/playPercussion scopes) so it threw a 2567 + // ReferenceError every time Delete was pressed in sample mode, and 2568 + // even when the error didn't trip it was just a hissy sample-rate 2569 + // smear that didn't fit the sample-mode palette. 2570 + sound.synth({ type: "triangle", tone: 440, duration: 0.06, volume: 0.18, attack: 0.002, decay: 0.05 }); 2571 + sound.synth({ type: "triangle", tone: 220, duration: 0.09, volume: 0.14, attack: 0.02, decay: 0.07 }); 2558 2572 return; 2559 2573 } 2560 2574 // Arrow left/right handled above (octave per side)