diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libwma/wmafixed.h | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libwma/wmafixed.h')
-rw-r--r-- | lib/rbcodec/codecs/libwma/wmafixed.h | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libwma/wmafixed.h b/lib/rbcodec/codecs/libwma/wmafixed.h new file mode 100644 index 0000000000..4225f165c9 --- /dev/null +++ b/lib/rbcodec/codecs/libwma/wmafixed.h | |||
@@ -0,0 +1,237 @@ | |||
1 | /**************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2007 Michael Giacomelli | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version 2 | ||
14 | * of the License, or (at your option) any later version. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ****************************************************************************/ | ||
20 | |||
21 | /* fixed precision code. We use a combination of Sign 15.16 and Sign.31 | ||
22 | precision here. | ||
23 | |||
24 | The WMA decoder does not always follow this convention, and occasionally | ||
25 | renormalizes values to other formats in order to maximize precision. | ||
26 | However, only the two precisions above are provided in this file. | ||
27 | |||
28 | */ | ||
29 | |||
30 | #include "types.h" | ||
31 | |||
32 | #define PRECISION 16 | ||
33 | #define PRECISION64 16 | ||
34 | |||
35 | |||
36 | #define fixtof64(x) (float)((float)(x) / (float)(1 << PRECISION64)) //does not work on int64_t! | ||
37 | #define ftofix32(x) ((fixed32)((x) * (float)(1 << PRECISION) + ((x) < 0 ? -0.5 : 0.5))) | ||
38 | #define itofix64(x) (IntTo64(x)) | ||
39 | #define itofix32(x) ((x) << PRECISION) | ||
40 | #define fixtoi32(x) ((x) >> PRECISION) | ||
41 | #define fixtoi64(x) (IntFrom64(x)) | ||
42 | |||
43 | |||
44 | /*fixed functions*/ | ||
45 | |||
46 | fixed64 IntTo64(int x); | ||
47 | int IntFrom64(fixed64 x); | ||
48 | fixed32 Fixed32From64(fixed64 x); | ||
49 | fixed64 Fixed32To64(fixed32 x); | ||
50 | fixed32 fixdiv32(fixed32 x, fixed32 y); | ||
51 | fixed64 fixdiv64(fixed64 x, fixed64 y); | ||
52 | fixed32 fixsqrt32(fixed32 x); | ||
53 | /* Inverse gain of circular cordic rotation in s0.31 format. */ | ||
54 | long fsincos(unsigned long phase, fixed32 *cos); | ||
55 | |||
56 | |||
57 | #ifdef CPU_ARM | ||
58 | |||
59 | /*Sign-15.16 format */ | ||
60 | #define fixmul32(x, y) \ | ||
61 | ({ int32_t __hi; \ | ||
62 | uint32_t __lo; \ | ||
63 | int32_t __result; \ | ||
64 | asm ("smull %0, %1, %3, %4\n\t" \ | ||
65 | "movs %0, %0, lsr %5\n\t" \ | ||
66 | "adc %2, %0, %1, lsl %6" \ | ||
67 | : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ | ||
68 | : "%r" (x), "r" (y), \ | ||
69 | "M" (PRECISION), "M" (32 - PRECISION) \ | ||
70 | : "cc"); \ | ||
71 | __result; \ | ||
72 | }) | ||
73 | |||
74 | #elif defined(CPU_COLDFIRE) | ||
75 | |||
76 | static inline int32_t fixmul32(int32_t x, int32_t y) | ||
77 | { | ||
78 | #if PRECISION != 16 | ||
79 | #warning Coldfire fixmul32() only works for PRECISION == 16 | ||
80 | #endif | ||
81 | int32_t t1; | ||
82 | asm ( | ||
83 | "mac.l %[x], %[y], %%acc0 \n" // multiply | ||
84 | "mulu.l %[y], %[x] \n" // get lower half, avoid emac stall | ||
85 | "movclr.l %%acc0, %[t1] \n" // get higher half | ||
86 | "lsr.l #1, %[t1] \n" | ||
87 | "move.w %[t1], %[x] \n" | ||
88 | "swap %[x] \n" | ||
89 | : [t1] "=&d" (t1), [x] "+d" (x) | ||
90 | : [y] "d" (y) | ||
91 | ); | ||
92 | return x; | ||
93 | } | ||
94 | |||
95 | #else | ||
96 | |||
97 | static inline fixed32 fixmul32(fixed32 x, fixed32 y) | ||
98 | { | ||
99 | fixed64 temp; | ||
100 | temp = x; | ||
101 | temp *= y; | ||
102 | |||
103 | temp >>= PRECISION; | ||
104 | |||
105 | return (fixed32)temp; | ||
106 | } | ||
107 | |||
108 | #endif | ||
109 | |||
110 | |||
111 | /* | ||
112 | * Helper functions for wma_window. | ||
113 | * | ||
114 | * | ||
115 | */ | ||
116 | |||
117 | #ifdef CPU_ARM | ||
118 | static inline void vector_fmul_add_add(fixed32 *dst, const fixed32 *data, | ||
119 | const fixed32 *window, int n) | ||
120 | { | ||
121 | /* Block sizes are always power of two */ | ||
122 | asm volatile ( | ||
123 | "0:" | ||
124 | "ldmia %[d]!, {r0, r1};" | ||
125 | "ldmia %[w]!, {r4, r5};" | ||
126 | /* consume the first data and window value so we can use those | ||
127 | * registers again */ | ||
128 | "smull r8, r9, r0, r4;" | ||
129 | "ldmia %[dst], {r0, r4};" | ||
130 | "add r0, r0, r9, lsl #1;" /* *dst=*dst+(r9<<1)*/ | ||
131 | "smull r8, r9, r1, r5;" | ||
132 | "add r1, r4, r9, lsl #1;" | ||
133 | "stmia %[dst]!, {r0, r1};" | ||
134 | "subs %[n], %[n], #2;" | ||
135 | "bne 0b;" | ||
136 | : [d] "+r" (data), [w] "+r" (window), [dst] "+r" (dst), [n] "+r" (n) | ||
137 | : : "r0", "r1", "r4", "r5", "r8", "r9", "memory", "cc"); | ||
138 | } | ||
139 | |||
140 | static inline void vector_fmul_reverse(fixed32 *dst, const fixed32 *src0, const fixed32 *src1, | ||
141 | int len) | ||
142 | { | ||
143 | /* Block sizes are always power of two */ | ||
144 | asm volatile ( | ||
145 | "add %[s1], %[s1], %[n], lsl #2;" | ||
146 | "0:" | ||
147 | "ldmia %[s0]!, {r0, r1};" | ||
148 | "ldmdb %[s1]!, {r4, r5};" | ||
149 | "smull r8, r9, r0, r5;" | ||
150 | "mov r0, r9, lsl #1;" | ||
151 | "smull r8, r9, r1, r4;" | ||
152 | "mov r1, r9, lsl #1;" | ||
153 | "stmia %[dst]!, {r0, r1};" | ||
154 | "subs %[n], %[n], #2;" | ||
155 | "bne 0b;" | ||
156 | : [s0] "+r" (src0), [s1] "+r" (src1), [dst] "+r" (dst), [n] "+r" (len) | ||
157 | : : "r0", "r1", "r4", "r5", "r8", "r9", "memory", "cc"); | ||
158 | } | ||
159 | |||
160 | #elif defined(CPU_COLDFIRE) | ||
161 | |||
162 | static inline void vector_fmul_add_add(fixed32 *dst, const fixed32 *data, | ||
163 | const fixed32 *window, int n) | ||
164 | { | ||
165 | /* Block sizes are always power of two. Smallest block is always way bigger | ||
166 | * than four too.*/ | ||
167 | asm volatile ( | ||
168 | "0:" | ||
169 | "movem.l (%[d]), %%d0-%%d3;" | ||
170 | "movem.l (%[w]), %%d4-%%d5/%%a0-%%a1;" | ||
171 | "mac.l %%d0, %%d4, %%acc0;" | ||
172 | "mac.l %%d1, %%d5, %%acc1;" | ||
173 | "mac.l %%d2, %%a0, %%acc2;" | ||
174 | "mac.l %%d3, %%a1, %%acc3;" | ||
175 | "lea.l (16, %[d]), %[d];" | ||
176 | "lea.l (16, %[w]), %[w];" | ||
177 | "movclr.l %%acc0, %%d0;" | ||
178 | "movclr.l %%acc1, %%d1;" | ||
179 | "movclr.l %%acc2, %%d2;" | ||
180 | "movclr.l %%acc3, %%d3;" | ||
181 | "movem.l (%[dst]), %%d4-%%d5/%%a0-%%a1;" | ||
182 | "add.l %%d4, %%d0;" | ||
183 | "add.l %%d5, %%d1;" | ||
184 | "add.l %%a0, %%d2;" | ||
185 | "add.l %%a1, %%d3;" | ||
186 | "movem.l %%d0-%%d3, (%[dst]);" | ||
187 | "lea.l (16, %[dst]), %[dst];" | ||
188 | "subq.l #4, %[n];" | ||
189 | "jne 0b;" | ||
190 | : [d] "+a" (data), [w] "+a" (window), [dst] "+a" (dst), [n] "+d" (n) | ||
191 | : : "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1", "memory", "cc"); | ||
192 | } | ||
193 | |||
194 | static inline void vector_fmul_reverse(fixed32 *dst, const fixed32 *src0, const fixed32 *src1, | ||
195 | int len) | ||
196 | { | ||
197 | /* Block sizes are always power of two. Smallest block is always way bigger | ||
198 | * than four too.*/ | ||
199 | asm volatile ( | ||
200 | "lea.l (-16, %[s1], %[n]*4), %[s1];" | ||
201 | "0:" | ||
202 | "movem.l (%[s0]), %%d0-%%d3;" | ||
203 | "movem.l (%[s1]), %%d4-%%d5/%%a0-%%a1;" | ||
204 | "mac.l %%d0, %%a1, %%acc0;" | ||
205 | "mac.l %%d1, %%a0, %%acc1;" | ||
206 | "mac.l %%d2, %%d5, %%acc2;" | ||
207 | "mac.l %%d3, %%d4, %%acc3;" | ||
208 | "lea.l (16, %[s0]), %[s0];" | ||
209 | "lea.l (-16, %[s1]), %[s1];" | ||
210 | "movclr.l %%acc0, %%d0;" | ||
211 | "movclr.l %%acc1, %%d1;" | ||
212 | "movclr.l %%acc2, %%d2;" | ||
213 | "movclr.l %%acc3, %%d3;" | ||
214 | "movem.l %%d0-%%d3, (%[dst]);" | ||
215 | "lea.l (16, %[dst]), %[dst];" | ||
216 | "subq.l #4, %[n];" | ||
217 | "jne 0b;" | ||
218 | : [s0] "+a" (src0), [s1] "+a" (src1), [dst] "+a" (dst), [n] "+d" (len) | ||
219 | : : "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1", "memory", "cc"); | ||
220 | } | ||
221 | |||
222 | #else | ||
223 | |||
224 | static inline void vector_fmul_add_add(fixed32 *dst, const fixed32 *src0, const fixed32 *src1, int len){ | ||
225 | int i; | ||
226 | for(i=0; i<len; i++) | ||
227 | dst[i] = fixmul32b(src0[i], src1[i]) + dst[i]; | ||
228 | } | ||
229 | |||
230 | static inline void vector_fmul_reverse(fixed32 *dst, const fixed32 *src0, const fixed32 *src1, int len){ | ||
231 | int i; | ||
232 | src1 += len-1; | ||
233 | for(i=0; i<len; i++) | ||
234 | dst[i] = fixmul32b(src0[i], src1[-i]); | ||
235 | } | ||
236 | |||
237 | #endif | ||