diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 4fda54eb..f28fcfae 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -66,19 +66,33 @@ export const getADSR = (attack, decay, sustain, release, velocity, begin, end) = return gainNode; }; -export function createFilter(context, type, frequency, Q, attack, decay, sustain, release, fenvmod, t) { +export const getParamADSR = (param, attack, decay, sustain, release, velocity, begin, end) => { + param.setValueAtTime(0, begin); + param.linearRampToValueAtTime(velocity, begin + attack); + param.linearRampToValueAtTime(sustain * velocity, begin + attack + decay); + param.setValueAtTime(sustain * velocity, end); + param.linearRampToValueAtTime(0, end + release - 0.1); +}; + +export function createFilter(context, type, frequency, Q, attack, decay, sustain, release, fenv, t) { const filter = context.createBiquadFilter(); filter.type = type; filter.frequency.value = frequency; filter.Q.value = Q; // Apply ADSR to filter frequency - if (fenvmod > 0) { - const sustainFreq = sustain * frequency; - filter.frequency.linearRampToValueAtTime(frequency * fenvmod, t + attack); - filter.frequency.linearRampToValueAtTime(sustainFreq, t + attack + decay); - filter.frequency.setValueAtTime(sustainFreq, end); - filter.frequency.linearRampToValueAtTime(frequency, end + release); + if (fenv > 0) { + const envelope = getParamADSR( + filter.frequency, + attack, + decay, + sustain, + release, + frequency * fenv > 22000 ? 22000 : frequency * fenv, + t, + t + attack + decay + release, + ); + return filter; } return filter; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 6605662a..b5c55b0a 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -179,32 +179,32 @@ export const superdough = async (value, deadline, hapDuration) => { gain = 0.8, // filters order = '12db', - fenvmod = 2, + fenv, // low pass - lpattack, - lpdecay, - lpsustain, - lprelease, cutoff, + lpattack = 0.01, + lpdecay = 0.5, + lpsustain = 0.6, + lprelease = 0.01, resonance = 1, // high pass - hpattack, - hpdecay, - hpsustain, - hprelease, hcutoff, + hpattack = 0.01, + hpdecay = 0.5, + hpsustain = 0.6, + hprelease = 0.01, hresonance = 1, + // band pass + bandf, + bpattack = 0.01, + bpdecay = 0.5, + bpsustain = 0.6, + bprelease = 0.01, + bandq = 1, // full adsr for filter lpadsr, hpadsr, bpadsr, - // band pass - bandf, - bpattack, - bpdecay, - bpsustain, - bprelease, - bandq = 1, // coarse, crush, @@ -230,8 +230,8 @@ export const superdough = async (value, deadline, hapDuration) => { s = `${bank}_${s}`; } lpadsr && (lpattack = lpadsr[0]) && (lpdecay = lpadsr[1]) && (lpsustain = lpadsr[2]) && (lprelease = lpadsr[3]); - bpadsr && (bpattack = bpadsr[0]) && (bpdecay = bpadsr[1]) && (bpsustain = bpadsr[2]) && (bprelease = bpadsr[3]); hpadsr && (hpattack = hpadsr[0]) && (hpdecay = hpadsr[1]) && (hpsustain = hpadsr[2]) && (hprelease = hpadsr[3]); + bpadsr && (bpattack = bpadsr[0]) && (bpdecay = bpadsr[1]) && (bpsustain = bpadsr[2]) && (bprelease = bpadsr[3]); // get source AudioNode let sourceNode; if (source) { @@ -262,38 +262,16 @@ export const superdough = async (value, deadline, hapDuration) => { chain.push(gainNode(gain)); if (cutoff !== undefined) { - const filter1 = createFilter(ac, 'lowpass', cutoff, resonance, lpattack, lpdecay, lpsustain, lprelease, fmodenv, t); + const filter1 = createFilter(ac, 'lowpass', cutoff, resonance, lpattack, lpdecay, lpsustain, lprelease, fenv, t); chain.push(filter1); if (order === '24db') { - const filter2 = createFilter( - ac, - 'lowpass', - cutoff, - resonance, - lpattack, - lpdecay, - lpsustain, - lprelease, - fmodenv, - t, - ); + const filter2 = createFilter(ac, 'lowpass', cutoff, resonance, lpattack, lpdecay, lpsustain, lprelease, fenv, t); chain.push(filter2); } } if (hcutoff !== undefined) { - const filter1 = createFilter( - ac, - 'highpass', - hcutoff, - hresonance, - hpattack, - hpdecay, - hpsustain, - hprelease, - fenvmod, - t, - ); + const filter1 = createFilter(ac, 'highpass', hcutoff, hresonance, hpattack, hpdecay, hpsustain, hprelease, fenv, t); chain.push(filter1); if (order === '24db') { const filter2 = createFilter( @@ -305,7 +283,7 @@ export const superdough = async (value, deadline, hapDuration) => { hpdecay, hpsustain, hprelease, - fenvmod, + fenv, t, ); chain.push(filter2); @@ -313,10 +291,10 @@ export const superdough = async (value, deadline, hapDuration) => { } if (bandf !== undefined) { - const filter1 = createFilter(ac, 'bandpass', bandf, bandq, bpattack, bpdecay, bpsustain, bprelease, fenvmod, t); + const filter1 = createFilter(ac, 'bandpass', bandf, bandq, bpattack, bpdecay, bpsustain, bprelease, fenv, t); chain.push(filter1); if (order === '24db') { - const filter2 = createFilter(ac, 'bandpass', bandf, bandq, bpattack, bpdecay, bpsustain, bprelease, fenvmod, t); + const filter2 = createFilter(ac, 'bandpass', bandf, bandq, bpattack, bpdecay, bpsustain, bprelease, fenv, t); chain.push(filter2); } }