xref: /aosp_15_r20/external/speex/libspeexdsp/math_approx.h (revision 28e138c64d234588b5cd2a8a403b584bd3036e4e)
1*28e138c6SAndroid Build Coastguard Worker /* Copyright (C) 2002 Jean-Marc Valin */
2*28e138c6SAndroid Build Coastguard Worker /**
3*28e138c6SAndroid Build Coastguard Worker    @file math_approx.h
4*28e138c6SAndroid Build Coastguard Worker    @brief Various math approximation functions for Speex
5*28e138c6SAndroid Build Coastguard Worker */
6*28e138c6SAndroid Build Coastguard Worker /*
7*28e138c6SAndroid Build Coastguard Worker    Redistribution and use in source and binary forms, with or without
8*28e138c6SAndroid Build Coastguard Worker    modification, are permitted provided that the following conditions
9*28e138c6SAndroid Build Coastguard Worker    are met:
10*28e138c6SAndroid Build Coastguard Worker 
11*28e138c6SAndroid Build Coastguard Worker    - Redistributions of source code must retain the above copyright
12*28e138c6SAndroid Build Coastguard Worker    notice, this list of conditions and the following disclaimer.
13*28e138c6SAndroid Build Coastguard Worker 
14*28e138c6SAndroid Build Coastguard Worker    - Redistributions in binary form must reproduce the above copyright
15*28e138c6SAndroid Build Coastguard Worker    notice, this list of conditions and the following disclaimer in the
16*28e138c6SAndroid Build Coastguard Worker    documentation and/or other materials provided with the distribution.
17*28e138c6SAndroid Build Coastguard Worker 
18*28e138c6SAndroid Build Coastguard Worker    - Neither the name of the Xiph.org Foundation nor the names of its
19*28e138c6SAndroid Build Coastguard Worker    contributors may be used to endorse or promote products derived from
20*28e138c6SAndroid Build Coastguard Worker    this software without specific prior written permission.
21*28e138c6SAndroid Build Coastguard Worker 
22*28e138c6SAndroid Build Coastguard Worker    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23*28e138c6SAndroid Build Coastguard Worker    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24*28e138c6SAndroid Build Coastguard Worker    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25*28e138c6SAndroid Build Coastguard Worker    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
26*28e138c6SAndroid Build Coastguard Worker    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27*28e138c6SAndroid Build Coastguard Worker    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28*28e138c6SAndroid Build Coastguard Worker    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29*28e138c6SAndroid Build Coastguard Worker    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30*28e138c6SAndroid Build Coastguard Worker    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31*28e138c6SAndroid Build Coastguard Worker    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32*28e138c6SAndroid Build Coastguard Worker    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*28e138c6SAndroid Build Coastguard Worker */
34*28e138c6SAndroid Build Coastguard Worker 
35*28e138c6SAndroid Build Coastguard Worker #ifndef MATH_APPROX_H
36*28e138c6SAndroid Build Coastguard Worker #define MATH_APPROX_H
37*28e138c6SAndroid Build Coastguard Worker 
38*28e138c6SAndroid Build Coastguard Worker #include "arch.h"
39*28e138c6SAndroid Build Coastguard Worker 
40*28e138c6SAndroid Build Coastguard Worker #ifndef FIXED_POINT
41*28e138c6SAndroid Build Coastguard Worker 
42*28e138c6SAndroid Build Coastguard Worker #define spx_sqrt sqrt
43*28e138c6SAndroid Build Coastguard Worker #define spx_acos acos
44*28e138c6SAndroid Build Coastguard Worker #define spx_exp exp
45*28e138c6SAndroid Build Coastguard Worker #define spx_cos_norm(x) (cos((.5f*M_PI)*(x)))
46*28e138c6SAndroid Build Coastguard Worker #define spx_atan atan
47*28e138c6SAndroid Build Coastguard Worker 
48*28e138c6SAndroid Build Coastguard Worker /** Generate a pseudo-random number */
speex_rand(spx_word16_t std,spx_int32_t * seed)49*28e138c6SAndroid Build Coastguard Worker static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
50*28e138c6SAndroid Build Coastguard Worker {
51*28e138c6SAndroid Build Coastguard Worker    const unsigned int jflone = 0x3f800000;
52*28e138c6SAndroid Build Coastguard Worker    const unsigned int jflmsk = 0x007fffff;
53*28e138c6SAndroid Build Coastguard Worker    union {int i; float f;} ran;
54*28e138c6SAndroid Build Coastguard Worker    *seed = 1664525 * *seed + 1013904223;
55*28e138c6SAndroid Build Coastguard Worker    ran.i = jflone | (jflmsk & *seed);
56*28e138c6SAndroid Build Coastguard Worker    ran.f -= 1.5;
57*28e138c6SAndroid Build Coastguard Worker    return 3.4642*std*ran.f;
58*28e138c6SAndroid Build Coastguard Worker }
59*28e138c6SAndroid Build Coastguard Worker 
60*28e138c6SAndroid Build Coastguard Worker 
61*28e138c6SAndroid Build Coastguard Worker #endif
62*28e138c6SAndroid Build Coastguard Worker 
63*28e138c6SAndroid Build Coastguard Worker 
spx_ilog2(spx_uint32_t x)64*28e138c6SAndroid Build Coastguard Worker static inline spx_int16_t spx_ilog2(spx_uint32_t x)
65*28e138c6SAndroid Build Coastguard Worker {
66*28e138c6SAndroid Build Coastguard Worker    int r=0;
67*28e138c6SAndroid Build Coastguard Worker    if (x>=(spx_int32_t)65536)
68*28e138c6SAndroid Build Coastguard Worker    {
69*28e138c6SAndroid Build Coastguard Worker       x >>= 16;
70*28e138c6SAndroid Build Coastguard Worker       r += 16;
71*28e138c6SAndroid Build Coastguard Worker    }
72*28e138c6SAndroid Build Coastguard Worker    if (x>=256)
73*28e138c6SAndroid Build Coastguard Worker    {
74*28e138c6SAndroid Build Coastguard Worker       x >>= 8;
75*28e138c6SAndroid Build Coastguard Worker       r += 8;
76*28e138c6SAndroid Build Coastguard Worker    }
77*28e138c6SAndroid Build Coastguard Worker    if (x>=16)
78*28e138c6SAndroid Build Coastguard Worker    {
79*28e138c6SAndroid Build Coastguard Worker       x >>= 4;
80*28e138c6SAndroid Build Coastguard Worker       r += 4;
81*28e138c6SAndroid Build Coastguard Worker    }
82*28e138c6SAndroid Build Coastguard Worker    if (x>=4)
83*28e138c6SAndroid Build Coastguard Worker    {
84*28e138c6SAndroid Build Coastguard Worker       x >>= 2;
85*28e138c6SAndroid Build Coastguard Worker       r += 2;
86*28e138c6SAndroid Build Coastguard Worker    }
87*28e138c6SAndroid Build Coastguard Worker    if (x>=2)
88*28e138c6SAndroid Build Coastguard Worker    {
89*28e138c6SAndroid Build Coastguard Worker       r += 1;
90*28e138c6SAndroid Build Coastguard Worker    }
91*28e138c6SAndroid Build Coastguard Worker    return r;
92*28e138c6SAndroid Build Coastguard Worker }
93*28e138c6SAndroid Build Coastguard Worker 
spx_ilog4(spx_uint32_t x)94*28e138c6SAndroid Build Coastguard Worker static inline spx_int16_t spx_ilog4(spx_uint32_t x)
95*28e138c6SAndroid Build Coastguard Worker {
96*28e138c6SAndroid Build Coastguard Worker    int r=0;
97*28e138c6SAndroid Build Coastguard Worker    if (x>=(spx_int32_t)65536)
98*28e138c6SAndroid Build Coastguard Worker    {
99*28e138c6SAndroid Build Coastguard Worker       x >>= 16;
100*28e138c6SAndroid Build Coastguard Worker       r += 8;
101*28e138c6SAndroid Build Coastguard Worker    }
102*28e138c6SAndroid Build Coastguard Worker    if (x>=256)
103*28e138c6SAndroid Build Coastguard Worker    {
104*28e138c6SAndroid Build Coastguard Worker       x >>= 8;
105*28e138c6SAndroid Build Coastguard Worker       r += 4;
106*28e138c6SAndroid Build Coastguard Worker    }
107*28e138c6SAndroid Build Coastguard Worker    if (x>=16)
108*28e138c6SAndroid Build Coastguard Worker    {
109*28e138c6SAndroid Build Coastguard Worker       x >>= 4;
110*28e138c6SAndroid Build Coastguard Worker       r += 2;
111*28e138c6SAndroid Build Coastguard Worker    }
112*28e138c6SAndroid Build Coastguard Worker    if (x>=4)
113*28e138c6SAndroid Build Coastguard Worker    {
114*28e138c6SAndroid Build Coastguard Worker       r += 1;
115*28e138c6SAndroid Build Coastguard Worker    }
116*28e138c6SAndroid Build Coastguard Worker    return r;
117*28e138c6SAndroid Build Coastguard Worker }
118*28e138c6SAndroid Build Coastguard Worker 
119*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
120*28e138c6SAndroid Build Coastguard Worker 
121*28e138c6SAndroid Build Coastguard Worker /** Generate a pseudo-random number */
speex_rand(spx_word16_t std,spx_int32_t * seed)122*28e138c6SAndroid Build Coastguard Worker static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
123*28e138c6SAndroid Build Coastguard Worker {
124*28e138c6SAndroid Build Coastguard Worker    spx_word32_t res;
125*28e138c6SAndroid Build Coastguard Worker    *seed = 1664525 * *seed + 1013904223;
126*28e138c6SAndroid Build Coastguard Worker    res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std);
127*28e138c6SAndroid Build Coastguard Worker    return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14));
128*28e138c6SAndroid Build Coastguard Worker }
129*28e138c6SAndroid Build Coastguard Worker 
130*28e138c6SAndroid Build Coastguard Worker /* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */
131*28e138c6SAndroid Build Coastguard Worker /*#define C0 3634
132*28e138c6SAndroid Build Coastguard Worker #define C1 21173
133*28e138c6SAndroid Build Coastguard Worker #define C2 -12627
134*28e138c6SAndroid Build Coastguard Worker #define C3 4215*/
135*28e138c6SAndroid Build Coastguard Worker 
136*28e138c6SAndroid Build Coastguard Worker /* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */
137*28e138c6SAndroid Build Coastguard Worker #define C0 3634
138*28e138c6SAndroid Build Coastguard Worker #define C1 21173
139*28e138c6SAndroid Build Coastguard Worker #define C2 -12627
140*28e138c6SAndroid Build Coastguard Worker #define C3 4204
141*28e138c6SAndroid Build Coastguard Worker 
spx_sqrt(spx_word32_t x)142*28e138c6SAndroid Build Coastguard Worker static inline spx_word16_t spx_sqrt(spx_word32_t x)
143*28e138c6SAndroid Build Coastguard Worker {
144*28e138c6SAndroid Build Coastguard Worker    int k;
145*28e138c6SAndroid Build Coastguard Worker    spx_word32_t rt;
146*28e138c6SAndroid Build Coastguard Worker    k = spx_ilog4(x)-6;
147*28e138c6SAndroid Build Coastguard Worker    x = VSHR32(x, (k<<1));
148*28e138c6SAndroid Build Coastguard Worker    rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
149*28e138c6SAndroid Build Coastguard Worker    rt = VSHR32(rt,7-k);
150*28e138c6SAndroid Build Coastguard Worker    return rt;
151*28e138c6SAndroid Build Coastguard Worker }
152*28e138c6SAndroid Build Coastguard Worker 
153*28e138c6SAndroid Build Coastguard Worker /* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */
154*28e138c6SAndroid Build Coastguard Worker 
155*28e138c6SAndroid Build Coastguard Worker 
156*28e138c6SAndroid Build Coastguard Worker #define A1 16469
157*28e138c6SAndroid Build Coastguard Worker #define A2 2242
158*28e138c6SAndroid Build Coastguard Worker #define A3 1486
159*28e138c6SAndroid Build Coastguard Worker 
spx_acos(spx_word16_t x)160*28e138c6SAndroid Build Coastguard Worker static inline spx_word16_t spx_acos(spx_word16_t x)
161*28e138c6SAndroid Build Coastguard Worker {
162*28e138c6SAndroid Build Coastguard Worker    int s=0;
163*28e138c6SAndroid Build Coastguard Worker    spx_word16_t ret;
164*28e138c6SAndroid Build Coastguard Worker    spx_word16_t sq;
165*28e138c6SAndroid Build Coastguard Worker    if (x<0)
166*28e138c6SAndroid Build Coastguard Worker    {
167*28e138c6SAndroid Build Coastguard Worker       s=1;
168*28e138c6SAndroid Build Coastguard Worker       x = NEG16(x);
169*28e138c6SAndroid Build Coastguard Worker    }
170*28e138c6SAndroid Build Coastguard Worker    x = SUB16(16384,x);
171*28e138c6SAndroid Build Coastguard Worker 
172*28e138c6SAndroid Build Coastguard Worker    x = x >> 1;
173*28e138c6SAndroid Build Coastguard Worker    sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));
174*28e138c6SAndroid Build Coastguard Worker    ret = spx_sqrt(SHL32(EXTEND32(sq),13));
175*28e138c6SAndroid Build Coastguard Worker 
176*28e138c6SAndroid Build Coastguard Worker    /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/
177*28e138c6SAndroid Build Coastguard Worker    if (s)
178*28e138c6SAndroid Build Coastguard Worker       ret = SUB16(25736,ret);
179*28e138c6SAndroid Build Coastguard Worker    return ret;
180*28e138c6SAndroid Build Coastguard Worker }
181*28e138c6SAndroid Build Coastguard Worker 
182*28e138c6SAndroid Build Coastguard Worker 
183*28e138c6SAndroid Build Coastguard Worker #define K1 8192
184*28e138c6SAndroid Build Coastguard Worker #define K2 -4096
185*28e138c6SAndroid Build Coastguard Worker #define K3 340
186*28e138c6SAndroid Build Coastguard Worker #define K4 -10
187*28e138c6SAndroid Build Coastguard Worker 
spx_cos(spx_word16_t x)188*28e138c6SAndroid Build Coastguard Worker static inline spx_word16_t spx_cos(spx_word16_t x)
189*28e138c6SAndroid Build Coastguard Worker {
190*28e138c6SAndroid Build Coastguard Worker    spx_word16_t x2;
191*28e138c6SAndroid Build Coastguard Worker 
192*28e138c6SAndroid Build Coastguard Worker    if (x<12868)
193*28e138c6SAndroid Build Coastguard Worker    {
194*28e138c6SAndroid Build Coastguard Worker       x2 = MULT16_16_P13(x,x);
195*28e138c6SAndroid Build Coastguard Worker       return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
196*28e138c6SAndroid Build Coastguard Worker    } else {
197*28e138c6SAndroid Build Coastguard Worker       x = SUB16(25736,x);
198*28e138c6SAndroid Build Coastguard Worker       x2 = MULT16_16_P13(x,x);
199*28e138c6SAndroid Build Coastguard Worker       return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
200*28e138c6SAndroid Build Coastguard Worker    }
201*28e138c6SAndroid Build Coastguard Worker }
202*28e138c6SAndroid Build Coastguard Worker 
203*28e138c6SAndroid Build Coastguard Worker #define L1 32767
204*28e138c6SAndroid Build Coastguard Worker #define L2 -7651
205*28e138c6SAndroid Build Coastguard Worker #define L3 8277
206*28e138c6SAndroid Build Coastguard Worker #define L4 -626
207*28e138c6SAndroid Build Coastguard Worker 
_spx_cos_pi_2(spx_word16_t x)208*28e138c6SAndroid Build Coastguard Worker static inline spx_word16_t _spx_cos_pi_2(spx_word16_t x)
209*28e138c6SAndroid Build Coastguard Worker {
210*28e138c6SAndroid Build Coastguard Worker    spx_word16_t x2;
211*28e138c6SAndroid Build Coastguard Worker 
212*28e138c6SAndroid Build Coastguard Worker    x2 = MULT16_16_P15(x,x);
213*28e138c6SAndroid Build Coastguard Worker    return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2))))))));
214*28e138c6SAndroid Build Coastguard Worker }
215*28e138c6SAndroid Build Coastguard Worker 
spx_cos_norm(spx_word32_t x)216*28e138c6SAndroid Build Coastguard Worker static inline spx_word16_t spx_cos_norm(spx_word32_t x)
217*28e138c6SAndroid Build Coastguard Worker {
218*28e138c6SAndroid Build Coastguard Worker    x = x&0x0001ffff;
219*28e138c6SAndroid Build Coastguard Worker    if (x>SHL32(EXTEND32(1), 16))
220*28e138c6SAndroid Build Coastguard Worker       x = SUB32(SHL32(EXTEND32(1), 17),x);
221*28e138c6SAndroid Build Coastguard Worker    if (x&0x00007fff)
222*28e138c6SAndroid Build Coastguard Worker    {
223*28e138c6SAndroid Build Coastguard Worker       if (x<SHL32(EXTEND32(1), 15))
224*28e138c6SAndroid Build Coastguard Worker       {
225*28e138c6SAndroid Build Coastguard Worker          return _spx_cos_pi_2(EXTRACT16(x));
226*28e138c6SAndroid Build Coastguard Worker       } else {
227*28e138c6SAndroid Build Coastguard Worker          return NEG32(_spx_cos_pi_2(EXTRACT16(65536-x)));
228*28e138c6SAndroid Build Coastguard Worker       }
229*28e138c6SAndroid Build Coastguard Worker    } else {
230*28e138c6SAndroid Build Coastguard Worker       if (x&0x0000ffff)
231*28e138c6SAndroid Build Coastguard Worker          return 0;
232*28e138c6SAndroid Build Coastguard Worker       else if (x&0x0001ffff)
233*28e138c6SAndroid Build Coastguard Worker          return -32767;
234*28e138c6SAndroid Build Coastguard Worker       else
235*28e138c6SAndroid Build Coastguard Worker          return 32767;
236*28e138c6SAndroid Build Coastguard Worker    }
237*28e138c6SAndroid Build Coastguard Worker }
238*28e138c6SAndroid Build Coastguard Worker 
239*28e138c6SAndroid Build Coastguard Worker /*
240*28e138c6SAndroid Build Coastguard Worker  K0 = 1
241*28e138c6SAndroid Build Coastguard Worker  K1 = log(2)
242*28e138c6SAndroid Build Coastguard Worker  K2 = 3-4*log(2)
243*28e138c6SAndroid Build Coastguard Worker  K3 = 3*log(2) - 2
244*28e138c6SAndroid Build Coastguard Worker */
245*28e138c6SAndroid Build Coastguard Worker #define D0 16384
246*28e138c6SAndroid Build Coastguard Worker #define D1 11356
247*28e138c6SAndroid Build Coastguard Worker #define D2 3726
248*28e138c6SAndroid Build Coastguard Worker #define D3 1301
249*28e138c6SAndroid Build Coastguard Worker /* Input in Q11 format, output in Q16 */
spx_exp2(spx_word16_t x)250*28e138c6SAndroid Build Coastguard Worker static inline spx_word32_t spx_exp2(spx_word16_t x)
251*28e138c6SAndroid Build Coastguard Worker {
252*28e138c6SAndroid Build Coastguard Worker    int integer;
253*28e138c6SAndroid Build Coastguard Worker    spx_word16_t frac;
254*28e138c6SAndroid Build Coastguard Worker    integer = SHR16(x,11);
255*28e138c6SAndroid Build Coastguard Worker    if (integer>14)
256*28e138c6SAndroid Build Coastguard Worker       return 0x7fffffff;
257*28e138c6SAndroid Build Coastguard Worker    else if (integer < -15)
258*28e138c6SAndroid Build Coastguard Worker       return 0;
259*28e138c6SAndroid Build Coastguard Worker    frac = SHL16(x-SHL16(integer,11),3);
260*28e138c6SAndroid Build Coastguard Worker    frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac))))));
261*28e138c6SAndroid Build Coastguard Worker    return VSHR32(EXTEND32(frac), -integer-2);
262*28e138c6SAndroid Build Coastguard Worker }
263*28e138c6SAndroid Build Coastguard Worker 
264*28e138c6SAndroid Build Coastguard Worker /* Input in Q11 format, output in Q16 */
spx_exp(spx_word16_t x)265*28e138c6SAndroid Build Coastguard Worker static inline spx_word32_t spx_exp(spx_word16_t x)
266*28e138c6SAndroid Build Coastguard Worker {
267*28e138c6SAndroid Build Coastguard Worker    if (x>21290)
268*28e138c6SAndroid Build Coastguard Worker       return 0x7fffffff;
269*28e138c6SAndroid Build Coastguard Worker    else if (x<-21290)
270*28e138c6SAndroid Build Coastguard Worker       return 0;
271*28e138c6SAndroid Build Coastguard Worker    else
272*28e138c6SAndroid Build Coastguard Worker       return spx_exp2(MULT16_16_P14(23637,x));
273*28e138c6SAndroid Build Coastguard Worker }
274*28e138c6SAndroid Build Coastguard Worker #define M1 32767
275*28e138c6SAndroid Build Coastguard Worker #define M2 -21
276*28e138c6SAndroid Build Coastguard Worker #define M3 -11943
277*28e138c6SAndroid Build Coastguard Worker #define M4 4936
278*28e138c6SAndroid Build Coastguard Worker 
spx_atan01(spx_word16_t x)279*28e138c6SAndroid Build Coastguard Worker static inline spx_word16_t spx_atan01(spx_word16_t x)
280*28e138c6SAndroid Build Coastguard Worker {
281*28e138c6SAndroid Build Coastguard Worker    return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
282*28e138c6SAndroid Build Coastguard Worker }
283*28e138c6SAndroid Build Coastguard Worker 
284*28e138c6SAndroid Build Coastguard Worker #undef M1
285*28e138c6SAndroid Build Coastguard Worker #undef M2
286*28e138c6SAndroid Build Coastguard Worker #undef M3
287*28e138c6SAndroid Build Coastguard Worker #undef M4
288*28e138c6SAndroid Build Coastguard Worker 
289*28e138c6SAndroid Build Coastguard Worker /* Input in Q15, output in Q14 */
spx_atan(spx_word32_t x)290*28e138c6SAndroid Build Coastguard Worker static inline spx_word16_t spx_atan(spx_word32_t x)
291*28e138c6SAndroid Build Coastguard Worker {
292*28e138c6SAndroid Build Coastguard Worker    if (x <= 32767)
293*28e138c6SAndroid Build Coastguard Worker    {
294*28e138c6SAndroid Build Coastguard Worker       return SHR16(spx_atan01(x),1);
295*28e138c6SAndroid Build Coastguard Worker    } else {
296*28e138c6SAndroid Build Coastguard Worker       int e = spx_ilog2(x);
297*28e138c6SAndroid Build Coastguard Worker       if (e>=29)
298*28e138c6SAndroid Build Coastguard Worker          return 25736;
299*28e138c6SAndroid Build Coastguard Worker       x = DIV32_16(SHL32(EXTEND32(32767),29-e), EXTRACT16(SHR32(x, e-14)));
300*28e138c6SAndroid Build Coastguard Worker       return SUB16(25736, SHR16(spx_atan01(x),1));
301*28e138c6SAndroid Build Coastguard Worker    }
302*28e138c6SAndroid Build Coastguard Worker }
303*28e138c6SAndroid Build Coastguard Worker #else
304*28e138c6SAndroid Build Coastguard Worker 
305*28e138c6SAndroid Build Coastguard Worker #ifndef M_PI
306*28e138c6SAndroid Build Coastguard Worker #define M_PI           3.14159265358979323846  /* pi */
307*28e138c6SAndroid Build Coastguard Worker #endif
308*28e138c6SAndroid Build Coastguard Worker 
309*28e138c6SAndroid Build Coastguard Worker #define C1 0.9999932946f
310*28e138c6SAndroid Build Coastguard Worker #define C2 -0.4999124376f
311*28e138c6SAndroid Build Coastguard Worker #define C3 0.0414877472f
312*28e138c6SAndroid Build Coastguard Worker #define C4 -0.0012712095f
313*28e138c6SAndroid Build Coastguard Worker 
314*28e138c6SAndroid Build Coastguard Worker 
315*28e138c6SAndroid Build Coastguard Worker #define SPX_PI_2 1.5707963268
spx_cos(spx_word16_t x)316*28e138c6SAndroid Build Coastguard Worker static inline spx_word16_t spx_cos(spx_word16_t x)
317*28e138c6SAndroid Build Coastguard Worker {
318*28e138c6SAndroid Build Coastguard Worker    if (x<SPX_PI_2)
319*28e138c6SAndroid Build Coastguard Worker    {
320*28e138c6SAndroid Build Coastguard Worker       x *= x;
321*28e138c6SAndroid Build Coastguard Worker       return C1 + x*(C2+x*(C3+C4*x));
322*28e138c6SAndroid Build Coastguard Worker    } else {
323*28e138c6SAndroid Build Coastguard Worker       x = M_PI-x;
324*28e138c6SAndroid Build Coastguard Worker       x *= x;
325*28e138c6SAndroid Build Coastguard Worker       return NEG16(C1 + x*(C2+x*(C3+C4*x)));
326*28e138c6SAndroid Build Coastguard Worker    }
327*28e138c6SAndroid Build Coastguard Worker }
328*28e138c6SAndroid Build Coastguard Worker 
329*28e138c6SAndroid Build Coastguard Worker #endif
330*28e138c6SAndroid Build Coastguard Worker 
331*28e138c6SAndroid Build Coastguard Worker 
332*28e138c6SAndroid Build Coastguard Worker #endif
333