Re: linear ramps and the Web Audio API

On Tue, Feb 7, 2012 at 9:42 AM, Phil Burk <philburk@mobileer.com> wrote:

> I am having fun experimenting with the Web Audio API. Great stuff.
>
> I tried to use the linear ramp function of the AudioGainNode.
>
>  <http://www.softsynth.com/**webaudio/gainramp.php<http://www.softsynth.com/webaudio/gainramp.php>
> >
>
> I had some problems when I tried using linearRampToValueAtTime(value,**time).
> I am getting pops and some unexpected behavior.
>
> The documentation is not very clear about whether the time is a duration
> or a target time. I think it is the time the value should be reached.
>

The time is a target time and the value is the ramp's end value.  One thing
that I haven't made clear in the specification is that the intended use to
first call setValueAtTime() to establish the initial (value,time).  Then
subsequent calls to linearRampToValueAtTime()
or exponentialRampToValueAtTime() can be made, and even chained one
after the other.  One case I probably haven't handled which I think you're
trying to test is how to call linearRampToValueAtTime() to establish the
end-point of the linear ramp, but where you don't know what the starting
value is (so a call to setValueAtTime() would not be possible).  Instead,
in this case, we would want to start ramping from *whatever* value the
parameter is "currently at".  In this case, instead of
calling setValueAtTime(), perhaps we need something like:

void anchorValueAtTime(in float time);

This would simply take whatever the current value is of the parameter at
the given time and establish it as the anchor point (startValue, startTime)
for a subsequent call to linearRampToValueAtTime(endValue, endTime)
or exponentialRampToValueAtTime.


>
> In mode=1 of my test I tried to ramp up a tone using:
>
>   gainNode.gain.**linearRampToValueAtTime(1.0,
>         context.currentTime + 1.0);
>
> But it jumped abruptly to 1.0 after a 1 second delay.
>

I believe this is because it was expecting an initial call to
setValueAtTime() to establish the initial point of the ramp.


>
> I then found that if I set a sort of breakpoint at the current value and
> current time then I could get a ramp that worked most of the time. But
> sometime it would jump uncontrollably.
>
>   // set beginning of ramp
>   gainNode.gain.**linearRampToValueAtTime(**gainNode.gain.value,
>         context.currentTime );
>
>   // set end of ramp
>   gainNode.gain.**linearRampToValueAtTime(1.0,
>         context.currentTime + 1.0);
>
> I had better luck with the setTargetValueAtTime() method. It usually gave
> me smooth ramps.
>

Yes, setTargetValueAtTime() is designed as a first-order filter
(exponential approach to target value), and is quite useful.


>
> It would be nice if there was a function that did the following:
>
>  linearRampWithDuration( targetValue, timeToStart, duration );
>
> At timeToStart the parameter will begin ramping from its current value
> towards the targetValue so as to arrive at the targetValue in duration
> seconds.
>
> The following calls could then be made:
>
>  var now = context.currentTime;
>
>  // Start ramping now from current value towards 1.0 over 2 seconds.
>  gain.linearRampWithDuration( 1.0, now, 2.0 );
>
>  // after 1 second start ramping down to 0.3 over 2 seconds
>  gain.linearRampWithDuration( 0.3, now+1.0, 2.0 );
>
> It is handy if the each ramp simply starts at the current value so that a
> ramp can be redirected without pops.
>

How about the proposed anchorValueAtTime() method I describe above?  That
way, it could also work with exponentialRampToValueAtTime() or any new type
of ramp curve we might define in the future.



>
> Thanks,
> Phil Burk
>
>

Received on Tuesday, 7 February 2012 21:08:41 UTC