From 2c880e2596c31d88b27b7df757351b3e7b1d932f Mon Sep 17 00:00:00 2001 From: superdirtspatz Date: Sat, 18 Jan 2025 15:06:07 +0100 Subject: [PATCH] added lowpass filter lfo --- packages/core/controls.mjs | 13 +++++++++++++ packages/superdough/helpers.mjs | 13 +++++++++---- packages/superdough/superdough.mjs | 2 ++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 5a2752944..58edf68b8 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -546,6 +546,19 @@ export const { cut } = registerControl('cut'); */ export const { cutoff, ctf, lpf, lp } = registerControl(['cutoff', 'resonance', 'lpenv'], 'ctf', 'lpf', 'lp'); +/** + * Sets the lowpass filter lfo modulation depth. + * @name lplfo + * @param {number | Pattern} modulation depth of the lowpass filter lfo between 0 and _n_ + * @example + * note("c2 e2 f2 g2") + * .sound('sawtooth') + * .lpf(300) + * .lplfo(2) + */ +export const { lplfo } = registerControl('lplfo'); + + /** * Sets the lowpass filter envelope modulation depth. * @name lpenv diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index e51156fec..64f7c12d6 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -112,11 +112,11 @@ export const getADSRValues = (params, curve = 'linear', defaultValues) => { return [Math.max(a ?? 0, envmin), Math.max(d ?? 0, envmin), Math.min(sustain, envmax), Math.max(r ?? 0, releaseMin)]; }; -export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fenv, start, end, fanchor, model, drive) { +export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fenv, start, end, fanchor, model, drive, flfo) { const curve = 'exponential'; const [attack, decay, sustain, release] = getADSRValues([att, dec, sus, rel], curve, [0.005, 0.14, 0, 0.1]); let filter; - let frequencyParam; + let frequencyParam,detuneParam; if (model === 'ladder') { filter = getWorklet(context, 'ladder-processor', { frequency, q: Q, drive }); frequencyParam = filter.parameters.get('frequency'); @@ -126,6 +126,7 @@ export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fe filter.Q.value = Q; filter.frequency.value = frequency; frequencyParam = filter.frequency; + detuneParam = filter.detune } // envelope is active when any of these values is set @@ -140,7 +141,11 @@ export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fe let max = clamp(2 ** (fenvAbs - offset) * frequency, 0, 20000); if (fenv < 0) [min, max] = [max, min]; getParamADSR(frequencyParam, attack, decay, sustain, release, min, max, start, end, curve); - return filter; + } + const hasLFO = detuneParam&&flfo !== undefined; + if (hasLFO !== undefined) { + let lfo = getVibratoOscillator(detuneParam, {vib:flfo,vibmod:4}, start); + } return filter; } @@ -243,7 +248,7 @@ export function applyFM(param, value, begin) { duration, } = value; let modulator; - let stop = () => {}; + let stop = () => { }; if (fmModulationIndex) { const ac = getAudioContext(); diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index b61f42637..3a9cc8f6b 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -357,6 +357,7 @@ export const superdough = async (value, t, hapDuration) => { lpdecay, lpsustain, lprelease, + lplfo, resonance = getDefaultValue('resonance'), // high pass hpenv, @@ -475,6 +476,7 @@ export const superdough = async (value, t, hapDuration) => { fanchor, ftype, drive, + lplfo, ); chain.push(lp()); if (ftype === '24db') {