Mercurial > mplayer.hg
annotate libfaad2/fixed.h @ 28816:6e5b9867646c
sync w/r28807
author | gpoirier |
---|---|
date | Fri, 06 Mar 2009 15:52:48 +0000 |
parents | 59b6fa5b4201 |
children | e83eef58b30a |
rev | line source |
---|---|
10725 | 1 /* |
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | |
12527 | 3 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com |
10725 | 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 ** | |
18141 | 25 ** $Id: fixed.h,v 1.26 2004/09/04 14:56:28 menno Exp $ |
10725 | 26 **/ |
27 | |
28 #ifndef __FIXED_H__ | |
29 #define __FIXED_H__ | |
30 | |
31 #ifdef __cplusplus | |
32 extern "C" { | |
33 #endif | |
34 | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
35 #if defined(_WIN32_WCE) && defined(_ARM_) |
12527 | 36 #include <cmnintrin.h> |
37 #endif | |
10725 | 38 |
39 #define COEF_BITS 28 | |
40 #define COEF_PRECISION (1 << COEF_BITS) | |
10989 | 41 #define REAL_BITS 14 // MAXIMUM OF 14 FOR FIXED POINT SBR |
10725 | 42 #define REAL_PRECISION (1 << REAL_BITS) |
43 | |
12527 | 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 | |
10725 | 49 |
50 typedef int32_t real_t; | |
51 | |
52 | |
12527 | 53 #define REAL_CONST(A) (((A) >= 0) ? ((real_t)((A)*(REAL_PRECISION)+0.5)) : ((real_t)((A)*(REAL_PRECISION)-0.5))) |
54 #define COEF_CONST(A) (((A) >= 0) ? ((real_t)((A)*(COEF_PRECISION)+0.5)) : ((real_t)((A)*(COEF_PRECISION)-0.5))) | |
55 #define FRAC_CONST(A) (((A) == 1.00) ? ((real_t)FRAC_MAX) : (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5)))) | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
56 //#define FRAC_CONST(A) (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5))) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
57 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
58 #define Q2_BITS 22 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
59 #define Q2_PRECISION (1 << Q2_BITS) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
60 #define Q2_CONST(A) (((A) >= 0) ? ((real_t)((A)*(Q2_PRECISION)+0.5)) : ((real_t)((A)*(Q2_PRECISION)-0.5))) |
10725 | 61 |
62 #if defined(_WIN32) && !defined(_WIN32_WCE) | |
63 | |
12527 | 64 /* multiply with real shift */ |
65 static INLINE real_t MUL_R(real_t A, real_t B) | |
10725 | 66 { |
67 _asm { | |
68 mov eax,A | |
69 imul B | |
70 shrd eax,edx,REAL_BITS | |
71 } | |
72 } | |
73 | |
12527 | 74 /* multiply with coef shift */ |
75 static INLINE real_t MUL_C(real_t A, real_t B) | |
10725 | 76 { |
77 _asm { | |
78 mov eax,A | |
79 imul B | |
80 shrd eax,edx,COEF_BITS | |
81 } | |
82 } | |
83 | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
84 static INLINE real_t MUL_Q2(real_t A, real_t B) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
85 { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
86 _asm { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
87 mov eax,A |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
88 imul B |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
89 shrd eax,edx,Q2_BITS |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
90 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
91 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
92 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
93 static INLINE real_t MUL_SHIFT6(real_t A, real_t B) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
94 { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
95 _asm { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
96 mov eax,A |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
97 imul B |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
98 shrd eax,edx,6 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
99 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
100 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
101 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
102 static INLINE real_t MUL_SHIFT23(real_t A, real_t B) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
103 { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
104 _asm { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
105 mov eax,A |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
106 imul B |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
107 shrd eax,edx,23 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
108 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
109 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
110 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
111 #if 1 |
12527 | 112 static INLINE real_t _MulHigh(real_t A, real_t B) |
10725 | 113 { |
114 _asm { | |
115 mov eax,A | |
116 imul B | |
12527 | 117 mov eax,edx |
10725 | 118 } |
119 } | |
120 | |
12527 | 121 /* multiply with fractional shift */ |
122 static INLINE real_t MUL_F(real_t A, real_t B) | |
123 { | |
124 return _MulHigh(A,B) << (FRAC_SIZE-FRAC_BITS); | |
125 } | |
126 | |
127 /* Complex multiplication */ | |
128 static INLINE void ComplexMult(real_t *y1, real_t *y2, | |
129 real_t x1, real_t x2, real_t c1, real_t c2) | |
130 { | |
131 *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS); | |
132 *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS); | |
133 } | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
134 #else |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
135 static INLINE real_t MUL_F(real_t A, real_t B) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
136 { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
137 _asm { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
138 mov eax,A |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
139 imul B |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
140 shrd eax,edx,FRAC_BITS |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
141 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
142 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
143 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
144 /* Complex multiplication */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
145 static INLINE void ComplexMult(real_t *y1, real_t *y2, |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
146 real_t x1, real_t x2, real_t c1, real_t c2) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
147 { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
148 *y1 = MUL_F(x1, c1) + MUL_F(x2, c2); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
149 *y2 = MUL_F(x2, c1) - MUL_F(x1, c2); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
150 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
151 #endif |
12527 | 152 |
10725 | 153 #elif defined(__GNUC__) && defined (__arm__) |
154 | |
155 /* taken from MAD */ | |
156 #define arm_mul(x, y, SCALEBITS) \ | |
12527 | 157 ({ \ |
158 uint32_t __hi; \ | |
159 uint32_t __lo; \ | |
160 uint32_t __result; \ | |
161 asm("smull %0, %1, %3, %4\n\t" \ | |
162 "movs %0, %0, lsr %5\n\t" \ | |
163 "adc %2, %0, %1, lsl %6" \ | |
164 : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ | |
165 : "%r" (x), "r" (y), \ | |
166 "M" (SCALEBITS), "M" (32 - (SCALEBITS)) \ | |
167 : "cc"); \ | |
168 __result; \ | |
169 }) | |
10725 | 170 |
12527 | 171 static INLINE real_t MUL_R(real_t A, real_t B) |
10725 | 172 { |
12527 | 173 return arm_mul(A, B, REAL_BITS); |
174 } | |
175 | |
176 static INLINE real_t MUL_C(real_t A, real_t B) | |
177 { | |
178 return arm_mul(A, B, COEF_BITS); | |
10725 | 179 } |
180 | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
181 static INLINE real_t MUL_Q2(real_t A, real_t B) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
182 { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
183 return arm_mul(A, B, Q2_BITS); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
184 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
185 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
186 static INLINE real_t MUL_SHIFT6(real_t A, real_t B) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
187 { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
188 return arm_mul(A, B, 6); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
189 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
190 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
191 static INLINE real_t MUL_SHIFT23(real_t A, real_t B) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
192 { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
193 return arm_mul(A, B, 23); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
194 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
195 |
12527 | 196 static INLINE real_t _MulHigh(real_t x, real_t y) |
10725 | 197 { |
12527 | 198 uint32_t __lo; |
199 uint32_t __hi; | |
200 asm("smull\t%0, %1, %2, %3" | |
201 : "=&r"(__lo),"=&r"(__hi) | |
202 : "%r"(x),"r"(y) | |
203 : "cc"); | |
204 return __hi; | |
205 } | |
206 | |
207 static INLINE real_t MUL_F(real_t A, real_t B) | |
208 { | |
209 return _MulHigh(A, B) << (FRAC_SIZE-FRAC_BITS); | |
10725 | 210 } |
211 | |
12527 | 212 /* Complex multiplication */ |
213 static INLINE void ComplexMult(real_t *y1, real_t *y2, | |
214 real_t x1, real_t x2, real_t c1, real_t c2) | |
10725 | 215 { |
12527 | 216 int32_t tmp, yt1, yt2; |
217 asm("smull %0, %1, %4, %6\n\t" | |
218 "smlal %0, %1, %5, %7\n\t" | |
219 "rsb %3, %4, #0\n\t" | |
220 "smull %0, %2, %5, %6\n\t" | |
221 "smlal %0, %2, %3, %7" | |
222 : "=&r" (tmp), "=&r" (yt1), "=&r" (yt2), "=r" (x1) | |
223 : "3" (x1), "r" (x2), "r" (c1), "r" (c2) | |
224 : "cc" ); | |
225 *y1 = yt1 << (FRAC_SIZE-FRAC_BITS); | |
226 *y2 = yt2 << (FRAC_SIZE-FRAC_BITS); | |
10725 | 227 } |
228 | |
229 #else | |
230 | |
12527 | 231 /* multiply with real shift */ |
232 #define MUL_R(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (REAL_BITS-1))) >> REAL_BITS) | |
233 /* multiply with coef shift */ | |
234 #define MUL_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS) | |
235 /* multiply with fractional shift */ | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
236 #if defined(_WIN32_WCE) && defined(_ARM_) |
12527 | 237 /* eVC for PocketPC has an intrinsic function that returns only the high 32 bits of a 32x32 bit multiply */ |
238 static INLINE real_t MUL_F(real_t A, real_t B) | |
239 { | |
240 return _MulHigh(A,B) << (32-FRAC_BITS); | |
241 } | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
242 #else |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
243 #define _MulHigh(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_SIZE-1))) >> FRAC_SIZE) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
244 #define MUL_F(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_BITS-1))) >> FRAC_BITS) |
12527 | 245 #endif |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
246 #define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
247 #define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
248 #define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23) |
12527 | 249 |
250 /* Complex multiplication */ | |
251 static INLINE void ComplexMult(real_t *y1, real_t *y2, | |
252 real_t x1, real_t x2, real_t c1, real_t c2) | |
253 { | |
254 *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS); | |
255 *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS); | |
256 } | |
10725 | 257 |
258 #endif | |
259 | |
260 | |
12527 | 261 |
10725 | 262 #ifdef __cplusplus |
263 } | |
264 #endif | |
265 #endif |