Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

We would've loved to have that too when porting the mad code.

Here's a quick overview:

bytestream is our general I/O abstract class - there's much room for improvement because it works with Strings. substream allows to have a 'view' of a slice of a bytestream.

filestream and ajaxstream are two implementations of bytestream, doing local File I/O (with the upcoming W3C File API) and XMLHttpRequest streaming. On Firefox 4.0+, ajaxstream takes advantage of mozBinaryResponse and uses Uint8Array(s) to 1) compute the amount of data read, and 2) implement getU8 (which is used a lot).

bit.js is a straight port of libmad's bit manipulation routines. Bit-level I/O is a must-have in an MP3 decoder because you have numbers stored on 7 bytes, 19 bytes, and other weird stuff like this (especially in the huffman decoding part).

huffman.js, imdct_s.js, rq_table.js are all tables used somewhere else in the process.

layer3.js is really the central part. it implements huffman decoding, the various IMDCT transforms, reordering, requantizing... all sorts of magic tricks I didn't fully grasp even while porting. Comparing the output was really our best weapon. The libmad guys are really the reference guys for this kind of question. We had to strip out all their fixed-point stuff because it's really of no use in Javascript, since JS only has floating point numbers - even if we can make them behave almost as integers, it's still as costly as FP arithmetic so we just went floating point all the way - hence, jsmad doesn't have 24-bit output like libmad has. libmad is wayyyy better at everything :)

synth.js is the second central part - it synthesizes the sound waves from the decoded MPEG Layer-III data. It's the most expensive part of the project, since it's just thousand meaningless arithmetic operations, something JavaScript doesn't excel at.

mad.js contains mostly constants (errors), a few utility functions

decoder.js isn't used anywhere, it's my attempt to port decoder.c from libmad, but it's unfinished.

player.js is our ill-fated attempt to play the decoded MP3 correctly - it's really naive (no seeking, stutter in some cases, no buffering of decoded frames, etc.)



Maybe it's a silly question, but how did you output sound after decoding the stream? I wasn't aware browser JavaScript had any APIs that work with sounds directly. There is Audio, but IIRC it just streams the file from the server.

I've looked at the sources, but couldn't fine the part that would answer my question.


You're talking about the HTML5 <audio> tag.

We're using audiolib.js, which abstracts over Mozilla's Audio Data API and Chrome's Web Audio API - both of which allow direct access to the sound device :)

(And no, it's a really good question! More people should know about this stuff!)




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: