Best practice for reading mp3s?

Hello, JUCE-y people.

I can see that our little non-free, non-open source Windows/Mac application will need to be reading mp3s in a few months so I thought I’d start my research now - which I’ve been doing. I suspect within the next year we’ll need to write mp3s as well so tips in that direction will be welcome too.

Of course, the issue is that mp3 is patent-protected so there don’t exist open source decoders that can be used in a commercial product - but at the same time you don’t want to unnecessarily pay royalties - or force your user to pay royalties.

It seems to me that there is no problem for Mac users - I believe all modern Macs come with Quicktime, or requiring them to download it is fine (they’re a Mac and should have QT).

And there’s no problem for Windows users who happen to have Quicktime either - BUT I don’t think it’s at all acceptable to require Windows users to download QT before using some features of our program, at least, I think I might find it objectionable if I were a client (though I don’t really know how Windows users think…) And Windows users with no QT comprise something like 80-90% of our market - of any market.

So we have a decision tree

  1. Is Quicktime available? Use that.
  2. Is Lame available? Use that.
  3. Otherwise, use some paid solution.

So my questions are…

  1. How do you detect and use dynamic libraries like Lame in a platform-independent (or at least dual-platform) way?
  2. What paid solutions for mp3 decoding have people successfully used?

Of course, I’m not necessarily expecting answers and will eventually post here with answers otherwise…

mpg123 is a real time MPEG 1.0/2.0/2.5 audio player/decoder for layers 1,2 and 3 (MPEG 1.0 layer 3 aka MP3 most commonly tested). Among others working with Linux, MacOSX, FreeBSD, SunOS4.1.3, Solaris 2.5, HPUX 9.x, SGI Irix and Cygwin or plain MS Windows.
It is free software licensed under LGPL 2.1 (the officially released sources, some files in subversion repository may differ).

Oh, right on!

I’d gotten it into my head that I couldn’t use LPGL’ed libraries for a commercial release but a little reading of their license shows that that does not appear to be the case as long as I’m careful about crediting and use dynamic libraries…

Thanks hugely for the recommendation, fiddling with it now…

Hey, how did this go?

I have been decoding mp3s with quicktime, but since it appears that Apple isn’t releasing quicktime for 64 bit systems and I would like to compile a 32/64 bit universal … I guess I’ll need to read mp3s some other way.

Did you have luck with this library?

Hey, it’s only been a day!


The library looks pretty damn decent… I expect to release an AudioFormat within a week or less… I got good support from their mailing list, too!

Don’t worry, I’ll post here when I’m done…

Ha … forgive the impatience. Should have checked the date I suppose.

Excited to see what you come up with.

It’s actually seeming likely that I’ll only be creating a reader. I don’t have a use-case for writing mp3s for months to come and probably can’t spare the time to do the work.

That said, I think the reader is the hard part and when I or someone else needs a writer it’ll be much easier to add when the reader is complete and hopefully robust.

I’m taking a different approach to that in hifiaudioplayer/MP3AudioFormat.cpp. I’m using the function mpg123_replace_reader_handle() (scroll to the very bottom) to directly use an InputStream instead of a file descriptor. The theory is that the mpg123 library should talk right to my InputStream without modifications, and for people who want to get more out of it like file tags, I can directly expose the “mpg123_handle”, the opaque struct that gives you access to all the

The fact I can do this so neatly is a tribute to the cleverness of the mpg123 creators… waxing lyrical for a few seconds, they have an extremely clever and robust system for dealing with all the disparate input types you might have - in C, not C++.

Behind the scenes, their opaque mpg123_handle contains a list of function pointers that handle the various services that you might ask for - it’s something like a vtable, except that you can do “mixins” where you take “one method from here, and one from there”.

Back to coding!