diff options
author | Yoshihisa Uchida <uchida@rockbox.org> | 2010-05-13 12:40:09 +0000 |
---|---|---|
committer | Yoshihisa Uchida <uchida@rockbox.org> | 2010-05-13 12:40:09 +0000 |
commit | 0f5c6d47d4fdd17260b840024880ba6dd3fdf935 (patch) | |
tree | 6d2526a58816aa9f6431a22a8f1a56278a445dfd /apps/codecs/libtta/filter_arm.S | |
parent | 889b4a8ce838bd4191c736d01d9665c177e6d390 (diff) | |
download | rockbox-0f5c6d47d4fdd17260b840024880ba6dd3fdf935.tar.gz rockbox-0f5c6d47d4fdd17260b840024880ba6dd3fdf935.zip |
add True Audio (TTA) codec
decoding speed iPod video ~153%
But in some players, the decoding speed is not enough.
(e.g., H180 52.4% (thanks amiconn), H300 55.09% (thanks n1s))
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25994 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libtta/filter_arm.S')
-rw-r--r-- | apps/codecs/libtta/filter_arm.S | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/apps/codecs/libtta/filter_arm.S b/apps/codecs/libtta/filter_arm.S new file mode 100644 index 0000000000..37c515d3a9 --- /dev/null +++ b/apps/codecs/libtta/filter_arm.S | |||
@@ -0,0 +1,203 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 Yoshihisa Uchida | ||
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 | #include "config.h" | ||
23 | |||
24 | /* | ||
25 | * The following are assembler optimised version of | ||
26 | * void hybrid_filter(fltst *fs, int *in) | ||
27 | */ | ||
28 | |||
29 | #ifdef USE_IRAM | ||
30 | .section .icode, "ax", %progbits | ||
31 | #else | ||
32 | .text | ||
33 | #endif | ||
34 | .align | ||
35 | .global hybrid_filter | ||
36 | .type hybrid_filter, %function | ||
37 | |||
38 | hybrid_filter: | ||
39 | @ input: r0 = fs, r1 = in | ||
40 | stmdb sp!, {r4 - r12, lr} | ||
41 | |||
42 | @ get fs members | ||
43 | @ r2 pA := fs->dl + fs->index | ||
44 | @ r3 pM := fs->dx + fs->index | ||
45 | @ r4 pB := fs->qm | ||
46 | @ r5 fs->index | ||
47 | @ r6 fs->error | ||
48 | @ lr sum := fs->round | ||
49 | |||
50 | add r2, r0, #148 @ r2 = fs->dl | ||
51 | add r3, r0, #52 @ r3 = fs->dx | ||
52 | add r4, r0, #20 @ r4 = fs->qm | ||
53 | ldmia r0, {r5, r6, lr} @ r5 = fs->index | ||
54 | @ r6 = fs->error | ||
55 | @ lr = fs->round | ||
56 | mov r5, r5, asl #2 | ||
57 | add r2, r2, r5 @ r2 = fs->dl + fs->index | ||
58 | add r3, r3, r5 @ r3 = fs->dx + fs->index | ||
59 | |||
60 | cmp r6, #0 | ||
61 | bne .hf_positive | ||
62 | |||
63 | @ case fs->error == 0 | ||
64 | |||
65 | add r3, r3, #32 | ||
66 | ldmia r4!, {r5, r6, r7, r8 } | ||
67 | ldmia r2!, {r9, r10, r11, r12} | ||
68 | mla lr, r5, r9, lr | ||
69 | mla lr, r6, r10, lr | ||
70 | mla lr, r7, r11, lr | ||
71 | mla lr, r8, r12, lr | ||
72 | ldmia r4!, {r5, r6, r7, r8 } | ||
73 | b .hf2 | ||
74 | |||
75 | .hf_positive: | ||
76 | blt .hf_negative | ||
77 | |||
78 | @ case fs->error > 0 | ||
79 | |||
80 | ldmia r4, {r5, r6, r7, r8 } | ||
81 | ldmia r3!, {r9, r10, r11, r12} | ||
82 | add r5, r5, r9 | ||
83 | add r6, r6, r10 | ||
84 | add r7, r7, r11 | ||
85 | add r8, r8, r12 | ||
86 | stmia r4!, {r5, r6, r7, r8 } @ update fs->qm[0], ..., fs->qm[3] | ||
87 | ldmia r2!, {r9, r10, r11, r12} | ||
88 | mla lr, r5, r9, lr | ||
89 | mla lr, r6, r10, lr | ||
90 | mla lr, r7, r11, lr | ||
91 | mla lr, r8, r12, lr | ||
92 | ldmia r4, {r5, r6, r7, r8 } | ||
93 | ldmia r3!, {r9, r10, r11, r12} | ||
94 | add r5, r5, r9 | ||
95 | add r6, r6, r10 | ||
96 | add r7, r7, r11 | ||
97 | add r8, r8, r12 | ||
98 | stmia r4!, {r5, r6, r7, r8 } @ update fs->qm[4], ..., fs->qm[7] | ||
99 | b .hf2 | ||
100 | |||
101 | .hf_negative: | ||
102 | @ case fs->error < 0 | ||
103 | |||
104 | ldmia r4, {r5, r6, r7, r8 } | ||
105 | ldmia r3!, {r9, r10, r11, r12} | ||
106 | sub r5, r5, r9 | ||
107 | sub r6, r6, r10 | ||
108 | sub r7, r7, r11 | ||
109 | sub r8, r8, r12 | ||
110 | stmia r4!, {r5, r6, r7, r8 } @ update fs->qm[0], ..., fs->qm[3] | ||
111 | ldmia r2!, {r9, r10, r11, r12} | ||
112 | mla lr, r5, r9, lr | ||
113 | mla lr, r6, r10, lr | ||
114 | mla lr, r7, r11, lr | ||
115 | mla lr, r8, r12, lr | ||
116 | ldmia r4, {r5, r6, r7, r8 } | ||
117 | ldmia r3!, {r9, r10, r11, r12} | ||
118 | sub r5, r5, r9 | ||
119 | sub r6, r6, r10 | ||
120 | sub r7, r7, r11 | ||
121 | sub r8, r8, r12 | ||
122 | stmia r4!, {r5, r6, r7, r8 } @ update fs->qm[4], ..., fs->qm[7] | ||
123 | |||
124 | .hf2: | ||
125 | ldmia r2!, {r9, r10, r11, r12} | ||
126 | mla lr, r5, r9, lr | ||
127 | mla lr, r6, r10, lr | ||
128 | mla lr, r7, r11, lr | ||
129 | mla lr, r8, r12, lr | ||
130 | |||
131 | @ fs->error = *in; | ||
132 | @ *in += (sum >> fs->shift) | ||
133 | @ *pA = *in | ||
134 | |||
135 | ldr r5, [r1] @ r5 = *in | ||
136 | ldr r6, [r0, #12] @ r6 = fs->shift | ||
137 | add lr, r5, lr, asr r6 | ||
138 | str lr, [r1] @ *in += (sum >> fs->shift) | ||
139 | |||
140 | @ update fs->index | ||
141 | |||
142 | ldr r1, [r0] @ r1 = fs->index | ||
143 | add r1, r1, #1 | ||
144 | ands r1, r1, #15 @ set Z flag (after this, CPSR must keep !!) | ||
145 | stmia r0, {r1, r5} @ fs->index = (++fs->index & 15) | ||
146 | @ fs->error = (original) *in | ||
147 | |||
148 | @ change *pM, *(pM-1), *(pM-2), *(pM-3) | ||
149 | @ r9 = *(pA-4), r5 = *(pM-3) | ||
150 | @ r10 = *(pA-3), r6 = *(pM-2) | ||
151 | @ r11 = *(pA-2), r7 = *(pM-1) | ||
152 | @ r12 = *(pA-1), r8 = *(pM-0) | ||
153 | @ lr = *(pA-0) | ||
154 | |||
155 | mov r4, #1 | ||
156 | orr r5, r4, r9, asr #30 | ||
157 | orr r6, r4, r10, asr #30 | ||
158 | orr r7, r4, r11, asr #30 | ||
159 | orr r8, r4, r12, asr #30 | ||
160 | mov r6, r6, lsl #1 | ||
161 | mov r7, r7, lsl #1 | ||
162 | mov r8, r8, lsl #2 | ||
163 | |||
164 | @ change *(pA-1), *(pA-2), *(pA-3) | ||
165 | sub r12, lr, r12 | ||
166 | sub r11, r12, r11 | ||
167 | sub r10, r11, r10 | ||
168 | |||
169 | @ check fs->index is zero | ||
170 | beq .hf_memshl | ||
171 | |||
172 | @ set to the memory: *pA, *(pA-1), *(pA-2), *(pA-3), *pM, *(pM-1), *(pM-2), *(pM-3) | ||
173 | stmda r2, {r10, r11, r12, lr} | ||
174 | stmda r3, {r5, r6, r7, r8} | ||
175 | ldmfd sp!, {r4-r12, pc} @ hybrid_filter end (when fs->index != 0) | ||
176 | |||
177 | .hf_memshl: | ||
178 | @ memshl (fs->dl) | ||
179 | @ r9 = fs->dl[16 + 3] | ||
180 | @ r10 = fs->dl[16 + 4] | ||
181 | @ r11 = fs->dl[16 + 5] | ||
182 | @ r12 = fs->dl[16 + 6] | ||
183 | @ lr = fs->dl[16 + 7] | ||
184 | |||
185 | add r2, r0, #212 @ r2 = fs->dl + 16 | ||
186 | ldmia r2, {r1, r3, r4} | ||
187 | sub r2, r2, #64 @ r2 = fs->dl | ||
188 | stmia r2, {r1, r3, r4, r9 - r12, lr} | ||
189 | |||
190 | @ memshl (fs->dx) | ||
191 | @ r5 = fs->dx[16 + 4] | ||
192 | @ r6 = fs->dx[16 + 5] | ||
193 | @ r7 = fs->dx[16 + 6] | ||
194 | @ r8 = fs->dx[16 + 7] | ||
195 | |||
196 | add r9, r0, #116 @ r9 = fs->dx + 16 | ||
197 | ldmia r9, {r1, r2, r3, r4} | ||
198 | sub r9, r9, #64 @ r9 = fs->dx | ||
199 | stmia r9, {r1 - r8} | ||
200 | ldmfd sp!, {r4 - r12, pc} @ hybrid_filter end (when fs->index == 0) | ||
201 | |||
202 | hybrid_filter_end: | ||
203 | .size hybrid_filter, hybrid_filter_end - hybrid_filter | ||