Thom Johansen | 5fff854 | 2006-02-01 00:04:55 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
| 8 | * $Id$ |
| 9 | * |
Thom Johansen | c4ccd9e | 2007-02-22 13:55:49 +0000 | [diff] [blame] | 10 | * Copyright (C) 2006-2007 Thom Johansen |
Thom Johansen | 5fff854 | 2006-02-01 00:04:55 +0000 | [diff] [blame] | 11 | * |
Daniel Stenberg | 2acc0ac | 2008-06-28 18:10:04 +0000 | [diff] [blame^] | 12 | * This program is free software; you can redistribute it and/or |
| 13 | * modify it under the terms of the GNU General Public License |
| 14 | * as published by the Free Software Foundation; either version 2 |
| 15 | * of the License, or (at your option) any later version. |
Thom Johansen | 5fff854 | 2006-02-01 00:04:55 +0000 | [diff] [blame] | 16 | * |
| 17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| 18 | * KIND, either express or implied. |
| 19 | * |
| 20 | ****************************************************************************/ |
| 21 | |
Jens Arnold | 163d72f | 2007-08-24 21:03:19 +0000 | [diff] [blame] | 22 | #include "config.h" |
| 23 | |
Thom Johansen | c4ccd9e | 2007-02-22 13:55:49 +0000 | [diff] [blame] | 24 | /* uncomment this to make filtering calculate lower bits after shifting. |
| 25 | * without this, "shift" of the lower bits will be lost here. |
| 26 | */ |
| 27 | /* #define HIGH_PRECISION */ |
| 28 | |
| 29 | /* |
| 30 | * void eq_filter(int32_t **x, struct eqfilter *f, unsigned num, |
| 31 | * unsigned channels, unsigned shift) |
| 32 | */ |
Jens Arnold | 163d72f | 2007-08-24 21:03:19 +0000 | [diff] [blame] | 33 | #if CONFIG_CPU == PP5002 |
| 34 | .section .icode,"ax",%progbits |
| 35 | #else |
Thom Johansen | 5fff854 | 2006-02-01 00:04:55 +0000 | [diff] [blame] | 36 | .text |
Jens Arnold | 163d72f | 2007-08-24 21:03:19 +0000 | [diff] [blame] | 37 | #endif |
Thom Johansen | 5fff854 | 2006-02-01 00:04:55 +0000 | [diff] [blame] | 38 | .global eq_filter |
| 39 | eq_filter: |
| 40 | ldr r12, [sp] @ get shift parameter |
| 41 | stmdb sp!, { r0-r11, lr } @ save all params and clobbered regs |
| 42 | ldmia r1!, { r4-r8 } @ load coefs |
| 43 | mov r10, r1 @ loop prelude expects filter struct addr in r10 |
| 44 | |
| 45 | .filterloop: |
| 46 | ldr r9, [sp] @ get pointer to this channels data |
| 47 | add r0, r9, #4 |
| 48 | str r0, [sp] @ save back pointer to next channels data |
| 49 | ldr r9, [r9] @ r9 = x[] |
| 50 | ldr r14, [sp, #8] @ r14 = numsamples |
| 51 | ldmia r10, { r0-r3 } @ load history, r10 should be filter struct addr |
| 52 | str r10, [sp, #4] @ save it for loop end |
Thom Johansen | c4ccd9e | 2007-02-22 13:55:49 +0000 | [diff] [blame] | 53 | |
Thom Johansen | 5fff854 | 2006-02-01 00:04:55 +0000 | [diff] [blame] | 54 | /* r0-r3 = history, r4-r8 = coefs, r9 = x[], r10..r11 = accumulator, |
Thom Johansen | c4ccd9e | 2007-02-22 13:55:49 +0000 | [diff] [blame] | 55 | * r12 = shift amount, r14 = number of samples. |
Thom Johansen | 5fff854 | 2006-02-01 00:04:55 +0000 | [diff] [blame] | 56 | */ |
Thom Johansen | c4ccd9e | 2007-02-22 13:55:49 +0000 | [diff] [blame] | 57 | .loop: |
| 58 | /* Direct form 1 filtering code. |
| 59 | * y[n] = b0*x[i] + b1*x[i - 1] + b2*x[i - 2] + a1*y[i - 1] + a2*y[i - 2], |
| 60 | * where y[] is output and x[] is input. This is performed out of order to |
| 61 | * reuse registers, we're pretty short on regs. |
| 62 | */ |
| 63 | smull r10, r11, r6, r1 @ acc = b2*x[i - 2] |
| 64 | mov r1, r0 @ fix input history |
| 65 | smlal r10, r11, r5, r0 @ acc += b1*x[i - 1] |
| 66 | ldr r0, [r9] @ load input and fix history in same operation |
| 67 | smlal r10, r11, r4, r0 @ acc += b0*x[i] |
| 68 | smlal r10, r11, r7, r2 @ acc += a1*y[i - 1] |
| 69 | smlal r10, r11, r8, r3 @ acc += a2*y[i - 2] |
| 70 | mov r3, r2 @ fix output history |
| 71 | mov r2, r11, asl r12 @ get upper part of result and shift left |
| 72 | #ifdef HIGH_PRECISION |
| 73 | rsb r11, r12, #32 @ get shift amount for lower part |
| 74 | orr r2, r2, r10, lsr r11 @ then mix in correctly shifted lower part |
| 75 | #endif |
| 76 | str r2, [r9], #4 @ save result |
| 77 | subs r14, r14, #1 @ are we done with this channel? |
Thom Johansen | 5fff854 | 2006-02-01 00:04:55 +0000 | [diff] [blame] | 78 | bne .loop |
| 79 | |
Thom Johansen | c4ccd9e | 2007-02-22 13:55:49 +0000 | [diff] [blame] | 80 | ldr r10, [sp, #4] @ load filter struct pointer |
| 81 | stmia r10!, { r0-r3 } @ save back history |
| 82 | ldr r11, [sp, #12] @ load number of channels |
| 83 | subs r11, r11, #1 @ all channels processed? |
Thom Johansen | 5fff854 | 2006-02-01 00:04:55 +0000 | [diff] [blame] | 84 | strne r11, [sp, #12] |
| 85 | bne .filterloop |
| 86 | |
Thom Johansen | c4ccd9e | 2007-02-22 13:55:49 +0000 | [diff] [blame] | 87 | add sp, sp, #16 @ compensate for temp storage |
Thom Johansen | 5fff854 | 2006-02-01 00:04:55 +0000 | [diff] [blame] | 88 | ldmia sp!, { r4-r11, pc } |
Thom Johansen | c4ccd9e | 2007-02-22 13:55:49 +0000 | [diff] [blame] | 89 | |