From 130ad4451b7af054371992220342a0658b9543d7 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 8 Oct 2023 00:30:12 +0200 Subject: [PATCH 1/4] add compressor + postgain --- packages/core/controls.mjs | 6 ++++++ packages/superdough/helpers.mjs | 11 +++++++++++ packages/superdough/superdough.mjs | 15 +++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 88c2c072..832b09dc 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -86,6 +86,7 @@ const generic_params = [ * */ ['gain'], + ['postgain'], /** * Like {@link gain}, but linear. * @@ -1051,6 +1052,11 @@ const generic_params = [ * */ ['shape'], + [['compressor', 'compressorRatio', 'compressorKnee', 'compressorAttack', 'compressorRelease']], + ['compressorKnee'], + ['compressorRatio'], + ['compressorAttack'], + ['compressorRelease'], /** * Changes the speed of sample playback, i.e. a cheap way of changing pitch. * diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 576ec3f1..d87ea94d 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -78,6 +78,17 @@ export const getParamADSR = (param, attack, decay, sustain, release, min, max, b param.linearRampToValueAtTime(min, end + Math.max(release, 0.1)); }; +export function getCompressor(ac, threshold, ratio, knee, attack, release) { + const options = { + threshold: threshold ?? -3, + ratio: ratio ?? 10, + knee: knee ?? 10, + attack: attack ?? 0.005, + release: release ?? 0.05, + }; + return new DynamicsCompressorNode(ac, options); +} + export function createFilter( context, type, diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 730e495d..410b7b96 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -9,7 +9,7 @@ import './reverb.mjs'; import './vowel.mjs'; import { clamp } from './util.mjs'; import workletsUrl from './worklets.mjs?url'; -import { createFilter, gainNode } from './helpers.mjs'; +import { createFilter, gainNode, getCompressor } from './helpers.mjs'; import { map } from 'nanostores'; import { logger } from './logger.mjs'; @@ -192,6 +192,7 @@ export const superdough = async (value, deadline, hapDuration) => { bank, source, gain = 0.8, + postgain = 1, // filters ftype = '12db', fanchor = 0.5, @@ -237,6 +238,11 @@ export const superdough = async (value, deadline, hapDuration) => { velocity = 1, analyze, // analyser wet fft = 8, // fftSize 0 - 10 + compressor: compressorThreshold, + compressorRatio, + compressorKnee, + compressorAttack, + compressorRelease, } = value; gain *= velocity; // legacy fix for velocity let toDisconnect = []; // audio nodes that will be disconnected when the source has ended @@ -351,6 +357,11 @@ export const superdough = async (value, deadline, hapDuration) => { crush !== undefined && chain.push(getWorklet(ac, 'crush-processor', { crush })); shape !== undefined && chain.push(getWorklet(ac, 'shape-processor', { shape })); + compressorThreshold !== undefined && + chain.push( + getCompressor(ac, compressorThreshold, compressorRatio, compressorKnee, compressorAttack, compressorRelease), + ); + // panning if (pan !== undefined) { const panner = ac.createStereoPanner(); @@ -359,7 +370,7 @@ export const superdough = async (value, deadline, hapDuration) => { } // last gain - const post = gainNode(1); + const post = gainNode(postgain); chain.push(post); post.connect(getDestination()); From 0a3692e459ca2eb807b71f55ee6698d36dfd2aa3 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 8 Oct 2023 13:37:39 +0200 Subject: [PATCH 2/4] compressor docs --- packages/core/controls.mjs | 19 +++++++++++++++++++ website/src/pages/learn/effects.mdx | 9 +++++++++ 2 files changed, 28 insertions(+) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 832b09dc..3abeb504 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -86,6 +86,15 @@ const generic_params = [ * */ ['gain'], + /** + * Gain applied after all effects have been processed. + * + * @name postgain + * @example + * s("bd sd,hh*4") + * .compressor("-20:20:10:.002:.02").postgain(1.5) + * + */ ['postgain'], /** * Like {@link gain}, but linear. @@ -1052,6 +1061,16 @@ const generic_params = [ * */ ['shape'], + /** + * Dynamics Compressor. The params are `compressor("threshold:ratio:knee:attack:release")` + * More info [here](https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode?retiredLocale=de#instance_properties) + * + * @name compressor + * @example + * s("bd sd,hh*4") + * .compressor("-20:20:10:.002:.02") + * + */ [['compressor', 'compressorRatio', 'compressorKnee', 'compressorAttack', 'compressorRelease']], ['compressorKnee'], ['compressorRatio'], diff --git a/website/src/pages/learn/effects.mdx b/website/src/pages/learn/effects.mdx index 2ee6c44a..11b74646 100644 --- a/website/src/pages/learn/effects.mdx +++ b/website/src/pages/learn/effects.mdx @@ -144,6 +144,15 @@ There is one filter envelope for each filter type and thus one set of envelope f +## compressor + + + +## postgain + + + + # Panning ## jux From 08ce8213fcb09eb2dd709650b1f5339138a774bc Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 8 Oct 2023 13:37:56 +0200 Subject: [PATCH 3/4] format --- website/src/pages/learn/effects.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/website/src/pages/learn/effects.mdx b/website/src/pages/learn/effects.mdx index 11b74646..0bb9da9e 100644 --- a/website/src/pages/learn/effects.mdx +++ b/website/src/pages/learn/effects.mdx @@ -152,7 +152,6 @@ There is one filter envelope for each filter type and thus one set of envelope f - # Panning ## jux From 56c14414946796436db34f4f565a9c9ec437674d Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 8 Oct 2023 13:38:18 +0200 Subject: [PATCH 4/4] snapshot --- test/__snapshots__/examples.test.mjs.snap | 58 +++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 18370903..f351a5a0 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -1185,6 +1185,35 @@ exports[`runs examples > example "compress" example index 0 1`] = ` ] `; +exports[`runs examples > example "compressor" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 0/1 → 1/2 | s:bd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 1/4 → 1/2 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 1/2 → 3/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 1/2 → 1/1 | s:sd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 3/4 → 1/1 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 1/1 → 5/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 1/1 → 3/2 | s:bd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 5/4 → 3/2 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 3/2 → 7/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 3/2 → 2/1 | s:sd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 7/4 → 2/1 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 2/1 → 9/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 2/1 → 5/2 | s:bd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 9/4 → 5/2 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 5/2 → 11/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 5/2 → 3/1 | s:sd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 11/4 → 3/1 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 3/1 → 13/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 3/1 → 7/2 | s:bd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 13/4 → 7/2 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 7/2 → 15/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 7/2 → 4/1 | s:sd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", + "[ 15/4 → 4/1 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 ]", +] +`; + exports[`runs examples > example "cosine" example index 0 1`] = ` [ "[ 0/1 → 1/8 | note:Eb4 ]", @@ -3293,6 +3322,35 @@ exports[`runs examples > example "polymeterSteps" example index 0 1`] = ` ] `; +exports[`runs examples > example "postgain" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 0/1 → 1/2 | s:bd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 1/4 → 1/2 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 1/2 → 3/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 1/2 → 1/1 | s:sd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 3/4 → 1/1 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 1/1 → 5/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 1/1 → 3/2 | s:bd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 5/4 → 3/2 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 3/2 → 7/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 3/2 → 2/1 | s:sd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 7/4 → 2/1 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 2/1 → 9/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 2/1 → 5/2 | s:bd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 9/4 → 5/2 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 5/2 → 11/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 5/2 → 3/1 | s:sd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 11/4 → 3/1 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 3/1 → 13/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 3/1 → 7/2 | s:bd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 13/4 → 7/2 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 7/2 → 15/4 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 7/2 → 4/1 | s:sd compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", + "[ 15/4 → 4/1 | s:hh compressor:-20 compressorRatio:20 compressorKnee:10 compressorAttack:0.002 compressorRelease:0.02 postgain:1.5 ]", +] +`; + exports[`runs examples > example "press" example index 0 1`] = ` [ "[ 0/1 → 1/2 | s:hh ]",