AUTO-ADMIN: Non-MP3, WAV, OGG, SoundCloud, YouTube, Vimeo, Twitter and Facebook links in this post have been protected automatically. Once the member reaches 5 posts the links will function as normal.
I would like to introduce a new library I have just published on github: OpenMP3 (https://github.com/audioboy77/OpenMP3)I needed MP3 decoding for use in a commercial project I am working on, but after wasting a day searching and trying to understand the various GPL licences (god I hate that stuff) I concluded there is no major decoder out there which can be used in commercial apps legally (without exposing your source, or using it in a .dll etc). I also did not particuarly like the interfaces of any of them either.
This really sucks because MP3 decoding is now patent-free and can be used anywhere without the need to pay royalties.
Finally however, I found a student project decoder on github that was released in the public domain without any restrictive licence (PDMP3 (https://github.com/technosaurus/PDMP3)). I did some testing and it works fine with all CBR files I created with Audacity/LAME (more on this below). The code however was like a 2000 lines of unreadable 'minified' code, and on a technical level the lib could not be used in a professional context as its reliance on a bunch of global data meant it could only be used single instance as an external app.
Although PDMP3 works fine with most MP3's I created (with Audacity/LAME) it does seem to have some problems with some VBR files (in terms of glitches in the output). This is a limitation I can work with for now, so I decided to refactor the library. The code was such a mess (fair enough, the author was a student) that this took over 3 days.
OpenMP3 is the result, which is object orientated, multi-instance/thead compatible, with streaming & parsing completley detached from the actual decoding engine, with zero external dependencies (not even std libs) and no internal memory allocations. I also did some basic optimisations along the way, but there are still lots to do (see the release notes for more info on design considerations and todo's).
So the bottom line: there is now a clean, licence-free (http://unlicense.org) library for decoding MP3 files, which anyone can use in their commercial apps... but sadly without 100% perfect output
Why I am telling you all this? Well its not really just because im a nice guy and want to give away 3 days work to the world for free. The reality is that I am not a DSP expert and it is beyond me to attempt to fix the output errors that exist on some files (see the 'fail' folder for an example, note the subtle 'scratchy' artefacts). I therefore decided to share the library in the hope of attracting some contributors who can focus on the DSP side and fix the output errors. I am happy to continue to maintain the overall architecture (for example add support for ID3 tags, do more internal optimisations etc) but I am very unlikely to fix the decoding errors.
Therefore I have released the lib as version 0.9. Would be really great if we could work together to make this a perfect 1.0. I really do think the world deserves a totally free MP3 decoder which we can all use in our apps without legal hassles. (And yeah, I know the JUCE guys already have one, but the rest of us don't.)
Example usage:
Code: Select all (#)
void DecodeMP3(const void * mp3_file, unsigned file_size)
{
OpenMP3::Library openmp3;
OpenMP3::Iterator itr(openmp3, (OpenMP3::UInt8*)mp3_file, file_size);
float buffer[2][1152];
std::vector <float> channels[2];
bool mono = true;
OpenMP3::Decoder decoder(openmp3);
OpenMP3::Frame frame;
while (itr.GetNext(frame))
{
OpenMP3::UInt nsamples = decoder.ProcessFrame(frame, buffer);
for(int ch = 0; ch < 2; ++ch)
{
auto & channel = channels[ch];
auto * data = buffer[ch];
for (OpenMP3::UInt idx = 0; idx < nsamples; ++idx) channel.push_back(*data++);
}
mono = mono && (frame.GetMode() == OpenMP3::kModeMono);
}
OpenMP3::UInt samples = channels[0].size();
}
