Skip to content

Commit

Permalink
Merge pull request tidalcycles#861 from tidalcycles/envelope-fix
Browse files Browse the repository at this point in the history
fix: finally repair envelopes
  • Loading branch information
felixroos authored Dec 12, 2023
2 parents 73fd801 + f38d1c2 commit 1d3f87a
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 17 deletions.
4 changes: 2 additions & 2 deletions packages/soundfonts/fontloader.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ export function registerSoundfonts() {
const { node: envelope, stop: releaseEnvelope } = getEnvelope(attack, decay, sustain, release, 0.3, time);
bufferSource.connect(envelope);
const stop = (releaseTime) => {
bufferSource.stop(releaseTime + release);
releaseEnvelope(releaseTime);
const silentAt = releaseEnvelope(releaseTime);
bufferSource.stop(silentAt);
};
bufferSource.onended = () => {
bufferSource.disconnect();
Expand Down
23 changes: 13 additions & 10 deletions packages/superdough/helpers.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,24 @@ export function gainNode(value) {
// alternative to getADSR returning the gain node and a stop handle to trigger the release anytime in the future
export const getEnvelope = (attack, decay, sustain, release, velocity, begin) => {
const gainNode = getAudioContext().createGain();
let phase = begin;
gainNode.gain.setValueAtTime(0, begin);
gainNode.gain.linearRampToValueAtTime(velocity, begin + attack); // attack
gainNode.gain.linearRampToValueAtTime(sustain * velocity, begin + attack + decay); // sustain start
phase += attack;
gainNode.gain.linearRampToValueAtTime(velocity, phase); // attack
phase += decay;
let sustainLevel = sustain * velocity;
gainNode.gain.linearRampToValueAtTime(sustainLevel, phase); // decay / sustain
// sustain end
return {
node: gainNode,
stop: (t) => {
//if (typeof gainNode.gain.cancelAndHoldAtTime === 'function') {
// gainNode.gain.cancelAndHoldAtTime(t); // this seems to release instantly....
// see https://discord.com/channels/779427371270275082/937365093082079272/1086053607360712735
//} 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);
// to make sure the release won't begin before sustain is reached
phase = Math.max(t, phase);
// see https://github.com/tidalcycles/strudel/issues/522
gainNode.gain.setValueAtTime(sustainLevel, phase);
phase += release;
gainNode.gain.linearRampToValueAtTime(0, phase); // release
return phase;
},
};
};
Expand Down
4 changes: 2 additions & 2 deletions packages/superdough/sampler.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,8 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) {
const bufferDuration = bufferSource.buffer.duration / bufferSource.playbackRate.value;
releaseTime = t + (end - begin) * bufferDuration;
}
bufferSource.stop(releaseTime + release);
releaseEnvelope(releaseTime);
const silentAt = releaseEnvelope(releaseTime);
bufferSource.stop(silentAt);
};
const handle = { node: out, bufferSource, stop };

Expand Down
5 changes: 2 additions & 3 deletions packages/superdough/synth.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,9 @@ export function registerSynthSounds() {
return {
node: o.connect(g).connect(envelope),
stop: (releaseTime) => {
releaseEnvelope(releaseTime);
const silentAt = releaseEnvelope(releaseTime);
triggerRelease?.(releaseTime);
let end = releaseTime + release;
stop(end);
stop(silentAt);
},
};
},
Expand Down

0 comments on commit 1d3f87a

Please sign in to comment.