15fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent/* 25fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * Copyright (C) 2008 The Android Open Source Project 35fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * 45fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 55fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * you may not use this file except in compliance with the License. 65fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * You may obtain a copy of the License at 75fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * 85fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * http://www.apache.org/licenses/LICENSE-2.0 95fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * 105fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * Unless required by applicable law or agreed to in writing, software 115fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 125fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * See the License for the specific language governing permissions and 145fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent * limitations under the License. 155fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent */ 165fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent#define LOG_TAG "EFFECTSMATH" 175fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent//#define LOG_NDEBUG 0 185fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent#include <cutils/log.h> 195fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent#include <assert.h> 205fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 215fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent#include "EffectsMath.h" 225fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 235fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// 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) 245fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// 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) 255fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// It is used for a better than piece wise approximation of lin to log2 conversion 265fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 275fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurentstatic const uint16_t gLogTab[] = 285fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent{ 295fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 0, 733, 1455, 2166, 305fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 2866, 3556, 4236, 4907, 315fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 5568, 6220, 6863, 7498, 325fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 8124, 8742, 9352, 9954, 335fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 10549, 11136, 11716, 12289, 345fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 12855, 13415, 13968, 14514, 355fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 15055, 15589, 16117, 16639, 365fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 17156, 17667, 18173, 18673, 375fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 19168, 19658, 20143, 20623, 385fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 21098, 21568, 22034, 22495, 395fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 22952, 23404, 23852, 24296, 405fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 24736, 25172, 25604, 26031, 415fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 26455, 26876, 27292, 27705, 425fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 28114, 28520, 28922, 29321, 435fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 29717, 30109, 30498, 30884, 445fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 31267, 31647, 32024, 32397, 455fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 32768 465fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent}; 475fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 485fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurentint32_t Effects_log2(uint32_t x) { 495fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent int32_t exp = 31 - __builtin_clz(x); 505fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent uint32_t segStart = x >> (exp - 6); 515fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent uint32_t i = segStart & 0x3F; 525fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent int32_t log = (int32_t)gLogTab[i]; 535fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent int32_t logEnd = (int32_t)gLogTab[i+1]; 545fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent segStart <<= exp - 6; 555fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 565fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent return (exp << 15) + log + (((x - segStart) * (logEnd - log)) >> (exp - 6)); 575fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent} 585fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 595fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// gExpTab[i] = (2^(i>>6)) << 22 605fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurentstatic const uint32_t gExpTab[] = { 615fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 4194304, 4239977, 4286147, 4332820, 625fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 4380002, 4427697, 4475911, 4524651, 635fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 4573921, 4623728, 4674077, 4724974, 645fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 4776426, 4828438, 4881016, 4934167, 655fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 4987896, 5042211, 5097117, 5152621, 665fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 5208729, 5265449, 5322786, 5380747, 675fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 5439339, 5498570, 5558445, 5618973, 685fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 5680159, 5742012, 5804539, 5867746, 695fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 5931642, 5996233, 6061528, 6127533, 705fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 6194258, 6261709, 6329894, 6398822, 715fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 6468501, 6538938, 6610143, 6682122, 725fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 6754886, 6828442, 6902799, 6977965, 735fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 7053950, 7130763, 7208412, 7286906, 745fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 7366255, 7446469, 7527555, 7609525, 755fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 7692387, 7776152, 7860829, 7946428, 765fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 8032959, 8120432, 8208857, 8298246, 775fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 8388608 785fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent}; 795fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 805fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 815fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurentuint32_t Effects_exp2(int32_t x) { 825fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent int32_t i = x >> 15; 835fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent assert(i < 32); 845fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent x &= (1 << 15) - 1; 855fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent int32_t j = x >> 9; 865fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent x &= (1 << 9) - 1; 875fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent uint32_t exp = gExpTab[j]; 885fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent uint32_t expEnd = gExpTab[j+1]; 895fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 905fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent return ((exp << 9) + (expEnd - exp) * x) >> (31 - i); 915fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent} 925fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 935fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 945fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurentint16_t Effects_MillibelsToLinear16 (int32_t nGain) 955fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent{ 965fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent nGain = ((nGain + MB_TO_LIN_K1) << 15 ) / MB_TO_LIN_K2; 975fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent uint32_t exp2 = Effects_exp2(nGain); 985fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 995fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent if (exp2 > 32767) exp2 = 32767; 1005fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1015fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent return (int16_t)exp2; 1025fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent} 1035fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1045fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1055fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurentint16_t Effects_Linear16ToMillibels (int32_t nGain) 1065fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent{ 1075fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent return (int16_t)(((MB_TO_LIN_K2*Effects_log2(nGain))>>15)-MB_TO_LIN_K1); 1085fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent} 1095fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1105fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1115fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurentint32_t Effects_Sqrt(int32_t in) 1125fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent{ 1135fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent int32_t tmp; 1145fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent int32_t out = 0; 1155fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent int32_t i; 1165fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent int32_t j; 1175fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1185fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1195fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent if (in == 0) return 0; 1205fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1215fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent if (in >= 0x10000000) 1225fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent { 1235fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent out = 0x4000; 1245fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent in -= 0x10000000; 1255fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent } 1265fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1275fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent j = 32 - __builtin_clz(in); 1285fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1295fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent if (j & 1) j++; 1305fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent j >>= 1; 1315fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1325fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent for (i = j; i > 0; i--) { 1335fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent tmp = (out << i) + (1 << ((i - 1)*2)); 1345fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent if (in >= tmp) 1355fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent { 1365fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent out += 1 << (i-1); 1375fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent in -= tmp; 1385fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent } 1395fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent } 1405fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 1415fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent return out; 1425fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent} 1435fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent 144