• Status Closed
  • Percent Complete
  • Task Type Patches
  • Category Codecs
  • Assigned To No-one
  • Operating System SW-codec
  • Severity Low
  • Priority Very Low
  • Reported Version
  • Due in Version Undecided
  • Due Date Undecided
  • Votes
  • Private
Attached to Project: Rockbox
Opened by tmal - 2007-02-27
Last edited by linuxstb - 2007-07-28

FS#6705 - Small ARM optimizations to MPA codec

Here are some optimizations that let me play mp3 files in realtime on Iriver iFP. The iFP benefits mostly by moving things into IRAM, since its external RAM is very slow (16-bit, 70 ns, no bursts). The patch needs some cleanup, but I won’t be working on it in the next weeks, so I put it here in case someone wants to look at it.

One warning: there is a bug somewhere in Makefiles and sometimes make needs to be run twice to recompile and relink the codec.

The biggest change is a different dct32 routine. It is worse in terms of number of executed instructions, but it’s smaller, so it fits in IRAM and uses less cache. Compared to my last patch ( FS#6670 ), it’s slightly bigger and faster. Overall gain in speed depends on speed of the external RAM, so it may differ from player to player. On Ipods libmad is currently compiled with -O instead of -O2, probably because the original dct32 is smaller and faster when compiled with -O. With the new dct32 it’s worth trying again with -O2.

Rest of the changes involve using ldm and stm instructions. Some give really minor gains.

With this patch the mpegplayer plugin does not compile on Ipod because of overfull IRAM.

Some ideas for further improvements:
- integrate III_overlap into III_imdct_l.
- at the cost of accuracy, we could try changing D coefficients (used in synth_full) to use at most 24 bits. ARM multiplies faster when some of the most significant bytes (bytes, not bits) of the last operand are 0.

   mpa.patch (33.8 KiB)
Closed by  linuxstb
2007-07-28 15:21
Reason for closing:  Accepted
Additional comments about closing:   Warning: Undefined array key "typography" in /home/rockbox/flyspray/plugins/dokuwiki/inc/parserutils.php on line 371 Warning: Undefined array key "camelcase" in /home/rockbox/flyspray/plugins/dokuwiki/inc/parserutils.php on line 407

Finally committed to SVN - thanks.

Hi tomal,
great work.
I tested your patch on the Sansa with the following result:

~18% performance increase of the codec in 192kBit files

Some WAV output samples differ between the current and your patch.
Do you know, where this rounding error comes from?

*** Posted to wrong Flyspray entry, sorry.

tmal commented on 2007-03-24 14:11

Thanks for testing. dct32 in this patch uses a different algorithm, so rounding errors are different.

Your patch works very nicely on my ipod nano with no noticeable difference in audio quality.

Music playback
normal file type: mp3 214 kbps (VBR) 44100Hz stereo boost level: 48%
patched file type: mp3 214 kbps (VBR) 44100Hz stereo boost level: 36%

Audio book playback
normal file type: mp3 81kbps (VBR) 22050Hz mono boost level: 0%
patched file type: mp3 81kbps (VBR) 22050Hz mono boost level: 0%

Hmm I think I got a warning

synth.c: In function ‘synth_full’:
synth.c:1053: warning: unused variable ‘sb’

I’ve just done some tests of this patch on my ipod (Color/Photo) with the new test_codec plugin. My test file was a 128kbps CBR lame-encoded MP3.

Current SVN decoded at 164% realtime.
With this patch applied - 175% realtime
With the two .S files and the synth_full function removed from IRAM - 183% realtime

Removing those functions from IRAM also means that mpegplayer compiles fine.

Just tested this plugin, and this plugin with linuxstb’s suggestion using the test_codec plugin. Here are the results:


128kbps MP3: 292.70% realtime
    VBR MP3: 150.89% realtime


128kbps MP3: 331.01% realtime
    VBR MP3: 169.95% realtime


128kbps MP3: 345.93% realtime
    VBR MP3: 180.56% realtime

Both MP3 files were about four minutes in length. These tests were done on an iriver H10. For me, mpegplayer did not compile after I removed the two .S files from IRAM. Attached is the patch file with the stuff removed from IRAM for those interested. I remember someone saying on IRC that we could also get mpegplayer to compile if we added a special conditional for mpegplayer so that it wouldn’t use the IRAM changes. However, I have no idea how to do this, so I’ll leave it to someone else…

Err… forget the file I attached above… it didn’t include the .S files for some reason. If you want to remove the added stuff from IRAM, simply change .icode to .text in the two S files.

Turns ou that linuxstb also did another little modification… Here are the results for the complete modifications of the attached patch:

128kbps MP3: 345.93% realtime
VBR MP3: 180.73% realtime

So it seems to be about the same. Attached is the patch with the modifications linuxstb did.

Tested on a 3G iPod:

Song: 193,12s, 192kBit/s

Recent SVN: 117,79% (163,94s)
MPA Patch: 154,50% (124,99s)
MPA no IRAM: 130,19% (148,33s)

Forgot to test a VBR mp3. I can do a test with one in a few hours if needed.

I tested this on my Sansa today with no issues. mpegplayer and mp3 playback work normally.

Is there something else holding up this patch?

I’ve tested a few files on my Sansa with and without this patch, and the difference between the two seems very small. Most samples are identical, and those that are off seem to be off by only 1 bit. I computed the RMS difference (sum((SVN-patched)^2)/length)^.5 for one 128k file and another lame -v2 vbr file at each less then ~-120dB.

I’ve also been listening to a my albums for the last couple days and not noticed any issues. Unless anyone else has objections, perhaps we could commit this patch and see if any problems are reported?


Available keyboard shortcuts


Task Details

Task Editing