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 <cutils/log.h> 19 #include <assert.h> 20 21 #include "EffectsMath.h" 22 23 // 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) 24 // 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) 25 // It is used for a better than piece wise approximation of lin to log2 conversion 26 27 static const uint16_t gLogTab[] = 28 { 29 0, 733, 1455, 2166, 30 2866, 3556, 4236, 4907, 31 5568, 6220, 6863, 7498, 32 8124, 8742, 9352, 9954, 33 10549, 11136, 11716, 12289, 34 12855, 13415, 13968, 14514, 35 15055, 15589, 16117, 16639, 36 17156, 17667, 18173, 18673, 37 19168, 19658, 20143, 20623, 38 21098, 21568, 22034, 22495, 39 22952, 23404, 23852, 24296, 40 24736, 25172, 25604, 26031, 41 26455, 26876, 27292, 27705, 42 28114, 28520, 28922, 29321, 43 29717, 30109, 30498, 30884, 44 31267, 31647, 32024, 32397, 45 32768 46 }; 47 48 int32_t Effects_log2(uint32_t x) { 49 int32_t exp = 31 - __builtin_clz(x); 50 uint32_t segStart = x >> (exp - 6); 51 uint32_t i = segStart & 0x3F; 52 int32_t log = (int32_t)gLogTab[i]; 53 int32_t logEnd = (int32_t)gLogTab[i+1]; 54 segStart <<= exp - 6; 55 56 return (exp << 15) + log + (((x - segStart) * (logEnd - log)) >> (exp - 6)); 57 } 58 59 // gExpTab[i] = (2^(i>>6)) << 22 60 static const uint32_t gExpTab[] = { 61 4194304, 4239977, 4286147, 4332820, 62 4380002, 4427697, 4475911, 4524651, 63 4573921, 4623728, 4674077, 4724974, 64 4776426, 4828438, 4881016, 4934167, 65 4987896, 5042211, 5097117, 5152621, 66 5208729, 5265449, 5322786, 5380747, 67 5439339, 5498570, 5558445, 5618973, 68 5680159, 5742012, 5804539, 5867746, 69 5931642, 5996233, 6061528, 6127533, 70 6194258, 6261709, 6329894, 6398822, 71 6468501, 6538938, 6610143, 6682122, 72 6754886, 6828442, 6902799, 6977965, 73 7053950, 7130763, 7208412, 7286906, 74 7366255, 7446469, 7527555, 7609525, 75 7692387, 7776152, 7860829, 7946428, 76 8032959, 8120432, 8208857, 8298246, 77 8388608 78 }; 79 80 81 uint32_t Effects_exp2(int32_t x) { 82 int32_t i = x >> 15; 83 assert(i < 32); 84 x &= (1 << 15) - 1; 85 int32_t j = x >> 9; 86 x &= (1 << 9) - 1; 87 uint32_t exp = gExpTab[j]; 88 uint32_t expEnd = gExpTab[j+1]; 89 90 return ((exp << 9) + (expEnd - exp) * x) >> (31 - i); 91 } 92 93 94 int16_t Effects_MillibelsToLinear16 (int32_t nGain) 95 { 96 nGain = ((nGain + MB_TO_LIN_K1) << 15 ) / MB_TO_LIN_K2; 97 uint32_t exp2 = Effects_exp2(nGain); 98 99 if (exp2 > 32767) exp2 = 32767; 100 101 return (int16_t)exp2; 102 } 103 104 105 int16_t Effects_Linear16ToMillibels (int32_t nGain) 106 { 107 return (int16_t)(((MB_TO_LIN_K2*Effects_log2(nGain))>>15)-MB_TO_LIN_K1); 108 } 109 110 111 int32_t Effects_Sqrt(int32_t in) 112 { 113 int32_t tmp; 114 int32_t out = 0; 115 int32_t i; 116 int32_t j; 117 118 119 if (in == 0) return 0; 120 121 if (in >= 0x10000000) 122 { 123 out = 0x4000; 124 in -= 0x10000000; 125 } 126 127 j = 32 - __builtin_clz(in); 128 129 if (j & 1) j++; 130 j >>= 1; 131 132 for (i = j; i > 0; i--) { 133 tmp = (out << i) + (1 << ((i - 1)*2)); 134 if (in >= tmp) 135 { 136 out += 1 << (i-1); 137 in -= tmp; 138 } 139 } 140 141 return out; 142 } 143 144