Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

future cancellations should run affected automations up to the cancellation point #3

Open
attilammagyar opened this issue Nov 6, 2022 · 0 comments

Comments

@attilammagyar
Copy link

According to the specifications, automations that are cancelled halfway through should run until the cancellation point like nothing happened. Unfortunately, the polyfill only removes the affected automation and sets its calculated value at cancelTime, which may work fine if the cancellation falls close to currentTime, but it results in a hard, discontinuous, audible change if the cancellation point is way in the future.

To fix this, after finding the automation which is happening at cancelTime, calculating its value at the cancellation point, and calling cancelScheduledValues(cancelTime), the polyfill should finally reintroduce the same type of automation but limited to the time interval between its original starting point and the cancellation point, with the calculated value as its target.

Demonstration:

const DELAY = 0.03,
      ATTACK = 0.3,
      HOLD = 0.5,
      DECAY = 3.0,
      PEAK = 0.7,
      SUSTAIN = 0.2,
      RELEASE = 1.0,
      NOTE_OFF = DELAY + ATTACK + HOLD + DECAY * 0.8;

var audio_ctx = new AudioContext(),
    osc, gain, ct;

gain = audio_ctx.createGain();
gain.gain.value = 0.0;

osc = audio_ctx.createOscillator();
osc.frequency.value = 220.0;
osc.type = "sine";

osc.connect(gain);
gain.connect(audio_ctx.destination);

ct = audio_ctx.currentTime;

// note on
osc.start(ct + DELAY);
gain.gain.setValueAtTime(0.0, ct + DELAY);
gain.gain.linearRampToValueAtTime(PEAK, ct + DELAY + ATTACK);
gain.gain.linearRampToValueAtTime(PEAK, ct + DELAY + ATTACK + HOLD);
gain.gain.linearRampToValueAtTime(SUSTAIN, ct + DELAY + ATTACK + HOLD + DECAY);

// note off
gain.gain.cancelAndHoldAtTime(ct + NOTE_OFF);
gain.gain.linearRampToValueAtTime(0.0, ct + NOTE_OFF + RELEASE);
osc.stop(ct + NOTE_OFF + RELEASE);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant