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