Badass JavaScript

A showcase of awesome JavaScript that pushes the boundaries of what's possible on the web, by @devongovett.

Introducing ALAC.js: An Apple Lossless Audio Decoder in JavaScript

December 19th 2011

Recently, Apple open sourced the original encoder and decoder for the Apple Lossless audio codec which is written in C/C++.  ALAC is, as its name implies, a lossless codec, which means that it is compressed but does not lose any quality.  When decoded, ALAC audio files are bit-for-bit identical to the original uncompressed audio file.

When our team at ofmlabs saw ALAC open sourced a few weeks back, we thought it might be fun to try to port it to JavaScript so one could listen to ALAC files in the browser.  After all, some of us were also on the team that brought you JSMad, the JavaScript MP3 decoder a few months ago.

Besides porting over the decoder (by hand, not with a tool like Emscripten), we have been working on a little framework called Aurora.js, which handles the boilerplate of writing a codec in JS, from actually streaming the file from the server and implementing the bitstream classes, to finding the correct demuxers and decoders and playing back the audio through the browser’s audio API as abstracted by Sink.js.  There are currently two competing audio APIs and a third in the works, so an abstraction like Sink.js was necessary.

We couldn’t do anything without a cool demo, so we built a site showcasing our two audio decoders, JSMad and ALAC.js, side-by-side.  If you notice your CPU usage a bit higher than expected, that is actually not the audio decoder but the visualizer.  You can click on the visualizer to disable it and see for yourself.  

Because only Chrome and Firefox have an API for writing audio data, those are the only two browsers that the demo will work in.  We are hoping that some agreement can be reached soon so that we have a standard API that other browsers will implement.  However, these demos show that even if a browser does not implement a particular format, JavaScript is powerful enough to do the job and fill in the gaps.  The HTML5 <audio> element is great in theory, but browsers all implement different codecs, which means that website authors must encode their audio files into a few different formats to get cross browser support.  Because we can implement audio codecs in JavaScript, once we have a cross browser audio data API, this will no longer be the case and we can have just about any audio format in browsers without waiting for them to implement.  Hurrah!

You can check out the code for ALAC.js on Github, and see our side-by-side demos here.  Enjoy!