From ee0aaca2b0725c05b111f9f42df57d2a63d7fdce Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 31 Aug 2023 04:13:41 +0200 Subject: [PATCH] only use fm envelope when needed --- packages/core/controls.mjs | 7 ++++++ packages/superdough/synth.mjs | 44 ++++++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index b8edd51c..9901f974 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -134,6 +134,13 @@ const generic_params = [ * */ [['fmi', 'fmh'], 'fm'], + // fm envelope + ['fmenv'], + ['fmattack'], + ['fmdecay'], + ['fmsustain'], + ['fmrelease'], + ['fmvelocity'], /** * Select the sound bank to use. To be used together with `s`. The bank name (+ "_") will be prepended to the value of `s`. diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index d8097745..dbaab5e4 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -26,7 +26,7 @@ export function registerSynthSounds() { wave, (t, value, onended) => { // destructure adsr here, because the default should be different for synths and samples - const { + let { attack = 0.001, decay = 0.05, sustain = 0.6, @@ -34,11 +34,11 @@ export function registerSynthSounds() { fmh: fmHarmonicity = 1, fmi: fmModulationIndex, fmenv: fmEnvelopeType = 'linear', - fmattack: fmAttack = 0.001, - fmdecay: fmDecay = 0.2, - fmsustain: fmSustain = 0.001, - fmrelease: fmRelease = 0.1, - fmvelocity: fmVelocity = 1, + fmattack: fmAttack, // = 0.001, + fmdecay: fmDecay, // = 0.2, + fmsustain: fmSustain, // = 0.001, + fmrelease: fmRelease, // = 0.1 + fmvelocity: fmVelocity, // = 1, fmwave: fmWaveform = 'sine', } = value; let { n, note, freq } = value; @@ -55,22 +55,37 @@ export function registerSynthSounds() { // make oscillator const { node: o, stop } = getOscillator({ t, s: wave, freq }); + // FM + FM envelope let stopFm, fmEnvelope; if (fmModulationIndex) { const { node: modulator, stop } = fm(o, fmHarmonicity, fmModulationIndex, fmWaveform); - fmEnvelope = getEnvelope(fmAttack, fmDecay, fmSustain, fmRelease, fmVelocity, t); - if (fmEnvelopeType === 'exp') { - fmEnvelope = getExpEnvelope(fmAttack, fmDecay, fmVelocity, t); - fmEnvelope.node.maxValue = fmModulationIndex * 2; - fmEnvelope.node.minValue = 0.00001; + if ([fmAttack, fmDecay, fmSustain, fmRelease, fmVelocity].find((v) => v !== undefined)) { + // no envelope by default + modulator.connect(o.frequency); + } else { + fmAttack = fmAttack ?? 0.001; + fmDecay = fmDecay ?? 0.001; + fmSustain = fmSustain ?? 1; + fmRelease = fmRelease ?? 0.001; + fmVelocity = fmVelocity ?? 1; + fmEnvelope = getEnvelope(fmAttack, fmDecay, fmSustain, fmRelease, fmVelocity, t); + if (fmEnvelopeType === 'exp') { + fmEnvelope = getExpEnvelope(fmAttack, fmDecay, fmVelocity, t); + fmEnvelope.node.maxValue = fmModulationIndex * 2; + fmEnvelope.node.minValue = 0.00001; + } + modulator.connect(fmEnvelope.node); + fmEnvelope.node.connect(o.frequency); } - modulator.connect(fmEnvelope.node); - fmEnvelope.node.connect(o.frequency); stopFm = stop; } + + // turn down const g = gainNode(0.3); - // envelope + + // gain envelope const { node: envelope, stop: releaseEnvelope } = getEnvelope(attack, decay, sustain, release, 1, t); + o.onended = () => { o.disconnect(); g.disconnect(); @@ -80,6 +95,7 @@ export function registerSynthSounds() { node: o.connect(g).connect(envelope), stop: (releaseTime) => { releaseEnvelope(releaseTime); + fmEnvelope?.stop(releaseTime); let end = releaseTime + release; stop(end); stopFm?.(end);