diff options
author | Thom Johansen <thomj@rockbox.org> | 2006-02-01 00:04:55 +0000 |
---|---|---|
committer | Thom Johansen <thomj@rockbox.org> | 2006-02-01 00:04:55 +0000 |
commit | 5fff854126b0367168bdcbb24f6c49f053c045ee (patch) | |
tree | b2636672e244e15aaf704af7e69a828c251f8aef /apps | |
parent | b69d59ba8e06de799f7fc13c00e9d038867c38df (diff) |
EQ filtering code for ARM targets.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8515 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/eq_arm.S | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/apps/eq_arm.S b/apps/eq_arm.S new file mode 100644 index 0000000000..85617dc2fb --- /dev/null +++ b/apps/eq_arm.S @@ -0,0 +1,67 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 Thom Johansen + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + .text + .global eq_filter +eq_filter: + ldr r12, [sp] @ get shift parameter + stmdb sp!, { r0-r11, lr } @ save all params and clobbered regs + ldmia r1!, { r4-r8 } @ load coefs + mov r10, r1 @ loop prelude expects filter struct addr in r10 + +.filterloop: + ldr r9, [sp] @ get pointer to this channels data + add r0, r9, #4 + str r0, [sp] @ save back pointer to next channels data + ldr r9, [r9] @ r9 = x[] + ldr r14, [sp, #8] @ r14 = numsamples + ldmia r10, { r0-r3 } @ load history, r10 should be filter struct addr + str r10, [sp, #4] @ save it for loop end +.loop: + /* r0-r3 = history, r4-r8 = coefs, r9 = x[], r10..r11 = accumulator, + r12 = shift amount, r14 = number of samples. + See eq_cf.S for explanation of what this loop does. Primary difference + is the reordering of the equation we do here, which is done for register + reuse reasons, we're pretty short on regs. + */ + smull r10, r11, r6, r1 @ acc = b2*x[i - 2] + mov r1, r0 @ fix input history + smlal r10, r11, r5, r0 @ acc += b1*x[i - 1] + ldr r0, [r9] @ load input and fix history in same operation + smlal r10, r11, r4, r0 @ acc += b0*x[i] + smlal r10, r11, r7, r2 @ acc += a1*y[i - 1] + smlal r10, r11, r8, r3 @ acc += a2*y[i - 2] + mov r3, r2 @ fix output history + mov r2, r11, lsl r12 @ get result + @ TODO: arm makes it easy to mix in lower bits from r10 for extended + @ precision here, but we don't have enough regs to save the shift factor + @ we would need (32 - r12). + str r2, [r9], #4 @ save result + subs r14, r14, #1 @ are we done with this channel? + bne .loop + + ldr r10, [sp, #4] @ load filter struct pointer + stmia r10!, { r0-r3 } @ save back history + ldr r11, [sp, #12] @ load number of channels + subs r11, r11, #1 @ all channels processed? + strne r11, [sp, #12] + bne .filterloop + + add sp, sp, #16 @ compensate for temp storage + ldmia sp!, { r4-r11, pc } |