- From: Lonce Wyse <lonce.wyse@zwhome.org>
- Date: Thu, 03 Jan 2013 09:56:46 +0800
- To: public-audio@w3.org
Hello, I have encountered some unexpected behavior in creating Attack, Hold, Release envelopes. Standard scenario: Let's say you want a 1 second attack to start on some "play" event, and a 1 second decay to start on some "release" event. You want the decay to start at whatever the *current* amplitude is (whether yourattack is still in progress or not). One might expect to be able to respond to the "release" event with the following code: now = config.audioContext.currentTime; stopTime = now + m_releaseTime; gainEnvNode.gain.cancelScheduledValues(now); gainEnvNode.gain.linearRampToValueAtTime(0, stopTime); However, the actual behavior of this code appears to be: a) if the attack has completed, the decay ramp is computed from the time the attack completed, rather than "now". Thus there is a sudden jump to the middle of the intended decay ramp values. b) if the attach has not completed, the sound stops suddenly with no decay (not sure how to explain that). So my comment/suggestion is : While it makes sense to schedule a ramp to begin at the last scheduled value, the *time* used to begin the new events should perhaps be the time of the last scheduled value, or "now" (whichever is greater). The only solution that I have found that works in each case is to insert a flat ramp to update the time and value of the envelope when the "release" event occurs: now = config.audioContext.currentTime; stopTime = now + m_releaseTime; gainEnvNode.gain.cancelScheduledValues(now); gainEnvNode.gain.linearRampToValueAtTime(gainEnvNode.gain.value, now); // THIS IS THE CHANGE FROM PREVIOUS CODE EXAMPLE gainEnvNode.gain.linearRampToValueAtTime(0, stopTime); This makes some sense when you get it, but is not very intuitive since (if I understand it correctly) since a) if the attack has not completed, the inserted ramp has 0 duration, and b) if the attack has completed, I am creating a ramp starting at a time long since passed. (Inserting gain.setValueAtTime(gainEnvNode.gain.value, now) instead would seem more intuitive, but it does not work either.) Of course, I may have missed a better way to do the AHD thing completely.... Congratulations on all the great work so far, - lonce
Received on Thursday, 3 January 2013 01:57:27 UTC