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);
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);
Share
Improve this question
edited Jan 9, 2016 at 15:31
Marcos Dimitrio
6,8726 gold badges41 silver badges64 bronze badges
asked Jan 9, 2016 at 14:21
EindbaasEindbaas
9851 gold badge8 silver badges19 bronze badges
1
- I have exactly the same problem, have been pulling my hair for days. The problem is that when you schedule the next note, it will cancel scheduled values, so it will totally cancel the ramp of the previous note if the decay is long enough. – Luis Crespo Commented Jan 14, 2016 at 0:10
3 Answers
Reset to default 4I 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./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 patibility table on MDN for updates. It does appear to be part of the official spec so it should be implemented across modern browsers eventually.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745322430a4622502.html
评论列表(0条)