Add a comment that explains why this header has no multiple inclusion guards.
[mplayer/greg.git] / libfaad2 / fixed.h
blobbfedd081b01048c9d60f8ac3159eb173603d92d2
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.
19 ** Any non-GPL usage of this software or parts of this software is strictly
20 ** forbidden.
22 ** Commercial non-GPL licensing of this software is possible.
23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
25 ** $Id: fixed.h,v 1.26 2004/09/04 14:56:28 menno Exp $
26 **/
28 #ifndef __FIXED_H__
29 #define __FIXED_H__
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
35 #if defined(_WIN32_WCE) && defined(_ARM_)
36 #include <cmnintrin.h>
37 #endif
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)
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
50 typedef int32_t real_t;
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))))
56 //#define FRAC_CONST(A) (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5)))
58 #define Q2_BITS 22
59 #define Q2_PRECISION (1 << Q2_BITS)
60 #define Q2_CONST(A) (((A) >= 0) ? ((real_t)((A)*(Q2_PRECISION)+0.5)) : ((real_t)((A)*(Q2_PRECISION)-0.5)))
62 #if defined(_WIN32) && !defined(_WIN32_WCE)
64 /* multiply with real shift */
65 static INLINE real_t MUL_R(real_t A, real_t B)
67 _asm {
68 mov eax,A
69 imul B
70 shrd eax,edx,REAL_BITS
74 /* multiply with coef shift */
75 static INLINE real_t MUL_C(real_t A, real_t B)
77 _asm {
78 mov eax,A
79 imul B
80 shrd eax,edx,COEF_BITS
84 static INLINE real_t MUL_Q2(real_t A, real_t B)
86 _asm {
87 mov eax,A
88 imul B
89 shrd eax,edx,Q2_BITS
93 static INLINE real_t MUL_SHIFT6(real_t A, real_t B)
95 _asm {
96 mov eax,A
97 imul B
98 shrd eax,edx,6
102 static INLINE real_t MUL_SHIFT23(real_t A, real_t B)
104 _asm {
105 mov eax,A
106 imul B
107 shrd eax,edx,23
111 #if 1
112 static INLINE real_t _MulHigh(real_t A, real_t B)
114 _asm {
115 mov eax,A
116 imul B
117 mov eax,edx
121 /* multiply with fractional shift */
122 static INLINE real_t MUL_F(real_t A, real_t B)
124 return _MulHigh(A,B) << (FRAC_SIZE-FRAC_BITS);
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)
131 *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS);
132 *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS);
134 #else
135 static INLINE real_t MUL_F(real_t A, real_t B)
137 _asm {
138 mov eax,A
139 imul B
140 shrd eax,edx,FRAC_BITS
144 /* Complex multiplication */
145 static INLINE void ComplexMult(real_t *y1, real_t *y2,
146 real_t x1, real_t x2, real_t c1, real_t c2)
148 *y1 = MUL_F(x1, c1) + MUL_F(x2, c2);
149 *y2 = MUL_F(x2, c1) - MUL_F(x1, c2);
151 #endif
153 #elif defined(__GNUC__) && defined (__arm__)
155 /* taken from MAD */
156 #define arm_mul(x, y, SCALEBITS) \
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; \
171 static INLINE real_t MUL_R(real_t A, real_t B)
173 return arm_mul(A, B, REAL_BITS);
176 static INLINE real_t MUL_C(real_t A, real_t B)
178 return arm_mul(A, B, COEF_BITS);
181 static INLINE real_t MUL_Q2(real_t A, real_t B)
183 return arm_mul(A, B, Q2_BITS);
186 static INLINE real_t MUL_SHIFT6(real_t A, real_t B)
188 return arm_mul(A, B, 6);
191 static INLINE real_t MUL_SHIFT23(real_t A, real_t B)
193 return arm_mul(A, B, 23);
196 static INLINE real_t _MulHigh(real_t x, real_t y)
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;
207 static INLINE real_t MUL_F(real_t A, real_t B)
209 return _MulHigh(A, B) << (FRAC_SIZE-FRAC_BITS);
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)
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);
229 #else
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 */
236 #if defined(_WIN32_WCE) && defined(_ARM_)
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)
240 return _MulHigh(A,B) << (32-FRAC_BITS);
242 #else
243 #define _MulHigh(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_SIZE-1))) >> FRAC_SIZE)
244 #define MUL_F(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_BITS-1))) >> FRAC_BITS)
245 #endif
246 #define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS)
247 #define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6)
248 #define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23)
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)
254 *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS);
255 *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS);
258 #endif
262 #ifdef __cplusplus
264 #endif
265 #endif