MP3 decoding in juce: it's here!


#1

I’ve written not one, but two mp3 decoders for juce.

  1. FFmpegAudioFormat is based on FFmpeg and it supports all the audio formats of FFmpeg. It is inefficient as it decodes the entire audio file in the constructor to determine the length, and then decodes it again in the read() function. Also for some formats it requires a FileInputStream rather than just an InputStream.

  2. MP3AudioFormat is based on a slightly modified mpadec, which is based on mpg123. It is smart enough to determine length without decoding, but I don’t know how accurate this is for VBR files. mpadec is a lot smaller than FFmpeg, so this is the one to use if you just need mp3.

FFmpeg & mpadec are both LGPL, but you will still be required to pay mp3 licensing royalties if you distribute an app that decodes mp3.

I have only done Windows builds, mac and linux should be trivial.

Neither support id3 tags, anybody want to take a look into that?

http://rabien.com/software/mp3.zip


#2

Do you know about “av_find_stream_info” ?

You can use it like :

// Retrieve stream information
if(av_find_stream_info(pFormatCtx)<0)
  return -1; // Couldn't find stream information

pFormatCtx is likely a MP3On4DecodeContext which contains the number of MP3 frames.
MP3 frames (they are MPADecodeContext) contains a frame_size number that is the number of sample in a mp3 frame. You can divide this by the sample rate to get the duration for that frame.

Sure, you’ll have to parse the whole file for VBR (because when the bitrate change, MP3 requires to put another header), but you don’t need to decode it.

If it helps. ffmpeg is not so easy to use at all.


#3

Thanks for that! I’ll have a look at it. Seems really cool, although I think that first decoding the entire file for knowing its length is inadmissible, it would take too long for 2-hour mixes and so.
For MP3s, you could incorporate a frame scanner (that’s how i did it in Quad http://www.quadscratch.com). I already implemented the Frame Scanner in Juce, but it seems as if CoreAudio does frame scanning, too, because you can jump to any frame in the MP3 and then read from it - but I’ll have to check this out, it could in fact also be that CoreAudio just forwards or rewinds from the actual playing frame to the wanted frame.


#4

There must be a way to do it with FFmpeg, I just don’t have the time to figure it out. The documentation is quite poor. Hopefully someone else on this forum can figure it out.


#5

Just tried your 2 decoders:

MP3AudioFormat reads MP3’s, but seems like seeking does not work, it always reads from the start of the MP3, even if “startsample” is not at the beginning of the file. Besides, the buffer seems not to be fully filled.

FFmpegAudioFormat does not work for MP3’s (at least not on my PC). I also had to download phtreadCG2.dll to get it run (this file was not included in your MP3.zip). WAV’s are read by the FFmpegAudioFormat, but there’s also the same problems as with MP3AudioFormat: startsample parameter seems to have no influence, and the buffer is not fully filled.

Do you perhaps know any solutions to these problems?


#6