W3C home > Mailing lists > Public > public-audio@w3.org > January to March 2016

Re: Attack, Sustain, Release using linearRampToValueAtTime

From: Stephen Band <stephband@cruncher.ch>
Date: Mon, 18 Jan 2016 16:22:53 +0100
Message-ID: <CABBNDnGwrpLaoOVwXScUMjTAL4LuKJp44rN4Dij2gHrTYiAEeQ@mail.gmail.com>
To: D <dilots@gmail.com>
Cc: "public-audio@w3.org" <public-audio@w3.org>
Hi.

I can see two possible problems in this code.

var currentValue = this.gain.value;

After values have been scheduled, the .value property of an AudioParam is
not guaranteed to return it's actual value. Someone on Slack told me it
'depends on whether the scheduling is deterministic'. In practise I have
been getting different results depending on the browser. Either way, it
cannot be relied upon. It isn't noted very well in the spec, if at all, so
it's seems to me to be a big grey area.

this.gain.exponentialRampToValueAtTime(0.01, now + this.releaseTime);

A descending exponential curve with a low target value begins to look like
a step function. Are you sure you don't want setTargetAtTime?

Stephen.



On 15 January 2016 at 22:12, D <dilots@gmail.com> wrote:

> Hello,
> I’m trying to implement an Attack-Sustain-Release envelope with WebAudio.
> The release part of the envelope does not work properly if the attack
> portion of the envelope has not finished yet. I tried using
> cancelScheduledValues to stop the attack envelope and snap the gain to its
> current position, but it immediately jumps back down to 0 when I do that.
> Any idea what I’m missing?
>
> Here’s a snippet of my code:
>
> function ASR_EnvelopeGenerator(context, peak) {
>   this.attackTime = 0.1;
>   this.sustainLevel = 0.5;
>   this.releaseTime = 0.3;
>   this.peak = peak;
>   this.gain = 0;
>
>   this.trigger = function() {
>     var now = context.currentTime;
>     this.gain.cancelScheduledValues(now);
>     this.gain.setValueAtTime(0, now);
>     this.gain.linearRampToValueAtTime(this.peak, now + this.attackTime);
>   };
>
>   this.release = function(){
>     var now = context.currentTime;
>     var currentValue = this.gain.value;
>     this.gain.cancelScheduledValues(now);
>     this.gain.setValueAtTime(currentValue, now);
>     this.gain.exponentialRampToValueAtTime(0.01, now + this.releaseTime);
>   }
>
>   this.connect = function(gain) {
>     this.gain = gain;
>   };
> };
>
> I found a similar question from 2 years ago here:
> https://lists.w3.org/Archives/Public/public-audio/2013JanMar/0020.html
> However, this solution seems to be the same as what I'm doing already.
>
> Cheers,
> David
> ​
>



-- 

Cheers,
Stephen


<http://cruncher.ch>
               *web*: cruncher.ch
               *twitter*: @cruncher <http://twitter.com/cruncher>
               *phone*: +41 76 547 30 32
               *email*: stephband@cruncher.ch
Received on Monday, 18 January 2016 15:23:22 UTC

This archive was generated by hypermail 2.3.1 : Monday, 18 January 2016 15:23:23 UTC