Web Audio Oscillators Suddenly Slide from One Frequency to Another in Chrome

The behavior I'm going to describe happens in Chrome 44, but it doesn't happen in Firefox 40.

If you create an oscillator, set it to 220 Hz, and then change the frequency to 440 Hz a second later, you can hear a great portamento effect: instead of instantly changing from 220 to 440, the generator slides from the original frequency to the new one.

The code below illustrates this phenomenon:

var ac = new AudioContext(); var osc = ac.createOscillator(); osc.connect( ac.destination ); osc.type = 'sawtooth'; osc.frequency.value = 220; osc.start( 0 ); window.setTimeout( function() { osc.frequency.value = 440; }, 1000 ); window.setTimeout( function() { osc.stop( 0 ); }, 2000 ); 

I studied the documents for the OscillatorNode object and did not mention this.

I also searched Google, and (surprisingly) I cannot find any other references to this phenomenon.

What's happening? This is not like correct behavior. If I wanted the frequency to slip, I would use the linearRampToValueAtTime () method. Setting the frequency directly to a specific value should simply ... do it.

Is this just a mistake? I know that this API is still on the move, but it seems rather egregious to be a mistake - it won’t miss the most superficial testing. But I also can’t imagine that Google will implement it in such a way intentionally.

Most important: is there a workaround?

+6
source share
2 answers

Pretty sure this is a mistake.

I cannot find anything in the specification that says direct assignment of value to AudioParam should do any interpolation.

It is possible that this went unnoticed, because usually people are likely to change the value using automation methods. This brings me to the issue of workarounds ...

If you really need an explicit delay, you can just do it (note that there is no setTimeout ).

 // change the value to 440Hz 1 second from now osc.frequency.setValueAtTime( 440, ac.currentTime + 1 ); 

If you want to immediately change the frequency (say, in response to a user action), you can simply do this:

 osc.frequency.setValueAtTime( 440, 0 ); 

Hope this helps.

By the way, you should consider pointing out a problem ( https://code.google.com/p/chromium/issues/list ).

+4
source

This is a built-in β€œblur” effect that the workgroup has come back and forth several times. As of June, the WG finally decided to remove dezippering (status: https://github.com/WebAudio/web-audio-api/issues/76 ). So yes, this is a chrome "error" - https://code.google.com/p/chromium/issues/detail?id=496282 ). Until this is fixed, use setValueAtTime (), as Kevin suggested.

+4
source

All Articles