I'm trying to implement volume envelopes that can restart on any given moment, even if it's already in the middle of a param-movement but I can't figure out how to do this without clicks in the resulting audio (which seem to be somewhat irregular with regards to when they occur).
Is this even possible? I see that AudioParam.cancelScheduledValues()
"cancels all scheduled future changes to the AudioParam", but I'm not sure what happens on a change that is currently going.
This is the code I'm using to start/restart the volume envelope.
var now = context.currentTime;
var currentVol = gain.gain.value;
gain.gain.cancelScheduledValues(now);
gain.gain.setValueAtTime(currentVol, now);
gain.gain.exponentialRampToValueAtTime(1, now + volAttack);
gain.gain.exponentialRampToValueAtTime(0.000001, now + volAttack + volDecay);
The close() method of the AudioContext Interface closes the audio context, releasing any system audio resources that it uses.
The Web Audio API provides a powerful and versatile system for controlling audio on the Web, allowing developers to choose audio sources, add effects to audio, create audio visualizations, apply spatial effects (such as panning) and much more.
I find custom curves work more reliably and are more controllable
function expCurve(start, end) {
var count = 10;
var t = 0;
var curve = new Float32Array(count + 1);
start = Math.max(start, 0.0000001);
end = Math.max(end, 0.0000001);
for (var i = 0; i <= count; ++i) {
curve[i] = start * Math.pow(end / start, t);
t += 1/count;
}
return curve;
}
gain.gain.cancelScheduledValues(0);
var currentVol = gain.gain.value;
var now = context.currentTime;
gain.gain.setValueCurveAtTime(expCurve(currentVol, 1), now, volAttack);
gain.gain.setValueCurveAtTime(expCurve(1, 0), now + volAttack, volDecay);
After asking at the slack Web Audio channel, they explained to me that this is a known issue of the current spec.
Here is the link to the issue at GitHub: https://github.com/WebAudio/web-audio-api/issues/344
So the short answer is that stopping ramps halfway through is currently not supported. So as a workaround, they have to be controlled at every segment.
I believe you may be looking for cancelAndHoldAtTime()
. According to MDN:
The cancelAndHoldAtTime() property of the AudioParam interface cancels all scheduled future changes to the AudioParam but holds its value at a given time until further changes are made using other methods.
The added ability to hold the value until further changes are made seem to be what you are looking for. I'm using the web audio API to create an amplitude envelope right now and it seems to be working.
Note: as of August 2022, this function is only implemented in Chrome and Safari. See the compatibility table on MDN for updates. It does appear to be part of the official spec so it should be implemented across modern browsers eventually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With