Sometime ago I wrote at newlc.com forum that create MP3 player for Series 60 by myself. I receiving a lot of mail with many questions about MP3 decoding and playing on Symbian.
Here you can read about one solution for decoding MP3 with usage of MAD library (it is licensed under GPL).
Introduction
Since Symbian 7.0s you can play MP3 on some smartphones via MMF, but what if your phone does not support MP3 decoder? Or if you want to receive decoded MP3 by yourself?
I will show you how to adopt MAD (MPEG audio decoder, libmad) for usage with Symbian.
Why MAD? Because it is high-quality MPEG audio decoder, which is already tested under ARM CPU (i.e. different Pocket PC and Palm MP3 players use it).
Porting MAD to Symbian
Get last MAD sources, you will need next files:
- inc
- D.dat
- imdct_s.dat
- qc_table.dat
- rq_table.dat
- sf_table.dat
- bit.h
- config.h
- decoder.h
- fixed.h
- frame.h
- global.h
- huffman.h
- layer12.h
- layer3.h
- mad.h
- stream.h
- synth.h
- timer.h
- version.h
- src
- bit.c
- decoder.c
- fixed.c
- frame.c
- huffman.c
- layer12.c
- layer3.c
- stream.c
- synth.c
- timer.c
- version.c
- imdct_l_arm.S
Fix static functions/variables to non-static (variables can be changed to "static const").
Edit mad.h - change it to define FPM_ARM for device targets and FPM_DEFAULT otherwise.
If your WINS compiler does not support big inline functions just do so:
#ifndef __WINS__
inline
#endif
There can stack error occures at layer3.c III_decode function - due to string:
mad_fixed_t xr[2][576];
You can alloc memory for this variable by yourself or (in case of simple application) just use trick for WINS target - make this variable static. On real device it will work correct.
imdct_l_arm.S is optimized for ARMI - to use it you must add its header (function III_imdct_l).
# ifndef __WINS__
void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36], unsigned int block_type);
# else
static
void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36], unsigned int block_type)
...
Attention! Optimized imdct_l_arm can not be compiled under THUMB, so just ARMI target can be used.
Creating MP3 Decode DLL
The best way to use MP3 Decoder is DLL - you can compile it once and useful multiple times, there is no any platform specific things. So - use TARGETTYPE dll.
Add \epoc32\include\libc to SYSTEMINCLUDE at MMP file - for libmad. If you want to use optimized III_imdct_l function, add to MMP:
#if !defined (WINS)
SOURCE imdct_l_arm.S
#endif
Also add to bld.inf (so imdct_l_arm can not be compiled for THUMB):
PRJ_PLATFORMS
ARMI WINS
If you use trick for stack fault at iii_decode function and you have no _chkstk function at your WINS libraries - add it by yourself (empty void _chkstk()).
To use DLL from your application, add there functions etc.
You can use main cycle of MP3 decoding based on madplay sources:
read file to buffer
decode MP3 frame
apply filter
synthesize decoded frame to PCM samples
resample PCM samples
Filter. Most of Symbian smartphones do not allow to play stereo sound, so you can merge sound to mono here. And you can implement equalizer here.
Frequency. Do not make not required calculations - if required frequency is more than half of current frame currency, change frame options after applying filter:
Frame.options |= MAD_OPTION_HALFSAMPLERATE;
Compilation
I recommend you use GCC 3 to compile this library. By my tests it is up to 20% faster than usual GCC 2.95 with MP3 decoding.
Do not forget that MAD is licensed under GNU General Public License version 2.
Download
You can download my own easyest MP3 Decode library (with equalizer support):

MP3DecodeDLL.zip
It is created just for test of MAD speed on Series 60 about 1 year ago, so if you want to use it in your software - add additional checks etc.
Conclusion
I hope, this article help you.
If you have any comments/suggestion - you are welcomed.
Compiling stuff on different compiler and SDk easilly takes half a day to get working.
How about supplying a version for S60v1 and one for S60v2&S60v2fp1?
Hi!
Can somebody describe me, which functions I need to play an mp3 files. Sorry, but I'm new in Symbian.
Thanks and regards Lorree
Hi!
I implemented the sources into my project. I did a decoding fram-by-frame. The result buffer I saved into a new file. I tried to play the new file as .pcm stream, but unsuccessful.
Please let me know, what U mean under the follows:
apply filter
synthesize decoded frame to PCM samples
resample PCM samples
Is it not enough to decode the mp3 file frame-by-frame?
Thanks and regards, Lorand
Hi All!
I also has finished with my mp3 player project, and has the same problem.
Regards, Lorand
Hello!
I'm using the MADLIB decoder only on 6600. The reason: it is not playing mp3 songs with good quality. I convert the mp3 frames into 8 Bit PCM. Can I convert this frames to play a wave file, or something else? I'm not pleased with the result. Maybe I'm doing something wrong.
Regards, Lorand