From 47c85f8540386d36c42c5bc64f952bde12ac79d5 Mon Sep 17 00:00:00 2001 From: jeromew Date: Thu, 16 Oct 2025 14:06:33 +0200 Subject: [PATCH 1/5] fix interoperability of `all` with hydra Hydra add methods on Array.prototype which breaks the Array enumeration with for...in. Use for...of instead cf https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of#difference_between_for...of_and_for...in for details on the issue without this fix, it is impossible to use both `await initHydra()` and `all` in the same strudel code. Strudel errors with "Error: got "undefined" instead of pattern." example code: https://strudel.cc/#YXdhaXQgaW5pdEh5ZHJhKCkKCmFsbChwaWFub3JvbGwpCgokOiBzKCJiZCIp --- packages/core/repl.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 171697eb9..064ef1eb8 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -227,8 +227,8 @@ export function repl({ pattern = eachTransform(pattern); } if (allTransforms.length) { - for (let i in allTransforms) { - pattern = allTransforms[i](pattern); + for (const transform of allTransforms) { + pattern = transform(pattern); } } From 907f03f3bfe35bc4b6695490030e6f4822747629 Mon Sep 17 00:00:00 2001 From: jeromew Date: Thu, 20 Nov 2025 17:40:51 +0000 Subject: [PATCH 2/5] [perf] fix `connect-leak` in fm modulation --- packages/superdough/helpers.mjs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index de64df0e8..58c4aa35e 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -362,9 +362,9 @@ const mod = (freq, range = 1, type = 'sine') => { } osc.start(); - const g = new GainNode(ctx, { gain: range }); + const g = gainNode(range); osc.connect(g); // -range, range - return { node: g, stop: (t) => osc.stop(t) }; + return { node: g, stop: (t) => osc.stop(t), osc: osc }; }; const fm = (frequencyparam, harmonicityRatio, modulationIndex, wave = 'sine') => { const carrfreq = frequencyparam.value; @@ -416,6 +416,11 @@ export function applyFM(param, value, begin) { modulator.connect(envGain); envGain.connect(param); } + fmmod.osc.onended = () => { + envGain.disconnect(); + modulator.disconnect(); + fmmod.osc.disconnect(); + }; } return { stop }; } From f637b8b0dd0c3bbe29c53d128a943b9e6260be9b Mon Sep 17 00:00:00 2001 From: jeromew Date: Thu, 20 Nov 2025 17:40:51 +0000 Subject: [PATCH 3/5] [perf] fix `connect-leak` in fm modulation --- packages/superdough/helpers.mjs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index de64df0e8..58c4aa35e 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -362,9 +362,9 @@ const mod = (freq, range = 1, type = 'sine') => { } osc.start(); - const g = new GainNode(ctx, { gain: range }); + const g = gainNode(range); osc.connect(g); // -range, range - return { node: g, stop: (t) => osc.stop(t) }; + return { node: g, stop: (t) => osc.stop(t), osc: osc }; }; const fm = (frequencyparam, harmonicityRatio, modulationIndex, wave = 'sine') => { const carrfreq = frequencyparam.value; @@ -416,6 +416,11 @@ export function applyFM(param, value, begin) { modulator.connect(envGain); envGain.connect(param); } + fmmod.osc.onended = () => { + envGain.disconnect(); + modulator.disconnect(); + fmmod.osc.disconnect(); + }; } return { stop }; } From 1d5f3a4f30c415b53ea1b0a5d88d31d318725631 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 22 Nov 2025 18:21:24 -0500 Subject: [PATCH 4/5] prevent filter modulation pops --- packages/superdough/helpers.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index de64df0e8..8e45f7bca 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -238,7 +238,7 @@ export function createFilter(context, start, end, params, cps) { if (sync != null) { rate = cps * sync; } - const lfoValues = { depth, dcoffset, skew, shape, frequency: rate }; + const lfoValues = { depth, dcoffset, skew, shape, frequency: rate, min: 10, max: 20000 }; getParamLfo(context, frequencyParam, start, end, lfoValues); return filter; } From adc3a9ac6cb780c653c843c5c296c5fbb8f106b0 Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 22 Nov 2025 20:51:30 -0600 Subject: [PATCH 5/5] Swap with temp variable --- packages/superdough/worklets.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index e60cd223e..bf633a63b 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -543,8 +543,9 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor { if (pn >= 1.0) pn -= 1.0; this.phase[n] = pn; // invert right and left gain + const tmp = gainL; gainL = gainR; - gainR = gainL; + gainR = tmp; } } return true;