Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

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

notepat: fix Shift-pluck (keyed on duration) + QR code in status bar

Two reported issues:

1. Shift+letter on harp sounded identical to non-shift. Root cause: the
short-pluck detection in generate_harp_sample was keyed on
`v->decay < 0.2`, but the default decay mode in notepat is "short"
(0.1s), so EVERY harp press — shift or not — got the short stretch
factor (0.990) and nothing resembling the 15-second pedal-harp
sustain ever played.

Switch to duration-based detection: short-pluck path fires when
duration is finite AND < 1.0s. Notepat passes duration=Infinity for
sustained notes (default harp) and duration=0.4 when Shift is held
(staccato pluck). Clean, unambiguous.

2. QR code in the top-left status bar linking to notepat.com. Bar was
14px tall; the smallest QR (version 1 "notepat.com" at scale=1 with
2-module quiet zone) is 25×25px. Grew topBarH to 26px to fit. QR
sits in the corner, "notepat.com" label shifts right to accommodate;
the whole zone (QR + label) remains a click target that jumps to
the prompt piece.

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

+29 -14
+20 -8
fedac/native/pieces/notepat.mjs
··· 3277 3277 } 3278 3278 3279 3279 // === STATUS BAR === 3280 - const topBarH = 14; 3281 - const barY = 2; 3280 + // Bar is tall enough to fit a 25px QR code (21-module QR version 1 with 3281 + // a 2-module quiet-zone margin, scale=1) in the top-left corner. 3282 + const topBarH = 26; 3283 + const barY = 10; // vertical offset for status text — matrix font is ~7px tall 3282 3284 3283 3285 ink(BAR_BG[0], BAR_BG[1], BAR_BG[2]); 3284 3286 box(0, 0, w, topBarH, true); ··· 3303 3305 if (reserveSysBrt >= 0) statusRightReserve += 4 + 16 + 2 + 3 * CH; 3304 3306 const statusRightLimit = Math.max(80, w - statusRightReserve - 8); 3305 3307 3306 - // Left: "notepat.com" — clickable, jumps to prompt piece 3307 - const npHovered = hoverX >= 0 && hoverX <= 46 && hoverY < topBarH; 3308 - if (npHovered) { ink(255, 255, 255, 20); box(0, 0, 48, topBarH, true); } 3308 + // Left: tiny QR code → notepat.com (25x25 at scale=1), then label. 3309 + // Clicking anywhere in the label zone still jumps to prompt piece. 3310 + if (globalThis.qr) { 3311 + // qr() handles its own white background + margin. 3312 + globalThis.qr("https://notepat.com", 1, 1, 1); 3313 + } 3314 + const qrW = 26; // 25px QR + 1px padding before label 3315 + const labelX = qrW + 4; 3316 + const labelW = 48; // "notepat.com" label width in matrix font at size=1 3317 + const npHovered = hoverX >= 0 && hoverX <= labelX + labelW && hoverY < topBarH; 3318 + if (npHovered) { ink(255, 255, 255, 20); box(labelX - 2, 0, labelW + 2, topBarH, true); } 3309 3319 ink(FG, FG, FG, npHovered ? 255 : 200); 3310 - write("notepat", { x: 2, y: barY, size: 1, font: "matrix" }); 3320 + write("notepat", { x: labelX, y: barY, size: 1, font: "matrix" }); 3311 3321 ink(dark ? 200 : 180, dark ? 100 : 60, dark ? 140 : 120, npHovered ? 255 : 200); 3312 - const dotComX = 2 + 7 * 4; 3322 + const dotComX = labelX + 7 * 4; 3313 3323 write(".com", { x: dotComX, y: barY, size: 1, font: "matrix" }); 3314 - globalThis.__npBtn = { w: 48, h: topBarH }; 3324 + // Whole top-left zone (QR + label) becomes the click target so tapping 3325 + // either the QR or the text jumps to prompt. 3326 + globalThis.__npBtn = { x: 0, w: labelX + labelW, h: topBarH }; 3315 3327 3316 3328 // Status area after notepat.com — auto-update indicator only (minimal) 3317 3329 let statusX = dotComX + 4 * 4 + 6;
+9 -6
fedac/native/src/audio.c
··· 311 311 // pattern decay exponentially. With the two-point LPF ≈ unity at DC, 312 312 // the per-cycle loss is dominated by S: amplitude ≈ S^(f·t) per second. 313 313 // S = 0.9985 gives T60 ≈ 15s at 440Hz — long sustain like a real 314 - // pedal harp letting the string ring out. Higher pitches still fade 315 - // faster than bass strings (matches physics of real strings). 314 + // pedal harp letting the string ring out. 316 315 // 317 - // "Short pluck" variant: when the caller passes decay > 0 (notepat 318 - // does this for Shift+letter), shorten the stretch factor so the 319 - // string dies in ~0.4s — feels like a damped/staccato pluck. 320 - double stretch = (v->decay > 0.0 && v->decay < 0.2) ? 0.990 : 0.9985; 316 + // "Short pluck" variant — triggered by a FINITE SHORT duration on the 317 + // voice. Notepat uses duration=Infinity for sustained harp notes and 318 + // duration≈0.4 for Shift+letter staccato plucks. The previous 319 + // implementation keyed on decay<0.2 but that collided with the 320 + // default decay mode (0.1s), so every harp press got short-stretch 321 + // and shift did nothing audible. 322 + double stretch = (!isinf(v->duration) && v->duration > 0.0 && v->duration < 1.0) 323 + ? 0.990 : 0.9985; 321 324 double decayed = filtered * stretch; 322 325 323 326 // Write back to close the delay loop.