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