JavaMP3

JavaMP3 is the first modern pure Java MP3 decoding library, to decode and play back MP3 audio files. An MP3 (short for MPEG-1 Layer III) decoder is a tool that takes MP3 encoded sound data (e.g. music files) and decodes it into raw PCM sound samples, i.e. the actual uncompressed sound wave. The decoding process is quite complicated, involving both parsing a binary format and applying various algorithms to process the parsed data.

I started this project in 2017, when making an osu!taiko clone in Java: I realized there was no modern fast pure Java library for decoding MP3 files. I needed MP3 because my clone would use the various music tracks (and other data) the user downloaded from their official osu!taiko client, but these were stored in MP3 files.

I soon understood why there was no such library: the MP3 specification is absolutely awful, the PDF costs 200~ US Dollars on the officiel ISO website, and is itself an OCR of the original MP3 specification physical paper. The OCR has quite a few parse errors in the very formulas used by the MP3 decoder, and furthermore the specification itself as written in the paper has other numerous (print?) errors. The specification is very bad-written and extremely hard to understand, and even though it is supposed to provide an implementation of an MP3 decoder, half of it is written in plain English sentences which if you do not understand properly is yet another hurdle to making a fully-compliant decoder.

So the only way to correctly implement an MP3 decoding library is to spend a few dozen hours reading the specification, then spending the same amount of time reading the source code of the various open source MP3 decoders, but the MP3 decoding algorithms are quite CPU-expensive so most maintstream MP3 decoders are actually extremely optimized C (and ASM!) code which are quite hard to understand.

MP3 is actually the third layer in terms of compression complexity, above MP2 (MPEG-1 Layer II) and MP1 (MPEG-1 Layer I), which are not used anymore. So I decided that I would first implement by myself, from scratch, fully-working MP1 and MP2 decoders in pure Java. After I finished developing those I got the chance to find an old official C implementation of these two decoders and I managed to make my decoder output the exact same bytes as the official decoder.

Then I had to develop the actual MP3 decoder, and I quite quickly decided not to try and implement it from scratch, but to rather port an already existing C implementation. It took me quite a while to find an implementation that was not too optimized (it shocked me that the great majority of them used hand-optimized assembler for various CPU architectures!!), and then to port it to Java and debug it by comparing my output to the C implementation.

Once this hard part was done I had to turn it into a user-friendly library (that would hide all the horrors of MP3 decoding), by having a straightforward and intuitive API design. I iterated quite a long time on the API design and asked a few developer friends for their opinion on it, and I finally found a design that I liked.

I then added comprehensive documentation on all the public API and the Github README, which also took quite some time, but I’m very happy with the result.

I still have some MPEG peculiarities to add to the library, but it is otherwise complete and I have already been using it for my osu!taiko clone and other small projects.

See the Github repository of the project for more details.

Updated: