diff --git a/packages/webaudio/helpers.mjs b/packages/webaudio/helpers.mjs index 1ed1e637..24ee03c8 100644 --- a/packages/webaudio/helpers.mjs +++ b/packages/webaudio/helpers.mjs @@ -27,12 +27,15 @@ export const getEnvelope = (attack, decay, sustain, release, velocity, begin) => return { node: gainNode, stop: (t) => { - gainNode.gain.setValueAtTime(sustain * velocity, t); + if (typeof gainNode.gain.cancelAndHoldAtTime === 'function') { + gainNode.gain.cancelAndHoldAtTime(t); + } else { + // firefox: this will glitch when the sustain has not been reached yet at the time of release + gainNode.gain.setValueAtTime(sustain * velocity, t); + } gainNode.gain.linearRampToValueAtTime(0, t + release); }, }; - // gainNode.gain.linearRampToValueAtTime(0, end + release); // release - // return gainNode; }; export const getADSR = (attack, decay, sustain, release, velocity, begin, end) => { diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index 4266455a..1f1325b7 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -223,9 +223,12 @@ export async function onTriggerSample(t, value, onended, bank) { }*/ const { node: envelope, stop: releaseEnvelope } = getEnvelope(attack, decay, sustain, release, 1, t); bufferSource.connect(envelope); + const out = ac.createGain(); // we need a separate gain for the cutgroups because firefox... + envelope.connect(out); bufferSource.onended = function () { bufferSource.disconnect(); envelope.disconnect(); + out.disconnect(); onended(); }; const stop = (endTime, playWholeBuffer = !clip) => { @@ -236,15 +239,14 @@ export async function onTriggerSample(t, value, onended, bank) { bufferSource.stop(releaseTime + release); releaseEnvelope(releaseTime); }; - const handle = { node: envelope, bufferSource, stop }; + const handle = { node: out, bufferSource, stop }; // cut groups - // TODO: sometimes, the cutting won't work for very fast triggering... - // it worked before :-/ if (cut !== undefined) { const prev = cutGroups[cut]; if (prev) { - prev.stop(time, false); + prev.node.gain.setValueAtTime(1, time); + prev.node.gain.linearRampToValueAtTime(0, time + 0.01); } cutGroups[cut] = handle; }