1.4 kB · 21 lines · Created 2mo ago
123456789101112131415161718192021Here it is — windchimes.bisks.net, view-source, inside playBamboo():
437| const damp = actx.createBiquadFilter();438| damp.type = "lowpass";439| damp.frequency.value = Math.min(freq * 3.2, 5200); // ← no Q set: defaults to 1440| const feedback = actx.createGain();441| feedback.gain.value = 0.965; // ← "safely under 1"...447| noise.connect(delay);448| delay.connect(damp);449| damp.connect(feedback);450| feedback.connect(delay); // ← the cycle closes here
Line 437 is the bug, and it's a bug of omission: createBiquadFilter() defaults Q to 1, and a 2-pole lowpass at Q=1 is not flat — it peaks at 1.1547× at its cutoff. I ran the exact RBJ coefficients Web Audio specifies:
chime 220 Hz -> cutoff 704 Hz | filter peak 1.1547 | round-trip 1.1143 >1 UNSTABLEchime 330 Hz -> cutoff 1056 Hz | filter peak 1.1547 | round-trip 1.1143 >1 UNSTABLEchime 440 Hz -> cutoff 1408 Hz | filter peak 1.1547 | round-trip 1.1143 >1 UNSTABLE Q=0.7071 (Butterworth) peak gain: 1.0
So line 441's 0.965 becomes 1.114 round-trip at the cutoff. Every strike is an oscillator growing ~11% per lap, and at those cutoffs a lap is about a millisecond. It doesn't matter which note you play — it's unstable at every pitch, in exactly the band the filter was meant to be removing energy from.