• Status Closed
  • Percent Complete
  • Task Type Patches
  • Category Codecs
  • Assigned To No-one
  • Operating System All players
  • Severity Low
  • Priority Very Low
  • Reported Version Daily build (which?)
  • Due in Version Undecided
  • Due Date Undecided
  • Votes
  • Private
Attached to Project: Rockbox
Opened by saratoga - 2010-11-01
Last edited by saratoga - 2010-11-10

FS#11709 - ARMv5E iQMF for libatrac

Work in progress iQMF using the ARMv5E 32×16 multiply instructions. So far this converts libatrac to using 16 bit iQMF coefficients, and then prescales everything going into the iQMF by 8 bits, then the output another 7 bits. Unfortunately, the sim audio is somewhat garbled because the prescaling isn’t performed correctly (scaling in the fixmul15 function works, but not prescaling the output of the imdct for some reason). I’m obviously missing something about how data is used in the codec, and either not scaling all the samples, or double scaling some of them.

I haven’t tested the asm code, but its fairly simple so it shouldn’t be too hard to fix once the sim is working. The ASM code is also not properly scheduled. Once its working it can be arranged to avoid pipeline stalls.

Closed by  saratoga
2010-11-10 18:30
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

Accepted in r28549.

The updated patch corrects scaling for simulation and preserves higher precision of the windowing coefficients.

I have defined a fixmul32x16(int16, int) which needs to do »=15 to receive a 32bit result. THis was the main fault in your scaling. All the other pre-/post-scaling could be removed – except the windowing coefficients themselves, of course.

Difference to svn decoding is max +/-4 of +/-32768 (~ -78 dB), and average ~ -110 dB. This is quite few.

I have defined a fixmul32x16(int16, int) which needs to do »=15 to receive a 32bit result. THis was the main fault in your scaling.

thanks, but I had that working, and am now trying to get it to work without a shift. I did some tests yesterday with the c code, and prescaling everything so that each multiply is a single smlaw<x> instruction gives acceptable results. The problem is I just can’t seem to get it work once I put it all together :)

Updated patch to fix various mistakes in the ARM asm pointed out by buschel. Also cleaned up comments. Still doesn’t work.

Thanks again buschel for spotting a stupid bug in the ASM. This version works. Further clean up and scheduling is still needed before this can be committed.

Speed up is quite large, 26% on my test file.

Restoring buschel’s rounding when truncating to 16 bit.

* Fix building on armv4, coldfire and sim
* Disable 16 bit optimizations on these targets because theres no performance benefit


* Improve scheduling
* Port this to mp3 filterbank …

* Cleaned up useless changes
* Scheduled for arm11 by overlapping memory accesses with multiply. 2 out of every 3 arm11 loads should incur no stall at all.

Interestingly the improved scheduling speeds up arm9e by 0.5MHz, presumably because some of the memory latency on a cache miss is now hidden.

If anyone has an arm11 target handy it would be interesting to see v7 verses v8 comparisons. Test file here:

I think this is ready to commit.

* Add cache alignment for the Beast.

* Improve scheduling on arm11

arm11 iQMF goes from 15 → 12MHz runtime. No speed up on arm9e.

On arm11 this version uses 2.8 cycles/tap, verses the ideal (zero wait state memory) 1.75 cycles/tap. However I don’t see anyway to improve memory performance. Forcing 32 byte alignment of all buffers does not improve cache performance measurably. It may just be that the Beast ram is fairly slow.


Available keyboard shortcuts


Task Details

Task Editing