diff options
Diffstat (limited to 'apps/codecs/libatrac/atrac3_arm.S')
-rwxr-xr-x | apps/codecs/libatrac/atrac3_arm.S | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/apps/codecs/libatrac/atrac3_arm.S b/apps/codecs/libatrac/atrac3_arm.S new file mode 100755 index 0000000000..be8b2a0e0e --- /dev/null +++ b/apps/codecs/libatrac/atrac3_arm.S | |||
@@ -0,0 +1,137 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: | ||
9 | * | ||
10 | * Copyright (C) 2009 by Andree Buschmann | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | .section .text, "ax", %progbits | ||
23 | |||
24 | /**************************************************************************** | ||
25 | * void atrac3_iqmf_matrixing(int32_t *dest, | ||
26 | * int32_t *inlo, | ||
27 | * int32_t *inhi, | ||
28 | * unsigned int count); | ||
29 | * | ||
30 | * Matrixing step within iqmf of atrac3 synthesis. Reference implementation: | ||
31 | * | ||
32 | * for(i=0; i<counter; i+=2){ | ||
33 | * dest[2*i+0] = inlo[i ] + inhi[i ]; | ||
34 | * dest[2*i+1] = inlo[i ] - inhi[i ]; | ||
35 | * dest[2*i+2] = inlo[i+1] + inhi[i+1]; | ||
36 | * dest[2*i+3] = inlo[i+1] - inhi[i+1]; | ||
37 | * } | ||
38 | * Note: r12 is a scratch register and can be used without restorage. | ||
39 | ****************************************************************************/ | ||
40 | .align 2 | ||
41 | .global atrac3_iqmf_matrixing | ||
42 | .type atrac3_iqmf_matrixing, %function | ||
43 | |||
44 | atrac3_iqmf_matrixing: | ||
45 | /* r0 = dest */ | ||
46 | /* r1 = inlo */ | ||
47 | /* r2 = inhi */ | ||
48 | /* r3 = counter */ | ||
49 | stmfd sp!, {r4-r9, lr} /* save non-scratch registers */ | ||
50 | |||
51 | .iqmf_matrixing_loop: | ||
52 | ldmia r1!, { r4, r6, r8, r12} /* load inlo[0...3] */ | ||
53 | ldmia r2!, { r5, r7, r9, lr } /* load inhi[0...3] */ | ||
54 | add r4, r4, r5 /* r4 = inlo[0] + inhi[0] */ | ||
55 | sub r5, r4, r5, asl #1 /* r5 = inlo[0] - inhi[0] */ | ||
56 | add r6, r6, r7 /* r6 = inlo[1] + inhi[1] */ | ||
57 | sub r7, r6, r7, asl #1 /* r7 = inlo[1] - inhi[1] */ | ||
58 | add r8, r8, r9 /* r8 = inlo[2] + inhi[2] */ | ||
59 | sub r9, r8, r9, asl #1 /* r9 = inlo[2] - inhi[2] */ | ||
60 | add r12, r12, lr /* r12 = inlo[3] + inhi[3] */ | ||
61 | sub lr , r12, lr, asl #1 /* lr = inlo[3] - inhi[3] */ | ||
62 | stmia r0!, {r4-r9, r12, lr} /* store results to dest */ | ||
63 | subs r3, r3, #4 /* counter -= 4 */ | ||
64 | bgt .iqmf_matrixing_loop | ||
65 | |||
66 | ldmfd sp!, {r4-r9, pc} /* restore registers */ | ||
67 | |||
68 | .atrac3_iqmf_matrixing_end: | ||
69 | .size atrac3_iqmf_matrixing,.atrac3_iqmf_matrixing_end-atrac3_iqmf_matrixing | ||
70 | |||
71 | |||
72 | /**************************************************************************** | ||
73 | * atrac3_iqmf_dewindowing(int32_t *out, | ||
74 | * int32_t *in, | ||
75 | * int32_t *win, | ||
76 | * unsigned int nIn); | ||
77 | * | ||
78 | * Dewindowing step within iqmf of atrac3 synthesis. Reference implementation: | ||
79 | * | ||
80 | * for (j = nIn; j != 0; j--) { | ||
81 | * s1 = fixmul32(in[0], win[0]); | ||
82 | * s2 = fixmul32(in[1], win[1]); | ||
83 | * for (i = 2; i < 48; i += 2) { | ||
84 | * s1 += fixmul32(in[i ], win[i ]); | ||
85 | * s2 += fixmul32(in[i+1], win[i+1]); | ||
86 | * } | ||
87 | * out[0] = s2 << 1; | ||
88 | * out[1] = s1 << 1; | ||
89 | * in += 2; | ||
90 | * out += 2; | ||
91 | * } | ||
92 | * Note: r12 is a scratch register and can be used without restorage. | ||
93 | ****************************************************************************/ | ||
94 | .align 2 | ||
95 | .global atrac3_iqmf_dewindowing | ||
96 | .type atrac3_iqmf_dewindowing, %function | ||
97 | |||
98 | atrac3_iqmf_dewindowing: | ||
99 | /* r0 = dest */ | ||
100 | /* r1 = input samples */ | ||
101 | /* r2 = window coefficients */ | ||
102 | /* r3 = counter */ | ||
103 | stmfd sp!, {r4-r10, lr} /* save non-scratch registers */ | ||
104 | |||
105 | .iqmf_dewindow_outer_loop: /* outer loop 0...counter-1 */ | ||
106 | |||
107 | ldmia r2!, {r5, r6} /* load win[0..1] */ | ||
108 | ldmia r1!, {r7, r8} /* load in[0..1] */ | ||
109 | smull lr , r10, r5, r7 /* s1 = win[0] * in[0] */ | ||
110 | smull r12, r9 , r6, r8 /* s2 = win[1] * in[1] */ | ||
111 | |||
112 | mov r4, #46 /* r4 = 46 */ | ||
113 | .iqmf_dewindow_inner_loop: /* inner loop i=2...48 */ | ||
114 | ldmia r2!, {r5, r6} /* load win[i...i+1] */ | ||
115 | ldmia r1!, {r7, r8} /* load in[i...i+1] */ | ||
116 | smlal lr , r10, r5, r7 /* s1 = win[i ] * in[i ] */ | ||
117 | smlal r12, r9 , r6, r8 /* s2 = win[i+1] * in[i+1] */ | ||
118 | |||
119 | subs r4, r4, #2 /* inner loop -= 2*/ | ||
120 | bgt .iqmf_dewindow_inner_loop | ||
121 | |||
122 | mov lr , lr , lsr #31 | ||
123 | orr r10, lr , r10, lsl #1 /* s1 = low>>31 || hi<<1 */ | ||
124 | mov r12, r12, lsr #31 | ||
125 | orr r9 , r12, r9 , lsl #1 /* s2 = low>>31 || hi<<1 */ | ||
126 | |||
127 | stmia r0!, {r9, r10} /* store result out[0]=s2, out[1]=s1 */ | ||
128 | sub r1, r1, #184 /* roll back 64 entries = 184 bytes */ | ||
129 | sub r2, r2, #192 /* roll back 48 entries = 192 bytes = win[0] */ | ||
130 | |||
131 | subs r3, r3, #1 /* outer loop -= 1 */ | ||
132 | bgt .iqmf_dewindow_outer_loop | ||
133 | |||
134 | ldmfd sp!, {r4-r10, pc} /* restore registers */ | ||
135 | |||
136 | .atrac3_iqmf_dewindowing_end: | ||
137 | .size atrac3_iqmf_dewindowing,.atrac3_iqmf_dewindowing_end-atrac3_iqmf_dewindowing | ||