xref: /aosp_15_r20/external/aac/libFDK/src/FDK_trigFcts.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 - 2018 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):   Haricharan Lakshman, Manuel Jander
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: Trigonometric functions fixed point fractional implementation.
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "FDK_trigFcts.h"
104*e5436536SAndroid Build Coastguard Worker 
105*e5436536SAndroid Build Coastguard Worker #include "fixpoint_math.h"
106*e5436536SAndroid Build Coastguard Worker 
107*e5436536SAndroid Build Coastguard Worker #define IMPROVE_ATAN2_ACCURACY 1 /* 0 --> 59 dB SNR     1 --> 65 dB SNR */
108*e5436536SAndroid Build Coastguard Worker #define MINSFTAB 7
109*e5436536SAndroid Build Coastguard Worker #define MAXSFTAB 25
110*e5436536SAndroid Build Coastguard Worker 
111*e5436536SAndroid Build Coastguard Worker #if IMPROVE_ATAN2_ACCURACY
112*e5436536SAndroid Build Coastguard Worker static const FIXP_DBL f_atan_expand_range[MAXSFTAB - (MINSFTAB - 1)] = {
113*e5436536SAndroid Build Coastguard Worker     /*****************************************************************************
114*e5436536SAndroid Build Coastguard Worker      *
115*e5436536SAndroid Build Coastguard Worker      *  Table holds fixp_atan() output values which are outside of input range
116*e5436536SAndroid Build Coastguard Worker      *  of fixp_atan() to improve SNR of fixp_atan2().
117*e5436536SAndroid Build Coastguard Worker      *
118*e5436536SAndroid Build Coastguard Worker      *  This Table might also be used in fixp_atan() so there a wider input
119*e5436536SAndroid Build Coastguard Worker      *  range can be covered, too.
120*e5436536SAndroid Build Coastguard Worker      *
121*e5436536SAndroid Build Coastguard Worker      *****************************************************************************/
122*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.775862990872099e-001),
123*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.814919928673978e-001),
124*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.834450483314648e-001),
125*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.844216021392089e-001),
126*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.849098823026687e-001),
127*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.851540227918509e-001),
128*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.852760930873737e-001),
129*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853371282415015e-001),
130*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853676458193612e-001),
131*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853829046083906e-001),
132*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853905340029177e-001),
133*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853943487001828e-001),
134*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853962560488155e-001),
135*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853972097231319e-001),
136*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853976865602901e-001),
137*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853979249788692e-001),
138*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853980441881587e-001),
139*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853981037928035e-001),
140*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(7.853981335951259e-001)
141*e5436536SAndroid Build Coastguard Worker     /* pi/4 = 0.785398163397448 = pi/2/ATO_SCALE */
142*e5436536SAndroid Build Coastguard Worker };
143*e5436536SAndroid Build Coastguard Worker #endif
144*e5436536SAndroid Build Coastguard Worker 
fixp_atan2(FIXP_DBL y,FIXP_DBL x)145*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_atan2(FIXP_DBL y, FIXP_DBL x) {
146*e5436536SAndroid Build Coastguard Worker   FIXP_DBL q;
147*e5436536SAndroid Build Coastguard Worker   FIXP_DBL at;  /* atan  out */
148*e5436536SAndroid Build Coastguard Worker   FIXP_DBL at2; /* atan2 out */
149*e5436536SAndroid Build Coastguard Worker   FIXP_DBL ret = FL2FXCONST_DBL(-1.0f);
150*e5436536SAndroid Build Coastguard Worker   INT sf, sfo, stf;
151*e5436536SAndroid Build Coastguard Worker 
152*e5436536SAndroid Build Coastguard Worker   /* --- division */
153*e5436536SAndroid Build Coastguard Worker 
154*e5436536SAndroid Build Coastguard Worker   if (y > FL2FXCONST_DBL(0.0f)) {
155*e5436536SAndroid Build Coastguard Worker     if (x > FL2FXCONST_DBL(0.0f)) {
156*e5436536SAndroid Build Coastguard Worker       q = fDivNormHighPrec(y, x, &sf); /* both pos. */
157*e5436536SAndroid Build Coastguard Worker     } else if (x < FL2FXCONST_DBL(0.0f)) {
158*e5436536SAndroid Build Coastguard Worker       q = -fDivNormHighPrec(y, -x, &sf); /* x neg. */
159*e5436536SAndroid Build Coastguard Worker     } else {                             /* (x == FL2FXCONST_DBL(0.0f)) */
160*e5436536SAndroid Build Coastguard Worker       q = FL2FXCONST_DBL(+1.0f);         /* y/x = pos/zero = +Inf */
161*e5436536SAndroid Build Coastguard Worker       sf = 0;
162*e5436536SAndroid Build Coastguard Worker     }
163*e5436536SAndroid Build Coastguard Worker   } else if (y < FL2FXCONST_DBL(0.0f)) {
164*e5436536SAndroid Build Coastguard Worker     if (x > FL2FXCONST_DBL(0.0f)) {
165*e5436536SAndroid Build Coastguard Worker       q = -fDivNormHighPrec(-y, x, &sf); /* y neg. */
166*e5436536SAndroid Build Coastguard Worker     } else if (x < FL2FXCONST_DBL(0.0f)) {
167*e5436536SAndroid Build Coastguard Worker       q = fDivNormHighPrec(-y, -x, &sf); /* both neg. */
168*e5436536SAndroid Build Coastguard Worker     } else {                             /* (x == FL2FXCONST_DBL(0.0f)) */
169*e5436536SAndroid Build Coastguard Worker       q = FL2FXCONST_DBL(-1.0f);         /* y/x = neg/zero = -Inf */
170*e5436536SAndroid Build Coastguard Worker       sf = 0;
171*e5436536SAndroid Build Coastguard Worker     }
172*e5436536SAndroid Build Coastguard Worker   } else { /* (y == FL2FXCONST_DBL(0.0f)) */
173*e5436536SAndroid Build Coastguard Worker     q = FL2FXCONST_DBL(0.0f);
174*e5436536SAndroid Build Coastguard Worker     sf = 0;
175*e5436536SAndroid Build Coastguard Worker   }
176*e5436536SAndroid Build Coastguard Worker   sfo = sf;
177*e5436536SAndroid Build Coastguard Worker 
178*e5436536SAndroid Build Coastguard Worker   /* --- atan() */
179*e5436536SAndroid Build Coastguard Worker 
180*e5436536SAndroid Build Coastguard Worker   if (sfo > ATI_SF) {
181*e5436536SAndroid Build Coastguard Worker   /* --- could not calc fixp_atan() here bec of input data out of range */
182*e5436536SAndroid Build Coastguard Worker   /*     ==> therefore give back boundary values */
183*e5436536SAndroid Build Coastguard Worker 
184*e5436536SAndroid Build Coastguard Worker #if IMPROVE_ATAN2_ACCURACY
185*e5436536SAndroid Build Coastguard Worker     if (sfo > MAXSFTAB) sfo = MAXSFTAB;
186*e5436536SAndroid Build Coastguard Worker #endif
187*e5436536SAndroid Build Coastguard Worker 
188*e5436536SAndroid Build Coastguard Worker     if (q > FL2FXCONST_DBL(0.0f)) {
189*e5436536SAndroid Build Coastguard Worker #if IMPROVE_ATAN2_ACCURACY
190*e5436536SAndroid Build Coastguard Worker       at = +f_atan_expand_range[sfo - ATI_SF - 1];
191*e5436536SAndroid Build Coastguard Worker #else
192*e5436536SAndroid Build Coastguard Worker       at = FL2FXCONST_DBL(+M_PI / 2 / ATO_SCALE);
193*e5436536SAndroid Build Coastguard Worker #endif
194*e5436536SAndroid Build Coastguard Worker     } else if (q < FL2FXCONST_DBL(0.0f)) {
195*e5436536SAndroid Build Coastguard Worker #if IMPROVE_ATAN2_ACCURACY
196*e5436536SAndroid Build Coastguard Worker       at = -f_atan_expand_range[sfo - ATI_SF - 1];
197*e5436536SAndroid Build Coastguard Worker #else
198*e5436536SAndroid Build Coastguard Worker       at = FL2FXCONST_DBL(-M_PI / 2 / ATO_SCALE);
199*e5436536SAndroid Build Coastguard Worker #endif
200*e5436536SAndroid Build Coastguard Worker     } else { /* q == FL2FXCONST_DBL(0.0f) */
201*e5436536SAndroid Build Coastguard Worker       at = FL2FXCONST_DBL(0.0f);
202*e5436536SAndroid Build Coastguard Worker     }
203*e5436536SAndroid Build Coastguard Worker   } else {
204*e5436536SAndroid Build Coastguard Worker     /* --- calc of fixp_atan() is possible; input data within range */
205*e5436536SAndroid Build Coastguard Worker     /*     ==> set q on fixed scale level as desired from fixp_atan() */
206*e5436536SAndroid Build Coastguard Worker     stf = sfo - ATI_SF;
207*e5436536SAndroid Build Coastguard Worker     if (stf > 0)
208*e5436536SAndroid Build Coastguard Worker       q = q << (INT)fMin(stf, DFRACT_BITS - 1);
209*e5436536SAndroid Build Coastguard Worker     else
210*e5436536SAndroid Build Coastguard Worker       q = q >> (INT)fMin(-stf, DFRACT_BITS - 1);
211*e5436536SAndroid Build Coastguard Worker     at = fixp_atan(q); /* ATO_SF */
212*e5436536SAndroid Build Coastguard Worker   }
213*e5436536SAndroid Build Coastguard Worker 
214*e5436536SAndroid Build Coastguard Worker   // --- atan2()
215*e5436536SAndroid Build Coastguard Worker 
216*e5436536SAndroid Build Coastguard Worker   at2 = at >> (AT2O_SF - ATO_SF);  // now AT2O_SF for atan2
217*e5436536SAndroid Build Coastguard Worker   if (x > FL2FXCONST_DBL(0.0f)) {
218*e5436536SAndroid Build Coastguard Worker     ret = at2;
219*e5436536SAndroid Build Coastguard Worker   } else if (x < FL2FXCONST_DBL(0.0f)) {
220*e5436536SAndroid Build Coastguard Worker     if (y >= FL2FXCONST_DBL(0.0f)) {
221*e5436536SAndroid Build Coastguard Worker       ret = at2 + FL2FXCONST_DBL(M_PI / AT2O_SCALE);
222*e5436536SAndroid Build Coastguard Worker     } else {
223*e5436536SAndroid Build Coastguard Worker       ret = at2 - FL2FXCONST_DBL(M_PI / AT2O_SCALE);
224*e5436536SAndroid Build Coastguard Worker     }
225*e5436536SAndroid Build Coastguard Worker   } else {
226*e5436536SAndroid Build Coastguard Worker     // x == 0
227*e5436536SAndroid Build Coastguard Worker     if (y > FL2FXCONST_DBL(0.0f)) {
228*e5436536SAndroid Build Coastguard Worker       ret = FL2FXCONST_DBL(+M_PI / 2 / AT2O_SCALE);
229*e5436536SAndroid Build Coastguard Worker     } else if (y < FL2FXCONST_DBL(0.0f)) {
230*e5436536SAndroid Build Coastguard Worker       ret = FL2FXCONST_DBL(-M_PI / 2 / AT2O_SCALE);
231*e5436536SAndroid Build Coastguard Worker     } else if (y == FL2FXCONST_DBL(0.0f)) {
232*e5436536SAndroid Build Coastguard Worker       ret = FL2FXCONST_DBL(0.0f);
233*e5436536SAndroid Build Coastguard Worker     }
234*e5436536SAndroid Build Coastguard Worker   }
235*e5436536SAndroid Build Coastguard Worker   return ret;
236*e5436536SAndroid Build Coastguard Worker }
237*e5436536SAndroid Build Coastguard Worker 
fixp_atan(FIXP_DBL x)238*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_atan(FIXP_DBL x) {
239*e5436536SAndroid Build Coastguard Worker   INT sign;
240*e5436536SAndroid Build Coastguard Worker   FIXP_DBL result, temp;
241*e5436536SAndroid Build Coastguard Worker 
242*e5436536SAndroid Build Coastguard Worker   /* SNR of fixp_atan() = 56 dB */
243*e5436536SAndroid Build Coastguard Worker   FIXP_DBL P281 = (FIXP_DBL)0x00013000;     // 0.281 in q18
244*e5436536SAndroid Build Coastguard Worker   FIXP_DBL ONEP571 = (FIXP_DBL)0x6487ef00;  // 1.571 in q30
245*e5436536SAndroid Build Coastguard Worker 
246*e5436536SAndroid Build Coastguard Worker   if (x < FIXP_DBL(0)) {
247*e5436536SAndroid Build Coastguard Worker     sign = 1;
248*e5436536SAndroid Build Coastguard Worker     x = -x;
249*e5436536SAndroid Build Coastguard Worker   } else {
250*e5436536SAndroid Build Coastguard Worker     sign = 0;
251*e5436536SAndroid Build Coastguard Worker   }
252*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(FL2FXCONST_DBL(1.0 / 64.0) == Q(Q_ATANINP));
253*e5436536SAndroid Build Coastguard Worker   /* calc of arctan */
254*e5436536SAndroid Build Coastguard Worker   if (x < FL2FXCONST_DBL(1.0 / 64.0))
255*e5436536SAndroid Build Coastguard Worker   /*
256*e5436536SAndroid Build Coastguard Worker     Chebyshev polynomial approximation of atan(x)
257*e5436536SAndroid Build Coastguard Worker     5th-order approximation: atan(x) = a1*x + a2*x^3 + a3*x^5 = x(a1 + x^2*(a2 +
258*e5436536SAndroid Build Coastguard Worker     a3*x^2)); a1 = 0.9949493661166540f, a2 = 0.2870606355326520f, a3 =
259*e5436536SAndroid Build Coastguard Worker     0.0780371764464410f; 7th-order approximation: atan(x) = a1*x + a2*x^3 +
260*e5436536SAndroid Build Coastguard Worker     a3*x^5 + a3*x^7 = x(a1 + x^2*(a2 + x^2*(a3 + a4*x^2))); a1 =
261*e5436536SAndroid Build Coastguard Worker     0.9991334482227801, a2 = -0.3205332923816640, a3 = 0.1449824901444650, a4 =
262*e5436536SAndroid Build Coastguard Worker     -0.0382544649702990; 7th-order approximation in use (the most accurate
263*e5436536SAndroid Build Coastguard Worker     solution)
264*e5436536SAndroid Build Coastguard Worker   */
265*e5436536SAndroid Build Coastguard Worker   {
266*e5436536SAndroid Build Coastguard Worker     x <<= ATI_SF;
267*e5436536SAndroid Build Coastguard Worker     FIXP_DBL x2 = fPow2(x);
268*e5436536SAndroid Build Coastguard Worker     temp = fMultAddDiv2((FL2FXCONST_DBL(0.1449824901444650f) >> 1), x2,
269*e5436536SAndroid Build Coastguard Worker                         FL2FXCONST_DBL(-0.0382544649702990));
270*e5436536SAndroid Build Coastguard Worker     temp = fMultAddDiv2((FL2FXCONST_DBL(-0.3205332923816640f) >> 2), x2, temp);
271*e5436536SAndroid Build Coastguard Worker     temp = fMultAddDiv2((FL2FXCONST_DBL(0.9991334482227801f) >> 3), x2, temp);
272*e5436536SAndroid Build Coastguard Worker     result = fMult(x, (temp << 2));
273*e5436536SAndroid Build Coastguard Worker   } else if (x < FL2FXCONST_DBL(1.28 / 64.0)) {
274*e5436536SAndroid Build Coastguard Worker     FIXP_DBL delta_fix;
275*e5436536SAndroid Build Coastguard Worker     FIXP_DBL PI_BY_4 = FL2FXCONST_DBL(3.1415926 / 4.0) >> 1; /* pi/4 in q30 */
276*e5436536SAndroid Build Coastguard Worker 
277*e5436536SAndroid Build Coastguard Worker     delta_fix = (x - FL2FXCONST_DBL(1.0 / 64.0)) << 5; /* q30 */
278*e5436536SAndroid Build Coastguard Worker     result = PI_BY_4 + (delta_fix >> 1) - (fPow2Div2(delta_fix));
279*e5436536SAndroid Build Coastguard Worker   } else {
280*e5436536SAndroid Build Coastguard Worker     /* Other approximation for |x| > 1.28 */
281*e5436536SAndroid Build Coastguard Worker     INT res_e;
282*e5436536SAndroid Build Coastguard Worker 
283*e5436536SAndroid Build Coastguard Worker     temp = fPow2Div2(x); /* q25 * q25 - (DFRACT_BITS-1) - 1 = q18 */
284*e5436536SAndroid Build Coastguard Worker     temp = temp + P281;  /* q18 + q18 = q18 */
285*e5436536SAndroid Build Coastguard Worker     result = fDivNorm(x, temp, &res_e);
286*e5436536SAndroid Build Coastguard Worker     result = scaleValue(result,
287*e5436536SAndroid Build Coastguard Worker                         (Q_ATANOUT - Q_ATANINP + 18 - DFRACT_BITS + 1) + res_e);
288*e5436536SAndroid Build Coastguard Worker     result = ONEP571 - result; /* q30 + q30 = q30 */
289*e5436536SAndroid Build Coastguard Worker   }
290*e5436536SAndroid Build Coastguard Worker   if (sign) {
291*e5436536SAndroid Build Coastguard Worker     result = -result;
292*e5436536SAndroid Build Coastguard Worker   }
293*e5436536SAndroid Build Coastguard Worker 
294*e5436536SAndroid Build Coastguard Worker   return (result);
295*e5436536SAndroid Build Coastguard Worker }
296*e5436536SAndroid Build Coastguard Worker 
297*e5436536SAndroid Build Coastguard Worker #include "FDK_tools_rom.h"
298*e5436536SAndroid Build Coastguard Worker 
fixp_cos(FIXP_DBL x,int scale)299*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_cos(FIXP_DBL x, int scale) {
300*e5436536SAndroid Build Coastguard Worker   FIXP_DBL residual, error, sine, cosine;
301*e5436536SAndroid Build Coastguard Worker 
302*e5436536SAndroid Build Coastguard Worker   residual = fixp_sin_cos_residual_inline(x, scale, &sine, &cosine);
303*e5436536SAndroid Build Coastguard Worker   error = fMult(sine, residual);
304*e5436536SAndroid Build Coastguard Worker 
305*e5436536SAndroid Build Coastguard Worker #ifdef SINETABLE_16BIT
306*e5436536SAndroid Build Coastguard Worker   return cosine - error;
307*e5436536SAndroid Build Coastguard Worker #else
308*e5436536SAndroid Build Coastguard Worker   /* Undo downscaling by 1 which was done at fixp_sin_cos_residual_inline */
309*e5436536SAndroid Build Coastguard Worker   return SATURATE_LEFT_SHIFT(cosine - error, 1, DFRACT_BITS);
310*e5436536SAndroid Build Coastguard Worker #endif
311*e5436536SAndroid Build Coastguard Worker }
312*e5436536SAndroid Build Coastguard Worker 
fixp_sin(FIXP_DBL x,int scale)313*e5436536SAndroid Build Coastguard Worker FIXP_DBL fixp_sin(FIXP_DBL x, int scale) {
314*e5436536SAndroid Build Coastguard Worker   FIXP_DBL residual, error, sine, cosine;
315*e5436536SAndroid Build Coastguard Worker 
316*e5436536SAndroid Build Coastguard Worker   residual = fixp_sin_cos_residual_inline(x, scale, &sine, &cosine);
317*e5436536SAndroid Build Coastguard Worker   error = fMult(cosine, residual);
318*e5436536SAndroid Build Coastguard Worker 
319*e5436536SAndroid Build Coastguard Worker #ifdef SINETABLE_16BIT
320*e5436536SAndroid Build Coastguard Worker   return sine + error;
321*e5436536SAndroid Build Coastguard Worker #else
322*e5436536SAndroid Build Coastguard Worker   return SATURATE_LEFT_SHIFT(sine + error, 1, DFRACT_BITS);
323*e5436536SAndroid Build Coastguard Worker #endif
324*e5436536SAndroid Build Coastguard Worker }
325*e5436536SAndroid Build Coastguard Worker 
fixp_cos_sin(FIXP_DBL x,int scale,FIXP_DBL * cos,FIXP_DBL * sin)326*e5436536SAndroid Build Coastguard Worker void fixp_cos_sin(FIXP_DBL x, int scale, FIXP_DBL *cos, FIXP_DBL *sin) {
327*e5436536SAndroid Build Coastguard Worker   FIXP_DBL residual, error0, error1, sine, cosine;
328*e5436536SAndroid Build Coastguard Worker 
329*e5436536SAndroid Build Coastguard Worker   residual = fixp_sin_cos_residual_inline(x, scale, &sine, &cosine);
330*e5436536SAndroid Build Coastguard Worker   error0 = fMult(sine, residual);
331*e5436536SAndroid Build Coastguard Worker   error1 = fMult(cosine, residual);
332*e5436536SAndroid Build Coastguard Worker 
333*e5436536SAndroid Build Coastguard Worker #ifdef SINETABLE_16BIT
334*e5436536SAndroid Build Coastguard Worker   *cos = cosine - error0;
335*e5436536SAndroid Build Coastguard Worker   *sin = sine + error1;
336*e5436536SAndroid Build Coastguard Worker #else
337*e5436536SAndroid Build Coastguard Worker   *cos = SATURATE_LEFT_SHIFT(cosine - error0, 1, DFRACT_BITS);
338*e5436536SAndroid Build Coastguard Worker   *sin = SATURATE_LEFT_SHIFT(sine + error1, 1, DFRACT_BITS);
339*e5436536SAndroid Build Coastguard Worker #endif
340*e5436536SAndroid Build Coastguard Worker }
341