JavaScript Synth in 4K

Want to let your browser do some number crunching?

This small JavaScript program will generate and play a two minutes long piece of music.

Small? Yes, it's just 3822 bytes, which is actually less than the size of the HTML document that you're currently reading!

The sound is generated with CD quality (44.1KHz, 16 bits stereo), and the size of the generated tune is 21 megabytes (all done client side, in your browser!). As a little bonus, the demo also has some animated graphics (courtesy of HTML 5 canvas).

PLAY IT!

Be prepared to wait for the sound generation to complete!

Browser compatibility

This demo requires a browser with support for the <audio> and <canvas> elements (HTML 5). The following browsers have been tested:

Browser Version Generation time* Comments Opera 11.01 24 s Sweet! Chromium 12.0.733.0 39 s Works nicely! Firefox 4.0 55 s Audio and graphics can be a bit out of sync. No looping. Firefox 3.6.16 643 s Slow JavaScript! Choppy sound. No looping.

* Time for the synth to generate the music (lower is obviously better). Measured under Ubuntu 10.04 (64-bit) on an AMD Athlon X2 4850e (2.5 GHz).

Technical

Quite frankly, this is a technical demo more than anything else (the music is just a simple composition in the proof-of-concept spirit, and the animated graphics was put there as a replacement for dull HTML text output).

So, here's a quick technical break down of the demo:

The core synth was actually ported from C (Sonant, originally written by Jake "Ferris" Taylor of Youth Uprising), and modified for optimal JavaScript performance. It's not the most advanced software synth, but: It has a portable C code implementation (good starting point) It comes with a ready-to-use music authoring tool (handy!) It was written to be as minimal as possible It makes it easy to compare C performance vs JavaScript performance (the fastest browsers are actually near native C performance!)

The software synth features: Several independent channels of sound (7 currently used) A handful of different waveforms Instrument envelope Stereo echo Filters Per channel polyphony Panning, LFO controllers, etc.

The audio data is generated in a CanvasPixelArray (in anticipation of true typed arrays), since it's much more memory efficient than a regular ECMAScipt array

The generated data is played back in an HTML audio element using a huge (56 MB!) base64-encoded data URI (in anticipation of a cross browser audio API)

The program was compressed using: The Google Closure Compiler, and... ...the CrunchMe JavaScript compressor

Want to see the compressed source? Obfuscation warning!

...if you have any comments, you can leave them here.

Resources