MP3 decoder


#1

FYI, I’ve just added a new class: MP3AudioFormat (just a decoder, not an encoder).

I needed to write this for a client anyway, and thought it might be handy for people in general.

The entire decoder is encapsulated in one file, with no dependencies. Originally I was planning on adding something like libmpg into the codebase, like I’ve done for zlib, ogg, etc, but the code out there was so awful that I decided to have a go at writing one properly in c++, and managed to do a complete implementation in about 3000 lines of code!


#2

Excellent! I’ll give it a try very soon!


#3

I just tried it in the JuceDemo (added the include MP3 format in the Introjucer), And it crashed on me when selecting a mp3 file, it’s a CBR 128kbps 44100HZ encoded with id3v2.3 i can attach it here (but i tried a few others with the same crash):

>	JuceDemo.exe!juce::MP3Decoder::MP3Stream::layer3DequantizeSample(float [18]* xr, int * scf, juce::MP3Decoder::Layer3SideInfo::Info & granule, int sampleRate, int part2bits)  Line 2702 + 0x5 bytes	C++
 	JuceDemo.exe!juce::MP3Decoder::MP3Stream::decodeLayer3Frame(float * const pcm0, float * const pcm1, int & samplesDone)  Line 1863 + 0x2e bytes	C++
 	JuceDemo.exe!juce::MP3Decoder::MP3Stream::decodeNextBlock(float * const out0, float * const out1, int & done)  Line 1553	C++
 	JuceDemo.exe!juce::MP3Decoder::MP3Reader::readNextBlock()  Line 3092 + 0x23 bytes	C++
 	JuceDemo.exe!juce::MP3Decoder::MP3Reader::MP3Reader(juce::InputStream * const in)  Line 2993 + 0x8 bytes	C++
 	JuceDemo.exe!juce::MP3AudioFormat::createReaderFor(juce::InputStream * sourceStream, const bool deleteStreamIfOpeningFails)  Line 3168 + 0x29 bytes	C++
 	JuceDemo.exe!juce::AudioFormatManager::createReaderFor(const juce::File & file)  Line 152 + 0x13 bytes	C++
 	JuceDemo.exe!AudioDemoPlaybackPage::loadFileIntoTransport(const juce::File & audioFile)  Line 343 + 0x12 bytes	C++
 	JuceDemo.exe!AudioDemoPlaybackPage::showFile(const juce::File & file)  Line 332	C++
 	JuceDemo.exe!AudioDemoPlaybackPage::selectionChanged()  Line 359 + 0x48 bytes	C++

#4

It worked on all the files I tried… Could you email me your problematic mp3s?


#5

[size=200]LOL[/size]


#6

Thanks for the test file - should be fixed now!


#7

Yep it’s not crashing but i found a file thats also CBR 128kbps and it’s not showing as a playable file. Would you like to see that one as well ?


#8

Sure, send it over. Probably something simple.


#9

How do you find the time to write an OGL renderer, a MP3 decoder (that is, understanding the ISO mess), rewrite the font code, all in the same time ?
I wonder how many brains and hands do you have ?
Are you insomniac ?


#10

[quote]How do you find the time to write an OGL renderer, a MP3 decoder (that is, understanding the ISO mess), rewrite the font code, all in the same time ?
I wonder how many brains and hands do you have ?
Are you insomniac ?[/quote]

My girlfriend’s away this week, so I’m being a bit more productive than usual…


#11

I should try that too. :wink:


#12

Is your MP3 decoder sample-accurate (as sample-accurate as reading in a WAV) ?


#13

If you’re reading continuously from the start of the file, then yes, but if you’re seeking into it, then I’m not too sure, it might take a couple of frames to get going after restarting. No guarantees!


#14

Great to see this Jules! I haven’t even gotten around to removing the JSON decoder in favor of the one you wrote yet.
And now I can add pulling out the old mp3 decoders in favor of this one too, I imagine.

I don’t suppose you have any plans to make a “streamingAudioSource” that can be created with a quick url to an mp3? That would be amazing!


#15

Well, the tricky bit is seeking… Any of the audio decoders will happily play from a URL stream if you just start it and leave it running - it’s only when you ask them to start jumping around that things will get a bit hairy!


#16

Great job on this, by the way. Cleaner and faster than the other implementations I’ve been using.

finally dropped in the JSON parser and was pretty stoked on how well that worked too.

Cheers all around!


#17

Thanks!

I would recommend not using it on Windows or OSX/iOS though - on those platforms the CoreAudio/Windows Media codecs will do the job without all the code bloat and legal ramifications that this entails.


#18

My experience with CoreAudio however was that it didn’t get any metadata … which kinda kills the deal for me.

Though, to avoid the legal ramification I think I’ll stick with a linked version of mpg123 for the moment.

Out of curiosity, who would I contact to purchase a license for the MP3Format code? Is that you or is there a third party somewhere? If you, do you have a price in mind?


#19

As of today, it seems that JUCE 2.0 plays MP3 right out of the box.

I just discovered that by putting an MP3 instead of a WAV, which I know are handled out-of-the-box by AudioFormatManager,
(see http://www.rawmaterialsoftware.com/api/classAudioFormatManager.html#a1a8510b3078662358013ad78239d688e)
that they too, play without an additional library.

The reader, but it’s mentioned nowhere in the docs.
+ __vfptr 0x016dbcb4 const juce::WindowsMediaCodec::WMAudioReader::`vftable’ *

I guess this would not be the same for Linux, can someone tell more about this mechanism ?


#20

I thought the patents relevant to decoding expired?