Playing mp3PRO files under Linux |
|
|||||||||
|
A reversing journey... (January 2008)
mp3PRO?From my local copy of Wikipedia:
A different way of describing it:
And halved it, it did. And I got some much needed disk space. And I installed Linux... Time passed... And, as expected, Linux (and the BSDs) shook my world... I became an addict; I learned to worship Stallman and Raymond, I coded in C and C++ and Perl and Python... I read manuals and infopages... I became a hermit... ...and after 10 years of working in silence, it dawned on me... now that I was using open-source OSes, how would I listen to my music? Closed formats: A Royal Pain In The...Ah, joy... To add insult to injury, in the years that passed, not only had Ogg Vorbis emerged, it had also surpassed mp3PRO in terms of quality/bitrate. So not only did my music collection suffer silence at the hands of a closed format, it was also sounding inferior...I contemplated re-coding all my CDs in Vorbis... But I am lazy... I am also a somewhat-adept coder, so I started investigating... Option 0: In-Duh-vidualWell, mp3PRO files are in fact valid MP3 files. You can listen to them with any MP3 decoder - but you are only listening to the first 22KHz of the spectrum... To hear the rest, you need an mp3PRO-aware decoder... So the quality of the sound is rather flat, similar to that of a radio station...Option 1: WineWINE is a great piece of software. Does it run Winamp, with its mp3PRO plugin?
![]() In the snapshot above, you can see the nice IceWM window decorations (I love spartan window managers). You can also see that the file being played is, in fact, an mp3PRO file - which sounds every bit as delicious as it does under Windows, at a smooth 44KHz. Option 2: Mass conversionThen again, WINE is a beast. Perhaps it is better to "bite the bullet" and transcode the files from mp3PRO to Vorbis... Harddisk space is now cheaper than air (almost), so I can use this nice "dBpowerAMP Music Converter" thingie that I downloaded from the Web, to convert my files to WAVs, and re-encode them in Vorbis. This tool supports mp3PRO through the Winamp plugin, so there, I am out of excuses... ![]() Do I have to Cick/Click/Click for all the music files I have? Hundreds of them...? Option 3: XMMSThen again, why transcode? The frequency information is there, why re-encode it in another format?All I want is to be able to listen to my files using a native Linux solution... Let's Google... What do you know!... THOMSON released an mp3PRO plugin for XMMS, back in 2005!... Now there's something I did not expect. Then again, people all over the web are complaining about it ("it doesn't work" - "it borks my XMMS") ... let's try it anyway...
bash$ rpm -qip libmp3PRO-1.0.1-1.i386.rpm
Name : libmp3PRO Relocations: (not relocateable)
Version : 1.0.1 Vendor: Coding Technologies GmbH <mp3PRO@CodingTechnologies.com>
Release : 1 Build Date: Wed 14 Sep 2005 03:41:15 PM EEST
Install Date: (not installed) Build Host: linux.local
Group : Applications/Multimedia Source RPM: libmp3PRO-1.0.1-1.src.rpm
Size : 391408 License: distributable
Signature : (none)
URL : http://www.mp3PROzone.com
Summary : XMMS input plugin to play mp3PRO files and streams.
Description :
The Coding Technologies mp3PRO Decoder plugin is a complete
ISO/IEC 11172-3 ("MPEG-1") and ISO/IEC 13818-3 ("MPEG-2") implementation
of the MPEG Layer-3 decoding algorithm with the additional ability to
handle the mp3PRO enhancement. The proprietary Fraunhofer IIS extension for
sampling frequencies of 8, 11.025 and 12 kHz ("MPEG-2.5") is also supported.
Install this plugin if you want to play mp3PRO files or streams. To ensure
using this plugin for mp3PRO files it is recommended to disable the built-in
MPEG Layer 1/2/3 Player.
Hmm, looks nice enough. Extracting the contents with alien (I use Debian), copying libmp3PRO.so into /usr/lib/xmms/Input/...
Hooray, it worked! (If it didn't work for you, keep reading...) Option 4: MPlayerWell then, why did these people complain? It works fine, in both my Gentoo and my Debian Etch... And now that I have an XMMS plugin, I can even use MPlayer's xmms demuxer, and do ANYTHING I want with my mp3PRO files... filter them, transcode them, flip them sideways...Let me show you - oh wait! Here's something weird... I compiled my MPlayer with --enable-xmms and fed it (using -demuxer xmms) with an mp3PRO file... I only get 22KHz! bash$ mplayer -demuxer xmms "SlaveChildrenCrusade.mp3" MPlayer 1.0rc2-4.2.2 (C) 2000-2007 MPlayer Team CPU: Intel(R) Core(TM)2 Duo CPU E4500 @ 2.20GHz (Family: 6, Model: 15, Stepping: 13) CPUflags: MMX: 1 MMX2: 1 3DNow: 0 3DNow2: 0 SSE: 1 SSE2: 1 Compiled for x86 CPU with extensions: MMX MMX2 SSE SSE2 115 audio & 237 video codecs Playing SlaveChildrenCrusade.mp3. Found plugin: libmp3PRO.so (). Found plugin: libmp4.so (MP4 & MPEG2/4-AAC audio player - 1.2.x). Found plugin: libwav.so (Wave Player 1.2.10). Found plugin: libmikmod.so (MikMod Player 1.2.10). Found plugin: libmodplugxmms.so (ModPlug Player). Found plugin: libcdaudio.so (CD Audio Player 1.2.10). Found plugin: libtonegen.so (Tone Generator 1.2.10). Waiting for the XMMS plugin to start playback of 'SlaveChildrenCrusade.mp3'... XMMS file format detected. ========================================================================== Opening audio decoder: [pcm] Uncompressed PCM audio decoder AUDIO: 22050 Hz, 2 ch, s16le, 705.6 kbit/100.00% (ratio: 88200->88200) Selected audio codec: [pcm] afm: pcm (Uncompressed PCM) ========================================================================== AO: [oss] 22050Hz 2ch s16le (2 bytes per sample) Video: no video Starting playback... Closing plugin: /usr/lib/xmms/Input/libtonegen.so. Closing plugin: /usr/lib/xmms/Input/libcdaudio.so. Closing plugin: /usr/lib/xmms/Input/libmodplugxmms.so. Closing plugin: /usr/lib/xmms/Input/libmikmod.so. Closing plugin: /usr/lib/xmms/Input/libwav.so. Closing plugin: /usr/lib/xmms/Input/libmp4.so. Closing plugin: /usr/lib/xmms/Input/libmp3PRO.so. Exiting... (Quit)MPlayer DID use the XMMS plugin, but something went wrong... Why? Hmm... How can the same plugin - the same executable code - behave differently under MPlayer? Is it locked, maybe? To only run under XMMS? (Binary blobs... Sigh... You can never tell...) Looking at the source code for libmpdemux/demux_xmms.c, I can see that a disk_open callback is called from code within the plugin, to provide the player with the "decoding details":
static int disk_open(AFormat fmt, int rate, int nch) {
switch (fmt) {
case FMT_U8:
xmms_afmt=...
In other words, it is the plugin that decides the quality of the output (parameter "rate"). The function pointer to "disk_open" is
passed to the plugin in a structure (of type OutputPlugin) during plugin initialization, and the plugin calls it when it knows enough about the input to decide what output it is going to generate.
The million dollar question, is why does the plugin call disk_open with 22KHz when used under MPlayer, but with 44KHz when used under XMMS? Well... it took some work with GDB to figure this out... The mp3PRO plugin contains a getbits function. That's not so bad, in itself... unless the shared library in question (libmp3PRO.so) is NOT the ONLY library that uses such a function... So what happens is this:
It turns out, that in my case, it used the getbits from libmp3lame.so! What this means, in plain terms, is that "ld" tried to put the shoes of a midget on Andre the Giant. The results, could have been ANYTHING. I was amazed to see that this didn't cause a crash; pure luck, as it turned out: a function inside the plugin (SbrCrcCheckMp3) tried to use getbits, and ended up calling the COMPLETELY different implementation of the function offered by the code inside libmp3lame. This foreign code, returned a completely unexpected value to SbrCrcCheckMp3, and so the poor function considered the Sbr information (spectral band replication) to be "bad" - and disabled the decoding of the upper frequencies (the ones above 22KHz!). This of course explains all the poor people that complain about this plugin "borking" their XMMS... What happens is truly random... In my case, I was lucky - my XMMS and its plugins didn't offer an alternative getbits, so everything was fine under XMMS. Under MPlayer, however, I could have gotten any kind of behaviour. Crash, corruption... Other people, apparently, were not so lucky. Executive summary: Friggin' binary blobs! If only we could dispose of them... So how do I fix this?Easy. You just have to build an MPlayer that...
bash$ ./mplayer -demuxer xmms "SlaveChildrenCrusade.mp3" ... XMMS file format detected. ========================================================================== Opening audio decoder: [pcm] Uncompressed PCM audio decoder AUDIO: 44100 Hz, 2 ch, s16le, 1411.2 kbit/100.00% (ratio: 176400->176400) Selected audio codec: [pcm] afm: pcm (Uncompressed PCM) ========================================================================== AO: [oss] 44100Hz 2ch s16le (2 bytes per sample) Video: no video Starting playback... ...And now, the sky's the limit... If I choose to, I can transcode my files into vorbis using pipes (and avoid the Gigabytes of WAVs that "Option 2" would require)... or I can apply any kind of runtime filter (e.g. -af sub, -af extrastereo, -af karaoke, etc). I am happy - I can listen to my collection again...
|
|
|||||||||