xref: /aosp_15_r20/external/aac/libFDK/src/fixpoint_math.cpp (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 - 2020 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 #include "fixpoint_math.h"
104*e5436536SAndroid Build Coastguard Worker 
105*e5436536SAndroid Build Coastguard Worker /*
106*e5436536SAndroid Build Coastguard Worker  * Hardware specific implementations
107*e5436536SAndroid Build Coastguard Worker  */
108*e5436536SAndroid Build Coastguard Worker 
109*e5436536SAndroid Build Coastguard Worker /*
110*e5436536SAndroid Build Coastguard Worker  * Fallback implementations
111*e5436536SAndroid Build Coastguard Worker  */
112*e5436536SAndroid Build Coastguard Worker 
113*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
114*e5436536SAndroid Build Coastguard Worker   functionname: LdDataVector
115*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
116*e5436536SAndroid Build Coastguard Worker LNK_SECTION_CODE_L1
LdDataVector(FIXP_DBL * srcVector,FIXP_DBL * destVector,INT n)117*e5436536SAndroid Build Coastguard Worker void LdDataVector(FIXP_DBL *srcVector, FIXP_DBL *destVector, INT n) {
118*e5436536SAndroid Build Coastguard Worker   INT i;
119*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < n; i++) {
120*e5436536SAndroid Build Coastguard Worker     destVector[i] = fLog2(srcVector[i], 0);
121*e5436536SAndroid Build Coastguard Worker   }
122*e5436536SAndroid Build Coastguard Worker }
123*e5436536SAndroid Build Coastguard Worker 
124*e5436536SAndroid Build Coastguard Worker #define MAX_POW2_PRECISION 8
125*e5436536SAndroid Build Coastguard Worker #ifndef SINETABLE_16BIT
126*e5436536SAndroid Build Coastguard Worker #define POW2_PRECISION MAX_POW2_PRECISION
127*e5436536SAndroid Build Coastguard Worker #else
128*e5436536SAndroid Build Coastguard Worker #define POW2_PRECISION 5
129*e5436536SAndroid Build Coastguard Worker #endif
130*e5436536SAndroid Build Coastguard Worker 
131*e5436536SAndroid Build Coastguard Worker /*
132*e5436536SAndroid Build Coastguard Worker   Taylor series coefficients of the function x^2. The first coefficient is
133*e5436536SAndroid Build Coastguard Worker   ommited (equal to 1.0).
134*e5436536SAndroid Build Coastguard Worker 
135*e5436536SAndroid Build Coastguard Worker   pow2Coeff[i-1] = (1/i!) d^i(2^x)/dx^i, i=1..MAX_POW2_PRECISION
136*e5436536SAndroid Build Coastguard Worker   To evaluate the taylor series around x = 0, the coefficients are: 1/!i *
137*e5436536SAndroid Build Coastguard Worker   ln(2)^i
138*e5436536SAndroid Build Coastguard Worker  */
139*e5436536SAndroid Build Coastguard Worker #ifndef POW2COEFF_16BIT
140*e5436536SAndroid Build Coastguard Worker RAM_ALIGN
141*e5436536SAndroid Build Coastguard Worker LNK_SECTION_CONSTDATA_L1
142*e5436536SAndroid Build Coastguard Worker static const FIXP_DBL pow2Coeff[MAX_POW2_PRECISION] = {
143*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(0.693147180559945309417232121458177),   /* ln(2)^1 /1! */
144*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(0.240226506959100712333551263163332),   /* ln(2)^2 /2! */
145*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(0.0555041086648215799531422637686218),  /* ln(2)^3 /3! */
146*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(0.00961812910762847716197907157365887), /* ln(2)^4 /4! */
147*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(0.00133335581464284434234122219879962), /* ln(2)^5 /5! */
148*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(1.54035303933816099544370973327423e-4), /* ln(2)^6 /6! */
149*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(1.52527338040598402800254390120096e-5), /* ln(2)^7 /7! */
150*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(1.32154867901443094884037582282884e-6)  /* ln(2)^8 /8! */
151*e5436536SAndroid Build Coastguard Worker };
152*e5436536SAndroid Build Coastguard Worker #else
153*e5436536SAndroid Build Coastguard Worker RAM_ALIGN
154*e5436536SAndroid Build Coastguard Worker LNK_SECTION_CONSTDATA_L1
155*e5436536SAndroid Build Coastguard Worker static const FIXP_SGL pow2Coeff[MAX_POW2_PRECISION] = {
156*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(0.693147180559945309417232121458177),   /* ln(2)^1 /1! */
157*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(0.240226506959100712333551263163332),   /* ln(2)^2 /2! */
158*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(0.0555041086648215799531422637686218),  /* ln(2)^3 /3! */
159*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(0.00961812910762847716197907157365887), /* ln(2)^4 /4! */
160*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(0.00133335581464284434234122219879962), /* ln(2)^5 /5! */
161*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(1.54035303933816099544370973327423e-4), /* ln(2)^6 /6! */
162*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(1.52527338040598402800254390120096e-5), /* ln(2)^7 /7! */
163*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_SGL(1.32154867901443094884037582282884e-6)  /* ln(2)^8 /8! */
164*e5436536SAndroid Build Coastguard Worker };
165*e5436536SAndroid Build Coastguard Worker #endif
166*e5436536SAndroid Build Coastguard Worker 
167*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
168*e5436536SAndroid Build Coastguard Worker 
169*e5436536SAndroid Build Coastguard Worker   functionname: CalcInvLdData
170*e5436536SAndroid Build Coastguard Worker   description:  Delivers the inverse of function CalcLdData().
171*e5436536SAndroid Build Coastguard Worker                 Delivers 2^(op*LD_DATA_SCALING)
172*e5436536SAndroid Build Coastguard Worker   input:        Input op is assumed to be fractional -1.0 < op < 1.0
173*e5436536SAndroid Build Coastguard Worker   output:       For op == 0, the result is MAXVAL_DBL (almost 1.0).
174*e5436536SAndroid Build Coastguard Worker                 For negative input values the output should be treated as a
175*e5436536SAndroid Build Coastguard Worker positive fractional value. For positive input values the output should be
176*e5436536SAndroid Build Coastguard Worker treated as a positive integer value. This function does not output negative
177*e5436536SAndroid Build Coastguard Worker values.
178*e5436536SAndroid Build Coastguard Worker 
179*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
180*e5436536SAndroid Build Coastguard Worker /* Date: 06-JULY-2012 Arthur Tritthart, IIS Fraunhofer Erlangen */
181*e5436536SAndroid Build Coastguard Worker /* Version with 3 table lookup and 1 linear interpolations      */
182*e5436536SAndroid Build Coastguard Worker /* Algorithm: compute power of 2, argument x is in Q7.25 format */
183*e5436536SAndroid Build Coastguard Worker /*  result = 2^(x/64)                                           */
184*e5436536SAndroid Build Coastguard Worker /*  We split exponent (x/64) into 5 components:                 */
185*e5436536SAndroid Build Coastguard Worker /*  integer part:      represented by b31..b25  (exp)           */
186*e5436536SAndroid Build Coastguard Worker /*  fractional part 1: represented by b24..b20  (lookup1)       */
187*e5436536SAndroid Build Coastguard Worker /*  fractional part 2: represented by b19..b15  (lookup2)       */
188*e5436536SAndroid Build Coastguard Worker /*  fractional part 3: represented by b14..b10  (lookup3)       */
189*e5436536SAndroid Build Coastguard Worker /*  fractional part 4: represented by b09..b00  (frac)          */
190*e5436536SAndroid Build Coastguard Worker /*  => result = (lookup1*lookup2*(lookup3+C1*frac)<<3)>>exp     */
191*e5436536SAndroid Build Coastguard Worker /* Due to the fact, that all lookup values contain a factor 0.5 */
192*e5436536SAndroid Build Coastguard Worker /* the result has to be shifted by 3 to the right also.         */
193*e5436536SAndroid Build Coastguard Worker /* Table exp2_tab_long contains the log2 for 0 to 1.0 in steps  */
194*e5436536SAndroid Build Coastguard Worker /* of 1/32, table exp2w_tab_long the log2 for 0 to 1/32 in steps*/
195*e5436536SAndroid Build Coastguard Worker /* of 1/1024, table exp2x_tab_long the log2 for 0 to 1/1024 in  */
196*e5436536SAndroid Build Coastguard Worker /* steps of 1/32768. Since the 2-logarithm of very very small   */
197*e5436536SAndroid Build Coastguard Worker /* negative value is rather linear, we can use interpolation.   */
198*e5436536SAndroid Build Coastguard Worker /* Limitations:                                                 */
199*e5436536SAndroid Build Coastguard Worker /* For x <= 0, the result is fractional positive                */
200*e5436536SAndroid Build Coastguard Worker /* For x > 0, the result is integer in range 1...7FFF.FFFF      */
201*e5436536SAndroid Build Coastguard Worker /* For x < -31/64, we have to clear the result                  */
202*e5436536SAndroid Build Coastguard Worker /* For x = 0, the result is ~1.0 (0x7FFF.FFFF)                  */
203*e5436536SAndroid Build Coastguard Worker /* For x >= 31/64, the result is 0x7FFF.FFFF                    */
204*e5436536SAndroid Build Coastguard Worker 
205*e5436536SAndroid Build Coastguard Worker /* This table is used for lookup 2^x with   */
206*e5436536SAndroid Build Coastguard Worker /* x in range [0...1.0[ in steps of 1/32 */
207*e5436536SAndroid Build Coastguard Worker LNK_SECTION_DATA_L1
208*e5436536SAndroid Build Coastguard Worker const UINT exp2_tab_long[32] = {
209*e5436536SAndroid Build Coastguard Worker     0x40000000, 0x4166C34C, 0x42D561B4, 0x444C0740, 0x45CAE0F2, 0x47521CC6,
210*e5436536SAndroid Build Coastguard Worker     0x48E1E9BA, 0x4A7A77D4, 0x4C1BF829, 0x4DC69CDD, 0x4F7A9930, 0x51382182,
211*e5436536SAndroid Build Coastguard Worker     0x52FF6B55, 0x54D0AD5A, 0x56AC1F75, 0x5891FAC1, 0x5A82799A, 0x5C7DD7A4,
212*e5436536SAndroid Build Coastguard Worker     0x5E8451D0, 0x60962665, 0x62B39509, 0x64DCDEC3, 0x6712460B, 0x69540EC9,
213*e5436536SAndroid Build Coastguard Worker     0x6BA27E65, 0x6DFDDBCC, 0x70666F76, 0x72DC8374, 0x75606374, 0x77F25CCE,
214*e5436536SAndroid Build Coastguard Worker     0x7A92BE8B, 0x7D41D96E
215*e5436536SAndroid Build Coastguard Worker     // 0x80000000
216*e5436536SAndroid Build Coastguard Worker };
217*e5436536SAndroid Build Coastguard Worker 
218*e5436536SAndroid Build Coastguard Worker /* This table is used for lookup 2^x with   */
219*e5436536SAndroid Build Coastguard Worker /* x in range [0...1/32[ in steps of 1/1024 */
220*e5436536SAndroid Build Coastguard Worker LNK_SECTION_DATA_L1
221*e5436536SAndroid Build Coastguard Worker const UINT exp2w_tab_long[32] = {
222*e5436536SAndroid Build Coastguard Worker     0x40000000, 0x400B1818, 0x4016321B, 0x40214E0C, 0x402C6BE9, 0x40378BB4,
223*e5436536SAndroid Build Coastguard Worker     0x4042AD6D, 0x404DD113, 0x4058F6A8, 0x40641E2B, 0x406F479E, 0x407A7300,
224*e5436536SAndroid Build Coastguard Worker     0x4085A051, 0x4090CF92, 0x409C00C4, 0x40A733E6, 0x40B268FA, 0x40BD9FFF,
225*e5436536SAndroid Build Coastguard Worker     0x40C8D8F5, 0x40D413DD, 0x40DF50B8, 0x40EA8F86, 0x40F5D046, 0x410112FA,
226*e5436536SAndroid Build Coastguard Worker     0x410C57A2, 0x41179E3D, 0x4122E6CD, 0x412E3152, 0x41397DCC, 0x4144CC3B,
227*e5436536SAndroid Build Coastguard Worker     0x41501CA0, 0x415B6EFB,
228*e5436536SAndroid Build Coastguard Worker     // 0x4166C34C,
229*e5436536SAndroid Build Coastguard Worker };
230*e5436536SAndroid Build Coastguard Worker /* This table is used for lookup 2^x with   */
231*e5436536SAndroid Build Coastguard Worker /* x in range [0...1/1024[ in steps of 1/32768 */
232*e5436536SAndroid Build Coastguard Worker LNK_SECTION_DATA_L1
233*e5436536SAndroid Build Coastguard Worker const UINT exp2x_tab_long[32] = {
234*e5436536SAndroid Build Coastguard Worker     0x40000000, 0x400058B9, 0x4000B173, 0x40010A2D, 0x400162E8, 0x4001BBA3,
235*e5436536SAndroid Build Coastguard Worker     0x4002145F, 0x40026D1B, 0x4002C5D8, 0x40031E95, 0x40037752, 0x4003D011,
236*e5436536SAndroid Build Coastguard Worker     0x400428CF, 0x4004818E, 0x4004DA4E, 0x4005330E, 0x40058BCE, 0x4005E48F,
237*e5436536SAndroid Build Coastguard Worker     0x40063D51, 0x40069613, 0x4006EED5, 0x40074798, 0x4007A05B, 0x4007F91F,
238*e5436536SAndroid Build Coastguard Worker     0x400851E4, 0x4008AAA8, 0x4009036E, 0x40095C33, 0x4009B4FA, 0x400A0DC0,
239*e5436536SAndroid Build Coastguard Worker     0x400A6688, 0x400ABF4F,
240*e5436536SAndroid Build Coastguard Worker     // 0x400B1818
241*e5436536SAndroid Build Coastguard Worker };
242*e5436536SAndroid Build Coastguard Worker 
243*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
244*e5436536SAndroid Build Coastguard Worker     functionname: InitLdInt and CalcLdInt
245*e5436536SAndroid Build Coastguard Worker     description:  Create and access table with integer LdData (0 to
246*e5436536SAndroid Build Coastguard Worker LD_INT_TAB_LEN)
247*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
248*e5436536SAndroid Build Coastguard Worker #ifndef LD_INT_TAB_LEN
249*e5436536SAndroid Build Coastguard Worker #define LD_INT_TAB_LEN \
250*e5436536SAndroid Build Coastguard Worker   193 /* Default tab length. Lower value should be set in fix.h */
251*e5436536SAndroid Build Coastguard Worker #endif
252*e5436536SAndroid Build Coastguard Worker 
253*e5436536SAndroid Build Coastguard Worker #if (LD_INT_TAB_LEN <= 120)
254*e5436536SAndroid Build Coastguard Worker LNK_SECTION_CONSTDATA_L1
255*e5436536SAndroid Build Coastguard Worker static const FIXP_DBL ldIntCoeff[] = {
256*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x80000001, (FIXP_DBL)0x00000000, (FIXP_DBL)0x02000000,
257*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x032b8034, (FIXP_DBL)0x04000000, (FIXP_DBL)0x04a4d3c2,
258*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x052b8034, (FIXP_DBL)0x059d5da0, (FIXP_DBL)0x06000000,
259*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x06570069, (FIXP_DBL)0x06a4d3c2, (FIXP_DBL)0x06eb3a9f,
260*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x072b8034, (FIXP_DBL)0x0766a009, (FIXP_DBL)0x079d5da0,
261*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x07d053f7, (FIXP_DBL)0x08000000, (FIXP_DBL)0x082cc7ee,
262*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x08570069, (FIXP_DBL)0x087ef05b, (FIXP_DBL)0x08a4d3c2,
263*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x08c8ddd4, (FIXP_DBL)0x08eb3a9f, (FIXP_DBL)0x090c1050,
264*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x092b8034, (FIXP_DBL)0x0949a785, (FIXP_DBL)0x0966a009,
265*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0982809d, (FIXP_DBL)0x099d5da0, (FIXP_DBL)0x09b74949,
266*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x09d053f7, (FIXP_DBL)0x09e88c6b, (FIXP_DBL)0x0a000000,
267*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0a16bad3, (FIXP_DBL)0x0a2cc7ee, (FIXP_DBL)0x0a423162,
268*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0a570069, (FIXP_DBL)0x0a6b3d79, (FIXP_DBL)0x0a7ef05b,
269*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0a92203d, (FIXP_DBL)0x0aa4d3c2, (FIXP_DBL)0x0ab7110e,
270*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0ac8ddd4, (FIXP_DBL)0x0ada3f60, (FIXP_DBL)0x0aeb3a9f,
271*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0afbd42b, (FIXP_DBL)0x0b0c1050, (FIXP_DBL)0x0b1bf312,
272*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0b2b8034, (FIXP_DBL)0x0b3abb40, (FIXP_DBL)0x0b49a785,
273*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0b584822, (FIXP_DBL)0x0b66a009, (FIXP_DBL)0x0b74b1fd,
274*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0b82809d, (FIXP_DBL)0x0b900e61, (FIXP_DBL)0x0b9d5da0,
275*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0baa708f, (FIXP_DBL)0x0bb74949, (FIXP_DBL)0x0bc3e9ca,
276*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0bd053f7, (FIXP_DBL)0x0bdc899b, (FIXP_DBL)0x0be88c6b,
277*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0bf45e09, (FIXP_DBL)0x0c000000, (FIXP_DBL)0x0c0b73cb,
278*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0c16bad3, (FIXP_DBL)0x0c21d671, (FIXP_DBL)0x0c2cc7ee,
279*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0c379085, (FIXP_DBL)0x0c423162, (FIXP_DBL)0x0c4caba8,
280*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0c570069, (FIXP_DBL)0x0c6130af, (FIXP_DBL)0x0c6b3d79,
281*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0c7527b9, (FIXP_DBL)0x0c7ef05b, (FIXP_DBL)0x0c88983f,
282*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0c92203d, (FIXP_DBL)0x0c9b8926, (FIXP_DBL)0x0ca4d3c2,
283*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0cae00d2, (FIXP_DBL)0x0cb7110e, (FIXP_DBL)0x0cc0052b,
284*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0cc8ddd4, (FIXP_DBL)0x0cd19bb0, (FIXP_DBL)0x0cda3f60,
285*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0ce2c97d, (FIXP_DBL)0x0ceb3a9f, (FIXP_DBL)0x0cf39355,
286*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0cfbd42b, (FIXP_DBL)0x0d03fda9, (FIXP_DBL)0x0d0c1050,
287*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d140ca0, (FIXP_DBL)0x0d1bf312, (FIXP_DBL)0x0d23c41d,
288*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d2b8034, (FIXP_DBL)0x0d3327c7, (FIXP_DBL)0x0d3abb40,
289*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d423b08, (FIXP_DBL)0x0d49a785, (FIXP_DBL)0x0d510118,
290*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d584822, (FIXP_DBL)0x0d5f7cff, (FIXP_DBL)0x0d66a009,
291*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d6db197, (FIXP_DBL)0x0d74b1fd, (FIXP_DBL)0x0d7ba190,
292*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d82809d, (FIXP_DBL)0x0d894f75, (FIXP_DBL)0x0d900e61,
293*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d96bdad, (FIXP_DBL)0x0d9d5da0, (FIXP_DBL)0x0da3ee7f,
294*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0daa708f, (FIXP_DBL)0x0db0e412, (FIXP_DBL)0x0db74949,
295*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0dbda072, (FIXP_DBL)0x0dc3e9ca, (FIXP_DBL)0x0dca258e};
296*e5436536SAndroid Build Coastguard Worker 
297*e5436536SAndroid Build Coastguard Worker #elif (LD_INT_TAB_LEN <= 193)
298*e5436536SAndroid Build Coastguard Worker LNK_SECTION_CONSTDATA_L1
299*e5436536SAndroid Build Coastguard Worker static const FIXP_DBL ldIntCoeff[] = {
300*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x80000001, (FIXP_DBL)0x00000000, (FIXP_DBL)0x02000000,
301*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x032b8034, (FIXP_DBL)0x04000000, (FIXP_DBL)0x04a4d3c2,
302*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x052b8034, (FIXP_DBL)0x059d5da0, (FIXP_DBL)0x06000000,
303*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x06570069, (FIXP_DBL)0x06a4d3c2, (FIXP_DBL)0x06eb3a9f,
304*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x072b8034, (FIXP_DBL)0x0766a009, (FIXP_DBL)0x079d5da0,
305*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x07d053f7, (FIXP_DBL)0x08000000, (FIXP_DBL)0x082cc7ee,
306*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x08570069, (FIXP_DBL)0x087ef05b, (FIXP_DBL)0x08a4d3c2,
307*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x08c8ddd4, (FIXP_DBL)0x08eb3a9f, (FIXP_DBL)0x090c1050,
308*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x092b8034, (FIXP_DBL)0x0949a785, (FIXP_DBL)0x0966a009,
309*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0982809d, (FIXP_DBL)0x099d5da0, (FIXP_DBL)0x09b74949,
310*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x09d053f7, (FIXP_DBL)0x09e88c6b, (FIXP_DBL)0x0a000000,
311*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0a16bad3, (FIXP_DBL)0x0a2cc7ee, (FIXP_DBL)0x0a423162,
312*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0a570069, (FIXP_DBL)0x0a6b3d79, (FIXP_DBL)0x0a7ef05b,
313*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0a92203d, (FIXP_DBL)0x0aa4d3c2, (FIXP_DBL)0x0ab7110e,
314*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0ac8ddd4, (FIXP_DBL)0x0ada3f60, (FIXP_DBL)0x0aeb3a9f,
315*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0afbd42b, (FIXP_DBL)0x0b0c1050, (FIXP_DBL)0x0b1bf312,
316*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0b2b8034, (FIXP_DBL)0x0b3abb40, (FIXP_DBL)0x0b49a785,
317*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0b584822, (FIXP_DBL)0x0b66a009, (FIXP_DBL)0x0b74b1fd,
318*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0b82809d, (FIXP_DBL)0x0b900e61, (FIXP_DBL)0x0b9d5da0,
319*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0baa708f, (FIXP_DBL)0x0bb74949, (FIXP_DBL)0x0bc3e9ca,
320*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0bd053f7, (FIXP_DBL)0x0bdc899b, (FIXP_DBL)0x0be88c6b,
321*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0bf45e09, (FIXP_DBL)0x0c000000, (FIXP_DBL)0x0c0b73cb,
322*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0c16bad3, (FIXP_DBL)0x0c21d671, (FIXP_DBL)0x0c2cc7ee,
323*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0c379085, (FIXP_DBL)0x0c423162, (FIXP_DBL)0x0c4caba8,
324*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0c570069, (FIXP_DBL)0x0c6130af, (FIXP_DBL)0x0c6b3d79,
325*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0c7527b9, (FIXP_DBL)0x0c7ef05b, (FIXP_DBL)0x0c88983f,
326*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0c92203d, (FIXP_DBL)0x0c9b8926, (FIXP_DBL)0x0ca4d3c2,
327*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0cae00d2, (FIXP_DBL)0x0cb7110e, (FIXP_DBL)0x0cc0052b,
328*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0cc8ddd4, (FIXP_DBL)0x0cd19bb0, (FIXP_DBL)0x0cda3f60,
329*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0ce2c97d, (FIXP_DBL)0x0ceb3a9f, (FIXP_DBL)0x0cf39355,
330*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0cfbd42b, (FIXP_DBL)0x0d03fda9, (FIXP_DBL)0x0d0c1050,
331*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d140ca0, (FIXP_DBL)0x0d1bf312, (FIXP_DBL)0x0d23c41d,
332*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d2b8034, (FIXP_DBL)0x0d3327c7, (FIXP_DBL)0x0d3abb40,
333*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d423b08, (FIXP_DBL)0x0d49a785, (FIXP_DBL)0x0d510118,
334*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d584822, (FIXP_DBL)0x0d5f7cff, (FIXP_DBL)0x0d66a009,
335*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d6db197, (FIXP_DBL)0x0d74b1fd, (FIXP_DBL)0x0d7ba190,
336*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d82809d, (FIXP_DBL)0x0d894f75, (FIXP_DBL)0x0d900e61,
337*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0d96bdad, (FIXP_DBL)0x0d9d5da0, (FIXP_DBL)0x0da3ee7f,
338*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0daa708f, (FIXP_DBL)0x0db0e412, (FIXP_DBL)0x0db74949,
339*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0dbda072, (FIXP_DBL)0x0dc3e9ca, (FIXP_DBL)0x0dca258e,
340*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0dd053f7, (FIXP_DBL)0x0dd6753e, (FIXP_DBL)0x0ddc899b,
341*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0de29143, (FIXP_DBL)0x0de88c6b, (FIXP_DBL)0x0dee7b47,
342*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0df45e09, (FIXP_DBL)0x0dfa34e1, (FIXP_DBL)0x0e000000,
343*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0e05bf94, (FIXP_DBL)0x0e0b73cb, (FIXP_DBL)0x0e111cd2,
344*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0e16bad3, (FIXP_DBL)0x0e1c4dfb, (FIXP_DBL)0x0e21d671,
345*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0e275460, (FIXP_DBL)0x0e2cc7ee, (FIXP_DBL)0x0e323143,
346*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0e379085, (FIXP_DBL)0x0e3ce5d8, (FIXP_DBL)0x0e423162,
347*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0e477346, (FIXP_DBL)0x0e4caba8, (FIXP_DBL)0x0e51daa8,
348*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0e570069, (FIXP_DBL)0x0e5c1d0b, (FIXP_DBL)0x0e6130af,
349*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0e663b74, (FIXP_DBL)0x0e6b3d79, (FIXP_DBL)0x0e7036db,
350*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0e7527b9, (FIXP_DBL)0x0e7a1030, (FIXP_DBL)0x0e7ef05b,
351*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0e83c857, (FIXP_DBL)0x0e88983f, (FIXP_DBL)0x0e8d602e,
352*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0e92203d, (FIXP_DBL)0x0e96d888, (FIXP_DBL)0x0e9b8926,
353*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0ea03232, (FIXP_DBL)0x0ea4d3c2, (FIXP_DBL)0x0ea96df0,
354*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0eae00d2, (FIXP_DBL)0x0eb28c7f, (FIXP_DBL)0x0eb7110e,
355*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0ebb8e96, (FIXP_DBL)0x0ec0052b, (FIXP_DBL)0x0ec474e4,
356*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0ec8ddd4, (FIXP_DBL)0x0ecd4012, (FIXP_DBL)0x0ed19bb0,
357*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0ed5f0c4, (FIXP_DBL)0x0eda3f60, (FIXP_DBL)0x0ede8797,
358*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0ee2c97d, (FIXP_DBL)0x0ee70525, (FIXP_DBL)0x0eeb3a9f,
359*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0eef69ff, (FIXP_DBL)0x0ef39355, (FIXP_DBL)0x0ef7b6b4,
360*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0efbd42b, (FIXP_DBL)0x0effebcd, (FIXP_DBL)0x0f03fda9,
361*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0f0809cf, (FIXP_DBL)0x0f0c1050, (FIXP_DBL)0x0f10113b,
362*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0f140ca0, (FIXP_DBL)0x0f18028d, (FIXP_DBL)0x0f1bf312,
363*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0f1fde3d, (FIXP_DBL)0x0f23c41d, (FIXP_DBL)0x0f27a4c0,
364*e5436536SAndroid Build Coastguard Worker     (FIXP_DBL)0x0f2b8034};
365*e5436536SAndroid Build Coastguard Worker 
366*e5436536SAndroid Build Coastguard Worker #else
367*e5436536SAndroid Build Coastguard Worker #error "ldInt table size too small"
368*e5436536SAndroid Build Coastguard Worker 
369*e5436536SAndroid Build Coastguard Worker #endif
370*e5436536SAndroid Build Coastguard Worker 
371*e5436536SAndroid Build Coastguard Worker LNK_SECTION_INITCODE
InitLdInt()372*e5436536SAndroid Build Coastguard Worker void InitLdInt() { /* nothing to do! Use preinitialized logarithm table */
373*e5436536SAndroid Build Coastguard Worker }
374*e5436536SAndroid Build Coastguard Worker 
375*e5436536SAndroid Build Coastguard Worker #if (LD_INT_TAB_LEN != 0)
376*e5436536SAndroid Build Coastguard Worker 
377*e5436536SAndroid Build Coastguard Worker LNK_SECTION_CODE_L1
CalcLdInt(INT i)378*e5436536SAndroid Build Coastguard Worker FIXP_DBL CalcLdInt(INT i) {
379*e5436536SAndroid Build Coastguard Worker   /* calculates ld(op)/LD_DATA_SCALING */
380*e5436536SAndroid Build Coastguard Worker   /* op is assumed to be an integer value between 1 and LD_INT_TAB_LEN */
381*e5436536SAndroid Build Coastguard Worker 
382*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT((LD_INT_TAB_LEN > 0) &&
383*e5436536SAndroid Build Coastguard Worker              ((FIXP_DBL)ldIntCoeff[0] ==
384*e5436536SAndroid Build Coastguard Worker               (FIXP_DBL)0x80000001)); /* tab has to be initialized */
385*e5436536SAndroid Build Coastguard Worker 
386*e5436536SAndroid Build Coastguard Worker   if ((i > 0) && (i < LD_INT_TAB_LEN))
387*e5436536SAndroid Build Coastguard Worker     return ldIntCoeff[i];
388*e5436536SAndroid Build Coastguard Worker   else {
389*e5436536SAndroid Build Coastguard Worker     return (0);
390*e5436536SAndroid Build Coastguard Worker   }
391*e5436536SAndroid Build Coastguard Worker }
392*e5436536SAndroid Build Coastguard Worker #endif /* (LD_INT_TAB_LEN!=0)  */
393*e5436536SAndroid Build Coastguard Worker 
394*e5436536SAndroid Build Coastguard Worker #if !defined(FUNCTION_schur_div)
395*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
396*e5436536SAndroid Build Coastguard Worker 
397*e5436536SAndroid Build Coastguard Worker     functionname: schur_div
398*e5436536SAndroid Build Coastguard Worker     description:  delivers op1/op2 with op3-bit accuracy
399*e5436536SAndroid Build Coastguard Worker 
400*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
401*e5436536SAndroid Build Coastguard Worker 
schur_div(FIXP_DBL num,FIXP_DBL denum,INT count)402*e5436536SAndroid Build Coastguard Worker FIXP_DBL schur_div(FIXP_DBL num, FIXP_DBL denum, INT count) {
403*e5436536SAndroid Build Coastguard Worker   INT L_num = (LONG)num >> 1;
404*e5436536SAndroid Build Coastguard Worker   INT L_denum = (LONG)denum >> 1;
405*e5436536SAndroid Build Coastguard Worker   INT div = 0;
406*e5436536SAndroid Build Coastguard Worker   INT k = count;
407*e5436536SAndroid Build Coastguard Worker 
408*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(num >= (FIXP_DBL)0);
409*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(denum > (FIXP_DBL)0);
410*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(num <= denum);
411*e5436536SAndroid Build Coastguard Worker 
412*e5436536SAndroid Build Coastguard Worker   if (L_num != 0)
413*e5436536SAndroid Build Coastguard Worker     while (--k) {
414*e5436536SAndroid Build Coastguard Worker       div <<= 1;
415*e5436536SAndroid Build Coastguard Worker       L_num <<= 1;
416*e5436536SAndroid Build Coastguard Worker       if (L_num >= L_denum) {
417*e5436536SAndroid Build Coastguard Worker         L_num -= L_denum;
418*e5436536SAndroid Build Coastguard Worker         div++;
419*e5436536SAndroid Build Coastguard Worker       }
420*e5436536SAndroid Build Coastguard Worker     }
421*e5436536SAndroid Build Coastguard Worker   return (FIXP_DBL)(div << (DFRACT_BITS - count));
422*e5436536SAndroid Build Coastguard Worker }
423*e5436536SAndroid Build Coastguard Worker 
424*e5436536SAndroid Build Coastguard Worker #endif /* !defined(FUNCTION_schur_div) */
425*e5436536SAndroid Build Coastguard Worker 
426*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fMultNorm
fMultNorm(FIXP_DBL f1,FIXP_DBL f2,INT * result_e)427*e5436536SAndroid Build Coastguard Worker FIXP_DBL fMultNorm(FIXP_DBL f1, FIXP_DBL f2, INT *result_e) {
428*e5436536SAndroid Build Coastguard Worker   INT product = 0;
429*e5436536SAndroid Build Coastguard Worker   INT norm_f1, norm_f2;
430*e5436536SAndroid Build Coastguard Worker 
431*e5436536SAndroid Build Coastguard Worker   if ((f1 == (FIXP_DBL)0) || (f2 == (FIXP_DBL)0)) {
432*e5436536SAndroid Build Coastguard Worker     *result_e = 0;
433*e5436536SAndroid Build Coastguard Worker     return (FIXP_DBL)0;
434*e5436536SAndroid Build Coastguard Worker   }
435*e5436536SAndroid Build Coastguard Worker   norm_f1 = CountLeadingBits(f1);
436*e5436536SAndroid Build Coastguard Worker   f1 = f1 << norm_f1;
437*e5436536SAndroid Build Coastguard Worker   norm_f2 = CountLeadingBits(f2);
438*e5436536SAndroid Build Coastguard Worker   f2 = f2 << norm_f2;
439*e5436536SAndroid Build Coastguard Worker 
440*e5436536SAndroid Build Coastguard Worker   if ((f1 == (FIXP_DBL)MINVAL_DBL) && (f2 == (FIXP_DBL)MINVAL_DBL)) {
441*e5436536SAndroid Build Coastguard Worker     product = -((FIXP_DBL)MINVAL_DBL >> 1);
442*e5436536SAndroid Build Coastguard Worker     *result_e = -(norm_f1 + norm_f2 - 1);
443*e5436536SAndroid Build Coastguard Worker   } else {
444*e5436536SAndroid Build Coastguard Worker     product = fMult(f1, f2);
445*e5436536SAndroid Build Coastguard Worker     *result_e = -(norm_f1 + norm_f2);
446*e5436536SAndroid Build Coastguard Worker   }
447*e5436536SAndroid Build Coastguard Worker 
448*e5436536SAndroid Build Coastguard Worker   return (FIXP_DBL)product;
449*e5436536SAndroid Build Coastguard Worker }
450*e5436536SAndroid Build Coastguard Worker #endif
451*e5436536SAndroid Build Coastguard Worker 
452*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fDivNorm
fDivNorm(FIXP_DBL L_num,FIXP_DBL L_denum,INT * result_e)453*e5436536SAndroid Build Coastguard Worker FIXP_DBL fDivNorm(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e) {
454*e5436536SAndroid Build Coastguard Worker   FIXP_DBL div;
455*e5436536SAndroid Build Coastguard Worker   INT norm_num, norm_den;
456*e5436536SAndroid Build Coastguard Worker 
457*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(L_num >= (FIXP_DBL)0);
458*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(L_denum > (FIXP_DBL)0);
459*e5436536SAndroid Build Coastguard Worker 
460*e5436536SAndroid Build Coastguard Worker   if (L_num == (FIXP_DBL)0) {
461*e5436536SAndroid Build Coastguard Worker     *result_e = 0;
462*e5436536SAndroid Build Coastguard Worker     return ((FIXP_DBL)0);
463*e5436536SAndroid Build Coastguard Worker   }
464*e5436536SAndroid Build Coastguard Worker 
465*e5436536SAndroid Build Coastguard Worker   norm_num = CountLeadingBits(L_num);
466*e5436536SAndroid Build Coastguard Worker   L_num = L_num << norm_num;
467*e5436536SAndroid Build Coastguard Worker   L_num = L_num >> 1;
468*e5436536SAndroid Build Coastguard Worker   *result_e = -norm_num + 1;
469*e5436536SAndroid Build Coastguard Worker 
470*e5436536SAndroid Build Coastguard Worker   norm_den = CountLeadingBits(L_denum);
471*e5436536SAndroid Build Coastguard Worker   L_denum = L_denum << norm_den;
472*e5436536SAndroid Build Coastguard Worker   *result_e -= -norm_den;
473*e5436536SAndroid Build Coastguard Worker 
474*e5436536SAndroid Build Coastguard Worker   div = schur_div(L_num, L_denum, FRACT_BITS);
475*e5436536SAndroid Build Coastguard Worker 
476*e5436536SAndroid Build Coastguard Worker   return div;
477*e5436536SAndroid Build Coastguard Worker }
478*e5436536SAndroid Build Coastguard Worker #endif /* !FUNCTION_fDivNorm */
479*e5436536SAndroid Build Coastguard Worker 
480*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fDivNorm
fDivNorm(FIXP_DBL num,FIXP_DBL denom)481*e5436536SAndroid Build Coastguard Worker FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom) {
482*e5436536SAndroid Build Coastguard Worker   INT e;
483*e5436536SAndroid Build Coastguard Worker   FIXP_DBL res;
484*e5436536SAndroid Build Coastguard Worker 
485*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(denom >= num);
486*e5436536SAndroid Build Coastguard Worker 
487*e5436536SAndroid Build Coastguard Worker   res = fDivNorm(num, denom, &e);
488*e5436536SAndroid Build Coastguard Worker 
489*e5436536SAndroid Build Coastguard Worker   /* Avoid overflow since we must output a value with exponent 0
490*e5436536SAndroid Build Coastguard Worker      there is no other choice than saturating to almost 1.0f */
491*e5436536SAndroid Build Coastguard Worker   if (res == (FIXP_DBL)(1 << (DFRACT_BITS - 2)) && e == 1) {
492*e5436536SAndroid Build Coastguard Worker     res = (FIXP_DBL)MAXVAL_DBL;
493*e5436536SAndroid Build Coastguard Worker   } else {
494*e5436536SAndroid Build Coastguard Worker     res = scaleValue(res, e);
495*e5436536SAndroid Build Coastguard Worker   }
496*e5436536SAndroid Build Coastguard Worker 
497*e5436536SAndroid Build Coastguard Worker   return res;
498*e5436536SAndroid Build Coastguard Worker }
499*e5436536SAndroid Build Coastguard Worker #endif /* !FUNCTION_fDivNorm */
500*e5436536SAndroid Build Coastguard Worker 
501*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fDivNormSigned
fDivNormSigned(FIXP_DBL num,FIXP_DBL denom)502*e5436536SAndroid Build Coastguard Worker FIXP_DBL fDivNormSigned(FIXP_DBL num, FIXP_DBL denom) {
503*e5436536SAndroid Build Coastguard Worker   INT e;
504*e5436536SAndroid Build Coastguard Worker   FIXP_DBL res;
505*e5436536SAndroid Build Coastguard Worker   int sign;
506*e5436536SAndroid Build Coastguard Worker 
507*e5436536SAndroid Build Coastguard Worker   if (denom == (FIXP_DBL)0) {
508*e5436536SAndroid Build Coastguard Worker     return (FIXP_DBL)MAXVAL_DBL;
509*e5436536SAndroid Build Coastguard Worker   }
510*e5436536SAndroid Build Coastguard Worker 
511*e5436536SAndroid Build Coastguard Worker   sign = ((num >= (FIXP_DBL)0) != (denom >= (FIXP_DBL)0));
512*e5436536SAndroid Build Coastguard Worker   res = fDivNormSigned(num, denom, &e);
513*e5436536SAndroid Build Coastguard Worker 
514*e5436536SAndroid Build Coastguard Worker   /* Saturate since we must output a value with exponent 0 */
515*e5436536SAndroid Build Coastguard Worker   if ((e > 0) && (fAbs(res) >= FL2FXCONST_DBL(0.5))) {
516*e5436536SAndroid Build Coastguard Worker     if (sign) {
517*e5436536SAndroid Build Coastguard Worker       res = (FIXP_DBL)MINVAL_DBL;
518*e5436536SAndroid Build Coastguard Worker     } else {
519*e5436536SAndroid Build Coastguard Worker       res = (FIXP_DBL)MAXVAL_DBL;
520*e5436536SAndroid Build Coastguard Worker     }
521*e5436536SAndroid Build Coastguard Worker   } else {
522*e5436536SAndroid Build Coastguard Worker     res = scaleValue(res, e);
523*e5436536SAndroid Build Coastguard Worker   }
524*e5436536SAndroid Build Coastguard Worker 
525*e5436536SAndroid Build Coastguard Worker   return res;
526*e5436536SAndroid Build Coastguard Worker }
fDivNormSigned(FIXP_DBL L_num,FIXP_DBL L_denum,INT * result_e)527*e5436536SAndroid Build Coastguard Worker FIXP_DBL fDivNormSigned(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e) {
528*e5436536SAndroid Build Coastguard Worker   FIXP_DBL div;
529*e5436536SAndroid Build Coastguard Worker   INT norm_num, norm_den;
530*e5436536SAndroid Build Coastguard Worker   int sign;
531*e5436536SAndroid Build Coastguard Worker 
532*e5436536SAndroid Build Coastguard Worker   sign = ((L_num >= (FIXP_DBL)0) != (L_denum >= (FIXP_DBL)0));
533*e5436536SAndroid Build Coastguard Worker 
534*e5436536SAndroid Build Coastguard Worker   if (L_num == (FIXP_DBL)0) {
535*e5436536SAndroid Build Coastguard Worker     *result_e = 0;
536*e5436536SAndroid Build Coastguard Worker     return ((FIXP_DBL)0);
537*e5436536SAndroid Build Coastguard Worker   }
538*e5436536SAndroid Build Coastguard Worker   if (L_denum == (FIXP_DBL)0) {
539*e5436536SAndroid Build Coastguard Worker     *result_e = 14;
540*e5436536SAndroid Build Coastguard Worker     return ((FIXP_DBL)MAXVAL_DBL);
541*e5436536SAndroid Build Coastguard Worker   }
542*e5436536SAndroid Build Coastguard Worker 
543*e5436536SAndroid Build Coastguard Worker   norm_num = CountLeadingBits(L_num);
544*e5436536SAndroid Build Coastguard Worker   L_num = L_num << norm_num;
545*e5436536SAndroid Build Coastguard Worker   L_num = L_num >> 2;
546*e5436536SAndroid Build Coastguard Worker   L_num = fAbs(L_num);
547*e5436536SAndroid Build Coastguard Worker   *result_e = -norm_num + 1;
548*e5436536SAndroid Build Coastguard Worker 
549*e5436536SAndroid Build Coastguard Worker   norm_den = CountLeadingBits(L_denum);
550*e5436536SAndroid Build Coastguard Worker   L_denum = L_denum << norm_den;
551*e5436536SAndroid Build Coastguard Worker   L_denum = L_denum >> 1;
552*e5436536SAndroid Build Coastguard Worker   L_denum = fAbs(L_denum);
553*e5436536SAndroid Build Coastguard Worker   *result_e -= -norm_den;
554*e5436536SAndroid Build Coastguard Worker 
555*e5436536SAndroid Build Coastguard Worker   div = schur_div(L_num, L_denum, FRACT_BITS);
556*e5436536SAndroid Build Coastguard Worker 
557*e5436536SAndroid Build Coastguard Worker   if (sign) {
558*e5436536SAndroid Build Coastguard Worker     div = -div;
559*e5436536SAndroid Build Coastguard Worker   }
560*e5436536SAndroid Build Coastguard Worker 
561*e5436536SAndroid Build Coastguard Worker   return div;
562*e5436536SAndroid Build Coastguard Worker }
563*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_fDivNormSigned */
564*e5436536SAndroid Build Coastguard Worker 
565*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fDivNormHighPrec
fDivNormHighPrec(FIXP_DBL num,FIXP_DBL denom,INT * result_e)566*e5436536SAndroid Build Coastguard Worker FIXP_DBL fDivNormHighPrec(FIXP_DBL num, FIXP_DBL denom, INT *result_e) {
567*e5436536SAndroid Build Coastguard Worker   FIXP_DBL div;
568*e5436536SAndroid Build Coastguard Worker   INT norm_num, norm_den;
569*e5436536SAndroid Build Coastguard Worker 
570*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(num >= (FIXP_DBL)0);
571*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(denom > (FIXP_DBL)0);
572*e5436536SAndroid Build Coastguard Worker 
573*e5436536SAndroid Build Coastguard Worker   if (num == (FIXP_DBL)0) {
574*e5436536SAndroid Build Coastguard Worker     *result_e = 0;
575*e5436536SAndroid Build Coastguard Worker     return ((FIXP_DBL)0);
576*e5436536SAndroid Build Coastguard Worker   }
577*e5436536SAndroid Build Coastguard Worker 
578*e5436536SAndroid Build Coastguard Worker   norm_num = CountLeadingBits(num);
579*e5436536SAndroid Build Coastguard Worker   num = num << norm_num;
580*e5436536SAndroid Build Coastguard Worker   num = num >> 1;
581*e5436536SAndroid Build Coastguard Worker   *result_e = -norm_num + 1;
582*e5436536SAndroid Build Coastguard Worker 
583*e5436536SAndroid Build Coastguard Worker   norm_den = CountLeadingBits(denom);
584*e5436536SAndroid Build Coastguard Worker   denom = denom << norm_den;
585*e5436536SAndroid Build Coastguard Worker   *result_e -= -norm_den;
586*e5436536SAndroid Build Coastguard Worker 
587*e5436536SAndroid Build Coastguard Worker   div = schur_div(num, denom, 31);
588*e5436536SAndroid Build Coastguard Worker   return div;
589*e5436536SAndroid Build Coastguard Worker }
590*e5436536SAndroid Build Coastguard Worker #endif /* !FUNCTION_fDivNormHighPrec */
591*e5436536SAndroid Build Coastguard Worker 
592*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fPow
f2Pow(const FIXP_DBL exp_m,const INT exp_e,INT * result_e)593*e5436536SAndroid Build Coastguard Worker FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e, INT *result_e) {
594*e5436536SAndroid Build Coastguard Worker   FIXP_DBL frac_part, result_m;
595*e5436536SAndroid Build Coastguard Worker   INT int_part;
596*e5436536SAndroid Build Coastguard Worker 
597*e5436536SAndroid Build Coastguard Worker   if (exp_e > 0) {
598*e5436536SAndroid Build Coastguard Worker     INT exp_bits = DFRACT_BITS - 1 - exp_e;
599*e5436536SAndroid Build Coastguard Worker     int_part = exp_m >> exp_bits;
600*e5436536SAndroid Build Coastguard Worker     frac_part = exp_m - (FIXP_DBL)(int_part << exp_bits);
601*e5436536SAndroid Build Coastguard Worker     frac_part = frac_part << exp_e;
602*e5436536SAndroid Build Coastguard Worker   } else {
603*e5436536SAndroid Build Coastguard Worker     int_part = 0;
604*e5436536SAndroid Build Coastguard Worker     frac_part = exp_m >> -exp_e;
605*e5436536SAndroid Build Coastguard Worker   }
606*e5436536SAndroid Build Coastguard Worker 
607*e5436536SAndroid Build Coastguard Worker   /* Best accuracy is around 0, so try to get there with the fractional part. */
608*e5436536SAndroid Build Coastguard Worker   if (frac_part > FL2FXCONST_DBL(0.5f)) {
609*e5436536SAndroid Build Coastguard Worker     int_part = int_part + 1;
610*e5436536SAndroid Build Coastguard Worker     frac_part = frac_part + FL2FXCONST_DBL(-1.0f);
611*e5436536SAndroid Build Coastguard Worker   }
612*e5436536SAndroid Build Coastguard Worker   if (frac_part < FL2FXCONST_DBL(-0.5f)) {
613*e5436536SAndroid Build Coastguard Worker     int_part = int_part - 1;
614*e5436536SAndroid Build Coastguard Worker     frac_part = -(FL2FXCONST_DBL(-1.0f) - frac_part);
615*e5436536SAndroid Build Coastguard Worker   }
616*e5436536SAndroid Build Coastguard Worker 
617*e5436536SAndroid Build Coastguard Worker   /* "+ 1" compensates fMultAddDiv2() of the polynomial evaluation below. */
618*e5436536SAndroid Build Coastguard Worker   *result_e = int_part + 1;
619*e5436536SAndroid Build Coastguard Worker 
620*e5436536SAndroid Build Coastguard Worker   /* Evaluate taylor polynomial which approximates 2^x */
621*e5436536SAndroid Build Coastguard Worker   {
622*e5436536SAndroid Build Coastguard Worker     FIXP_DBL p;
623*e5436536SAndroid Build Coastguard Worker 
624*e5436536SAndroid Build Coastguard Worker     /* result_m ~= 2^frac_part */
625*e5436536SAndroid Build Coastguard Worker     p = frac_part;
626*e5436536SAndroid Build Coastguard Worker     /* First taylor series coefficient a_0 = 1.0, scaled by 0.5 due to
627*e5436536SAndroid Build Coastguard Worker      * fMultDiv2(). */
628*e5436536SAndroid Build Coastguard Worker     result_m = FL2FXCONST_DBL(1.0f / 2.0f);
629*e5436536SAndroid Build Coastguard Worker     for (INT i = 0; i < POW2_PRECISION; i++) {
630*e5436536SAndroid Build Coastguard Worker       /* next taylor series term: a_i * x^i, x=0 */
631*e5436536SAndroid Build Coastguard Worker       result_m = fMultAddDiv2(result_m, pow2Coeff[i], p);
632*e5436536SAndroid Build Coastguard Worker       p = fMult(p, frac_part);
633*e5436536SAndroid Build Coastguard Worker     }
634*e5436536SAndroid Build Coastguard Worker   }
635*e5436536SAndroid Build Coastguard Worker   return result_m;
636*e5436536SAndroid Build Coastguard Worker }
637*e5436536SAndroid Build Coastguard Worker 
f2Pow(const FIXP_DBL exp_m,const INT exp_e)638*e5436536SAndroid Build Coastguard Worker FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e) {
639*e5436536SAndroid Build Coastguard Worker   FIXP_DBL result_m;
640*e5436536SAndroid Build Coastguard Worker   INT result_e;
641*e5436536SAndroid Build Coastguard Worker 
642*e5436536SAndroid Build Coastguard Worker   result_m = f2Pow(exp_m, exp_e, &result_e);
643*e5436536SAndroid Build Coastguard Worker   result_e = fixMin(DFRACT_BITS - 1, fixMax(-(DFRACT_BITS - 1), result_e));
644*e5436536SAndroid Build Coastguard Worker 
645*e5436536SAndroid Build Coastguard Worker   return scaleValue(result_m, result_e);
646*e5436536SAndroid Build Coastguard Worker }
647*e5436536SAndroid Build Coastguard Worker 
fPow(FIXP_DBL base_m,INT base_e,FIXP_DBL exp_m,INT exp_e,INT * result_e)648*e5436536SAndroid Build Coastguard Worker FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
649*e5436536SAndroid Build Coastguard Worker               INT *result_e) {
650*e5436536SAndroid Build Coastguard Worker   INT ans_lg2_e, baselg2_e;
651*e5436536SAndroid Build Coastguard Worker   FIXP_DBL base_lg2, ans_lg2, result;
652*e5436536SAndroid Build Coastguard Worker 
653*e5436536SAndroid Build Coastguard Worker   if (base_m <= (FIXP_DBL)0) {
654*e5436536SAndroid Build Coastguard Worker     result = (FIXP_DBL)0;
655*e5436536SAndroid Build Coastguard Worker     *result_e = 0;
656*e5436536SAndroid Build Coastguard Worker     return result;
657*e5436536SAndroid Build Coastguard Worker   }
658*e5436536SAndroid Build Coastguard Worker 
659*e5436536SAndroid Build Coastguard Worker   /* Calc log2 of base */
660*e5436536SAndroid Build Coastguard Worker   base_lg2 = fLog2(base_m, base_e, &baselg2_e);
661*e5436536SAndroid Build Coastguard Worker 
662*e5436536SAndroid Build Coastguard Worker   /* Prepare exp */
663*e5436536SAndroid Build Coastguard Worker   {
664*e5436536SAndroid Build Coastguard Worker     INT leadingBits;
665*e5436536SAndroid Build Coastguard Worker 
666*e5436536SAndroid Build Coastguard Worker     leadingBits = CountLeadingBits(fAbs(exp_m));
667*e5436536SAndroid Build Coastguard Worker     exp_m = exp_m << leadingBits;
668*e5436536SAndroid Build Coastguard Worker     exp_e -= leadingBits;
669*e5436536SAndroid Build Coastguard Worker   }
670*e5436536SAndroid Build Coastguard Worker 
671*e5436536SAndroid Build Coastguard Worker   /* Calc base pow exp */
672*e5436536SAndroid Build Coastguard Worker   ans_lg2 = fMult(base_lg2, exp_m);
673*e5436536SAndroid Build Coastguard Worker   ans_lg2_e = exp_e + baselg2_e;
674*e5436536SAndroid Build Coastguard Worker 
675*e5436536SAndroid Build Coastguard Worker   /* Calc antilog */
676*e5436536SAndroid Build Coastguard Worker   result = f2Pow(ans_lg2, ans_lg2_e, result_e);
677*e5436536SAndroid Build Coastguard Worker 
678*e5436536SAndroid Build Coastguard Worker   return result;
679*e5436536SAndroid Build Coastguard Worker }
680*e5436536SAndroid Build Coastguard Worker 
fLdPow(FIXP_DBL baseLd_m,INT baseLd_e,FIXP_DBL exp_m,INT exp_e,INT * result_e)681*e5436536SAndroid Build Coastguard Worker FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e,
682*e5436536SAndroid Build Coastguard Worker                 INT *result_e) {
683*e5436536SAndroid Build Coastguard Worker   INT ans_lg2_e;
684*e5436536SAndroid Build Coastguard Worker   FIXP_DBL ans_lg2, result;
685*e5436536SAndroid Build Coastguard Worker 
686*e5436536SAndroid Build Coastguard Worker   /* Prepare exp */
687*e5436536SAndroid Build Coastguard Worker   {
688*e5436536SAndroid Build Coastguard Worker     INT leadingBits;
689*e5436536SAndroid Build Coastguard Worker 
690*e5436536SAndroid Build Coastguard Worker     leadingBits = CountLeadingBits(fAbs(exp_m));
691*e5436536SAndroid Build Coastguard Worker     exp_m = exp_m << leadingBits;
692*e5436536SAndroid Build Coastguard Worker     exp_e -= leadingBits;
693*e5436536SAndroid Build Coastguard Worker   }
694*e5436536SAndroid Build Coastguard Worker 
695*e5436536SAndroid Build Coastguard Worker   /* Calc base pow exp */
696*e5436536SAndroid Build Coastguard Worker   ans_lg2 = fMult(baseLd_m, exp_m);
697*e5436536SAndroid Build Coastguard Worker   ans_lg2_e = exp_e + baseLd_e;
698*e5436536SAndroid Build Coastguard Worker 
699*e5436536SAndroid Build Coastguard Worker   /* Calc antilog */
700*e5436536SAndroid Build Coastguard Worker   result = f2Pow(ans_lg2, ans_lg2_e, result_e);
701*e5436536SAndroid Build Coastguard Worker 
702*e5436536SAndroid Build Coastguard Worker   return result;
703*e5436536SAndroid Build Coastguard Worker }
704*e5436536SAndroid Build Coastguard Worker 
fLdPow(FIXP_DBL baseLd_m,INT baseLd_e,FIXP_DBL exp_m,INT exp_e)705*e5436536SAndroid Build Coastguard Worker FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e) {
706*e5436536SAndroid Build Coastguard Worker   FIXP_DBL result_m;
707*e5436536SAndroid Build Coastguard Worker   int result_e;
708*e5436536SAndroid Build Coastguard Worker 
709*e5436536SAndroid Build Coastguard Worker   result_m = fLdPow(baseLd_m, baseLd_e, exp_m, exp_e, &result_e);
710*e5436536SAndroid Build Coastguard Worker 
711*e5436536SAndroid Build Coastguard Worker   return SATURATE_SHIFT(result_m, -result_e, DFRACT_BITS);
712*e5436536SAndroid Build Coastguard Worker }
713*e5436536SAndroid Build Coastguard Worker 
fPowInt(FIXP_DBL base_m,INT base_e,INT exp,INT * pResult_e)714*e5436536SAndroid Build Coastguard Worker FIXP_DBL fPowInt(FIXP_DBL base_m, INT base_e, INT exp, INT *pResult_e) {
715*e5436536SAndroid Build Coastguard Worker   FIXP_DBL result;
716*e5436536SAndroid Build Coastguard Worker 
717*e5436536SAndroid Build Coastguard Worker   if (exp != 0) {
718*e5436536SAndroid Build Coastguard Worker     INT result_e = 0;
719*e5436536SAndroid Build Coastguard Worker 
720*e5436536SAndroid Build Coastguard Worker     if (base_m != (FIXP_DBL)0) {
721*e5436536SAndroid Build Coastguard Worker       {
722*e5436536SAndroid Build Coastguard Worker         INT leadingBits;
723*e5436536SAndroid Build Coastguard Worker         leadingBits = CountLeadingBits(base_m);
724*e5436536SAndroid Build Coastguard Worker         base_m <<= leadingBits;
725*e5436536SAndroid Build Coastguard Worker         base_e -= leadingBits;
726*e5436536SAndroid Build Coastguard Worker       }
727*e5436536SAndroid Build Coastguard Worker 
728*e5436536SAndroid Build Coastguard Worker       result = base_m;
729*e5436536SAndroid Build Coastguard Worker 
730*e5436536SAndroid Build Coastguard Worker       {
731*e5436536SAndroid Build Coastguard Worker         int i;
732*e5436536SAndroid Build Coastguard Worker         for (i = 1; i < fAbs(exp); i++) {
733*e5436536SAndroid Build Coastguard Worker           result = fMult(result, base_m);
734*e5436536SAndroid Build Coastguard Worker         }
735*e5436536SAndroid Build Coastguard Worker       }
736*e5436536SAndroid Build Coastguard Worker 
737*e5436536SAndroid Build Coastguard Worker       if (exp < 0) {
738*e5436536SAndroid Build Coastguard Worker         /* 1.0 / ans */
739*e5436536SAndroid Build Coastguard Worker         result = fDivNorm(FL2FXCONST_DBL(0.5f), result, &result_e);
740*e5436536SAndroid Build Coastguard Worker         result_e++;
741*e5436536SAndroid Build Coastguard Worker       } else {
742*e5436536SAndroid Build Coastguard Worker         int ansScale = CountLeadingBits(result);
743*e5436536SAndroid Build Coastguard Worker         result <<= ansScale;
744*e5436536SAndroid Build Coastguard Worker         result_e -= ansScale;
745*e5436536SAndroid Build Coastguard Worker       }
746*e5436536SAndroid Build Coastguard Worker 
747*e5436536SAndroid Build Coastguard Worker       result_e += exp * base_e;
748*e5436536SAndroid Build Coastguard Worker 
749*e5436536SAndroid Build Coastguard Worker     } else {
750*e5436536SAndroid Build Coastguard Worker       result = (FIXP_DBL)0;
751*e5436536SAndroid Build Coastguard Worker     }
752*e5436536SAndroid Build Coastguard Worker     *pResult_e = result_e;
753*e5436536SAndroid Build Coastguard Worker   } else {
754*e5436536SAndroid Build Coastguard Worker     result = FL2FXCONST_DBL(0.5f);
755*e5436536SAndroid Build Coastguard Worker     *pResult_e = 1;
756*e5436536SAndroid Build Coastguard Worker   }
757*e5436536SAndroid Build Coastguard Worker 
758*e5436536SAndroid Build Coastguard Worker   return result;
759*e5436536SAndroid Build Coastguard Worker }
760*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_fPow */
761*e5436536SAndroid Build Coastguard Worker 
762*e5436536SAndroid Build Coastguard Worker #ifndef FUNCTION_fLog2
CalcLog2(FIXP_DBL base_m,INT base_e,INT * result_e)763*e5436536SAndroid Build Coastguard Worker FIXP_DBL CalcLog2(FIXP_DBL base_m, INT base_e, INT *result_e) {
764*e5436536SAndroid Build Coastguard Worker   return fLog2(base_m, base_e, result_e);
765*e5436536SAndroid Build Coastguard Worker }
766*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_fLog2 */
767*e5436536SAndroid Build Coastguard Worker 
fixp_floorToInt(FIXP_DBL f_inp,INT sf)768*e5436536SAndroid Build Coastguard Worker INT fixp_floorToInt(FIXP_DBL f_inp, INT sf) {
769*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(sf >= 0);
770*e5436536SAndroid Build Coastguard Worker   INT floorInt = (INT)(f_inp >> ((DFRACT_BITS - 1) - sf));
771*e5436536SAndroid Build Coastguard Worker   return floorInt;
772*e5436536SAndroid Build Coastguard Worker }
773*e5436536SAndroid Build Coastguard Worker 
fixp_floor(FIXP_DBL f_inp,INT sf)774*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_floor(FIXP_DBL f_inp, INT sf) {
775*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(sf >= 0);
776*e5436536SAndroid Build Coastguard Worker   INT floorInt = fixp_floorToInt(f_inp, sf);
777*e5436536SAndroid Build Coastguard Worker   FIXP_DBL f_floor = (FIXP_DBL)(floorInt << ((DFRACT_BITS - 1) - sf));
778*e5436536SAndroid Build Coastguard Worker   return f_floor;
779*e5436536SAndroid Build Coastguard Worker }
780*e5436536SAndroid Build Coastguard Worker 
fixp_ceilToInt(FIXP_DBL f_inp,INT sf)781*e5436536SAndroid Build Coastguard Worker INT fixp_ceilToInt(FIXP_DBL f_inp, INT sf)  // sf  mantissaBits left of dot
782*e5436536SAndroid Build Coastguard Worker {
783*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(sf >= 0);
784*e5436536SAndroid Build Coastguard Worker   INT sx = (DFRACT_BITS - 1) - sf;  // sx  mantissaBits right of dot
785*e5436536SAndroid Build Coastguard Worker   INT inpINT = (INT)f_inp;
786*e5436536SAndroid Build Coastguard Worker 
787*e5436536SAndroid Build Coastguard Worker   INT mask = (0x1 << sx) - 1;
788*e5436536SAndroid Build Coastguard Worker   INT ceilInt = (INT)(f_inp >> sx);
789*e5436536SAndroid Build Coastguard Worker 
790*e5436536SAndroid Build Coastguard Worker   if (inpINT & mask) {
791*e5436536SAndroid Build Coastguard Worker     ceilInt++;  // increment only, if there is at least one set mantissaBit
792*e5436536SAndroid Build Coastguard Worker                 // right of dot [in inpINT]
793*e5436536SAndroid Build Coastguard Worker   }
794*e5436536SAndroid Build Coastguard Worker 
795*e5436536SAndroid Build Coastguard Worker   return ceilInt;
796*e5436536SAndroid Build Coastguard Worker }
797*e5436536SAndroid Build Coastguard Worker 
fixp_ceil(FIXP_DBL f_inp,INT sf)798*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_ceil(FIXP_DBL f_inp, INT sf) {
799*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(sf >= 0);
800*e5436536SAndroid Build Coastguard Worker   INT sx = (DFRACT_BITS - 1) - sf;
801*e5436536SAndroid Build Coastguard Worker   INT ceilInt = fixp_ceilToInt(f_inp, sf);
802*e5436536SAndroid Build Coastguard Worker   ULONG mask = (ULONG)0x1 << (DFRACT_BITS - 1);  // 0x80000000
803*e5436536SAndroid Build Coastguard Worker   ceilInt = ceilInt
804*e5436536SAndroid Build Coastguard Worker             << sx;  // no fract warn bec. shift into saturation done on int side
805*e5436536SAndroid Build Coastguard Worker 
806*e5436536SAndroid Build Coastguard Worker   if ((f_inp > FL2FXCONST_DBL(0.0f)) && (ceilInt & mask)) {
807*e5436536SAndroid Build Coastguard Worker     --ceilInt;
808*e5436536SAndroid Build Coastguard Worker   }
809*e5436536SAndroid Build Coastguard Worker   FIXP_DBL f_ceil = (FIXP_DBL)ceilInt;
810*e5436536SAndroid Build Coastguard Worker 
811*e5436536SAndroid Build Coastguard Worker   return f_ceil;
812*e5436536SAndroid Build Coastguard Worker }
813*e5436536SAndroid Build Coastguard Worker 
814*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
815*e5436536SAndroid Build Coastguard Worker    fixp_truncateToInt()
816*e5436536SAndroid Build Coastguard Worker      Just remove the fractional part which is located right of decimal point
817*e5436536SAndroid Build Coastguard Worker      Same as which is done when a float is casted to (INT) :
818*e5436536SAndroid Build Coastguard Worker      result_INTtype = (INT)b_floatTypeInput;
819*e5436536SAndroid Build Coastguard Worker 
820*e5436536SAndroid Build Coastguard Worker    returns INT
821*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
fixp_truncateToInt(FIXP_DBL f_inp,INT sf)822*e5436536SAndroid Build Coastguard Worker INT fixp_truncateToInt(FIXP_DBL f_inp, INT sf)  // sf  mantissaBits left  of dot
823*e5436536SAndroid Build Coastguard Worker                                                 // (without sign)  e.g. at width
824*e5436536SAndroid Build Coastguard Worker                                                 // 32 this would be [sign]7.
825*e5436536SAndroid Build Coastguard Worker                                                 // supposed sf equals 8.
826*e5436536SAndroid Build Coastguard Worker {
827*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(sf >= 0);
828*e5436536SAndroid Build Coastguard Worker   INT sx = (DFRACT_BITS - 1) - sf;  // sx  mantissaBits right of dot
829*e5436536SAndroid Build Coastguard Worker                                     // at width 32 this would be        .24
830*e5436536SAndroid Build Coastguard Worker                                     // supposed sf equals 8.
831*e5436536SAndroid Build Coastguard Worker   INT fbaccu = (INT)f_inp;
832*e5436536SAndroid Build Coastguard Worker   INT mask = (0x1 << sx);
833*e5436536SAndroid Build Coastguard Worker 
834*e5436536SAndroid Build Coastguard Worker   if ((fbaccu < 0) && (fbaccu & (mask - 1))) {
835*e5436536SAndroid Build Coastguard Worker     fbaccu = fbaccu + mask;
836*e5436536SAndroid Build Coastguard Worker   }
837*e5436536SAndroid Build Coastguard Worker 
838*e5436536SAndroid Build Coastguard Worker   fbaccu = fbaccu >> sx;
839*e5436536SAndroid Build Coastguard Worker   return fbaccu;
840*e5436536SAndroid Build Coastguard Worker }
841*e5436536SAndroid Build Coastguard Worker 
842*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
843*e5436536SAndroid Build Coastguard Worker    fixp_truncate()
844*e5436536SAndroid Build Coastguard Worker      Just remove the fractional part which is located right of decimal point
845*e5436536SAndroid Build Coastguard Worker 
846*e5436536SAndroid Build Coastguard Worker    returns FIXP_DBL
847*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
fixp_truncate(FIXP_DBL f_inp,INT sf)848*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_truncate(FIXP_DBL f_inp, INT sf) {
849*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(sf >= 0);
850*e5436536SAndroid Build Coastguard Worker   INT truncateInt = fixp_truncateToInt(f_inp, sf);
851*e5436536SAndroid Build Coastguard Worker   FIXP_DBL f_truncate = (FIXP_DBL)(truncateInt << ((DFRACT_BITS - 1) - sf));
852*e5436536SAndroid Build Coastguard Worker   return f_truncate;
853*e5436536SAndroid Build Coastguard Worker }
854*e5436536SAndroid Build Coastguard Worker 
855*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
856*e5436536SAndroid Build Coastguard Worker   fixp_roundToInt()
857*e5436536SAndroid Build Coastguard Worker     round [typical rounding]
858*e5436536SAndroid Build Coastguard Worker 
859*e5436536SAndroid Build Coastguard Worker     See fct roundRef() [which is the reference]
860*e5436536SAndroid Build Coastguard Worker   returns INT
861*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
fixp_roundToInt(FIXP_DBL f_inp,INT sf)862*e5436536SAndroid Build Coastguard Worker INT fixp_roundToInt(FIXP_DBL f_inp, INT sf) {
863*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(sf >= 0);
864*e5436536SAndroid Build Coastguard Worker   INT sx = DFRACT_BITS - 1 - sf;
865*e5436536SAndroid Build Coastguard Worker   INT inp = (INT)f_inp;
866*e5436536SAndroid Build Coastguard Worker   INT mask1 = (0x1 << (sx - 1));
867*e5436536SAndroid Build Coastguard Worker   INT mask2 = (0x1 << (sx)) - 1;
868*e5436536SAndroid Build Coastguard Worker   INT mask3 = 0x7FFFFFFF;
869*e5436536SAndroid Build Coastguard Worker   INT iam = inp & mask2;
870*e5436536SAndroid Build Coastguard Worker   INT rnd;
871*e5436536SAndroid Build Coastguard Worker 
872*e5436536SAndroid Build Coastguard Worker   if ((inp < 0) && !(iam == mask1))
873*e5436536SAndroid Build Coastguard Worker     rnd = inp + mask1;
874*e5436536SAndroid Build Coastguard Worker   else if ((inp > 0) && !(inp == mask3))
875*e5436536SAndroid Build Coastguard Worker     rnd = inp + mask1;
876*e5436536SAndroid Build Coastguard Worker   else
877*e5436536SAndroid Build Coastguard Worker     rnd = inp;
878*e5436536SAndroid Build Coastguard Worker 
879*e5436536SAndroid Build Coastguard Worker   rnd = rnd >> sx;
880*e5436536SAndroid Build Coastguard Worker 
881*e5436536SAndroid Build Coastguard Worker   if (inp == mask3) rnd++;
882*e5436536SAndroid Build Coastguard Worker 
883*e5436536SAndroid Build Coastguard Worker   return rnd;
884*e5436536SAndroid Build Coastguard Worker }
885*e5436536SAndroid Build Coastguard Worker 
886*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
887*e5436536SAndroid Build Coastguard Worker   fixp_round()
888*e5436536SAndroid Build Coastguard Worker     round [typical rounding]
889*e5436536SAndroid Build Coastguard Worker 
890*e5436536SAndroid Build Coastguard Worker     See fct roundRef() [which is the reference]
891*e5436536SAndroid Build Coastguard Worker   returns FIXP_DBL
892*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
fixp_round(FIXP_DBL f_inp,INT sf)893*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_round(FIXP_DBL f_inp, INT sf) {
894*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(sf >= 0);
895*e5436536SAndroid Build Coastguard Worker   INT sx = DFRACT_BITS - 1 - sf;
896*e5436536SAndroid Build Coastguard Worker   INT r = fixp_roundToInt(f_inp, sf);
897*e5436536SAndroid Build Coastguard Worker   ULONG mask = (ULONG)0x1 << (DFRACT_BITS - 1);  // 0x80000000
898*e5436536SAndroid Build Coastguard Worker   r = r << sx;
899*e5436536SAndroid Build Coastguard Worker 
900*e5436536SAndroid Build Coastguard Worker   if ((f_inp > FL2FXCONST_DBL(0.0f)) && (r & mask)) {
901*e5436536SAndroid Build Coastguard Worker     --r;
902*e5436536SAndroid Build Coastguard Worker   }
903*e5436536SAndroid Build Coastguard Worker 
904*e5436536SAndroid Build Coastguard Worker   FIXP_DBL f_round = (FIXP_DBL)r;
905*e5436536SAndroid Build Coastguard Worker   return f_round;
906*e5436536SAndroid Build Coastguard Worker }
907