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/libfaad/fixed.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/libfaad/fixed.h')
-rw-r--r-- | lib/rbcodec/codecs/libfaad/fixed.h | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libfaad/fixed.h b/lib/rbcodec/codecs/libfaad/fixed.h new file mode 100644 index 0000000000..ca0402e4d3 --- /dev/null +++ b/lib/rbcodec/codecs/libfaad/fixed.h | |||
@@ -0,0 +1,230 @@ | |||
1 | /* | ||
2 | ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | ||
3 | ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com | ||
4 | ** | ||
5 | ** This program is free software; you can redistribute it and/or modify | ||
6 | ** it under the terms of the GNU General Public License as published by | ||
7 | ** the Free Software Foundation; either version 2 of the License, or | ||
8 | ** (at your option) any later version. | ||
9 | ** | ||
10 | ** This program is distributed in the hope that it will be useful, | ||
11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | ** GNU General Public License for more details. | ||
14 | ** | ||
15 | ** You should have received a copy of the GNU General Public License | ||
16 | ** along with this program; if not, write to the Free Software | ||
17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | ** | ||
19 | ** Any non-GPL usage of this software or parts of this software is strictly | ||
20 | ** forbidden. | ||
21 | ** | ||
22 | ** Commercial non-GPL licensing of this software is possible. | ||
23 | ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. | ||
24 | ** | ||
25 | ** $Id$ | ||
26 | **/ | ||
27 | |||
28 | #ifndef __FIXED_H__ | ||
29 | #define __FIXED_H__ | ||
30 | |||
31 | #ifdef __cplusplus | ||
32 | extern "C" { | ||
33 | #endif | ||
34 | |||
35 | #if defined(_WIN32_WCE) && defined(_ARM_) | ||
36 | #include <cmnintrin.h> | ||
37 | #endif | ||
38 | |||
39 | #define COEF_BITS 28 | ||
40 | #define COEF_PRECISION (1 << COEF_BITS) | ||
41 | #define REAL_BITS 14 // MAXIMUM OF 14 FOR FIXED POINT SBR | ||
42 | #define REAL_PRECISION (1 << REAL_BITS) | ||
43 | |||
44 | /* FRAC is the fractional only part of the fixed point number [0.0..1.0) */ | ||
45 | #define FRAC_SIZE 32 /* frac is a 32 bit integer */ | ||
46 | #define FRAC_BITS 31 | ||
47 | #define FRAC_PRECISION ((uint32_t)(1 << FRAC_BITS)) | ||
48 | #define FRAC_MAX 0x7FFFFFFF | ||
49 | |||
50 | typedef int32_t real_t; | ||
51 | |||
52 | #define FIX_CONST(A,PRECISION) (((A) >= 0) ? ((real_t)((A)*(PRECISION)+0.5)) : ((real_t)((A)*(PRECISION)-0.5))) | ||
53 | #define REAL_CONST(A) FIX_CONST((A),(REAL_PRECISION)) | ||
54 | #define COEF_CONST(A) FIX_CONST((A),(COEF_PRECISION)) | ||
55 | #define FRAC_CONST(A) (((A) == 1.00) ? ((real_t)FRAC_MAX) : FIX_CONST((A),(FRAC_PRECISION))) | ||
56 | //#define FRAC_CONST(A) (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5))) | ||
57 | |||
58 | #define Q2_BITS 22 | ||
59 | #define Q2_PRECISION (1 << Q2_BITS) | ||
60 | #define Q2_CONST(A) FIX_CONST((A),(Q2_PRECISION)) | ||
61 | |||
62 | #if defined(CPU_COLDFIRE) | ||
63 | |||
64 | static INLINE real_t MUL_F(real_t A, real_t B) | ||
65 | { | ||
66 | asm volatile ( | ||
67 | "mac.l %[A], %[B], %%acc0\n\t" | ||
68 | "movclr.l %%acc0, %[A]" | ||
69 | : [A] "+&r" (A) : [B] "r" (B) | ||
70 | ); | ||
71 | return A; | ||
72 | } | ||
73 | |||
74 | static INLINE real_t MUL_C(real_t A, real_t B) | ||
75 | { | ||
76 | asm volatile ( | ||
77 | "mac.l %[A], %[B], %%acc0\n\t" | ||
78 | "movclr.l %%acc0, %[A]\n\t" | ||
79 | : [A] "+&d" (A) : [B] "r" (B) | ||
80 | ); | ||
81 | return A << 3; | ||
82 | } | ||
83 | |||
84 | /* MUL_R needs too many shifts for us to just operate on the top 32 bits the | ||
85 | emac unit gives as usual, so we do a full 64 bit mul here. */ | ||
86 | static INLINE real_t MUL_R(real_t x, real_t y) | ||
87 | { | ||
88 | real_t t1, t2; | ||
89 | asm volatile ( | ||
90 | "mac.l %[x],%[y],%%acc0\n" /* multiply */ | ||
91 | "mulu.l %[y],%[x] \n" /* get lower half, avoid emac stall */ | ||
92 | "movclr.l %%acc0,%[t1] \n" /* get higher half */ | ||
93 | "moveq.l #17,%[t2] \n" | ||
94 | "asl.l %[t2],%[t1] \n" /* hi <<= 17, plus one free */ | ||
95 | "moveq.l #14,%[t2] \n" | ||
96 | "lsr.l %[t2],%[x] \n" /* (unsigned)lo >>= 14 */ | ||
97 | "or.l %[x],%[t1] \n" /* combine result */ | ||
98 | : /* outputs */ | ||
99 | [t1]"=&d"(t1), | ||
100 | [t2]"=&d"(t2), | ||
101 | [x] "+d" (x) | ||
102 | : /* inputs */ | ||
103 | [y] "d" (y) | ||
104 | ); | ||
105 | return t1; | ||
106 | } | ||
107 | |||
108 | static INLINE void ComplexMult(real_t *y1, real_t *y2, | ||
109 | real_t x1, real_t x2, real_t c1, real_t c2) | ||
110 | { | ||
111 | asm volatile( | ||
112 | "mac.l %[x1], %[c1], %%acc0\n\t" | ||
113 | "mac.l %[x2], %[c2], %%acc0\n\t" | ||
114 | "mac.l %[x2], %[c1], %%acc1\n\t" | ||
115 | "msac.l %[x1], %[c2], %%acc1\n\t" | ||
116 | "movclr.l %%acc0, %[x1]\n\t" | ||
117 | "move.l %[x1], (%[y1])\n\t" | ||
118 | "movclr.l %%acc1, %[x1]\n\t" | ||
119 | "move.l %[x1], (%[y2])" | ||
120 | : [x1] "+&r" (x1) | ||
121 | : [x2] "r" (x2), [y1] "a" (y1), [y2] "a" (y2), | ||
122 | [c1] "r" (c1), [c2] "r" (c2) | ||
123 | : "memory" | ||
124 | ); | ||
125 | } | ||
126 | |||
127 | /* the following see little or no use, so just ignore them for now */ | ||
128 | #define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS) | ||
129 | |||
130 | #elif defined(__GNUC__) && defined (__arm__) | ||
131 | |||
132 | /* taken from MAD */ | ||
133 | #define arm_mul(x, y, SCALEBITS) \ | ||
134 | ({ \ | ||
135 | uint32_t __hi; \ | ||
136 | uint32_t __lo; \ | ||
137 | uint32_t __result; \ | ||
138 | asm("smull %0, %1, %3, %4\n\t" \ | ||
139 | "movs %0, %0, lsr %5\n\t" \ | ||
140 | "adc %2, %0, %1, lsl %6" \ | ||
141 | : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ | ||
142 | : "%r" (x), "r" (y), \ | ||
143 | "M" (SCALEBITS), "M" (32 - (SCALEBITS)) \ | ||
144 | : "cc"); \ | ||
145 | __result; \ | ||
146 | }) | ||
147 | |||
148 | static INLINE real_t MUL_R(real_t A, real_t B) | ||
149 | { | ||
150 | return arm_mul(A, B, REAL_BITS); | ||
151 | } | ||
152 | |||
153 | static INLINE real_t MUL_C(real_t A, real_t B) | ||
154 | { | ||
155 | return arm_mul(A, B, COEF_BITS); | ||
156 | } | ||
157 | |||
158 | static INLINE real_t MUL_Q2(real_t A, real_t B) | ||
159 | { | ||
160 | return arm_mul(A, B, Q2_BITS); | ||
161 | } | ||
162 | |||
163 | static INLINE real_t _MulHigh(real_t x, real_t y) | ||
164 | { | ||
165 | uint32_t __lo; | ||
166 | uint32_t __hi; | ||
167 | asm("smull\t%0, %1, %2, %3" | ||
168 | : "=&r"(__lo),"=&r"(__hi) | ||
169 | : "%r"(x),"r"(y) | ||
170 | : "cc"); | ||
171 | return __hi; | ||
172 | } | ||
173 | |||
174 | static INLINE real_t MUL_F(real_t A, real_t B) | ||
175 | { | ||
176 | return _MulHigh(A, B) << (FRAC_SIZE-FRAC_BITS); | ||
177 | } | ||
178 | |||
179 | /* Complex multiplication */ | ||
180 | static INLINE void ComplexMult(real_t *y1, real_t *y2, | ||
181 | real_t x1, real_t x2, real_t c1, real_t c2) | ||
182 | { | ||
183 | int32_t tmp, yt1, yt2; | ||
184 | asm("smull %0, %1, %4, %6\n\t" | ||
185 | "smlal %0, %1, %5, %7\n\t" | ||
186 | "rsb %3, %4, #0\n\t" | ||
187 | "smull %0, %2, %5, %6\n\t" | ||
188 | "smlal %0, %2, %3, %7" | ||
189 | : "=&r" (tmp), "=&r" (yt1), "=&r" (yt2), "=r" (x1) | ||
190 | : "3" (x1), "r" (x2), "r" (c1), "r" (c2) | ||
191 | : "cc" ); | ||
192 | *y1 = yt1 << (FRAC_SIZE-FRAC_BITS); | ||
193 | *y2 = yt2 << (FRAC_SIZE-FRAC_BITS); | ||
194 | } | ||
195 | |||
196 | #else | ||
197 | |||
198 | /* multiply with real shift */ | ||
199 | #define MUL_R(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (REAL_BITS-1))) >> REAL_BITS) | ||
200 | /* multiply with coef shift */ | ||
201 | #define MUL_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS) | ||
202 | /* multiply with fractional shift */ | ||
203 | #if defined(_WIN32_WCE) && defined(_ARM_) | ||
204 | /* eVC for PocketPC has an intrinsic function that returns only the high 32 bits of a 32x32 bit multiply */ | ||
205 | static INLINE real_t MUL_F(real_t A, real_t B) | ||
206 | { | ||
207 | return _MulHigh(A,B) << (32-FRAC_BITS); | ||
208 | } | ||
209 | #else | ||
210 | #define _MulHigh(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_SIZE-1))) >> FRAC_SIZE) | ||
211 | #define MUL_F(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_BITS-1))) >> FRAC_BITS) | ||
212 | #endif | ||
213 | #define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS) | ||
214 | |||
215 | /* Complex multiplication */ | ||
216 | static INLINE void ComplexMult(real_t *y1, real_t *y2, | ||
217 | real_t x1, real_t x2, real_t c1, real_t c2) | ||
218 | { | ||
219 | *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS); | ||
220 | *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS); | ||
221 | } | ||
222 | |||
223 | #endif | ||
224 | |||
225 | |||
226 | |||
227 | #ifdef __cplusplus | ||
228 | } | ||
229 | #endif | ||
230 | #endif | ||