xref: /aosp_15_r20/external/aac/libFDK/include/fixpoint_math.h (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker 
7*e5436536SAndroid Build Coastguard Worker  1.    INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker 
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker 
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker 
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker 
34*e5436536SAndroid Build Coastguard Worker 2.    COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker 
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker 
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker 
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker 
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker 
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker 
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker 
61*e5436536SAndroid Build Coastguard Worker 3.    NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker 
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker 
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker 
71*e5436536SAndroid Build Coastguard Worker 4.    DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker 
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker 
84*e5436536SAndroid Build Coastguard Worker 5.    CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker 
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker 
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker 
95*e5436536SAndroid Build Coastguard Worker /******************* Library for basic calculation routines ********************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):   M. Gayer
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: Fixed point specific mathematical functions
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #ifndef FIXPOINT_MATH_H
104*e5436536SAndroid Build Coastguard Worker #define FIXPOINT_MATH_H
105*e5436536SAndroid Build Coastguard Worker 
106*e5436536SAndroid Build Coastguard Worker #include "common_fix.h"
107*e5436536SAndroid Build Coastguard Worker #include "scale.h"
108*e5436536SAndroid Build Coastguard Worker 
109*e5436536SAndroid Build Coastguard Worker /*
110*e5436536SAndroid Build Coastguard Worker  * Data definitions
111*e5436536SAndroid Build Coastguard Worker  */
112*e5436536SAndroid Build Coastguard Worker 
113*e5436536SAndroid Build Coastguard Worker #define LD_DATA_SCALING (64.0f)
114*e5436536SAndroid Build Coastguard Worker #define LD_DATA_SHIFT 6 /* pow(2, LD_DATA_SHIFT) = LD_DATA_SCALING */
115*e5436536SAndroid Build Coastguard Worker 
116*e5436536SAndroid Build Coastguard Worker #define MAX_LD_PRECISION 10
117*e5436536SAndroid Build Coastguard Worker #define LD_PRECISION 10
118*e5436536SAndroid Build Coastguard Worker 
119*e5436536SAndroid Build Coastguard Worker /* Taylor series coefficients for ln(1-x), centered at 0 (MacLaurin polynomial).
120*e5436536SAndroid Build Coastguard Worker  */
121*e5436536SAndroid Build Coastguard Worker #ifndef LDCOEFF_16BIT
122*e5436536SAndroid Build Coastguard Worker LNK_SECTION_CONSTDATA_L1
123*e5436536SAndroid Build Coastguard Worker static const FIXP_DBL ldCoeff[MAX_LD_PRECISION] = {
124*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(-1.0),       FL2FXCONST_DBL(-1.0 / 2.0),
125*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(-1.0 / 3.0), FL2FXCONST_DBL(-1.0 / 4.0),
126*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(-1.0 / 5.0), FL2FXCONST_DBL(-1.0 / 6.0),
127*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(-1.0 / 7.0), FL2FXCONST_DBL(-1.0 / 8.0),
128*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(-1.0 / 9.0), FL2FXCONST_DBL(-1.0 / 10.0)};
129*e5436536SAndroid Build Coastguard Worker #else  /* LDCOEFF_16BIT */
130*e5436536SAndroid Build Coastguard Worker LNK_SECTION_CONSTDATA_L1
131*e5436536SAndroid Build Coastguard Worker static const FIXP_SGL ldCoeff[MAX_LD_PRECISION] = {
132*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(-1.0),       FL2FXCONST_SGL(-1.0 / 2.0),
133*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(-1.0 / 3.0), FL2FXCONST_SGL(-1.0 / 4.0),
134*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(-1.0 / 5.0), FL2FXCONST_SGL(-1.0 / 6.0),
135*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(-1.0 / 7.0), FL2FXCONST_SGL(-1.0 / 8.0),
136*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(-1.0 / 9.0), FL2FXCONST_SGL(-1.0 / 10.0)};
137*e5436536SAndroid Build Coastguard Worker #endif /* LDCOEFF_16BIT */
138*e5436536SAndroid Build Coastguard Worker 
139*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
140*e5436536SAndroid Build Coastguard Worker 
141*e5436536SAndroid Build Coastguard Worker     functionname: invSqrtNorm2
142*e5436536SAndroid Build Coastguard Worker     description:  delivers 1/sqrt(op) normalized to .5...1 and the shift value
143*e5436536SAndroid Build Coastguard Worker of the OUTPUT
144*e5436536SAndroid Build Coastguard Worker 
145*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
146*e5436536SAndroid Build Coastguard Worker #define SQRT_BITS 7
147*e5436536SAndroid Build Coastguard Worker #define SQRT_VALUES (128 + 2)
148*e5436536SAndroid Build Coastguard Worker #define SQRT_BITS_MASK 0x7f
149*e5436536SAndroid Build Coastguard Worker #define SQRT_FRACT_BITS_MASK 0x007FFFFF
150*e5436536SAndroid Build Coastguard Worker 
151*e5436536SAndroid Build Coastguard Worker extern const FIXP_DBL invSqrtTab[SQRT_VALUES];
152*e5436536SAndroid Build Coastguard Worker 
153*e5436536SAndroid Build Coastguard Worker /*
154*e5436536SAndroid Build Coastguard Worker  * Hardware specific implementations
155*e5436536SAndroid Build Coastguard Worker  */
156*e5436536SAndroid Build Coastguard Worker 
157*e5436536SAndroid Build Coastguard Worker #if defined(__x86__)
158*e5436536SAndroid Build Coastguard Worker #include "x86/fixpoint_math_x86.h"
159*e5436536SAndroid Build Coastguard Worker #endif /* target architecture selector */
160*e5436536SAndroid Build Coastguard Worker 
161*e5436536SAndroid Build Coastguard Worker /*
162*e5436536SAndroid Build Coastguard Worker  * Fallback implementations
163*e5436536SAndroid Build Coastguard Worker  */
164*e5436536SAndroid Build Coastguard Worker #if !defined(FUNCTION_fIsLessThan)
165*e5436536SAndroid Build Coastguard Worker /**
166*e5436536SAndroid Build Coastguard Worker  * \brief Compares two fixpoint values incl. scaling.
167*e5436536SAndroid Build Coastguard Worker  * \param a_m mantissa of the first input value.
168*e5436536SAndroid Build Coastguard Worker  * \param a_e exponent of the first input value.
169*e5436536SAndroid Build Coastguard Worker  * \param b_m mantissa of the second input value.
170*e5436536SAndroid Build Coastguard Worker  * \param b_e exponent of the second input value.
171*e5436536SAndroid Build Coastguard Worker  * \return non-zero if (a_m*2^a_e) < (b_m*2^b_e), 0 otherwise
172*e5436536SAndroid Build Coastguard Worker  */
fIsLessThan(FIXP_DBL a_m,INT a_e,FIXP_DBL b_m,INT b_e)173*e5436536SAndroid Build Coastguard Worker FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e) {
174*e5436536SAndroid Build Coastguard Worker   INT n;
175*e5436536SAndroid Build Coastguard Worker 
176*e5436536SAndroid Build Coastguard Worker   n = fixnorm_D(a_m);
177*e5436536SAndroid Build Coastguard Worker   a_m <<= n;
178*e5436536SAndroid Build Coastguard Worker   a_e -= n;
179*e5436536SAndroid Build Coastguard Worker 
180*e5436536SAndroid Build Coastguard Worker   n = fixnorm_D(b_m);
181*e5436536SAndroid Build Coastguard Worker   b_m <<= n;
182*e5436536SAndroid Build Coastguard Worker   b_e -= n;
183*e5436536SAndroid Build Coastguard Worker 
184*e5436536SAndroid Build Coastguard Worker   if (a_m == (FIXP_DBL)0) a_e = b_e;
185*e5436536SAndroid Build Coastguard Worker   if (b_m == (FIXP_DBL)0) b_e = a_e;
186*e5436536SAndroid Build Coastguard Worker 
187*e5436536SAndroid Build Coastguard Worker   if (a_e > b_e) {
188*e5436536SAndroid Build Coastguard Worker     return ((b_m >> fMin(a_e - b_e, DFRACT_BITS - 1)) > a_m);
189*e5436536SAndroid Build Coastguard Worker   } else {
190*e5436536SAndroid Build Coastguard Worker     return ((a_m >> fMin(b_e - a_e, DFRACT_BITS - 1)) < b_m);
191*e5436536SAndroid Build Coastguard Worker   }
192*e5436536SAndroid Build Coastguard Worker }
193*e5436536SAndroid Build Coastguard Worker 
fIsLessThan(FIXP_SGL a_m,INT a_e,FIXP_SGL b_m,INT b_e)194*e5436536SAndroid Build Coastguard Worker FDK_INLINE INT fIsLessThan(FIXP_SGL a_m, INT a_e, FIXP_SGL b_m, INT b_e) {
195*e5436536SAndroid Build Coastguard Worker   INT n;
196*e5436536SAndroid Build Coastguard Worker 
197*e5436536SAndroid Build Coastguard Worker   n = fixnorm_S(a_m);
198*e5436536SAndroid Build Coastguard Worker   a_m <<= n;
199*e5436536SAndroid Build Coastguard Worker   a_e -= n;
200*e5436536SAndroid Build Coastguard Worker 
201*e5436536SAndroid Build Coastguard Worker   n = fixnorm_S(b_m);
202*e5436536SAndroid Build Coastguard Worker   b_m <<= n;
203*e5436536SAndroid Build Coastguard Worker   b_e -= n;
204*e5436536SAndroid Build Coastguard Worker 
205*e5436536SAndroid Build Coastguard Worker   if (a_m == (FIXP_SGL)0) a_e = b_e;
206*e5436536SAndroid Build Coastguard Worker   if (b_m == (FIXP_SGL)0) b_e = a_e;
207*e5436536SAndroid Build Coastguard Worker 
208*e5436536SAndroid Build Coastguard Worker   if (a_e > b_e) {
209*e5436536SAndroid Build Coastguard Worker     return ((b_m >> fMin(a_e - b_e, FRACT_BITS - 1)) > a_m);
210*e5436536SAndroid Build Coastguard Worker   } else {
211*e5436536SAndroid Build Coastguard Worker     return ((a_m >> fMin(b_e - a_e, FRACT_BITS - 1)) < b_m);
212*e5436536SAndroid Build Coastguard Worker   }
213*e5436536SAndroid Build Coastguard Worker }
214*e5436536SAndroid Build Coastguard Worker #endif
215*e5436536SAndroid Build Coastguard Worker 
216*e5436536SAndroid Build Coastguard Worker /**
217*e5436536SAndroid Build Coastguard Worker  * \brief deprecated. Use fLog2() instead.
218*e5436536SAndroid Build Coastguard Worker  */
219*e5436536SAndroid Build Coastguard Worker #define CalcLdData(op) fLog2(op, 0)
220*e5436536SAndroid Build Coastguard Worker 
221*e5436536SAndroid Build Coastguard Worker void LdDataVector(FIXP_DBL *srcVector, FIXP_DBL *destVector, INT number);
222*e5436536SAndroid Build Coastguard Worker 
223*e5436536SAndroid Build Coastguard Worker extern const UINT exp2_tab_long[32];
224*e5436536SAndroid Build Coastguard Worker extern const UINT exp2w_tab_long[32];
225*e5436536SAndroid Build Coastguard Worker extern const UINT exp2x_tab_long[32];
226*e5436536SAndroid Build Coastguard Worker 
227*e5436536SAndroid Build Coastguard Worker LNK_SECTION_CODE_L1
CalcInvLdData(const FIXP_DBL x)228*e5436536SAndroid Build Coastguard Worker FDK_INLINE FIXP_DBL CalcInvLdData(const FIXP_DBL x) {
229*e5436536SAndroid Build Coastguard Worker   int set_zero = (x < FL2FXCONST_DBL(-31.0 / 64.0)) ? 0 : 1;
230*e5436536SAndroid Build Coastguard Worker   int set_max = (x >= FL2FXCONST_DBL(31.0 / 64.0)) | (x == FL2FXCONST_DBL(0.0));
231*e5436536SAndroid Build Coastguard Worker 
232*e5436536SAndroid Build Coastguard Worker   FIXP_SGL frac = (FIXP_SGL)((LONG)x & 0x3FF);
233*e5436536SAndroid Build Coastguard Worker   UINT index3 = (UINT)(LONG)(x >> 10) & 0x1F;
234*e5436536SAndroid Build Coastguard Worker   UINT index2 = (UINT)(LONG)(x >> 15) & 0x1F;
235*e5436536SAndroid Build Coastguard Worker   UINT index1 = (UINT)(LONG)(x >> 20) & 0x1F;
236*e5436536SAndroid Build Coastguard Worker   int exp = fMin(31, ((x > FL2FXCONST_DBL(0.0f)) ? (31 - (int)(x >> 25))
237*e5436536SAndroid Build Coastguard Worker                                                  : (int)(-(x >> 25))));
238*e5436536SAndroid Build Coastguard Worker 
239*e5436536SAndroid Build Coastguard Worker   UINT lookup1 = exp2_tab_long[index1] * set_zero;
240*e5436536SAndroid Build Coastguard Worker   UINT lookup2 = exp2w_tab_long[index2];
241*e5436536SAndroid Build Coastguard Worker   UINT lookup3 = exp2x_tab_long[index3];
242*e5436536SAndroid Build Coastguard Worker   UINT lookup3f =
243*e5436536SAndroid Build Coastguard Worker       lookup3 + (UINT)(LONG)fMultDiv2((FIXP_DBL)(0x0016302F), (FIXP_SGL)frac);
244*e5436536SAndroid Build Coastguard Worker 
245*e5436536SAndroid Build Coastguard Worker   UINT lookup12 = (UINT)(LONG)fMult((FIXP_DBL)lookup1, (FIXP_DBL)lookup2);
246*e5436536SAndroid Build Coastguard Worker   UINT lookup = (UINT)(LONG)fMult((FIXP_DBL)lookup12, (FIXP_DBL)lookup3f);
247*e5436536SAndroid Build Coastguard Worker 
248*e5436536SAndroid Build Coastguard Worker   FIXP_DBL retVal = (lookup << 3) >> exp;
249*e5436536SAndroid Build Coastguard Worker 
250*e5436536SAndroid Build Coastguard Worker   if (set_max) {
251*e5436536SAndroid Build Coastguard Worker     retVal = (FIXP_DBL)MAXVAL_DBL;
252*e5436536SAndroid Build Coastguard Worker   }
253*e5436536SAndroid Build Coastguard Worker 
254*e5436536SAndroid Build Coastguard Worker   return retVal;
255*e5436536SAndroid Build Coastguard Worker }
256*e5436536SAndroid Build Coastguard Worker 
257*e5436536SAndroid Build Coastguard Worker void InitLdInt();
258*e5436536SAndroid Build Coastguard Worker FIXP_DBL CalcLdInt(INT i);
259*e5436536SAndroid Build Coastguard Worker 
260*e5436536SAndroid Build Coastguard Worker extern const USHORT sqrt_tab[49];
261*e5436536SAndroid Build Coastguard Worker 
sqrtFixp_lookup(FIXP_DBL x)262*e5436536SAndroid Build Coastguard Worker inline FIXP_DBL sqrtFixp_lookup(FIXP_DBL x) {
263*e5436536SAndroid Build Coastguard Worker   UINT y = (INT)x;
264*e5436536SAndroid Build Coastguard Worker   UCHAR is_zero = (y == 0);
265*e5436536SAndroid Build Coastguard Worker   INT zeros = fixnormz_D(y) & 0x1e;
266*e5436536SAndroid Build Coastguard Worker   y <<= zeros;
267*e5436536SAndroid Build Coastguard Worker   UINT idx = (y >> 26) - 16;
268*e5436536SAndroid Build Coastguard Worker   USHORT frac = (y >> 10) & 0xffff;
269*e5436536SAndroid Build Coastguard Worker   USHORT nfrac = 0xffff ^ frac;
270*e5436536SAndroid Build Coastguard Worker   UINT t = (UINT)nfrac * sqrt_tab[idx] + (UINT)frac * sqrt_tab[idx + 1];
271*e5436536SAndroid Build Coastguard Worker   t = t >> (zeros >> 1);
272*e5436536SAndroid Build Coastguard Worker   return (is_zero ? 0 : t);
273*e5436536SAndroid Build Coastguard Worker }
274*e5436536SAndroid Build Coastguard Worker 
sqrtFixp_lookup(FIXP_DBL x,INT * x_e)275*e5436536SAndroid Build Coastguard Worker inline FIXP_DBL sqrtFixp_lookup(FIXP_DBL x, INT *x_e) {
276*e5436536SAndroid Build Coastguard Worker   UINT y = (INT)x;
277*e5436536SAndroid Build Coastguard Worker   INT e;
278*e5436536SAndroid Build Coastguard Worker 
279*e5436536SAndroid Build Coastguard Worker   if (x == (FIXP_DBL)0) {
280*e5436536SAndroid Build Coastguard Worker     return x;
281*e5436536SAndroid Build Coastguard Worker   }
282*e5436536SAndroid Build Coastguard Worker 
283*e5436536SAndroid Build Coastguard Worker   /* Normalize */
284*e5436536SAndroid Build Coastguard Worker   e = fixnormz_D(y);
285*e5436536SAndroid Build Coastguard Worker   y <<= e;
286*e5436536SAndroid Build Coastguard Worker   e = *x_e - e + 2;
287*e5436536SAndroid Build Coastguard Worker 
288*e5436536SAndroid Build Coastguard Worker   /* Correct odd exponent. */
289*e5436536SAndroid Build Coastguard Worker   if (e & 1) {
290*e5436536SAndroid Build Coastguard Worker     y >>= 1;
291*e5436536SAndroid Build Coastguard Worker     e++;
292*e5436536SAndroid Build Coastguard Worker   }
293*e5436536SAndroid Build Coastguard Worker   /* Get square root */
294*e5436536SAndroid Build Coastguard Worker   UINT idx = (y >> 26) - 16;
295*e5436536SAndroid Build Coastguard Worker   USHORT frac = (y >> 10) & 0xffff;
296*e5436536SAndroid Build Coastguard Worker   USHORT nfrac = 0xffff ^ frac;
297*e5436536SAndroid Build Coastguard Worker   UINT t = (UINT)nfrac * sqrt_tab[idx] + (UINT)frac * sqrt_tab[idx + 1];
298*e5436536SAndroid Build Coastguard Worker 
299*e5436536SAndroid Build Coastguard Worker   /* Write back exponent */
300*e5436536SAndroid Build Coastguard Worker   *x_e = e >> 1;
301*e5436536SAndroid Build Coastguard Worker   return (FIXP_DBL)(LONG)(t >> 1);
302*e5436536SAndroid Build Coastguard Worker }
303*e5436536SAndroid Build Coastguard Worker 
304*e5436536SAndroid Build Coastguard Worker void InitInvSqrtTab();
305*e5436536SAndroid Build Coastguard Worker 
306*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_invSqrtNorm2
307*e5436536SAndroid Build Coastguard Worker /**
308*e5436536SAndroid Build Coastguard Worker  * \brief calculate 1.0/sqrt(op)
309*e5436536SAndroid Build Coastguard Worker  * \param op_m mantissa of input value.
310*e5436536SAndroid Build Coastguard Worker  * \param result_e pointer to return the exponent of the result
311*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result
312*e5436536SAndroid Build Coastguard Worker  */
313*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
314*e5436536SAndroid Build Coastguard Worker   delivers 1/sqrt(op) normalized to .5...1 and the shift value of the OUTPUT,
315*e5436536SAndroid Build Coastguard Worker   i.e. the denormalized result is 1/sqrt(op) = invSqrtNorm(op) * 2^(shift)
316*e5436536SAndroid Build Coastguard Worker   uses Newton-iteration for approximation
317*e5436536SAndroid Build Coastguard Worker       Q(n+1) = Q(n) + Q(n) * (0.5 - 2 * V * Q(n)^2)
318*e5436536SAndroid Build Coastguard Worker       with Q = 0.5* V ^-0.5; 0.5 <= V < 1.0
319*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
invSqrtNorm2(FIXP_DBL op,INT * shift)320*e5436536SAndroid Build Coastguard Worker static FDK_FORCEINLINE FIXP_DBL invSqrtNorm2(FIXP_DBL op, INT *shift) {
321*e5436536SAndroid Build Coastguard Worker   FIXP_DBL val = op;
322*e5436536SAndroid Build Coastguard Worker   FIXP_DBL reg1, reg2;
323*e5436536SAndroid Build Coastguard Worker 
324*e5436536SAndroid Build Coastguard Worker   if (val == FL2FXCONST_DBL(0.0)) {
325*e5436536SAndroid Build Coastguard Worker     *shift = 16;
326*e5436536SAndroid Build Coastguard Worker     return ((LONG)MAXVAL_DBL); /* maximum positive value */
327*e5436536SAndroid Build Coastguard Worker   }
328*e5436536SAndroid Build Coastguard Worker 
329*e5436536SAndroid Build Coastguard Worker #define INVSQRTNORM2_LINEAR_INTERPOLATE
330*e5436536SAndroid Build Coastguard Worker #define INVSQRTNORM2_LINEAR_INTERPOLATE_HQ
331*e5436536SAndroid Build Coastguard Worker 
332*e5436536SAndroid Build Coastguard Worker   /* normalize input, calculate shift value */
333*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(val > FL2FXCONST_DBL(0.0));
334*e5436536SAndroid Build Coastguard Worker   *shift = fNormz(val) - 1; /* CountLeadingBits() is not necessary here since
335*e5436536SAndroid Build Coastguard Worker                                test value is always > 0 */
336*e5436536SAndroid Build Coastguard Worker   val <<= *shift;           /* normalized input V */
337*e5436536SAndroid Build Coastguard Worker   *shift += 2;              /* bias for exponent */
338*e5436536SAndroid Build Coastguard Worker 
339*e5436536SAndroid Build Coastguard Worker #if defined(INVSQRTNORM2_LINEAR_INTERPOLATE)
340*e5436536SAndroid Build Coastguard Worker   INT index =
341*e5436536SAndroid Build Coastguard Worker       (INT)(val >> (DFRACT_BITS - 1 - (SQRT_BITS + 1))) & SQRT_BITS_MASK;
342*e5436536SAndroid Build Coastguard Worker   FIXP_DBL Fract =
343*e5436536SAndroid Build Coastguard Worker       (FIXP_DBL)(((INT)val & SQRT_FRACT_BITS_MASK) << (SQRT_BITS + 1));
344*e5436536SAndroid Build Coastguard Worker   FIXP_DBL diff = invSqrtTab[index + 1] - invSqrtTab[index];
345*e5436536SAndroid Build Coastguard Worker   reg1 = invSqrtTab[index] + (fMultDiv2(diff, Fract) << 1);
346*e5436536SAndroid Build Coastguard Worker #if defined(INVSQRTNORM2_LINEAR_INTERPOLATE_HQ)
347*e5436536SAndroid Build Coastguard Worker   /* reg1 = t[i] + (t[i+1]-t[i])*fract ... already computed ...
348*e5436536SAndroid Build Coastguard Worker                                        + (1-fract)fract*(t[i+2]-t[i+1])/2 */
349*e5436536SAndroid Build Coastguard Worker   if (Fract != (FIXP_DBL)0) {
350*e5436536SAndroid Build Coastguard Worker     /* fract = fract * (1 - fract) */
351*e5436536SAndroid Build Coastguard Worker     Fract = fMultDiv2(Fract, (FIXP_DBL)((ULONG)0x80000000 - (ULONG)Fract)) << 1;
352*e5436536SAndroid Build Coastguard Worker     diff = diff - (invSqrtTab[index + 2] - invSqrtTab[index + 1]);
353*e5436536SAndroid Build Coastguard Worker     reg1 = fMultAddDiv2(reg1, Fract, diff);
354*e5436536SAndroid Build Coastguard Worker   }
355*e5436536SAndroid Build Coastguard Worker #endif /* INVSQRTNORM2_LINEAR_INTERPOLATE_HQ */
356*e5436536SAndroid Build Coastguard Worker #else
357*e5436536SAndroid Build Coastguard Worker #error \
358*e5436536SAndroid Build Coastguard Worker     "Either define INVSQRTNORM2_NEWTON_ITERATE or INVSQRTNORM2_LINEAR_INTERPOLATE"
359*e5436536SAndroid Build Coastguard Worker #endif
360*e5436536SAndroid Build Coastguard Worker   /* calculate the output exponent = input exp/2 */
361*e5436536SAndroid Build Coastguard Worker   if (*shift & 0x00000001) { /* odd shift values ? */
362*e5436536SAndroid Build Coastguard Worker     /* Note: Do not use rounded value 0x5A82799A to avoid overflow with
363*e5436536SAndroid Build Coastguard Worker      * shift-by-2 */
364*e5436536SAndroid Build Coastguard Worker     reg2 = (FIXP_DBL)0x5A827999;
365*e5436536SAndroid Build Coastguard Worker     /* FL2FXCONST_DBL(0.707106781186547524400844362104849f);*/ /* 1/sqrt(2);
366*e5436536SAndroid Build Coastguard Worker                                                                 */
367*e5436536SAndroid Build Coastguard Worker     reg1 = fMultDiv2(reg1, reg2) << 2;
368*e5436536SAndroid Build Coastguard Worker   }
369*e5436536SAndroid Build Coastguard Worker 
370*e5436536SAndroid Build Coastguard Worker   *shift = *shift >> 1;
371*e5436536SAndroid Build Coastguard Worker 
372*e5436536SAndroid Build Coastguard Worker   return (reg1);
373*e5436536SAndroid Build Coastguard Worker }
374*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_invSqrtNorm2 */
375*e5436536SAndroid Build Coastguard Worker 
376*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_sqrtFixp
sqrtFixp(FIXP_DBL op)377*e5436536SAndroid Build Coastguard Worker static FDK_FORCEINLINE FIXP_DBL sqrtFixp(FIXP_DBL op) {
378*e5436536SAndroid Build Coastguard Worker   INT tmp_exp = 0;
379*e5436536SAndroid Build Coastguard Worker   FIXP_DBL tmp_inv = invSqrtNorm2(op, &tmp_exp);
380*e5436536SAndroid Build Coastguard Worker 
381*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(tmp_exp > 0);
382*e5436536SAndroid Build Coastguard Worker   return ((FIXP_DBL)(fMultDiv2((op << (tmp_exp - 1)), tmp_inv) << 2));
383*e5436536SAndroid Build Coastguard Worker }
384*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_sqrtFixp */
385*e5436536SAndroid Build Coastguard Worker 
386*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_invFixp
387*e5436536SAndroid Build Coastguard Worker /**
388*e5436536SAndroid Build Coastguard Worker  * \brief calculate 1.0/op
389*e5436536SAndroid Build Coastguard Worker  * \param op mantissa of the input value.
390*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result with implicit exponent of 31
391*e5436536SAndroid Build Coastguard Worker  * \exceptions are provided for op=0,1 setting max. positive value
392*e5436536SAndroid Build Coastguard Worker  */
invFixp(FIXP_DBL op)393*e5436536SAndroid Build Coastguard Worker static inline FIXP_DBL invFixp(FIXP_DBL op) {
394*e5436536SAndroid Build Coastguard Worker   if ((op == (FIXP_DBL)0x00000000) || (op == (FIXP_DBL)0x00000001)) {
395*e5436536SAndroid Build Coastguard Worker     return ((LONG)MAXVAL_DBL);
396*e5436536SAndroid Build Coastguard Worker   }
397*e5436536SAndroid Build Coastguard Worker   INT tmp_exp;
398*e5436536SAndroid Build Coastguard Worker   FIXP_DBL tmp_inv = invSqrtNorm2(op, &tmp_exp);
399*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT((31 - (2 * tmp_exp + 1)) >= 0);
400*e5436536SAndroid Build Coastguard Worker   int shift = 31 - (2 * tmp_exp + 1);
401*e5436536SAndroid Build Coastguard Worker   tmp_inv = fPow2Div2(tmp_inv);
402*e5436536SAndroid Build Coastguard Worker   if (shift) {
403*e5436536SAndroid Build Coastguard Worker     tmp_inv = ((tmp_inv >> (shift - 1)) + (FIXP_DBL)1) >> 1;
404*e5436536SAndroid Build Coastguard Worker   }
405*e5436536SAndroid Build Coastguard Worker   return tmp_inv;
406*e5436536SAndroid Build Coastguard Worker }
407*e5436536SAndroid Build Coastguard Worker 
408*e5436536SAndroid Build Coastguard Worker /**
409*e5436536SAndroid Build Coastguard Worker  * \brief calculate 1.0/(op_m * 2^op_e)
410*e5436536SAndroid Build Coastguard Worker  * \param op_m mantissa of the input value.
411*e5436536SAndroid Build Coastguard Worker  * \param op_e pointer into were the exponent of the input value is stored, and
412*e5436536SAndroid Build Coastguard Worker  * the result will be stored into.
413*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result
414*e5436536SAndroid Build Coastguard Worker  */
invFixp(FIXP_DBL op_m,int * op_e)415*e5436536SAndroid Build Coastguard Worker static inline FIXP_DBL invFixp(FIXP_DBL op_m, int *op_e) {
416*e5436536SAndroid Build Coastguard Worker   if ((op_m == (FIXP_DBL)0x00000000) || (op_m == (FIXP_DBL)0x00000001)) {
417*e5436536SAndroid Build Coastguard Worker     *op_e = 31 - *op_e;
418*e5436536SAndroid Build Coastguard Worker     return ((LONG)MAXVAL_DBL);
419*e5436536SAndroid Build Coastguard Worker   }
420*e5436536SAndroid Build Coastguard Worker 
421*e5436536SAndroid Build Coastguard Worker   INT tmp_exp;
422*e5436536SAndroid Build Coastguard Worker   FIXP_DBL tmp_inv = invSqrtNorm2(op_m, &tmp_exp);
423*e5436536SAndroid Build Coastguard Worker 
424*e5436536SAndroid Build Coastguard Worker   *op_e = (tmp_exp << 1) - *op_e + 1;
425*e5436536SAndroid Build Coastguard Worker   return fPow2Div2(tmp_inv);
426*e5436536SAndroid Build Coastguard Worker }
427*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_invFixp */
428*e5436536SAndroid Build Coastguard Worker 
429*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_schur_div
430*e5436536SAndroid Build Coastguard Worker 
431*e5436536SAndroid Build Coastguard Worker /**
432*e5436536SAndroid Build Coastguard Worker  * \brief Divide two FIXP_DBL values with given precision.
433*e5436536SAndroid Build Coastguard Worker  * \param num dividend
434*e5436536SAndroid Build Coastguard Worker  * \param denum divisor
435*e5436536SAndroid Build Coastguard Worker  * \param count amount of significant bits of the result (starting to the MSB)
436*e5436536SAndroid Build Coastguard Worker  * \return num/divisor
437*e5436536SAndroid Build Coastguard Worker  */
438*e5436536SAndroid Build Coastguard Worker 
439*e5436536SAndroid Build Coastguard Worker FIXP_DBL schur_div(FIXP_DBL num, FIXP_DBL denum, INT count);
440*e5436536SAndroid Build Coastguard Worker 
441*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_schur_div */
442*e5436536SAndroid Build Coastguard Worker 
443*e5436536SAndroid Build Coastguard Worker FIXP_DBL mul_dbl_sgl_rnd(const FIXP_DBL op1, const FIXP_SGL op2);
444*e5436536SAndroid Build Coastguard Worker 
445*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fMultNorm
446*e5436536SAndroid Build Coastguard Worker /**
447*e5436536SAndroid Build Coastguard Worker  * \brief multiply two values with normalization, thus max precision.
448*e5436536SAndroid Build Coastguard Worker  * Author: Robert Weidner
449*e5436536SAndroid Build Coastguard Worker  *
450*e5436536SAndroid Build Coastguard Worker  * \param f1 first factor
451*e5436536SAndroid Build Coastguard Worker  * \param f2 second factor
452*e5436536SAndroid Build Coastguard Worker  * \param result_e pointer to an INT where the exponent of the result is stored
453*e5436536SAndroid Build Coastguard Worker  * into
454*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the product f1*f2
455*e5436536SAndroid Build Coastguard Worker  */
456*e5436536SAndroid Build Coastguard Worker FIXP_DBL fMultNorm(FIXP_DBL f1, FIXP_DBL f2, INT *result_e);
457*e5436536SAndroid Build Coastguard Worker 
458*e5436536SAndroid Build Coastguard Worker /**
459*e5436536SAndroid Build Coastguard Worker  * \brief Multiply 2 values using maximum precision. The exponent of the result
460*e5436536SAndroid Build Coastguard Worker  * is 0.
461*e5436536SAndroid Build Coastguard Worker  * \param f1_m mantissa of factor 1
462*e5436536SAndroid Build Coastguard Worker  * \param f2_m mantissa of factor 2
463*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result with exponent equal to 0
464*e5436536SAndroid Build Coastguard Worker  */
fMultNorm(FIXP_DBL f1,FIXP_DBL f2)465*e5436536SAndroid Build Coastguard Worker inline FIXP_DBL fMultNorm(FIXP_DBL f1, FIXP_DBL f2) {
466*e5436536SAndroid Build Coastguard Worker   FIXP_DBL m;
467*e5436536SAndroid Build Coastguard Worker   INT e;
468*e5436536SAndroid Build Coastguard Worker 
469*e5436536SAndroid Build Coastguard Worker   m = fMultNorm(f1, f2, &e);
470*e5436536SAndroid Build Coastguard Worker 
471*e5436536SAndroid Build Coastguard Worker   m = scaleValueSaturate(m, e);
472*e5436536SAndroid Build Coastguard Worker 
473*e5436536SAndroid Build Coastguard Worker   return m;
474*e5436536SAndroid Build Coastguard Worker }
475*e5436536SAndroid Build Coastguard Worker 
476*e5436536SAndroid Build Coastguard Worker /**
477*e5436536SAndroid Build Coastguard Worker  * \brief Multiply 2 values with exponent and use given exponent for the
478*e5436536SAndroid Build Coastguard Worker  * mantissa of the result.
479*e5436536SAndroid Build Coastguard Worker  * \param f1_m mantissa of factor 1
480*e5436536SAndroid Build Coastguard Worker  * \param f1_e exponent of factor 1
481*e5436536SAndroid Build Coastguard Worker  * \param f2_m mantissa of factor 2
482*e5436536SAndroid Build Coastguard Worker  * \param f2_e exponent of factor 2
483*e5436536SAndroid Build Coastguard Worker  * \param result_e exponent for the returned mantissa of the result
484*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result with exponent equal to result_e
485*e5436536SAndroid Build Coastguard Worker  */
fMultNorm(FIXP_DBL f1_m,INT f1_e,FIXP_DBL f2_m,INT f2_e,INT result_e)486*e5436536SAndroid Build Coastguard Worker inline FIXP_DBL fMultNorm(FIXP_DBL f1_m, INT f1_e, FIXP_DBL f2_m, INT f2_e,
487*e5436536SAndroid Build Coastguard Worker                           INT result_e) {
488*e5436536SAndroid Build Coastguard Worker   FIXP_DBL m;
489*e5436536SAndroid Build Coastguard Worker   INT e;
490*e5436536SAndroid Build Coastguard Worker 
491*e5436536SAndroid Build Coastguard Worker   m = fMultNorm(f1_m, f2_m, &e);
492*e5436536SAndroid Build Coastguard Worker 
493*e5436536SAndroid Build Coastguard Worker   m = scaleValueSaturate(m, e + f1_e + f2_e - result_e);
494*e5436536SAndroid Build Coastguard Worker 
495*e5436536SAndroid Build Coastguard Worker   return m;
496*e5436536SAndroid Build Coastguard Worker }
497*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_fMultNorm */
498*e5436536SAndroid Build Coastguard Worker 
499*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fMultI
500*e5436536SAndroid Build Coastguard Worker /**
501*e5436536SAndroid Build Coastguard Worker  * \brief Multiplies a fractional value and a integer value and performs
502*e5436536SAndroid Build Coastguard Worker  * rounding to nearest
503*e5436536SAndroid Build Coastguard Worker  * \param a fractional value
504*e5436536SAndroid Build Coastguard Worker  * \param b integer value
505*e5436536SAndroid Build Coastguard Worker  * \return integer value
506*e5436536SAndroid Build Coastguard Worker  */
fMultI(FIXP_DBL a,INT b)507*e5436536SAndroid Build Coastguard Worker inline INT fMultI(FIXP_DBL a, INT b) {
508*e5436536SAndroid Build Coastguard Worker   FIXP_DBL m, mi;
509*e5436536SAndroid Build Coastguard Worker   INT m_e;
510*e5436536SAndroid Build Coastguard Worker 
511*e5436536SAndroid Build Coastguard Worker   m = fMultNorm(a, (FIXP_DBL)b, &m_e);
512*e5436536SAndroid Build Coastguard Worker 
513*e5436536SAndroid Build Coastguard Worker   if (m_e < (INT)0) {
514*e5436536SAndroid Build Coastguard Worker     if (m_e > (INT)-DFRACT_BITS) {
515*e5436536SAndroid Build Coastguard Worker       m = m >> ((-m_e) - 1);
516*e5436536SAndroid Build Coastguard Worker       mi = (m + (FIXP_DBL)1) >> 1;
517*e5436536SAndroid Build Coastguard Worker     } else {
518*e5436536SAndroid Build Coastguard Worker       mi = (FIXP_DBL)0;
519*e5436536SAndroid Build Coastguard Worker     }
520*e5436536SAndroid Build Coastguard Worker   } else {
521*e5436536SAndroid Build Coastguard Worker     mi = scaleValueSaturate(m, m_e);
522*e5436536SAndroid Build Coastguard Worker   }
523*e5436536SAndroid Build Coastguard Worker 
524*e5436536SAndroid Build Coastguard Worker   return ((INT)mi);
525*e5436536SAndroid Build Coastguard Worker }
526*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_fMultI */
527*e5436536SAndroid Build Coastguard Worker 
528*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fMultIfloor
529*e5436536SAndroid Build Coastguard Worker /**
530*e5436536SAndroid Build Coastguard Worker  * \brief Multiplies a fractional value and a integer value and performs floor
531*e5436536SAndroid Build Coastguard Worker  * rounding
532*e5436536SAndroid Build Coastguard Worker  * \param a fractional value
533*e5436536SAndroid Build Coastguard Worker  * \param b integer value
534*e5436536SAndroid Build Coastguard Worker  * \return integer value
535*e5436536SAndroid Build Coastguard Worker  */
fMultIfloor(FIXP_DBL a,INT b)536*e5436536SAndroid Build Coastguard Worker inline INT fMultIfloor(FIXP_DBL a, INT b) {
537*e5436536SAndroid Build Coastguard Worker   FIXP_DBL m, mi;
538*e5436536SAndroid Build Coastguard Worker   INT m_e;
539*e5436536SAndroid Build Coastguard Worker 
540*e5436536SAndroid Build Coastguard Worker   m = fMultNorm(a, (FIXP_DBL)b, &m_e);
541*e5436536SAndroid Build Coastguard Worker 
542*e5436536SAndroid Build Coastguard Worker   if (m_e < (INT)0) {
543*e5436536SAndroid Build Coastguard Worker     if (m_e > (INT)-DFRACT_BITS) {
544*e5436536SAndroid Build Coastguard Worker       mi = m >> (-m_e);
545*e5436536SAndroid Build Coastguard Worker     } else {
546*e5436536SAndroid Build Coastguard Worker       mi = (FIXP_DBL)0;
547*e5436536SAndroid Build Coastguard Worker       if (m < (FIXP_DBL)0) {
548*e5436536SAndroid Build Coastguard Worker         mi = (FIXP_DBL)-1;
549*e5436536SAndroid Build Coastguard Worker       }
550*e5436536SAndroid Build Coastguard Worker     }
551*e5436536SAndroid Build Coastguard Worker   } else {
552*e5436536SAndroid Build Coastguard Worker     mi = scaleValueSaturate(m, m_e);
553*e5436536SAndroid Build Coastguard Worker   }
554*e5436536SAndroid Build Coastguard Worker 
555*e5436536SAndroid Build Coastguard Worker   return ((INT)mi);
556*e5436536SAndroid Build Coastguard Worker }
557*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_fMultIfloor */
558*e5436536SAndroid Build Coastguard Worker 
559*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fMultIceil
560*e5436536SAndroid Build Coastguard Worker /**
561*e5436536SAndroid Build Coastguard Worker  * \brief Multiplies a fractional value and a integer value and performs ceil
562*e5436536SAndroid Build Coastguard Worker  * rounding
563*e5436536SAndroid Build Coastguard Worker  * \param a fractional value
564*e5436536SAndroid Build Coastguard Worker  * \param b integer value
565*e5436536SAndroid Build Coastguard Worker  * \return integer value
566*e5436536SAndroid Build Coastguard Worker  */
fMultIceil(FIXP_DBL a,INT b)567*e5436536SAndroid Build Coastguard Worker inline INT fMultIceil(FIXP_DBL a, INT b) {
568*e5436536SAndroid Build Coastguard Worker   FIXP_DBL m, mi;
569*e5436536SAndroid Build Coastguard Worker   INT m_e;
570*e5436536SAndroid Build Coastguard Worker 
571*e5436536SAndroid Build Coastguard Worker   m = fMultNorm(a, (FIXP_DBL)b, &m_e);
572*e5436536SAndroid Build Coastguard Worker 
573*e5436536SAndroid Build Coastguard Worker   if (m_e < (INT)0) {
574*e5436536SAndroid Build Coastguard Worker     if (m_e > (INT) - (DFRACT_BITS - 1)) {
575*e5436536SAndroid Build Coastguard Worker       mi = (m >> (-m_e));
576*e5436536SAndroid Build Coastguard Worker       if ((LONG)m & ((1 << (-m_e)) - 1)) {
577*e5436536SAndroid Build Coastguard Worker         mi = mi + (FIXP_DBL)1;
578*e5436536SAndroid Build Coastguard Worker       }
579*e5436536SAndroid Build Coastguard Worker     } else {
580*e5436536SAndroid Build Coastguard Worker       if (m > (FIXP_DBL)0) {
581*e5436536SAndroid Build Coastguard Worker         mi = (FIXP_DBL)1;
582*e5436536SAndroid Build Coastguard Worker       } else {
583*e5436536SAndroid Build Coastguard Worker         if ((m_e == -(DFRACT_BITS - 1)) && (m == (FIXP_DBL)MINVAL_DBL)) {
584*e5436536SAndroid Build Coastguard Worker           mi = (FIXP_DBL)-1;
585*e5436536SAndroid Build Coastguard Worker         } else {
586*e5436536SAndroid Build Coastguard Worker           mi = (FIXP_DBL)0;
587*e5436536SAndroid Build Coastguard Worker         }
588*e5436536SAndroid Build Coastguard Worker       }
589*e5436536SAndroid Build Coastguard Worker     }
590*e5436536SAndroid Build Coastguard Worker   } else {
591*e5436536SAndroid Build Coastguard Worker     mi = scaleValueSaturate(m, m_e);
592*e5436536SAndroid Build Coastguard Worker   }
593*e5436536SAndroid Build Coastguard Worker 
594*e5436536SAndroid Build Coastguard Worker   return ((INT)mi);
595*e5436536SAndroid Build Coastguard Worker }
596*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_fMultIceil */
597*e5436536SAndroid Build Coastguard Worker 
598*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fDivNorm
599*e5436536SAndroid Build Coastguard Worker /**
600*e5436536SAndroid Build Coastguard Worker  * \brief Divide 2 FIXP_DBL values with normalization of input values.
601*e5436536SAndroid Build Coastguard Worker  * \param num numerator
602*e5436536SAndroid Build Coastguard Worker  * \param denum denominator
603*e5436536SAndroid Build Coastguard Worker  * \param result_e pointer to an INT where the exponent of the result is stored
604*e5436536SAndroid Build Coastguard Worker  * into
605*e5436536SAndroid Build Coastguard Worker  * \return num/denum with exponent = *result_e
606*e5436536SAndroid Build Coastguard Worker  */
607*e5436536SAndroid Build Coastguard Worker FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom, INT *result_e);
608*e5436536SAndroid Build Coastguard Worker 
609*e5436536SAndroid Build Coastguard Worker /**
610*e5436536SAndroid Build Coastguard Worker  * \brief Divide 2 positive FIXP_DBL values with normalization of input values.
611*e5436536SAndroid Build Coastguard Worker  * \param num numerator
612*e5436536SAndroid Build Coastguard Worker  * \param denum denominator
613*e5436536SAndroid Build Coastguard Worker  * \return num/denum with exponent = 0
614*e5436536SAndroid Build Coastguard Worker  */
615*e5436536SAndroid Build Coastguard Worker FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom);
616*e5436536SAndroid Build Coastguard Worker 
617*e5436536SAndroid Build Coastguard Worker /**
618*e5436536SAndroid Build Coastguard Worker  * \brief Divide 2 signed FIXP_DBL values with normalization of input values.
619*e5436536SAndroid Build Coastguard Worker  * \param num numerator
620*e5436536SAndroid Build Coastguard Worker  * \param denum denominator
621*e5436536SAndroid Build Coastguard Worker  * \param result_e pointer to an INT where the exponent of the result is stored
622*e5436536SAndroid Build Coastguard Worker  * into
623*e5436536SAndroid Build Coastguard Worker  * \return num/denum with exponent = *result_e
624*e5436536SAndroid Build Coastguard Worker  */
625*e5436536SAndroid Build Coastguard Worker FIXP_DBL fDivNormSigned(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e);
626*e5436536SAndroid Build Coastguard Worker 
627*e5436536SAndroid Build Coastguard Worker /**
628*e5436536SAndroid Build Coastguard Worker  * \brief Divide 2 signed FIXP_DBL values with normalization of input values.
629*e5436536SAndroid Build Coastguard Worker  * \param num numerator
630*e5436536SAndroid Build Coastguard Worker  * \param denum denominator
631*e5436536SAndroid Build Coastguard Worker  * \return num/denum with exponent = 0
632*e5436536SAndroid Build Coastguard Worker  */
633*e5436536SAndroid Build Coastguard Worker FIXP_DBL fDivNormSigned(FIXP_DBL num, FIXP_DBL denom);
634*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_fDivNorm */
635*e5436536SAndroid Build Coastguard Worker 
636*e5436536SAndroid Build Coastguard Worker /**
637*e5436536SAndroid Build Coastguard Worker  * \brief Adjust mantissa to exponent -1
638*e5436536SAndroid Build Coastguard Worker  * \param a_m mantissa of value to be adjusted
639*e5436536SAndroid Build Coastguard Worker  * \param pA_e pointer to the exponen of a_m
640*e5436536SAndroid Build Coastguard Worker  * \return adjusted mantissa
641*e5436536SAndroid Build Coastguard Worker  */
fAdjust(FIXP_DBL a_m,INT * pA_e)642*e5436536SAndroid Build Coastguard Worker inline FIXP_DBL fAdjust(FIXP_DBL a_m, INT *pA_e) {
643*e5436536SAndroid Build Coastguard Worker   INT shift;
644*e5436536SAndroid Build Coastguard Worker 
645*e5436536SAndroid Build Coastguard Worker   shift = fNorm(a_m) - 1;
646*e5436536SAndroid Build Coastguard Worker   *pA_e -= shift;
647*e5436536SAndroid Build Coastguard Worker 
648*e5436536SAndroid Build Coastguard Worker   return scaleValue(a_m, shift);
649*e5436536SAndroid Build Coastguard Worker }
650*e5436536SAndroid Build Coastguard Worker 
651*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fAddNorm
652*e5436536SAndroid Build Coastguard Worker /**
653*e5436536SAndroid Build Coastguard Worker  * \brief Add two values with normalization
654*e5436536SAndroid Build Coastguard Worker  * \param a_m mantissa of first summand
655*e5436536SAndroid Build Coastguard Worker  * \param a_e exponent of first summand
656*e5436536SAndroid Build Coastguard Worker  * \param a_m mantissa of second summand
657*e5436536SAndroid Build Coastguard Worker  * \param a_e exponent of second summand
658*e5436536SAndroid Build Coastguard Worker  * \param pResult_e pointer to where the exponent of the result will be stored
659*e5436536SAndroid Build Coastguard Worker  * to.
660*e5436536SAndroid Build Coastguard Worker  * \return mantissa of result
661*e5436536SAndroid Build Coastguard Worker  */
fAddNorm(FIXP_DBL a_m,INT a_e,FIXP_DBL b_m,INT b_e,INT * pResult_e)662*e5436536SAndroid Build Coastguard Worker inline FIXP_DBL fAddNorm(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e,
663*e5436536SAndroid Build Coastguard Worker                          INT *pResult_e) {
664*e5436536SAndroid Build Coastguard Worker   INT result_e;
665*e5436536SAndroid Build Coastguard Worker   FIXP_DBL result_m;
666*e5436536SAndroid Build Coastguard Worker 
667*e5436536SAndroid Build Coastguard Worker   /* If one of the summands is zero, return the other.
668*e5436536SAndroid Build Coastguard Worker      This is necessary for the summation of a very small number to zero */
669*e5436536SAndroid Build Coastguard Worker   if (a_m == (FIXP_DBL)0) {
670*e5436536SAndroid Build Coastguard Worker     *pResult_e = b_e;
671*e5436536SAndroid Build Coastguard Worker     return b_m;
672*e5436536SAndroid Build Coastguard Worker   }
673*e5436536SAndroid Build Coastguard Worker   if (b_m == (FIXP_DBL)0) {
674*e5436536SAndroid Build Coastguard Worker     *pResult_e = a_e;
675*e5436536SAndroid Build Coastguard Worker     return a_m;
676*e5436536SAndroid Build Coastguard Worker   }
677*e5436536SAndroid Build Coastguard Worker 
678*e5436536SAndroid Build Coastguard Worker   a_m = fAdjust(a_m, &a_e);
679*e5436536SAndroid Build Coastguard Worker   b_m = fAdjust(b_m, &b_e);
680*e5436536SAndroid Build Coastguard Worker 
681*e5436536SAndroid Build Coastguard Worker   if (a_e > b_e) {
682*e5436536SAndroid Build Coastguard Worker     result_m = a_m + (b_m >> fMin(a_e - b_e, DFRACT_BITS - 1));
683*e5436536SAndroid Build Coastguard Worker     result_e = a_e;
684*e5436536SAndroid Build Coastguard Worker   } else {
685*e5436536SAndroid Build Coastguard Worker     result_m = (a_m >> fMin(b_e - a_e, DFRACT_BITS - 1)) + b_m;
686*e5436536SAndroid Build Coastguard Worker     result_e = b_e;
687*e5436536SAndroid Build Coastguard Worker   }
688*e5436536SAndroid Build Coastguard Worker 
689*e5436536SAndroid Build Coastguard Worker   *pResult_e = result_e;
690*e5436536SAndroid Build Coastguard Worker   return result_m;
691*e5436536SAndroid Build Coastguard Worker }
692*e5436536SAndroid Build Coastguard Worker 
fAddNorm(FIXP_DBL a_m,INT a_e,FIXP_DBL b_m,INT b_e,INT result_e)693*e5436536SAndroid Build Coastguard Worker inline FIXP_DBL fAddNorm(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e,
694*e5436536SAndroid Build Coastguard Worker                          INT result_e) {
695*e5436536SAndroid Build Coastguard Worker   FIXP_DBL result_m;
696*e5436536SAndroid Build Coastguard Worker 
697*e5436536SAndroid Build Coastguard Worker   a_m = scaleValue(a_m, a_e - result_e);
698*e5436536SAndroid Build Coastguard Worker   b_m = scaleValue(b_m, b_e - result_e);
699*e5436536SAndroid Build Coastguard Worker 
700*e5436536SAndroid Build Coastguard Worker   result_m = a_m + b_m;
701*e5436536SAndroid Build Coastguard Worker 
702*e5436536SAndroid Build Coastguard Worker   return result_m;
703*e5436536SAndroid Build Coastguard Worker }
704*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_fAddNorm */
705*e5436536SAndroid Build Coastguard Worker 
706*e5436536SAndroid Build Coastguard Worker /**
707*e5436536SAndroid Build Coastguard Worker  * \brief Divide 2 FIXP_DBL values with normalization of input values.
708*e5436536SAndroid Build Coastguard Worker  * \param num numerator
709*e5436536SAndroid Build Coastguard Worker  * \param denum denomintator
710*e5436536SAndroid Build Coastguard Worker  * \return num/denum with exponent = 0
711*e5436536SAndroid Build Coastguard Worker  */
712*e5436536SAndroid Build Coastguard Worker FIXP_DBL fDivNormHighPrec(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e);
713*e5436536SAndroid Build Coastguard Worker 
714*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fPow
715*e5436536SAndroid Build Coastguard Worker /**
716*e5436536SAndroid Build Coastguard Worker  * \brief return 2 ^ (exp_m * 2^exp_e)
717*e5436536SAndroid Build Coastguard Worker  * \param exp_m mantissa of the exponent to 2.0f
718*e5436536SAndroid Build Coastguard Worker  * \param exp_e exponent of the exponent to 2.0f
719*e5436536SAndroid Build Coastguard Worker  * \param result_e pointer to a INT where the exponent of the result will be
720*e5436536SAndroid Build Coastguard Worker  * stored into
721*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result
722*e5436536SAndroid Build Coastguard Worker  */
723*e5436536SAndroid Build Coastguard Worker FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e, INT *result_e);
724*e5436536SAndroid Build Coastguard Worker 
725*e5436536SAndroid Build Coastguard Worker /**
726*e5436536SAndroid Build Coastguard Worker  * \brief return 2 ^ (exp_m * 2^exp_e). This version returns only the mantissa
727*e5436536SAndroid Build Coastguard Worker  * with implicit exponent of zero.
728*e5436536SAndroid Build Coastguard Worker  * \param exp_m mantissa of the exponent to 2.0f
729*e5436536SAndroid Build Coastguard Worker  * \param exp_e exponent of the exponent to 2.0f
730*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result
731*e5436536SAndroid Build Coastguard Worker  */
732*e5436536SAndroid Build Coastguard Worker FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e);
733*e5436536SAndroid Build Coastguard Worker 
734*e5436536SAndroid Build Coastguard Worker /**
735*e5436536SAndroid Build Coastguard Worker  * \brief return x ^ (exp_m * 2^exp_e), where log2(x) = baseLd_m * 2^(baseLd_e).
736*e5436536SAndroid Build Coastguard Worker  * This saves the need to compute log2() of constant values (when x is a
737*e5436536SAndroid Build Coastguard Worker  * constant).
738*e5436536SAndroid Build Coastguard Worker  * \param baseLd_m mantissa of log2() of x.
739*e5436536SAndroid Build Coastguard Worker  * \param baseLd_e exponent of log2() of x.
740*e5436536SAndroid Build Coastguard Worker  * \param exp_m mantissa of the exponent to 2.0f
741*e5436536SAndroid Build Coastguard Worker  * \param exp_e exponent of the exponent to 2.0f
742*e5436536SAndroid Build Coastguard Worker  * \param result_e pointer to a INT where the exponent of the result will be
743*e5436536SAndroid Build Coastguard Worker  * stored into
744*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result
745*e5436536SAndroid Build Coastguard Worker  */
746*e5436536SAndroid Build Coastguard Worker FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e,
747*e5436536SAndroid Build Coastguard Worker                 INT *result_e);
748*e5436536SAndroid Build Coastguard Worker 
749*e5436536SAndroid Build Coastguard Worker /**
750*e5436536SAndroid Build Coastguard Worker  * \brief return x ^ (exp_m * 2^exp_e), where log2(x) = baseLd_m * 2^(baseLd_e).
751*e5436536SAndroid Build Coastguard Worker  * This saves the need to compute log2() of constant values (when x is a
752*e5436536SAndroid Build Coastguard Worker  * constant). This version does not return an exponent, which is
753*e5436536SAndroid Build Coastguard Worker  * implicitly 0.
754*e5436536SAndroid Build Coastguard Worker  * \param baseLd_m mantissa of log2() of x.
755*e5436536SAndroid Build Coastguard Worker  * \param baseLd_e exponent of log2() of x.
756*e5436536SAndroid Build Coastguard Worker  * \param exp_m mantissa of the exponent to 2.0f
757*e5436536SAndroid Build Coastguard Worker  * \param exp_e exponent of the exponent to 2.0f
758*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result
759*e5436536SAndroid Build Coastguard Worker  */
760*e5436536SAndroid Build Coastguard Worker FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e);
761*e5436536SAndroid Build Coastguard Worker 
762*e5436536SAndroid Build Coastguard Worker /**
763*e5436536SAndroid Build Coastguard Worker  * \brief return (base_m * 2^base_e) ^ (exp * 2^exp_e). Use fLdPow() instead
764*e5436536SAndroid Build Coastguard Worker  * whenever possible.
765*e5436536SAndroid Build Coastguard Worker  * \param base_m mantissa of the base.
766*e5436536SAndroid Build Coastguard Worker  * \param base_e exponent of the base.
767*e5436536SAndroid Build Coastguard Worker  * \param exp_m mantissa of power to be calculated of the base.
768*e5436536SAndroid Build Coastguard Worker  * \param exp_e exponent of power to be calculated of the base.
769*e5436536SAndroid Build Coastguard Worker  * \param result_e pointer to a INT where the exponent of the result will be
770*e5436536SAndroid Build Coastguard Worker  * stored into.
771*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result.
772*e5436536SAndroid Build Coastguard Worker  */
773*e5436536SAndroid Build Coastguard Worker FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
774*e5436536SAndroid Build Coastguard Worker               INT *result_e);
775*e5436536SAndroid Build Coastguard Worker 
776*e5436536SAndroid Build Coastguard Worker /**
777*e5436536SAndroid Build Coastguard Worker  * \brief return (base_m * 2^base_e) ^ N
778*e5436536SAndroid Build Coastguard Worker  * \param base_m mantissa of the base. Must not be negative.
779*e5436536SAndroid Build Coastguard Worker  * \param base_e exponent of the base
780*e5436536SAndroid Build Coastguard Worker  * \param N power to be calculated of the base
781*e5436536SAndroid Build Coastguard Worker  * \param result_e pointer to a INT where the exponent of the result will be
782*e5436536SAndroid Build Coastguard Worker  * stored into
783*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result
784*e5436536SAndroid Build Coastguard Worker  */
785*e5436536SAndroid Build Coastguard Worker FIXP_DBL fPowInt(FIXP_DBL base_m, INT base_e, INT N, INT *result_e);
786*e5436536SAndroid Build Coastguard Worker #endif /* #ifndef FUNCTION_fPow */
787*e5436536SAndroid Build Coastguard Worker 
788*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fLog2
789*e5436536SAndroid Build Coastguard Worker /**
790*e5436536SAndroid Build Coastguard Worker  * \brief Calculate log(argument)/log(2) (logarithm with base 2). deprecated.
791*e5436536SAndroid Build Coastguard Worker  * Use fLog2() instead.
792*e5436536SAndroid Build Coastguard Worker  * \param arg mantissa of the argument
793*e5436536SAndroid Build Coastguard Worker  * \param arg_e exponent of the argument
794*e5436536SAndroid Build Coastguard Worker  * \param result_e pointer to an INT to store the exponent of the result
795*e5436536SAndroid Build Coastguard Worker  * \return the mantissa of the result.
796*e5436536SAndroid Build Coastguard Worker  * \param
797*e5436536SAndroid Build Coastguard Worker  */
798*e5436536SAndroid Build Coastguard Worker FIXP_DBL CalcLog2(FIXP_DBL arg, INT arg_e, INT *result_e);
799*e5436536SAndroid Build Coastguard Worker 
800*e5436536SAndroid Build Coastguard Worker /**
801*e5436536SAndroid Build Coastguard Worker  * \brief calculate logarithm of base 2 of x_m * 2^(x_e)
802*e5436536SAndroid Build Coastguard Worker  * \param x_m mantissa of the input value.
803*e5436536SAndroid Build Coastguard Worker  * \param x_e exponent of the input value.
804*e5436536SAndroid Build Coastguard Worker  * \param pointer to an INT where the exponent of the result is returned into.
805*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result.
806*e5436536SAndroid Build Coastguard Worker  */
fLog2(FIXP_DBL x_m,INT x_e,INT * result_e)807*e5436536SAndroid Build Coastguard Worker FDK_INLINE FIXP_DBL fLog2(FIXP_DBL x_m, INT x_e, INT *result_e) {
808*e5436536SAndroid Build Coastguard Worker   FIXP_DBL result_m;
809*e5436536SAndroid Build Coastguard Worker 
810*e5436536SAndroid Build Coastguard Worker   /* Short cut for zero and negative numbers. */
811*e5436536SAndroid Build Coastguard Worker   if (x_m <= FL2FXCONST_DBL(0.0f)) {
812*e5436536SAndroid Build Coastguard Worker     *result_e = DFRACT_BITS - 1;
813*e5436536SAndroid Build Coastguard Worker     return FL2FXCONST_DBL(-1.0f);
814*e5436536SAndroid Build Coastguard Worker   }
815*e5436536SAndroid Build Coastguard Worker 
816*e5436536SAndroid Build Coastguard Worker   /* Calculate log2() */
817*e5436536SAndroid Build Coastguard Worker   {
818*e5436536SAndroid Build Coastguard Worker     FIXP_DBL x2_m;
819*e5436536SAndroid Build Coastguard Worker 
820*e5436536SAndroid Build Coastguard Worker     /* Move input value x_m * 2^x_e toward 1.0, where the taylor approximation
821*e5436536SAndroid Build Coastguard Worker        of the function log(1-x) centered at 0 is most accurate. */
822*e5436536SAndroid Build Coastguard Worker     {
823*e5436536SAndroid Build Coastguard Worker       INT b_norm;
824*e5436536SAndroid Build Coastguard Worker 
825*e5436536SAndroid Build Coastguard Worker       b_norm = fNormz(x_m) - 1;
826*e5436536SAndroid Build Coastguard Worker       x2_m = x_m << b_norm;
827*e5436536SAndroid Build Coastguard Worker       x_e = x_e - b_norm;
828*e5436536SAndroid Build Coastguard Worker     }
829*e5436536SAndroid Build Coastguard Worker 
830*e5436536SAndroid Build Coastguard Worker     /* map x from log(x) domain to log(1-x) domain. */
831*e5436536SAndroid Build Coastguard Worker     x2_m = -(x2_m + FL2FXCONST_DBL(-1.0));
832*e5436536SAndroid Build Coastguard Worker 
833*e5436536SAndroid Build Coastguard Worker     /* Taylor polynomial approximation of ln(1-x) */
834*e5436536SAndroid Build Coastguard Worker     {
835*e5436536SAndroid Build Coastguard Worker       FIXP_DBL px2_m;
836*e5436536SAndroid Build Coastguard Worker       result_m = FL2FXCONST_DBL(0.0);
837*e5436536SAndroid Build Coastguard Worker       px2_m = x2_m;
838*e5436536SAndroid Build Coastguard Worker       for (int i = 0; i < LD_PRECISION; i++) {
839*e5436536SAndroid Build Coastguard Worker         result_m = fMultAddDiv2(result_m, ldCoeff[i], px2_m);
840*e5436536SAndroid Build Coastguard Worker         px2_m = fMult(px2_m, x2_m);
841*e5436536SAndroid Build Coastguard Worker       }
842*e5436536SAndroid Build Coastguard Worker     }
843*e5436536SAndroid Build Coastguard Worker     /* Multiply result with 1/ln(2) = 1.0 + 0.442695040888 (get log2(x) from
844*e5436536SAndroid Build Coastguard Worker      * ln(x) result). */
845*e5436536SAndroid Build Coastguard Worker     result_m =
846*e5436536SAndroid Build Coastguard Worker         fMultAddDiv2(result_m, result_m,
847*e5436536SAndroid Build Coastguard Worker                      FL2FXCONST_DBL(2.0 * 0.4426950408889634073599246810019));
848*e5436536SAndroid Build Coastguard Worker 
849*e5436536SAndroid Build Coastguard Worker     /* Add exponent part. log2(x_m * 2^x_e) = log2(x_m) + x_e */
850*e5436536SAndroid Build Coastguard Worker     if (x_e != 0) {
851*e5436536SAndroid Build Coastguard Worker       int enorm;
852*e5436536SAndroid Build Coastguard Worker 
853*e5436536SAndroid Build Coastguard Worker       enorm = DFRACT_BITS - fNorm((FIXP_DBL)x_e);
854*e5436536SAndroid Build Coastguard Worker       /* The -1 in the right shift of result_m compensates the fMultDiv2() above
855*e5436536SAndroid Build Coastguard Worker        * in the taylor polynomial evaluation loop.*/
856*e5436536SAndroid Build Coastguard Worker       result_m = (result_m >> (enorm - 1)) +
857*e5436536SAndroid Build Coastguard Worker                  ((FIXP_DBL)x_e << (DFRACT_BITS - 1 - enorm));
858*e5436536SAndroid Build Coastguard Worker 
859*e5436536SAndroid Build Coastguard Worker       *result_e = enorm;
860*e5436536SAndroid Build Coastguard Worker     } else {
861*e5436536SAndroid Build Coastguard Worker       /* 1 compensates the fMultDiv2() above in the taylor polynomial evaluation
862*e5436536SAndroid Build Coastguard Worker        * loop.*/
863*e5436536SAndroid Build Coastguard Worker       *result_e = 1;
864*e5436536SAndroid Build Coastguard Worker     }
865*e5436536SAndroid Build Coastguard Worker   }
866*e5436536SAndroid Build Coastguard Worker 
867*e5436536SAndroid Build Coastguard Worker   return result_m;
868*e5436536SAndroid Build Coastguard Worker }
869*e5436536SAndroid Build Coastguard Worker 
870*e5436536SAndroid Build Coastguard Worker /**
871*e5436536SAndroid Build Coastguard Worker  * \brief calculate logarithm of base 2 of x_m * 2^(x_e)
872*e5436536SAndroid Build Coastguard Worker  * \param x_m mantissa of the input value.
873*e5436536SAndroid Build Coastguard Worker  * \param x_e exponent of the input value.
874*e5436536SAndroid Build Coastguard Worker  * \return mantissa of the result with implicit exponent of LD_DATA_SHIFT.
875*e5436536SAndroid Build Coastguard Worker  */
fLog2(FIXP_DBL x_m,INT x_e)876*e5436536SAndroid Build Coastguard Worker FDK_INLINE FIXP_DBL fLog2(FIXP_DBL x_m, INT x_e) {
877*e5436536SAndroid Build Coastguard Worker   if (x_m <= FL2FXCONST_DBL(0.0f)) {
878*e5436536SAndroid Build Coastguard Worker     x_m = FL2FXCONST_DBL(-1.0f);
879*e5436536SAndroid Build Coastguard Worker   } else {
880*e5436536SAndroid Build Coastguard Worker     INT result_e;
881*e5436536SAndroid Build Coastguard Worker     x_m = fLog2(x_m, x_e, &result_e);
882*e5436536SAndroid Build Coastguard Worker     x_m = scaleValue(x_m, result_e - LD_DATA_SHIFT);
883*e5436536SAndroid Build Coastguard Worker   }
884*e5436536SAndroid Build Coastguard Worker   return x_m;
885*e5436536SAndroid Build Coastguard Worker }
886*e5436536SAndroid Build Coastguard Worker 
887*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_fLog2 */
888*e5436536SAndroid Build Coastguard Worker 
889*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fAddSaturate
890*e5436536SAndroid Build Coastguard Worker /**
891*e5436536SAndroid Build Coastguard Worker  * \brief Add with saturation of the result.
892*e5436536SAndroid Build Coastguard Worker  * \param a first summand
893*e5436536SAndroid Build Coastguard Worker  * \param b second summand
894*e5436536SAndroid Build Coastguard Worker  * \return saturated sum of a and b.
895*e5436536SAndroid Build Coastguard Worker  */
fAddSaturate(const FIXP_SGL a,const FIXP_SGL b)896*e5436536SAndroid Build Coastguard Worker inline FIXP_SGL fAddSaturate(const FIXP_SGL a, const FIXP_SGL b) {
897*e5436536SAndroid Build Coastguard Worker   LONG sum;
898*e5436536SAndroid Build Coastguard Worker 
899*e5436536SAndroid Build Coastguard Worker   sum = (LONG)(SHORT)a + (LONG)(SHORT)b;
900*e5436536SAndroid Build Coastguard Worker   sum = fMax(fMin((INT)sum, (INT)MAXVAL_SGL), (INT)MINVAL_SGL);
901*e5436536SAndroid Build Coastguard Worker   return (FIXP_SGL)(SHORT)sum;
902*e5436536SAndroid Build Coastguard Worker }
903*e5436536SAndroid Build Coastguard Worker 
904*e5436536SAndroid Build Coastguard Worker /**
905*e5436536SAndroid Build Coastguard Worker  * \brief Add with saturation of the result.
906*e5436536SAndroid Build Coastguard Worker  * \param a first summand
907*e5436536SAndroid Build Coastguard Worker  * \param b second summand
908*e5436536SAndroid Build Coastguard Worker  * \return saturated sum of a and b.
909*e5436536SAndroid Build Coastguard Worker  */
fAddSaturate(const FIXP_DBL a,const FIXP_DBL b)910*e5436536SAndroid Build Coastguard Worker inline FIXP_DBL fAddSaturate(const FIXP_DBL a, const FIXP_DBL b) {
911*e5436536SAndroid Build Coastguard Worker   LONG sum;
912*e5436536SAndroid Build Coastguard Worker 
913*e5436536SAndroid Build Coastguard Worker   sum = (LONG)(a >> 1) + (LONG)(b >> 1);
914*e5436536SAndroid Build Coastguard Worker   sum = fMax(fMin((INT)sum, (INT)(MAXVAL_DBL >> 1)), (INT)(MINVAL_DBL >> 1));
915*e5436536SAndroid Build Coastguard Worker   return (FIXP_DBL)(LONG)(sum << 1);
916*e5436536SAndroid Build Coastguard Worker }
917*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_fAddSaturate */
918*e5436536SAndroid Build Coastguard Worker 
919*e5436536SAndroid Build Coastguard Worker INT fixp_floorToInt(FIXP_DBL f_inp, INT sf);
920*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_floor(FIXP_DBL f_inp, INT sf);
921*e5436536SAndroid Build Coastguard Worker 
922*e5436536SAndroid Build Coastguard Worker INT fixp_ceilToInt(FIXP_DBL f_inp, INT sf);
923*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_ceil(FIXP_DBL f_inp, INT sf);
924*e5436536SAndroid Build Coastguard Worker 
925*e5436536SAndroid Build Coastguard Worker INT fixp_truncateToInt(FIXP_DBL f_inp, INT sf);
926*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_truncate(FIXP_DBL f_inp, INT sf);
927*e5436536SAndroid Build Coastguard Worker 
928*e5436536SAndroid Build Coastguard Worker INT fixp_roundToInt(FIXP_DBL f_inp, INT sf);
929*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_round(FIXP_DBL f_inp, INT sf);
930*e5436536SAndroid Build Coastguard Worker 
931*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
932*e5436536SAndroid Build Coastguard Worker 
933*e5436536SAndroid Build Coastguard Worker  array for 1/n, n=1..80
934*e5436536SAndroid Build Coastguard Worker 
935*e5436536SAndroid Build Coastguard Worker ****************************************************************************/
936*e5436536SAndroid Build Coastguard Worker 
937*e5436536SAndroid Build Coastguard Worker extern const FIXP_DBL invCount[80];
938*e5436536SAndroid Build Coastguard Worker 
939*e5436536SAndroid Build Coastguard Worker LNK_SECTION_INITCODE
InitInvInt(void)940*e5436536SAndroid Build Coastguard Worker inline void InitInvInt(void) {}
941*e5436536SAndroid Build Coastguard Worker 
942*e5436536SAndroid Build Coastguard Worker /**
943*e5436536SAndroid Build Coastguard Worker  * \brief Calculate the value of 1/i where i is a integer value. It supports
944*e5436536SAndroid Build Coastguard Worker  *        input values from 1 upto (80-1).
945*e5436536SAndroid Build Coastguard Worker  * \param intValue Integer input value.
946*e5436536SAndroid Build Coastguard Worker  * \param FIXP_DBL representation of 1/intValue
947*e5436536SAndroid Build Coastguard Worker  */
GetInvInt(int intValue)948*e5436536SAndroid Build Coastguard Worker inline FIXP_DBL GetInvInt(int intValue) {
949*e5436536SAndroid Build Coastguard Worker   return invCount[fMin(fMax(intValue, 0), 80 - 1)];
950*e5436536SAndroid Build Coastguard Worker }
951*e5436536SAndroid Build Coastguard Worker 
952*e5436536SAndroid Build Coastguard Worker #endif /* FIXPOINT_MATH_H */
953