EffectsMath.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * Copyright (C) 2008 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define LOG_TAG "EFFECTSMATH"
  17. //#define LOG_NDEBUG 0
  18. #include <assert.h>
  19. #include <android/log.h>
  20. #include "EffectsMath.h"
  21. // gLogTab contains pre-calculated values of log2(1 + ai5*2^-1 + ai4*2^-2 + ai3*2^-3 + ai2*2^-4 + ai1*2^-5 + ai0*2^-6)
  22. // for integers in the range 0 to 63 (i = ai5*2^5 + ai4*2^4 + ai3*2^3 + ai2*2^2 + ai1*2^1 + ai0*2^0)
  23. // It is used for a better than piece wise approximation of lin to log2 conversion
  24. static const uint16_t gLogTab[] =
  25. {
  26. 0, 733, 1455, 2166,
  27. 2866, 3556, 4236, 4907,
  28. 5568, 6220, 6863, 7498,
  29. 8124, 8742, 9352, 9954,
  30. 10549, 11136, 11716, 12289,
  31. 12855, 13415, 13968, 14514,
  32. 15055, 15589, 16117, 16639,
  33. 17156, 17667, 18173, 18673,
  34. 19168, 19658, 20143, 20623,
  35. 21098, 21568, 22034, 22495,
  36. 22952, 23404, 23852, 24296,
  37. 24736, 25172, 25604, 26031,
  38. 26455, 26876, 27292, 27705,
  39. 28114, 28520, 28922, 29321,
  40. 29717, 30109, 30498, 30884,
  41. 31267, 31647, 32024, 32397,
  42. 32768
  43. };
  44. int32_t Effects_log2(uint32_t x) {
  45. int32_t exp = 31 - __builtin_clz(x);
  46. uint32_t segStart = x >> (exp - 6);
  47. uint32_t i = segStart & 0x3F;
  48. int32_t log = (int32_t)gLogTab[i];
  49. int32_t logEnd = (int32_t)gLogTab[i+1];
  50. segStart <<= exp - 6;
  51. return (exp << 15) + log + (((x - segStart) * (logEnd - log)) >> (exp - 6));
  52. }
  53. // gExpTab[i] = (2^(i>>6)) << 22
  54. static const uint32_t gExpTab[] = {
  55. 4194304, 4239977, 4286147, 4332820,
  56. 4380002, 4427697, 4475911, 4524651,
  57. 4573921, 4623728, 4674077, 4724974,
  58. 4776426, 4828438, 4881016, 4934167,
  59. 4987896, 5042211, 5097117, 5152621,
  60. 5208729, 5265449, 5322786, 5380747,
  61. 5439339, 5498570, 5558445, 5618973,
  62. 5680159, 5742012, 5804539, 5867746,
  63. 5931642, 5996233, 6061528, 6127533,
  64. 6194258, 6261709, 6329894, 6398822,
  65. 6468501, 6538938, 6610143, 6682122,
  66. 6754886, 6828442, 6902799, 6977965,
  67. 7053950, 7130763, 7208412, 7286906,
  68. 7366255, 7446469, 7527555, 7609525,
  69. 7692387, 7776152, 7860829, 7946428,
  70. 8032959, 8120432, 8208857, 8298246,
  71. 8388608
  72. };
  73. uint32_t Effects_exp2(int32_t x) {
  74. int32_t i = x >> 15;
  75. assert(i < 32);
  76. x &= (1 << 15) - 1;
  77. int32_t j = x >> 9;
  78. x &= (1 << 9) - 1;
  79. uint32_t exp = gExpTab[j];
  80. uint32_t expEnd = gExpTab[j+1];
  81. return ((exp << 9) + (expEnd - exp) * x) >> (31 - i);
  82. }
  83. int16_t Effects_MillibelsToLinear16 (int32_t nGain)
  84. {
  85. nGain = ((nGain + MB_TO_LIN_K1) << 15 ) / MB_TO_LIN_K2;
  86. uint32_t exp2 = Effects_exp2(nGain);
  87. if (exp2 > 32767) exp2 = 32767;
  88. return (int16_t)exp2;
  89. }
  90. int16_t Effects_Linear16ToMillibels (int32_t nGain)
  91. {
  92. return (int16_t)(((MB_TO_LIN_K2*Effects_log2(nGain))>>15)-MB_TO_LIN_K1);
  93. }
  94. int32_t Effects_Sqrt(int32_t in)
  95. {
  96. int32_t tmp;
  97. int32_t out = 0;
  98. int32_t i;
  99. int32_t j;
  100. if (in == 0) return 0;
  101. if (in >= 0x10000000)
  102. {
  103. out = 0x4000;
  104. in -= 0x10000000;
  105. }
  106. j = 32 - __builtin_clz(in);
  107. if (j & 1) j++;
  108. j >>= 1;
  109. for (i = j; i > 0; i--) {
  110. tmp = (out << i) + (1 << ((i - 1)*2));
  111. if (in >= tmp)
  112. {
  113. out += 1 << (i-1);
  114. in -= tmp;
  115. }
  116. }
  117. return out;
  118. }