1135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/*
2135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Copyright (C) 2008 The Android Open Source Project
3135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
4135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * you may not use this file except in compliance with the License.
6135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * You may obtain a copy of the License at
7135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
8135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
10135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Unless required by applicable law or agreed to in writing, software
11135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * See the License for the specific language governing permissions and
14135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * limitations under the License.
15135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent */
16135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#define LOG_TAG "EFFECTSMATH"
17135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//#define LOG_NDEBUG 0
18135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <cutils/log.h>
19135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <assert.h>
20135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
21135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "EffectsMath.h"
22135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
23135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric 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)
24135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric 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)
25135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// It is used for a better than piece wise approximation of lin to log2 conversion
26135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
27135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic const uint16_t gLogTab[] =
28135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
29135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    0, 733, 1455, 2166,
30135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    2866, 3556, 4236, 4907,
31135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    5568, 6220, 6863, 7498,
32135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    8124, 8742, 9352, 9954,
33135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    10549, 11136, 11716, 12289,
34135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    12855, 13415, 13968, 14514,
35135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    15055, 15589, 16117, 16639,
36135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    17156, 17667, 18173, 18673,
37135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    19168, 19658, 20143, 20623,
38135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    21098, 21568, 22034, 22495,
39135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    22952, 23404, 23852, 24296,
40135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    24736, 25172, 25604, 26031,
41135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    26455, 26876, 27292, 27705,
42135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    28114, 28520, 28922, 29321,
43135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    29717, 30109, 30498, 30884,
44135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    31267, 31647, 32024, 32397,
45135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    32768
46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
47135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
48135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint32_t Effects_log2(uint32_t x) {
49135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t exp = 31 - __builtin_clz(x);
50135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t segStart = x >> (exp - 6);
51135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t i = segStart & 0x3F;
52135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t log = (int32_t)gLogTab[i];
53135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t logEnd = (int32_t)gLogTab[i+1];
54135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    segStart <<= exp - 6;
55135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
56135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return (exp << 15) + log + (((x - segStart) * (logEnd - log)) >> (exp - 6));
57135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
58135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
59135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// gExpTab[i] = (2^(i>>6)) << 22
60135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic const uint32_t gExpTab[] = {
61135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            4194304, 4239977, 4286147, 4332820,
62135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            4380002, 4427697, 4475911, 4524651,
63135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            4573921, 4623728, 4674077, 4724974,
64135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            4776426, 4828438, 4881016, 4934167,
65135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            4987896, 5042211, 5097117, 5152621,
66135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            5208729, 5265449, 5322786, 5380747,
67135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            5439339, 5498570, 5558445, 5618973,
68135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            5680159, 5742012, 5804539, 5867746,
69135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            5931642, 5996233, 6061528, 6127533,
70135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            6194258, 6261709, 6329894, 6398822,
71135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            6468501, 6538938, 6610143, 6682122,
72135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            6754886, 6828442, 6902799, 6977965,
73135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            7053950, 7130763, 7208412, 7286906,
74135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            7366255, 7446469, 7527555, 7609525,
75135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            7692387, 7776152, 7860829, 7946428,
76135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            8032959, 8120432, 8208857, 8298246,
77135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            8388608
78135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
79135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentuint32_t Effects_exp2(int32_t x) {
82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t i = x >> 15;
83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(i < 32);
84135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    x &= (1 << 15) - 1;
85135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t j = x >> 9;
86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    x &= (1 << 9) - 1;
87135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t exp = gExpTab[j];
88135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t expEnd = gExpTab[j+1];
89135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
90135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ((exp << 9) + (expEnd - exp) * x) >> (31 - i);
91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint16_t Effects_MillibelsToLinear16 (int32_t nGain)
95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    nGain = ((nGain + MB_TO_LIN_K1) << 15 ) / MB_TO_LIN_K2;
97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t exp2 = Effects_exp2(nGain);
98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
99135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (exp2 > 32767) exp2 = 32767;
100135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
101135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return (int16_t)exp2;
102135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
103135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
104135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
105135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint16_t Effects_Linear16ToMillibels (int32_t nGain)
106135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
107135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return (int16_t)(((MB_TO_LIN_K2*Effects_log2(nGain))>>15)-MB_TO_LIN_K1);
108135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
109135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
111135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint32_t Effects_Sqrt(int32_t in)
112135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
113135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t tmp;
114135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t out = 0;
115135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t i;
116135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t j;
117135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
118135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
119135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (in == 0) return 0;
120135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
121135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (in >= 0x10000000)
122135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    {
123135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        out = 0x4000;
124135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        in -= 0x10000000;
125135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
126135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
127135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    j = 32 - __builtin_clz(in);
128135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
129135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (j & 1) j++;
130135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    j >>= 1;
131135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
132135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    for (i = j; i > 0; i--) {
133135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        tmp = (out << i) + (1 << ((i - 1)*2));
134135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (in >= tmp)
135135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        {
136135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            out += 1 << (i-1);
137135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            in -= tmp;
138135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
139135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
140135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
141135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return out;
142135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
143135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
144