Shape a sound with every filter type, a Q and a slope (#318)
The Filter node from #335 only knew low-pass, high-pass and band-pass and had a Resonance from 0 to 1. It now has every type Web Audio offers, a Q as a plain factor and a slope up to 48 dB per octave. - Types: low-pass, high-pass, band-pass, notch, low shelf, high shelf, peaking and all-pass. The cutoff row is now labelled Frequency, its key stays `cutoff`. - Q from 0.1 to 30, 0.707 by default, replaces Resonance. Web Audio takes the Q of a low- or high-pass in dB, so it is converted when the voice is wired. No project used the node. - Gain in dB is an input only for the shelves and the peak. It is a derived port, so the sound FX compiler now resolves derived ports. - Slope 12, 24 or 48 dB/oct runs 1, 2 or 4 filters in a row. They share one cutoff carried by a ConstantSource, only the last has the Q. Shelves, peak and all-pass hide the row. - The Chip Presets get the Q their resonance gave before. Mutate moves Q in octaves and gain by up to a dB. - bindStage in the instrument compiler binds every amount of a stage generically, so new stages need no case of their own there. Finding: FLAT_Q was in dB and the delay damping used it. It is a factor now, the damping takes it through passQ and is unchanged. Tests: - Unit envelope 13, sound-library 96 (2 new), chip-presets 14, soundfx 45, all green. - Counter-checks: the Q on every filter in a row, the gain row for every type. Each turns one test red. - e2e 34 (melektaus-atx): ALL PASSED, 76 checks (1 new). Chrome offline, 2 kHz through a low-pass at 1 kHz: -12.37 dB at 12 dB/oct, -49.5 dB at 48. A +6 dB peak gives 6.00 dB, a notch -124 dB. - The gate runs once on the last commit of this series. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
daeffe0f9d
commit
e1ca6a5f5a
9 files changed
+282
-98
No files matched your search
@@ -939,6 +939,42 @@ export async function sound(t) {
|
||||
JSON.stringify(swirled.sweeping.slice(1).map(([i]) => i)) === JSON.stringify([533, 534]),
|
||||
JSON.stringify(swirled),
|
||||
);
|
||||
// #318: the Filter rendered offline. A 2 kHz sine at 0.5 through a low-pass at 1 kHz with no bump
|
||||
// falls by 12.3 dB at 12 dB/oct and by four times that at 48 dB/oct. A peak of +6 dB at
|
||||
// 1 kHz raises a 1 kHz sine by 6 dB, a notch there takes it out.
|
||||
const filtered = await evaluate(`
|
||||
(async () => {
|
||||
const RATE = 48000;
|
||||
const level = async (hz, stage) => {
|
||||
const context = new OfflineAudioContext(1, RATE / 2, RATE);
|
||||
const tone = context.createOscillator();
|
||||
tone.frequency.value = hz;
|
||||
const half = context.createGain();
|
||||
half.gain.value = 0.5;
|
||||
const nodes = __gm.sound.stageNodes(context, { kind: 'pass', stages: 1, cutoff: 1000, q: 0.7071, gain: 0, ...stage });
|
||||
tone.connect(half).connect(nodes.input);
|
||||
nodes.output.connect(context.destination);
|
||||
tone.start();
|
||||
const out = (await context.startRendering()).getChannelData(0).subarray(RATE / 4);
|
||||
let sum = 0;
|
||||
for (const v of out) sum += v * v;
|
||||
return +(20 * Math.log10(Math.sqrt(sum / out.length) / (0.5 * Math.SQRT1_2))).toFixed(2);
|
||||
};
|
||||
return {
|
||||
low12: await level(2000, { filter: 'lowpass', q: -3.0103 }),
|
||||
low48: await level(2000, { filter: 'lowpass', q: -3.0103, stages: 4 }),
|
||||
peak: await level(1000, { filter: 'peaking', q: 1, gain: 6 }),
|
||||
notch: await level(1000, { filter: 'notch', q: 1 }),
|
||||
};
|
||||
})()`);
|
||||
check(
|
||||
'a Filter at 48 dB/oct falls four times as steeply as at 12, a peak raises its frequency by its gain, a notch takes it out',
|
||||
Math.abs(filtered.low12 + 12.3) < 0.2 &&
|
||||
Math.abs(filtered.low48 + 49.2) < 0.8 &&
|
||||
Math.abs(filtered.peak - 6) < 0.1 &&
|
||||
filtered.notch < -40,
|
||||
JSON.stringify(filtered),
|
||||
);
|
||||
// #329: the Chip on the worklet, rendered offline. A square at 220 Hz with a pitch of 12 and a duty
|
||||
// of 0.25, starting at 0.25 s: silence until then, 440 periods a second after it, up a
|
||||
// quarter of each. Sliding two octaves a second down from 440 Hz with a lowest frequency of
|
||||
|
||||
Reference in new issue
Block a user