Writing Web Audio API code that works in every browser

You probably have already read the announcement on the Web Audio API coming to Firefox, and are totally excited and ready to make your until-now-WebKit-only sites work with Firefox, which uses the unprefixed version of the spec.

Unfortunately, Chrome, Safari and Opera still use the webkitAudioContext prefixed name. Furthermore, as a result of the spec being still in flux, some browsers use deprecated properties and method names that are not present in standards-compliant browsers: Safari uses the old method names, Firefox uses the new ones, and Chrome and Opera use both. In addition, not all features of Web Audio are already implemented in Firefox yet.

What do we do!?

We don’t want to maintain two or more separate code bases, and feature detection code is cumbersome! Plus we want to write code that reliably works in the future, or at least, works with a minimum amount of changes. Is there a way to satisfy all these constraints at the same time? Probably!

Writing for today (and tomorrow)

First, get a copy of AudioContext-MonkeyPatch by Chris Wilson. This little library will “normalise” the interfaces for you and make it look as if your code is running in a standards compliant browser, by aliasing prefixed names to the unprefixed versions. And it won’t do anything if the unprefixed versions are already present.

Once you include it in your page, you can write in “modern Web Audio API” style, and do things such as:

var audioContext = new AudioContext();

everywhere, including Chrome/ium, Opera, Safari, and —of course!— Firefox.

Also, if new methods such as start are not detected in some nodes, the library will also alias them to their old names. Thus, start is mapped to noteOn, stop to noteOff, and so on.

If you’re porting moderately “old” code (say, a year old) it’s possible that it uses some methods that AudioContext-MonkeyPatch doesn’t alias, because it helps you to write code in the new style. For example, the way to create instances of GainNode used to be

var gain = audioContext.createGainNode();

but nowadays it is just

var gain = audioContext.createGain();

Since the old method names are not present in Firefox, existing code may crash with something like createGainNode is not a function, and you now know why.

There’s a section in the spec that lists the old names and their updated equivalences; be sure to check it out and change your code accordingly. You can also check this article on porting which covers more cases and has many code samples.

Things that are not ready yet

Second, ensure that your project doesn’t use node types that are not implemented yet in Firefox: MediaStreamAudioSourceNode, MediaElementAudioSourceNode and OscillatorNode.

If it’s using, for example, OscillatorNode, you will have to wait until it is supported, or maybe, if you’re really eager, hack in some replacement using ScriptProcessorNode, which allows you to write a node with callbacks that get called periodically, so that your JavaScript code generates or processes audio.

The node parameters you use must also be supported in Firefox too. If they aren’t, you might be able to change them into something “acceptable” for the time being, and count on the talented audio developers to implement those very soon.

For example, up until a couple of days ago PannerNode did not support the default HRTF panning model yet, and attempting to use a PannerNode with that configuration simply resulted in silence or a mono output coming out from that node, depending on the build you used.

Today the support is already present in Nightly, but not quite yet in Aurora. In the meantime, you can explicitly specify 'equalpower' instead:

var panner = new audioContext.PannerNode();
panner.panningModel = 'equalpower';

Keep track

The best way to know what’s going on in the Web Audio API land is to subscribe to the mailing list. Be aware that there might be a bit of high level tech discussions from time to time, and you might not understand it all, but you will learn a lot even if only by skimming through it.

You might also want to subscribe to the umbrella bug that tracks the Web Audio API implementation in Firefox, so that you get alerts when associated bugs get updated or resolved.

Finally, there’s also a list of projects built with the Web Audio API, specifying which ones use the standard AudioContext and which browsers do they work on. If you’re a person that learns by example, it might be interesting to have a look at their source and see how they have resolved the compatibility issues.

About Robert Nyman [Editor emeritus]

Technical Evangelist & Editor of Mozilla Hacks. Gives talks & blogs about HTML5, JavaScript & the Open Web. Robert is a strong believer in HTML5 and the Open Web and has been working since 1999 with Front End development for the web - in Sweden and in New York City. He regularly also blogs at http://robertnyman.com and loves to travel and meet people.

More articles by Robert Nyman [Editor emeritus]…

About Soledad Penadés

Sole works at the Developer Tools team at Mozilla, helping people make amazing things on the Web, preferably real time. Find her on #devtools at irc.mozilla.org

More articles by Soledad Penadés…


2 comments

  1. Mark Boas

    As I just tweeted – a much needed update – thanks!

    One beef is that I find it really difficult to sign up to the W3C mailing list, although I’d love to find out that it’s just me and the process is actually very easy! :)

    August 21st, 2013 at 03:32

    1. Soledad Penadés

      You’re welcome!

      I didn’t find anything unusually complicated about the mailing list, but that’s probably because I’m already used to Mailman. Probably most of the people will find it harder than, say, any other forum. Sadly it’s not something I can fix :D

      August 21st, 2013 at 03:38

Comments are closed for this article.