From 93a4efcf6d0ac943298d118de56a0203928c3003 Mon Sep 17 00:00:00 2001 From: Jade Rowland Date: Sat, 16 Dec 2023 13:21:23 -0500 Subject: [PATCH] updated fontloader --- packages/soundfonts/fontloader.mjs | 12 +++++++-- packages/superdough/helpers.mjs | 43 +++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/packages/soundfonts/fontloader.mjs b/packages/soundfonts/fontloader.mjs index 017ba763..b6c8c8b4 100644 --- a/packages/soundfonts/fontloader.mjs +++ b/packages/soundfonts/fontloader.mjs @@ -1,5 +1,5 @@ import { noteToMidi, freqToMidi } from '@strudel.cycles/core'; -import { getAudioContext, registerSound, getEnvelope } from '@strudel.cycles/webaudio'; +import { getAudioContext, registerSound, getEnvelope, getADSRValues } from '@strudel.cycles/webaudio'; import gm from './gm.mjs'; let loadCache = {}; @@ -131,7 +131,15 @@ export function registerSoundfonts() { name, async (time, value, onended) => { const { n = 0 } = value; - const { attack = 0.001, decay = 0.001, sustain = 1, release = 0.001 } = value; + const [attack, decay, sustain, release] = getADSRValues([ + value.attack, + value.decay, + value.sustain, + value.release, + ]); + + console.log(attack, decay, sustain, release); + const font = fonts[n % fonts.length]; const ctx = getAudioContext(); const bufferSource = await getFontBufferSource(font, value, ctx); diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 1bc1a878..e8c695b8 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -70,18 +70,41 @@ export const getADSR = (attack, decay, sustain, release, velocity, begin, end) = return gainNode; }; -export const getParamADSR = (param, attack, decay, sustain, release, min, max, begin, end) => { - // let phase = begin; +export const getParamADSR = ( + context, + param, + attack, + decay, + sustain, + release, + min, + max, + begin, + end, + //exponential works better for frequency modulations (such as filter cutoff) due to human ear perception + curve = 'exponential', +) => { + const ramp = curve === 'exponential' ? 'exponentialRampToValueAtTime' : 'linearRampToValueAtTime'; + let phase = begin; const range = max - min; const peak = min + range; - const sustainLevel = min + sustain * range; + param.setValueAtTime(min, begin); - param.exponentialRampToValueAtTime(peak, begin + attack); - param.exponentialRampToValueAtTime(sustainLevel, begin + attack + decay); - //stop current envelope ramp at event end, and begin release ramp - console.log(param); - param.cancelAndHoldAtTime(end); - param.exponentialRampToValueAtTime(min, end + Math.max(release, 0.1)); + phase += attack; + //attack + param[ramp](peak, phase); + phase += decay; + const sustainLevel = min + sustain * range; + //decay + param[ramp](sustainLevel, phase); + //this timeout can be replaced with cancelAndHoldAtTime once it is implemented in Firefox + setTimeout(() => { + //sustain at current value + param.cancelScheduledValues(0); + phase += Math.max(release, 0.1); + //release + param[ramp](min, phase); + }, (end - context.currentTime) * 1000); }; export function getCompressor(ac, threshold, ratio, knee, attack, release) { @@ -123,7 +146,7 @@ export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fe const min = clamp(2 ** -offset * frequency, 0, 20000); const max = clamp(2 ** (fenv - offset) * frequency, 0, 20000); - getParamADSR(filter.frequency, attack, decay, sustain, release, min, max, start, end); + getParamADSR(context, filter.frequency, attack, decay, sustain, release, min, max, start, end); return filter; }