sbrmath.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Source last modified: $Id: sbrmath.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $
  3. *
  4. * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
  5. *
  6. * The contents of this file, and the files included with this file,
  7. * are subject to the current version of the RealNetworks Public
  8. * Source License (the "RPSL") available at
  9. * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10. * the file under the current version of the RealNetworks Community
  11. * Source License (the "RCSL") available at
  12. * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13. * will apply. You may also obtain the license terms directly from
  14. * RealNetworks. You may not use this file except in compliance with
  15. * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16. * to this file, the RCSL. Please see the applicable RPSL or RCSL for
  17. * the rights, obligations and limitations governing use of the
  18. * contents of the file.
  19. *
  20. * This file is part of the Helix DNA Technology. RealNetworks is the
  21. * developer of the Original Code and owns the copyrights in the
  22. * portions it created.
  23. *
  24. * This file, and the files included with this file, is distributed
  25. * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  26. * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  27. * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  28. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  29. * ENJOYMENT OR NON-INFRINGEMENT.
  30. *
  31. * Technology Compatibility Kit Test Suite(s) Location:
  32. * http://www.helixcommunity.org/content/tck
  33. *
  34. * Contributor(s):
  35. *
  36. * ***** END LICENSE BLOCK ***** */
  37. /**************************************************************************************
  38. * Fixed-point HE-AAC decoder
  39. * Jon Recker (jrecker@real.com)
  40. * February 2005
  41. *
  42. * sbrmath.c - fixed-point math functions for SBR
  43. **************************************************************************************/
  44. #include "sbr.h"
  45. #include "assembly.h"
  46. #define Q28_2 0x20000000 /* Q28: 2.0 */
  47. #define Q28_15 0x30000000 /* Q28: 1.5 */
  48. #define NUM_ITER_IRN 5
  49. /**************************************************************************************
  50. * Function: InvRNormalized
  51. *
  52. * Description: use Newton's method to solve for x = 1/r
  53. *
  54. * Inputs: r = Q31, range = [0.5, 1) (normalize your inputs to this range)
  55. *
  56. * Outputs: none
  57. *
  58. * Return: x = Q29, range ~= [1.0, 2.0]
  59. *
  60. * Notes: guaranteed to converge and not overflow for any r in [0.5, 1)
  61. *
  62. * xn+1 = xn - f(xn)/f'(xn)
  63. * f(x) = 1/r - x = 0 (find root)
  64. * = 1/x - r
  65. * f'(x) = -1/x^2
  66. *
  67. * so xn+1 = xn - (1/xn - r) / (-1/xn^2)
  68. * = xn * (2 - r*xn)
  69. *
  70. * NUM_ITER_IRN = 2, maxDiff = 6.2500e-02 (precision of about 4 bits)
  71. * NUM_ITER_IRN = 3, maxDiff = 3.9063e-03 (precision of about 8 bits)
  72. * NUM_ITER_IRN = 4, maxDiff = 1.5288e-05 (precision of about 16 bits)
  73. * NUM_ITER_IRN = 5, maxDiff = 3.0034e-08 (precision of about 24 bits)
  74. **************************************************************************************/
  75. int InvRNormalized(int r)
  76. {
  77. int i, xn, t;
  78. /* r = [0.5, 1.0)
  79. * 1/r = (1.0, 2.0]
  80. * so use 1.5 as initial guess
  81. */
  82. xn = Q28_15;
  83. /* xn = xn*(2.0 - r*xn) */
  84. for (i = NUM_ITER_IRN; i != 0; i--) {
  85. t = MULSHIFT32(r, xn); /* Q31*Q29 = Q28 */
  86. t = Q28_2 - t; /* Q28 */
  87. xn = MULSHIFT32(xn, t) << 4; /* Q29*Q28 << 4 = Q29 */
  88. }
  89. return xn;
  90. }
  91. #define NUM_TERMS_RPI 5
  92. #define LOG2_EXP_INV 0x58b90bfc /* 1/log2(e), Q31 */
  93. /* invTab[x] = 1/(x+1), format = Q30 */
  94. static const int invTab[NUM_TERMS_RPI] PROGMEM = {0x40000000, 0x20000000, 0x15555555, 0x10000000, 0x0ccccccd};
  95. /**************************************************************************************
  96. * Function: RatioPowInv
  97. *
  98. * Description: use Taylor (MacLaurin) series expansion to calculate (a/b) ^ (1/c)
  99. *
  100. * Inputs: a = [1, 64], b = [1, 64], c = [1, 64], a >= b
  101. *
  102. * Outputs: none
  103. *
  104. * Return: y = Q24, range ~= [0.015625, 64]
  105. **************************************************************************************/
  106. int RatioPowInv(int a, int b, int c)
  107. {
  108. int lna, lnb, i, p, t, y;
  109. if (a < 1 || b < 1 || c < 1 || a > 64 || b > 64 || c > 64 || a < b)
  110. return 0;
  111. lna = MULSHIFT32(log2Tab[a], LOG2_EXP_INV) << 1; /* ln(a), Q28 */
  112. lnb = MULSHIFT32(log2Tab[b], LOG2_EXP_INV) << 1; /* ln(b), Q28 */
  113. p = (lna - lnb) / c; /* Q28 */
  114. /* sum in Q24 */
  115. y = (1 << 24);
  116. t = p >> 4; /* t = p^1 * 1/1! (Q24)*/
  117. y += t;
  118. for (i = 2; i <= NUM_TERMS_RPI; i++) {
  119. t = MULSHIFT32(invTab[i-1], t) << 2;
  120. t = MULSHIFT32(p, t) << 4; /* t = p^i * 1/i! (Q24) */
  121. y += t;
  122. }
  123. return y;
  124. }
  125. /**************************************************************************************
  126. * Function: SqrtFix
  127. *
  128. * Description: use binary search to calculate sqrt(q)
  129. *
  130. * Inputs: q = Q30
  131. * number of fraction bits in input
  132. *
  133. * Outputs: number of fraction bits in output
  134. *
  135. * Return: lo = Q(fBitsOut)
  136. *
  137. * Notes: absolute precision varies depending on fBitsIn
  138. * normalizes input to range [0x200000000, 0x7fffffff] and takes
  139. * floor(sqrt(input)), and sets fBitsOut appropriately
  140. **************************************************************************************/
  141. int SqrtFix(int q, int fBitsIn, int *fBitsOut)
  142. {
  143. int z, lo, hi, mid;
  144. if (q <= 0) {
  145. *fBitsOut = fBitsIn;
  146. return 0;
  147. }
  148. /* force even fBitsIn */
  149. z = fBitsIn & 0x01;
  150. q >>= z;
  151. fBitsIn -= z;
  152. /* for max precision, normalize to [0x20000000, 0x7fffffff] */
  153. z = (CLZ(q) - 1);
  154. z >>= 1;
  155. q <<= (2*z);
  156. /* choose initial bounds */
  157. lo = 1;
  158. if (q >= 0x10000000)
  159. lo = 16384; /* (int)sqrt(0x10000000) */
  160. hi = 46340; /* (int)sqrt(0x7fffffff) */
  161. /* do binary search with 32x32->32 multiply test */
  162. do {
  163. mid = (lo + hi) >> 1;
  164. if (mid*mid > q)
  165. hi = mid - 1;
  166. else
  167. lo = mid + 1;
  168. } while (hi >= lo);
  169. lo--;
  170. *fBitsOut = ((fBitsIn + 2*z) >> 1);
  171. return lo;
  172. }