| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- /* Copyright (C) 2002 Jean-Marc Valin
- File: math_approx.c
- Various math approximation functions for Speex
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- - Neither the name of the Xiph.org Foundation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "math_approx.h"
- #include "misc.h"
- #ifdef FIXED_POINT
- /* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */
- #define C0 3634
- #define C1 21173
- #define C2 -12627
- #define C3 4215
- spx_word16_t spx_sqrt(spx_word32_t x)
- {
- int k=0;
- spx_word32_t rt;
- if (x==0)
- return 0;
- #if 1
- if (x>16777216)
- {
- x>>=10;
- k+=5;
- }
- if (x>1048576)
- {
- x>>=6;
- k+=3;
- }
- if (x>262144)
- {
- x>>=4;
- k+=2;
- }
- if (x>32768)
- {
- x>>=2;
- k+=1;
- }
- if (x>16384)
- {
- x>>=2;
- k+=1;
- }
- #else
- while (x>16384)
- {
- x>>=2;
- k++;
- }
- #endif
- while (x<4096)
- {
- x<<=2;
- k--;
- }
- rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
- if (k>0)
- rt <<= k;
- else
- rt >>= -k;
- rt >>=7;
- return rt;
- }
- /* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */
- #define A1 16469
- #define A2 2242
- #define A3 1486
- spx_word16_t spx_acos(spx_word16_t x)
- {
- int s=0;
- spx_word16_t ret;
- spx_word16_t sq;
- if (x<0)
- {
- s=1;
- x = NEG16(x);
- }
- x = SUB16(16384,x);
-
- x = x >> 1;
- sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));
- ret = spx_sqrt(SHL32(EXTEND32(sq),13));
-
- /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/
- if (s)
- ret = SUB16(25736,ret);
- return ret;
- }
- #define K1 8192
- #define K2 -4096
- #define K3 340
- #define K4 -10
- spx_word16_t spx_cos(spx_word16_t x)
- {
- spx_word16_t x2;
- if (x<12868)
- {
- x2 = MULT16_16_P13(x,x);
- return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
- } else {
- x = SUB16(25736,x);
- x2 = MULT16_16_P13(x,x);
- return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
- }
- }
- #else
- #ifndef M_PI
- #define M_PI 3.14159265358979323846 /* pi */
- #endif
- #define C1 0.9999932946f
- #define C2 -0.4999124376f
- #define C3 0.0414877472f
- #define C4 -0.0012712095f
- #define SPX_PI_2 1.5707963268
- spx_word16_t spx_cos(spx_word16_t x)
- {
- if (x<SPX_PI_2)
- {
- x *= x;
- return C1 + x*(C2+x*(C3+C4*x));
- } else {
- x = M_PI-x;
- x *= x;
- return NEG16(C1 + x*(C2+x*(C3+C4*x)));
- }
- }
- #endif
|