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