Creating MP3 Decoder
28 Apr 2005 - 09:18
Keywords :

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

Submitted by vMarinov (not verified) on Wed, 2005-05-04 08:40.

Thanks fo wonderful article

Submitted by Joonas Kekoni (not verified) on Fri, 2005-05-06 13:51.

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?


Submitted by Denis Mingulov (not verified) on Tue, 2005-06-14 06:13.

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

Submitted by Anonymous on Tue, 2005-09-06 15:53.

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.

Submitted by mp3 (not verified) on Fri, 2006-05-26 20:05.

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.

Submitted by ashwin rath (not verified) on Mon, 2005-06-06 12:36.

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

Submitted by ken (not verified) on Mon, 2005-07-18 14:34.

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.

Submitted by Lorree (not verified) on Thu, 2005-07-21 08:32.

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


Submitted by Anonymous on Wed, 2005-09-21 19:20.

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

Submitted by Lorand (not verified) on Sat, 2005-10-01 08:00.

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


Submitted by Anonymous on Sat, 2005-11-26 18:40.

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

Submitted by abdul cader (not verified) on Thu, 2006-05-18 15:02.

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

Submitted by ad209 (not verified) on Mon, 2005-12-19 07:30.

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?

Submitted by lorand (not verified) on Tue, 2006-01-10 18:19.

Hi All!

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

Regards, Lorand


Submitted by Lorand (not verified) on Thu, 2006-02-16 06:58.

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



copyright 2003-2009 NewLC SARL