summaryrefslogtreecommitdiff
path: root/apps/codecs/libfaad/fixed.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libfaad/fixed.h')
-rw-r--r--apps/codecs/libfaad/fixed.h265
1 files changed, 265 insertions, 0 deletions
diff --git a/apps/codecs/libfaad/fixed.h b/apps/codecs/libfaad/fixed.h
new file mode 100644
index 0000000000..ac916ba0b9
--- /dev/null
+++ b/apps/codecs/libfaad/fixed.h
@@ -0,0 +1,265 @@
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
32extern "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
50typedef int32_t real_t;
51
52
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)))
57
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)))
61
62#if defined(_WIN32) && !defined(_WIN32_WCE)
63
64/* multiply with real shift */
65static INLINE real_t MUL_R(real_t A, real_t B)
66{
67 _asm {
68 mov eax,A
69 imul B
70 shrd eax,edx,REAL_BITS
71 }
72}
73
74/* multiply with coef shift */
75static INLINE real_t MUL_C(real_t A, real_t B)
76{
77 _asm {
78 mov eax,A
79 imul B
80 shrd eax,edx,COEF_BITS
81 }
82}
83
84static INLINE real_t MUL_Q2(real_t A, real_t B)
85{
86 _asm {
87 mov eax,A
88 imul B
89 shrd eax,edx,Q2_BITS
90 }
91}
92
93static INLINE real_t MUL_SHIFT6(real_t A, real_t B)
94{
95 _asm {
96 mov eax,A
97 imul B
98 shrd eax,edx,6
99 }
100}
101
102static INLINE real_t MUL_SHIFT23(real_t A, real_t B)
103{
104 _asm {
105 mov eax,A
106 imul B
107 shrd eax,edx,23
108 }
109}
110
111#if 1
112static INLINE real_t _MulHigh(real_t A, real_t B)
113{
114 _asm {
115 mov eax,A
116 imul B
117 mov eax,edx
118 }
119}
120
121/* multiply with fractional shift */
122static 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 */
128static 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}
134#else
135static INLINE real_t MUL_F(real_t A, real_t B)
136{
137 _asm {
138 mov eax,A
139 imul B
140 shrd eax,edx,FRAC_BITS
141 }
142}
143
144/* Complex multiplication */
145static INLINE void ComplexMult(real_t *y1, real_t *y2,
146 real_t x1, real_t x2, real_t c1, real_t c2)
147{
148 *y1 = MUL_F(x1, c1) + MUL_F(x2, c2);
149 *y2 = MUL_F(x2, c1) - MUL_F(x1, c2);
150}
151#endif
152
153#elif defined(__GNUC__) && defined (__arm__)
154
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; \
169})
170
171static INLINE real_t MUL_R(real_t A, real_t B)
172{
173 return arm_mul(A, B, REAL_BITS);
174}
175
176static INLINE real_t MUL_C(real_t A, real_t B)
177{
178 return arm_mul(A, B, COEF_BITS);
179}
180
181static INLINE real_t MUL_Q2(real_t A, real_t B)
182{
183 return arm_mul(A, B, Q2_BITS);
184}
185
186static INLINE real_t MUL_SHIFT6(real_t A, real_t B)
187{
188 return arm_mul(A, B, 6);
189}
190
191static INLINE real_t MUL_SHIFT23(real_t A, real_t B)
192{
193 return arm_mul(A, B, 23);
194}
195
196static INLINE real_t _MulHigh(real_t x, real_t y)
197{
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
207static INLINE real_t MUL_F(real_t A, real_t B)
208{
209 return _MulHigh(A, B) << (FRAC_SIZE-FRAC_BITS);
210}
211
212/* Complex multiplication */
213static INLINE void ComplexMult(real_t *y1, real_t *y2,
214 real_t x1, real_t x2, real_t c1, real_t c2)
215{
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);
227}
228
229#else
230
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)
239 {
240 return _MulHigh(A,B) << (32-FRAC_BITS);
241 }
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)
249
250/* Complex multiplication */
251static 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}
257
258#endif
259
260
261
262#ifdef __cplusplus
263}
264#endif
265#endif