Web Audio changes
At Google, we love standards. We’re on a mission to build out the standards-defined Web platform. One of the small warts on that for some time has been the webkit- prefixed implementation of the Web Audio API (notably the webkitAudioContext object), and some of the deprecated bits of Web Audio that we’ve continued to support.
We will remove the support for the prefix completely after m36, likely in a couple of releases. We’ll make an announcement here when the change is imminent, and we are continuing to reach out to authors to fix their Web Audio applications.
Why have we done this, rather than reverting to the previous implementation? Well, in part, we’ve been reticent to move too far backwards; we’ve already removed those APIs, and as a nice side-effect to this aliasing, applications can then work nicely on Firefox, which has never supported a prefixed AudioContext object (and quite right, too!) in their Web Audio support initially released last fall.
The rest of this update provides a guide to fixing things that may be broken in your code due to this change. The great thing about fixing these problems is that your code is then quite likely to just work in Firefox, too! (I’d thought for a long time that my Vocoder application was broken due to Firefox’s implementation, but it turned out to be one of these problems!)
If you just want to get up and running, you may want to take a look at a monkey-patch library I wrote for applications that were written to the old Web Audio code - this can help you get up and running in a minimum amount of time, as it will alias the objects and methods appropriately. Indeed, the patches the library lists is a good guide to the things that have changed.
First and foremost:
Any references to
window.webkitAudioContext should be made to
window.AudioContext instead. Frequently, this has been fixed with a simple:
window.AudioContext = window.AudioContext || window.webkitAudioContext;
If your app is responding with something like “Unfortunately, your browser does not support Web Audio. Please use Chrome or Safari.” - it’s quite likely explicitly looking for
webkitAudioContext. Bad developer! You could have been supporting Firefox for months!
But there are a few other, more subtle code removals, some of which can be less obvious.
- The BiquadFilter enumerated type constants for the
.typeattribute (which is now a string) no longer appear on the
BiquadFilterNodeobject, and we do not support them on the
.typeattribute. So you don’t use
.LOWPASS(or 0) anymore - you set it to “lowpass”.
- Also, the
Oscillator.typeattribute is similarly now a string enumerated type - no more
PannerNode.typeis also now a string enumerated type.
PannerNode.distanceModelis also now a string enumerated type.
createGainNodewas renamed to
createDelayNodewas renamed to
AudioBufferSourceNode.noteOn()is now replaced by
AudioBufferSourceNode.noteGrainOn()is also now replaced by
AudioBufferSourceNode.noteOff()is renamed to
OscillatorNode.noteOn()is renamed to
OscillatorNode.noteOff()is renamed to
AudioParam.setTargetValueAtTime()is renamed to
OscillatorNode.setWaveTable()are now renamed
AudioBufferSourceNode.loopingwas removed, in favor of
AudioContext.createBuffer(ArrayBuffer, boolean)to synchronously decode a blob of encoded audio data has been removed. Synchronous calls that take a long time to complete are poor coding practice; use the asynchronous decodeAudioData call instead. This is one of the more challenging changes - you need to actually change logic flow - but a far better practice. Mozilla’s Ehsan Angkari wrote a nice example of how to do this in their post on converting to standard Web Audio.
Many of these (like the renaming of createGainNode, and the removal of the synchronous decoding in createBuffer) will obviously show up in the developer tools console as an error - however, some others, like this usage:
myFilterNode.type = myFilterNode.BANDPASS;
will not show up at all, and silently fail (myFilterNode.BANDPASS will now resolve to undefined, and the attempt to set .type to undefined will simply fail to produce any effect. This, by the way, was what was causing the vocoder to fail.) Likewise, just assigning the filter.type to a number used to work:
myFilterNode.type = 2;
But now, you need to use the string enumeration:
myFilterNode.type = “bandpass”;
So, you may wish to grep your code for the following terms:
.type(yes, this will have lots of false positives - but it’s the only way to catch the last example above!)
Once more, if you’re in a hurry and want to get up and running, just grab a copy of my monkeypatch webkitAudioContext library and include it in your application. Happy Audio Hacking!