math_approx.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* Copyright (C) 2002 Jean-Marc Valin
  2. File: math_approx.c
  3. Various math approximation functions for Speex
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions
  6. are met:
  7. - Redistributions of source code must retain the above copyright
  8. notice, this list of conditions and the following disclaimer.
  9. - Redistributions in binary form must reproduce the above copyright
  10. notice, this list of conditions and the following disclaimer in the
  11. documentation and/or other materials provided with the distribution.
  12. - Neither the name of the Xiph.org Foundation nor the names of its
  13. contributors may be used to endorse or promote products derived from
  14. this software without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  18. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
  19. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  20. EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  21. PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  22. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  23. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  24. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #ifdef HAVE_CONFIG_H
  28. #include "config.h"
  29. #endif
  30. #include "math_approx.h"
  31. #include "misc.h"
  32. #ifdef FIXED_POINT
  33. /* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */
  34. #define C0 3634
  35. #define C1 21173
  36. #define C2 -12627
  37. #define C3 4215
  38. spx_word16_t spx_sqrt(spx_word32_t x)
  39. {
  40. int k=0;
  41. spx_word32_t rt;
  42. if (x==0)
  43. return 0;
  44. #if 1
  45. if (x>16777216)
  46. {
  47. x>>=10;
  48. k+=5;
  49. }
  50. if (x>1048576)
  51. {
  52. x>>=6;
  53. k+=3;
  54. }
  55. if (x>262144)
  56. {
  57. x>>=4;
  58. k+=2;
  59. }
  60. if (x>32768)
  61. {
  62. x>>=2;
  63. k+=1;
  64. }
  65. if (x>16384)
  66. {
  67. x>>=2;
  68. k+=1;
  69. }
  70. #else
  71. while (x>16384)
  72. {
  73. x>>=2;
  74. k++;
  75. }
  76. #endif
  77. while (x<4096)
  78. {
  79. x<<=2;
  80. k--;
  81. }
  82. rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
  83. if (k>0)
  84. rt <<= k;
  85. else
  86. rt >>= -k;
  87. rt >>=7;
  88. return rt;
  89. }
  90. /* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */
  91. #define A1 16469
  92. #define A2 2242
  93. #define A3 1486
  94. spx_word16_t spx_acos(spx_word16_t x)
  95. {
  96. int s=0;
  97. spx_word16_t ret;
  98. spx_word16_t sq;
  99. if (x<0)
  100. {
  101. s=1;
  102. x = NEG16(x);
  103. }
  104. x = SUB16(16384,x);
  105. x = x >> 1;
  106. sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));
  107. ret = spx_sqrt(SHL32(EXTEND32(sq),13));
  108. /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/
  109. if (s)
  110. ret = SUB16(25736,ret);
  111. return ret;
  112. }
  113. #define K1 8192
  114. #define K2 -4096
  115. #define K3 340
  116. #define K4 -10
  117. spx_word16_t spx_cos(spx_word16_t x)
  118. {
  119. spx_word16_t x2;
  120. if (x<12868)
  121. {
  122. x2 = MULT16_16_P13(x,x);
  123. return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
  124. } else {
  125. x = SUB16(25736,x);
  126. x2 = MULT16_16_P13(x,x);
  127. return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2))))));
  128. }
  129. }
  130. #else
  131. #ifndef M_PI
  132. #define M_PI 3.14159265358979323846 /* pi */
  133. #endif
  134. #define C1 0.9999932946f
  135. #define C2 -0.4999124376f
  136. #define C3 0.0414877472f
  137. #define C4 -0.0012712095f
  138. #define SPX_PI_2 1.5707963268
  139. spx_word16_t spx_cos(spx_word16_t x)
  140. {
  141. if (x<SPX_PI_2)
  142. {
  143. x *= x;
  144. return C1 + x*(C2+x*(C3+C4*x));
  145. } else {
  146. x = M_PI-x;
  147. x *= x;
  148. return NEG16(C1 + x*(C2+x*(C3+C4*x)));
  149. }
  150. }
  151. #endif
粤ICP备19079148号