Skip to content
This repository was archived by the owner on Jun 19, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/core/controls.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,18 @@ 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
Expand Down
26 changes: 23 additions & 3 deletions packages/superdough/helpers.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,27 @@ 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');
Expand All @@ -126,6 +142,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
Expand All @@ -140,7 +157,10 @@ 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;
}
Expand Down
2 changes: 2 additions & 0 deletions packages/superdough/superdough.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ export const superdough = async (value, t, hapDuration) => {
lpdecay,
lpsustain,
lprelease,
lplfo,
resonance = getDefaultValue('resonance'),
// high pass
hpenv,
Expand Down Expand Up @@ -475,6 +476,7 @@ export const superdough = async (value, t, hapDuration) => {
fanchor,
ftype,
drive,
lplfo,
);
chain.push(lp());
if (ftype === '24db') {
Expand Down
21 changes: 21 additions & 0 deletions test/__snapshots__/examples.test.mjs.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4496,6 +4496,27 @@ exports[`runs examples > example "lpf" example index 1 1`] = `
]
`;

exports[`runs examples > example "lplfo" example index 0 1`] = `
[
"[ 0/1 → 1/4 | note:c2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 1/4 → 1/2 | note:e2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 1/2 → 3/4 | note:f2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 3/4 → 1/1 | note:g2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 1/1 → 5/4 | note:c2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 5/4 → 3/2 | note:e2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 3/2 → 7/4 | note:f2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 7/4 → 2/1 | note:g2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 2/1 → 9/4 | note:c2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 9/4 → 5/2 | note:e2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 5/2 → 11/4 | note:f2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 11/4 → 3/1 | note:g2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 3/1 → 13/4 | note:c2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 13/4 → 7/2 | note:e2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 7/2 → 15/4 | note:f2 s:sawtooth cutoff:300 lplfo:2 ]",
"[ 15/4 → 4/1 | note:g2 s:sawtooth cutoff:300 lplfo:2 ]",
]
`;

exports[`runs examples > example "lpq" example index 0 1`] = `
[
"[ 0/1 → 1/8 | s:hh cutoff:2000 resonance:0 ]",
Expand Down
Loading