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).
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
- Sonant — the original 4k synth by Youth Uprising
- js-sonant — the JavaScript port of the player routine
- Sonant JavaScript conversion tool — convert SNT to JS online
- Doing a sound synth in JavaScript — post about the JavaScript synth