xref: /aosp_15_r20/frameworks/av/media/libeffects/testlibs/EffectsMath.c (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2008 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "EFFECTSMATH"
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker 
19*ec779b8eSAndroid Build Coastguard Worker #include <assert.h>
20*ec779b8eSAndroid Build Coastguard Worker 
21*ec779b8eSAndroid Build Coastguard Worker #include <android/log.h>
22*ec779b8eSAndroid Build Coastguard Worker 
23*ec779b8eSAndroid Build Coastguard Worker #include "EffectsMath.h"
24*ec779b8eSAndroid Build Coastguard Worker 
25*ec779b8eSAndroid Build Coastguard Worker // 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*ec779b8eSAndroid Build Coastguard Worker // 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*ec779b8eSAndroid Build Coastguard Worker // It is used for a better than piece wise approximation of lin to log2 conversion
28*ec779b8eSAndroid Build Coastguard Worker 
29*ec779b8eSAndroid Build Coastguard Worker static const uint16_t gLogTab[] =
30*ec779b8eSAndroid Build Coastguard Worker {
31*ec779b8eSAndroid Build Coastguard Worker     0, 733, 1455, 2166,
32*ec779b8eSAndroid Build Coastguard Worker     2866, 3556, 4236, 4907,
33*ec779b8eSAndroid Build Coastguard Worker     5568, 6220, 6863, 7498,
34*ec779b8eSAndroid Build Coastguard Worker     8124, 8742, 9352, 9954,
35*ec779b8eSAndroid Build Coastguard Worker     10549, 11136, 11716, 12289,
36*ec779b8eSAndroid Build Coastguard Worker     12855, 13415, 13968, 14514,
37*ec779b8eSAndroid Build Coastguard Worker     15055, 15589, 16117, 16639,
38*ec779b8eSAndroid Build Coastguard Worker     17156, 17667, 18173, 18673,
39*ec779b8eSAndroid Build Coastguard Worker     19168, 19658, 20143, 20623,
40*ec779b8eSAndroid Build Coastguard Worker     21098, 21568, 22034, 22495,
41*ec779b8eSAndroid Build Coastguard Worker     22952, 23404, 23852, 24296,
42*ec779b8eSAndroid Build Coastguard Worker     24736, 25172, 25604, 26031,
43*ec779b8eSAndroid Build Coastguard Worker     26455, 26876, 27292, 27705,
44*ec779b8eSAndroid Build Coastguard Worker     28114, 28520, 28922, 29321,
45*ec779b8eSAndroid Build Coastguard Worker     29717, 30109, 30498, 30884,
46*ec779b8eSAndroid Build Coastguard Worker     31267, 31647, 32024, 32397,
47*ec779b8eSAndroid Build Coastguard Worker     32768
48*ec779b8eSAndroid Build Coastguard Worker };
49*ec779b8eSAndroid Build Coastguard Worker 
Effects_log2(uint32_t x)50*ec779b8eSAndroid Build Coastguard Worker int32_t Effects_log2(uint32_t x) {
51*ec779b8eSAndroid Build Coastguard Worker     int32_t exp = 31 - __builtin_clz(x);
52*ec779b8eSAndroid Build Coastguard Worker     uint32_t segStart = x >> (exp - 6);
53*ec779b8eSAndroid Build Coastguard Worker     uint32_t i = segStart & 0x3F;
54*ec779b8eSAndroid Build Coastguard Worker     int32_t log = (int32_t)gLogTab[i];
55*ec779b8eSAndroid Build Coastguard Worker     int32_t logEnd = (int32_t)gLogTab[i+1];
56*ec779b8eSAndroid Build Coastguard Worker     segStart <<= exp - 6;
57*ec779b8eSAndroid Build Coastguard Worker 
58*ec779b8eSAndroid Build Coastguard Worker     return (exp << 15) + log + (((x - segStart) * (logEnd - log)) >> (exp - 6));
59*ec779b8eSAndroid Build Coastguard Worker }
60*ec779b8eSAndroid Build Coastguard Worker 
61*ec779b8eSAndroid Build Coastguard Worker // gExpTab[i] = (2^(i>>6)) << 22
62*ec779b8eSAndroid Build Coastguard Worker static const uint32_t gExpTab[] = {
63*ec779b8eSAndroid Build Coastguard Worker             4194304, 4239977, 4286147, 4332820,
64*ec779b8eSAndroid Build Coastguard Worker             4380002, 4427697, 4475911, 4524651,
65*ec779b8eSAndroid Build Coastguard Worker             4573921, 4623728, 4674077, 4724974,
66*ec779b8eSAndroid Build Coastguard Worker             4776426, 4828438, 4881016, 4934167,
67*ec779b8eSAndroid Build Coastguard Worker             4987896, 5042211, 5097117, 5152621,
68*ec779b8eSAndroid Build Coastguard Worker             5208729, 5265449, 5322786, 5380747,
69*ec779b8eSAndroid Build Coastguard Worker             5439339, 5498570, 5558445, 5618973,
70*ec779b8eSAndroid Build Coastguard Worker             5680159, 5742012, 5804539, 5867746,
71*ec779b8eSAndroid Build Coastguard Worker             5931642, 5996233, 6061528, 6127533,
72*ec779b8eSAndroid Build Coastguard Worker             6194258, 6261709, 6329894, 6398822,
73*ec779b8eSAndroid Build Coastguard Worker             6468501, 6538938, 6610143, 6682122,
74*ec779b8eSAndroid Build Coastguard Worker             6754886, 6828442, 6902799, 6977965,
75*ec779b8eSAndroid Build Coastguard Worker             7053950, 7130763, 7208412, 7286906,
76*ec779b8eSAndroid Build Coastguard Worker             7366255, 7446469, 7527555, 7609525,
77*ec779b8eSAndroid Build Coastguard Worker             7692387, 7776152, 7860829, 7946428,
78*ec779b8eSAndroid Build Coastguard Worker             8032959, 8120432, 8208857, 8298246,
79*ec779b8eSAndroid Build Coastguard Worker             8388608
80*ec779b8eSAndroid Build Coastguard Worker };
81*ec779b8eSAndroid Build Coastguard Worker 
82*ec779b8eSAndroid Build Coastguard Worker 
Effects_exp2(int32_t x)83*ec779b8eSAndroid Build Coastguard Worker uint32_t Effects_exp2(int32_t x) {
84*ec779b8eSAndroid Build Coastguard Worker     int32_t i = x >> 15;
85*ec779b8eSAndroid Build Coastguard Worker     assert(i < 32);
86*ec779b8eSAndroid Build Coastguard Worker     x &= (1 << 15) - 1;
87*ec779b8eSAndroid Build Coastguard Worker     int32_t j = x >> 9;
88*ec779b8eSAndroid Build Coastguard Worker     x &= (1 << 9) - 1;
89*ec779b8eSAndroid Build Coastguard Worker     uint32_t exp = gExpTab[j];
90*ec779b8eSAndroid Build Coastguard Worker     uint32_t expEnd = gExpTab[j+1];
91*ec779b8eSAndroid Build Coastguard Worker 
92*ec779b8eSAndroid Build Coastguard Worker     return ((exp << 9) + (expEnd - exp) * x) >> (31 - i);
93*ec779b8eSAndroid Build Coastguard Worker }
94*ec779b8eSAndroid Build Coastguard Worker 
95*ec779b8eSAndroid Build Coastguard Worker 
Effects_MillibelsToLinear16(int32_t nGain)96*ec779b8eSAndroid Build Coastguard Worker int16_t Effects_MillibelsToLinear16 (int32_t nGain)
97*ec779b8eSAndroid Build Coastguard Worker {
98*ec779b8eSAndroid Build Coastguard Worker     nGain = ((nGain + MB_TO_LIN_K1) << 15 ) / MB_TO_LIN_K2;
99*ec779b8eSAndroid Build Coastguard Worker     uint32_t exp2 = Effects_exp2(nGain);
100*ec779b8eSAndroid Build Coastguard Worker 
101*ec779b8eSAndroid Build Coastguard Worker     if (exp2 > 32767) exp2 = 32767;
102*ec779b8eSAndroid Build Coastguard Worker 
103*ec779b8eSAndroid Build Coastguard Worker     return (int16_t)exp2;
104*ec779b8eSAndroid Build Coastguard Worker }
105*ec779b8eSAndroid Build Coastguard Worker 
106*ec779b8eSAndroid Build Coastguard Worker 
Effects_Linear16ToMillibels(int32_t nGain)107*ec779b8eSAndroid Build Coastguard Worker int16_t Effects_Linear16ToMillibels (int32_t nGain)
108*ec779b8eSAndroid Build Coastguard Worker {
109*ec779b8eSAndroid Build Coastguard Worker     return (int16_t)(((MB_TO_LIN_K2*Effects_log2(nGain))>>15)-MB_TO_LIN_K1);
110*ec779b8eSAndroid Build Coastguard Worker }
111*ec779b8eSAndroid Build Coastguard Worker 
112*ec779b8eSAndroid Build Coastguard Worker 
Effects_Sqrt(int32_t in)113*ec779b8eSAndroid Build Coastguard Worker int32_t Effects_Sqrt(int32_t in)
114*ec779b8eSAndroid Build Coastguard Worker {
115*ec779b8eSAndroid Build Coastguard Worker     int32_t tmp;
116*ec779b8eSAndroid Build Coastguard Worker     int32_t out = 0;
117*ec779b8eSAndroid Build Coastguard Worker     int32_t i;
118*ec779b8eSAndroid Build Coastguard Worker     int32_t j;
119*ec779b8eSAndroid Build Coastguard Worker 
120*ec779b8eSAndroid Build Coastguard Worker 
121*ec779b8eSAndroid Build Coastguard Worker     if (in == 0) return 0;
122*ec779b8eSAndroid Build Coastguard Worker 
123*ec779b8eSAndroid Build Coastguard Worker     if (in >= 0x10000000)
124*ec779b8eSAndroid Build Coastguard Worker     {
125*ec779b8eSAndroid Build Coastguard Worker         out = 0x4000;
126*ec779b8eSAndroid Build Coastguard Worker         in -= 0x10000000;
127*ec779b8eSAndroid Build Coastguard Worker     }
128*ec779b8eSAndroid Build Coastguard Worker 
129*ec779b8eSAndroid Build Coastguard Worker     j = 32 - __builtin_clz(in);
130*ec779b8eSAndroid Build Coastguard Worker 
131*ec779b8eSAndroid Build Coastguard Worker     if (j & 1) j++;
132*ec779b8eSAndroid Build Coastguard Worker     j >>= 1;
133*ec779b8eSAndroid Build Coastguard Worker 
134*ec779b8eSAndroid Build Coastguard Worker     for (i = j; i > 0; i--) {
135*ec779b8eSAndroid Build Coastguard Worker         tmp = (out << i) + (1 << ((i - 1)*2));
136*ec779b8eSAndroid Build Coastguard Worker         if (in >= tmp)
137*ec779b8eSAndroid Build Coastguard Worker         {
138*ec779b8eSAndroid Build Coastguard Worker             out += 1 << (i-1);
139*ec779b8eSAndroid Build Coastguard Worker             in -= tmp;
140*ec779b8eSAndroid Build Coastguard Worker         }
141*ec779b8eSAndroid Build Coastguard Worker     }
142*ec779b8eSAndroid Build Coastguard Worker 
143*ec779b8eSAndroid Build Coastguard Worker     return out;
144*ec779b8eSAndroid Build Coastguard Worker }
145*ec779b8eSAndroid Build Coastguard Worker 
146