From df047fd48dbb4df27ca596f2ca085eeb2fb86c4d Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 23 Nov 2025 22:28:10 -0600 Subject: [PATCH] Optimizations --- packages/core/controls.mjs | 14 +++++++++++++- packages/superdough/superdough.mjs | 2 -- packages/superdough/worklets.mjs | 16 +++++++++++----- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 80a244efc..bca7036ad 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -2585,4 +2585,16 @@ export const scrub = register( false, ); -export const { transient } = registerControl(['transient', 'transsustain', 'transattack']); +/** + * Transient shaper. Gives independent control over the emphasis on transients + * and sustains + * + * @name transient + * @param {number | Pattern} attack Emphasis on transients; between -1 (deaccentuate) and 1 (accentuate) + * @param {number | Pattern} sustain Emphasis on the sustains; between -1 (deaccentuate) and 1 (accentuate) + * @example + * s("bd").transient("<-1 -0.5 0 0.5 1>") + * @example + * s("hh*16").bank("tr909").transient("<-1:1 1:-1>") + */ +export const { transient } = registerControl(['transient', 'transsustain']); diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index acf6edef2..ac6ca7322 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -453,7 +453,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) compressorRelease, transient, transsustain, - transattack, } = value; delaytime = delaytime ?? cycleToSeconds(delaysync, cps); @@ -545,7 +544,6 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) processorOptions: { attack: transient, sustain: transsustain, - attackTime: transattack, }, }, ), diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 6af7dffc1..6b370166c 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -1412,6 +1412,10 @@ class TransientProcessor extends AudioWorkletProcessor { this.sustainAmt = clamp(sustain, -1, 1); this.scaling = 0.5 + 5 * clamp(sensitivity, 0, 1); this.mix = clamp(mix, 0, 1); + const maxAttackDb = this.attackAmt * 6; + const maxSustainDb = this.sustainAmt * 36; + this.attackMaxGain = dbToLin(maxAttackDb) - 1; // increasing from 1 + this.sustainMaxGain = dbToLin(maxSustainDb) - 1; } process(inputs, outputs, _params) { @@ -1433,15 +1437,17 @@ class TransientProcessor extends AudioWorkletProcessor { attEnv = lerp(attEnv, x, this.attackCoeff); susEnv = lerp(susEnv, x, this.sustainCoeff); const peakiness = clamp((this.scaling * (attEnv - susEnv)) / (susEnv + 1e-6), -1.5, 1.5); - const attScale = Math.max(0, peakiness); - const susScale = Math.max(0, -peakiness); - const attackGain = dbToLin(this.attackAmt * attScale * 18); // max 18db - const sustainGain = dbToLin(this.sustainAmt * susScale * 36); // max 36db + const attScale = peakiness > 0 ? peakiness : 0; + const susScale = peakiness < 0 ? -peakiness : 0; + const attackGain = 1 + attScale * this.attackMaxGain; + const sustainGain = 1 + susScale * this.sustainMaxGain; const gain = clamp(attackGain * sustainGain, 0, 8); avgGain = lerp(avgGain, gain, this.gainCoeff); const makeup = avgGain > 1e-3 ? 1 / avgGain : 1; const wet = x * gain * makeup; - output[ch][n] = lerp(sample, wet, this.mix); + let y = lerp(sample, wet, this.mix); + y /= (1 + Math.abs(y)); // soft clip + output[ch][n] = y; } this.attackEnv[ch] = attEnv; this.sustainEnv[ch] = susEnv;