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