Creating MP3 Decoder
Adopt MAD (MPEG audio decoder library) to usage with Symbian

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
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.

Tutorial posted April 28th, 2005 by denis categories [ ]

> Creating MP3 Decoder

Thanks fo wonderful article

> Creating MP3 Decoder

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?

> Creating MP3 Decoder

This DLL is independent to SDK - so it will work everywhere

> Creating MP3 Decoder

hi i dont know how to do it to have a mp3 decoder can you make one and sent to me. this is so as my panasonic does not come with mp3 decoder.

> Creating MP3 Decoder

thnx for tutorial, but i think its too hard for some people. pls can someone upload his dll's to rapidshare and just give us a link? thnx billion times.

> Creating MP3 Decoder

Excellent article , anything to read the mp3 tags for song info ??

> Creating MP3 Decoder

hi i dont know how to do it to have a mp3 decoder can you make one and sent to me. this is so as my panasonic does not come with mp3 decoder.

> Creating MP3 Decoder

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

> Creating MP3 Decoder

thats very complicated.thanks will this work in nokia 6600?? how can i do aaall this??

> Creating MP3 Decoder

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

> Creating MP3 Decoder

Well PCM streams will not work unless u filter it and try to fuse the 2 channels into one. u will find some information in the minimad.c file which comes as a part of the libmad tarball. infact if u just compile it under linux , open a mp3 file and pipe output to /dev/dsp u can hear it well (slightly distorted though). the trick is in the function "scale"( something just check the name i am too lazy to open that file now). check it out. this is the one that does the "filtering" before output in small endian format. i am sure u will find a way out cheers-- ashwin

> Creating MP3 Decoder

hi i want to paly mp3 file in my linux pc using minimad i did make minimad ./minimad <mp3filename> test.wav but it doesnt play.....so how i play mp3 using minimad? help me? regards cader

> Creating MP3 Decoder

Hi,I has been finished our mp3 soft-decode with your MP3DECODEDLL project. Thank you. But I try to run our player over 12 hours , my phone(panasonic X700) show a message :"Out of memory! Close other applications." , then my player is closed . I tried to check where lost memory in my program , like following : I replace this line only: iMP3Decode->DecodeOneFrame(iBuffer16);//decode one frame with: iBuffer16.Fillz(iBuffer16.MaxLength);//Directly fill zero to my buffer and not use real decoder So my program can run many many hours and not lose memory. I think , Maybe the MP3DecodeDLL has bug?

> Creating MP3 Decoder

Hi All!

I also has finished with my mp3 player project, and has the same problem.

Regards, Lorand

Creating MP3 Decoder

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