From 4c99f4866b03ba5ad7498bfa11da6408e7609153 Mon Sep 17 00:00:00 2001 From: Aria Date: Thu, 4 Dec 2025 22:50:28 -0600 Subject: [PATCH] Use setvalueattime to pin values and prevent bleed --- packages/superdough/helpers.mjs | 15 ++++++++------- packages/superdough/synth.mjs | 7 ++++--- packages/superdough/wavetable.mjs | 7 ++++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 1a9ed3797..1430b5642 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -137,11 +137,10 @@ export function getCompressor(ac, threshold, ratio, knee, attack, release) { attack: attack ?? 0.005, release: release ?? 0.05, }; - node.threshold.value = options.threshold; - node.ratio.value = options.ratio; - node.knee.value = options.knee; - node.attack.value = options.attack; - node.release.value = options.release; + const now = ac.currentTime; + Object.entries(options).forEach(([key, value]) => { + node[key].setValueAtTime(value, now); + }); return node; } @@ -224,8 +223,10 @@ export function createFilter(context, start, end, params, cps, cycle) { const factory = () => context.createBiquadFilter(); filter = getNodeFromPool('filter', factory); filter.type = type; - filter.Q.value = q; - filter.frequency.value = frequency; + const now = context.currentTime; + Object.entries({ Q: q, frequency }).forEach(([key, value]) => { + filter[key].setValueAtTime(value, now); + }); frequencyParam = filter.frequency; } const envelopeValues = [params.attack, params.decay, params.sustain, params.release]; diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 6bf7a1379..8f9efa40f 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -175,10 +175,11 @@ export function registerSynthSounds() { }; const factory = () => new AudioWorkletNode(ac, 'supersaw-oscillator', { outputChannelCount: [2] }); const o = getNodeFromPool('supersaw', factory); + const now = ac.currentTime; Object.entries(params).forEach(([key, value]) => { - if (value !== undefined) { - o.parameters.get(key).value = value; - } + const param = o.parameters.get(key); + const target = value !== undefined ? value : param.defaultValue; + param.setValueAtTime(target, now); }); o.port.postMessage({ type: 'initialize' }); o.port.onmessage = (e) => { diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 2cac9fac5..ea075c608 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -238,10 +238,11 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) { }; const factory = () => new AudioWorkletNode(ac, 'wavetable-oscillator-processor', { outputChannelCount: [2] }); const source = getNodeFromPool('wavetable', factory); + const now = ac.currentTime; Object.entries(params).forEach(([key, value]) => { - if (value !== undefined) { - source.parameters.get(key).value = value; - } + const param = source.parameters.get(key); + const target = value !== undefined ? value : param.defaultValue; + param.setValueAtTime(target, now); }); source.port.postMessage({ type: 'initialize', payload }); source.port.onmessage = (e) => {