Spangles Not Included

Everybody is (fairly rightly) decrying the new maps in iOS6, but there are some really neat new features in Mobile Safari that are worth the upgrade. For a start, you can finally upload photos from within the browser, something that should have been in iOS 1. But there’s more! Safari also implements the Web Audio API, allowing music synthesis from within Javascript. And what better way to show off said API than to create a web page that sounds like a bunch of characters from an 1970s Oliver Postgate programme? Exactly.


var context = new webkitAudioContext();
var sine = context.createOscillator(),
    triangle = context.createOscillator();

sine.type = 0;
triangle.type = 3;

sine.frequency.value = 200;
triangle.frequency.value = 200;

sine.connect(context.destination);
triangle.connect(context.destination);

sine.noteOn(0);
triangle.noteOn(0);

window.ondeviceorientation = function(event) {

  sine.frequency.value =  (Math.floor(event.alpha) *1.5)+300;
  triangle.frequency.value =  (Math.floor(event.gamma) *1.5)+100;

}

There’s not a lot going on here - if you look at the Web Audio API specification, you’ll see that an AudioContext is required for playing all sounds - while you can have more than one, for simple scripts (and even pretty complex ones, as an individual context can handle a large audio graph), one will be fine. AudioNodes are then connected to each other to create sounds and effects and then connected to the context for output. I’m using webkitAudioContext() due to the implementation being prefixed while the spec is finalized (it’s not supported in Firefox yet).

Having grabbed a context, I then create two Oscillator AudioNodes, one a sine wave (the default) and the other a triangle wave (sawtooth and square waves are also available, plus you can set up your own wavetables if you’re feeling really fancy). Setting the initial frequency of the waves comes next, and then, via the connect() call, I connect them to the AudioContext. Oh, and finally, the Oscilliators need to be switched on via the noteOn method (there’s a noteOff() too).

Finally, I add a function to the ondeviceorientation event to alter the frequency of the waves based on the position of the device, so if you you pull the iPhone or iPad forwards and backwards, and/or twist it, it’ll alter the frequency of the waves, and make Clanger-esque talking sounds.

Maps? Who needs maps?