xref: /aosp_15_r20/frameworks/av/media/libeffects/testlibs/EffectsMath.h (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 
17*ec779b8eSAndroid Build Coastguard Worker #ifndef ANDROID_EFFECTSMATH_H_
18*ec779b8eSAndroid Build Coastguard Worker #define ANDROID_EFFECTSMATH_H_
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker #include <stdint.h>
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker #if __cplusplus
23*ec779b8eSAndroid Build Coastguard Worker extern "C" {
24*ec779b8eSAndroid Build Coastguard Worker #endif
25*ec779b8eSAndroid Build Coastguard Worker 
26*ec779b8eSAndroid Build Coastguard Worker /** coefs for pan, generates sin, cos */
27*ec779b8eSAndroid Build Coastguard Worker #define COEFF_PAN_G2    -27146    /* -0.82842712474619 = 2 - 4/sqrt(2) */
28*ec779b8eSAndroid Build Coastguard Worker #define COEFF_PAN_G0    23170     /* 0.707106781186547 = 1/sqrt(2) */
29*ec779b8eSAndroid Build Coastguard Worker 
30*ec779b8eSAndroid Build Coastguard Worker /*
31*ec779b8eSAndroid Build Coastguard Worker coefficients for approximating
32*ec779b8eSAndroid Build Coastguard Worker 2^x = gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3
33*ec779b8eSAndroid Build Coastguard Worker where x is a int.frac number representing number of octaves.
34*ec779b8eSAndroid Build Coastguard Worker Actually, we approximate only the 2^(frac) using the power series
35*ec779b8eSAndroid Build Coastguard Worker and implement the 2^(int) as a shift, so that
36*ec779b8eSAndroid Build Coastguard Worker 2^x == 2^(int.frac) == 2^(int) * 2^(fract)
37*ec779b8eSAndroid Build Coastguard Worker     == (gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3) << (int)
38*ec779b8eSAndroid Build Coastguard Worker 
39*ec779b8eSAndroid Build Coastguard Worker The gn2toX.. were generated using a best fit for a 3rd
40*ec779b8eSAndroid Build Coastguard Worker order polynomial, instead of taking the coefficients from
41*ec779b8eSAndroid Build Coastguard Worker a truncated Taylor (or Maclaurin?) series.
42*ec779b8eSAndroid Build Coastguard Worker */
43*ec779b8eSAndroid Build Coastguard Worker 
44*ec779b8eSAndroid Build Coastguard Worker #define GN2_TO_X0    32768    /*    1                    */
45*ec779b8eSAndroid Build Coastguard Worker #define GN2_TO_X1    22833    /*    0.696807861328125    */
46*ec779b8eSAndroid Build Coastguard Worker #define GN2_TO_X2    7344    /*    0.22412109375        */
47*ec779b8eSAndroid Build Coastguard Worker #define GN2_TO_X3    2588    /*    0.0789794921875        */
48*ec779b8eSAndroid Build Coastguard Worker 
49*ec779b8eSAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
50*ec779b8eSAndroid Build Coastguard Worker  * Fixed Point Math
51*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
52*ec779b8eSAndroid Build Coastguard Worker  * These macros are used for fixed point multiplies. If the processor
53*ec779b8eSAndroid Build Coastguard Worker  * supports fixed point multiplies, replace these macros with inline
54*ec779b8eSAndroid Build Coastguard Worker  * assembly code to improve performance.
55*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
56*ec779b8eSAndroid Build Coastguard Worker */
57*ec779b8eSAndroid Build Coastguard Worker 
58*ec779b8eSAndroid Build Coastguard Worker /* Fixed point multiply 0.15 x 0.15 = 0.15 returned as 32-bits */
59*ec779b8eSAndroid Build Coastguard Worker #define FMUL_15x15(a,b) \
60*ec779b8eSAndroid Build Coastguard Worker     /*lint -e(704) <avoid multiply for performance>*/ \
61*ec779b8eSAndroid Build Coastguard Worker     (((int32_t)(a) * (int32_t)(b)) >> 15)
62*ec779b8eSAndroid Build Coastguard Worker 
63*ec779b8eSAndroid Build Coastguard Worker /* Fixed point multiply 0.7 x 0.7 = 0.15 returned as 32-bits */
64*ec779b8eSAndroid Build Coastguard Worker #define FMUL_7x7(a,b) \
65*ec779b8eSAndroid Build Coastguard Worker     /*lint -e(704) <avoid multiply for performance>*/ \
66*ec779b8eSAndroid Build Coastguard Worker     (((int32_t)(a) * (int32_t)(b) ) << 1)
67*ec779b8eSAndroid Build Coastguard Worker 
68*ec779b8eSAndroid Build Coastguard Worker /* Fixed point multiply 0.8 x 0.8 = 0.15 returned as 32-bits */
69*ec779b8eSAndroid Build Coastguard Worker #define FMUL_8x8(a,b) \
70*ec779b8eSAndroid Build Coastguard Worker     /*lint -e(704) <avoid multiply for performance>*/ \
71*ec779b8eSAndroid Build Coastguard Worker     (((int32_t)(a) * (int32_t)(b) ) >> 1)
72*ec779b8eSAndroid Build Coastguard Worker 
73*ec779b8eSAndroid Build Coastguard Worker /* Fixed point multiply 0.8 x 1.15 = 0.15 returned as 32-bits */
74*ec779b8eSAndroid Build Coastguard Worker #define FMUL_8x15(a,b) \
75*ec779b8eSAndroid Build Coastguard Worker     /*lint -e(704) <avoid divide for performance>*/ \
76*ec779b8eSAndroid Build Coastguard Worker     (((int32_t)((a) << 7) * (int32_t)(b)) >> 15)
77*ec779b8eSAndroid Build Coastguard Worker 
78*ec779b8eSAndroid Build Coastguard Worker /* macros for fractional phase accumulator */
79*ec779b8eSAndroid Build Coastguard Worker /*
80*ec779b8eSAndroid Build Coastguard Worker Note: changed the _U32 to _I32 on 03/14/02. This should not
81*ec779b8eSAndroid Build Coastguard Worker affect the phase calculations, and should allow us to reuse these
82*ec779b8eSAndroid Build Coastguard Worker macros for other audio sample related math.
83*ec779b8eSAndroid Build Coastguard Worker */
84*ec779b8eSAndroid Build Coastguard Worker #define HARDWARE_BIT_WIDTH        32
85*ec779b8eSAndroid Build Coastguard Worker 
86*ec779b8eSAndroid Build Coastguard Worker #define NUM_PHASE_INT_BITS        1
87*ec779b8eSAndroid Build Coastguard Worker #define NUM_PHASE_FRAC_BITS       15
88*ec779b8eSAndroid Build Coastguard Worker 
89*ec779b8eSAndroid Build Coastguard Worker #define PHASE_FRAC_MASK           (uint32_t) ((0x1L << NUM_PHASE_FRAC_BITS) -1)
90*ec779b8eSAndroid Build Coastguard Worker 
91*ec779b8eSAndroid Build Coastguard Worker #define GET_PHASE_INT_PART(x)     (uint32_t)((uint32_t)(x) >> NUM_PHASE_FRAC_BITS)
92*ec779b8eSAndroid Build Coastguard Worker #define GET_PHASE_FRAC_PART(x)    (uint32_t)((uint32_t)(x) & PHASE_FRAC_MASK)
93*ec779b8eSAndroid Build Coastguard Worker 
94*ec779b8eSAndroid Build Coastguard Worker #define DEFAULT_PHASE_FRAC        0
95*ec779b8eSAndroid Build Coastguard Worker #define DEFAULT_PHASE_INT         0
96*ec779b8eSAndroid Build Coastguard Worker 
97*ec779b8eSAndroid Build Coastguard Worker /*
98*ec779b8eSAndroid Build Coastguard Worker Linear interpolation calculates:
99*ec779b8eSAndroid Build Coastguard Worker output = (1-frac) * sample[n] + (frac) * sample[n+1]
100*ec779b8eSAndroid Build Coastguard Worker 
101*ec779b8eSAndroid Build Coastguard Worker where conceptually    0 <= frac < 1
102*ec779b8eSAndroid Build Coastguard Worker 
103*ec779b8eSAndroid Build Coastguard Worker For a fixed point implementation, frac is actually an integer value
104*ec779b8eSAndroid Build Coastguard Worker with an implied binary point one position to the left. The value of
105*ec779b8eSAndroid Build Coastguard Worker one (unity) is given by PHASE_ONE
106*ec779b8eSAndroid Build Coastguard Worker one half and one quarter are useful for 4-point linear interp.
107*ec779b8eSAndroid Build Coastguard Worker */
108*ec779b8eSAndroid Build Coastguard Worker #define PHASE_ONE                (int32_t) (0x1L << NUM_PHASE_FRAC_BITS)
109*ec779b8eSAndroid Build Coastguard Worker 
110*ec779b8eSAndroid Build Coastguard Worker /*
111*ec779b8eSAndroid Build Coastguard Worker  Multiply the signed audio sample by the unsigned fraction.
112*ec779b8eSAndroid Build Coastguard Worker -  a is the signed audio sample
113*ec779b8eSAndroid Build Coastguard Worker -  b is the unsigned fraction (cast to signed int as long as coef
114*ec779b8eSAndroid Build Coastguard Worker     uses (n-1) or less bits, where n == hardware bit width)
115*ec779b8eSAndroid Build Coastguard Worker */
116*ec779b8eSAndroid Build Coastguard Worker #define MULT_AUDIO_COEF(audio,coef)         /*lint -e704 <avoid divide for performance>*/ \
117*ec779b8eSAndroid Build Coastguard Worker             (int32_t)(                                    \
118*ec779b8eSAndroid Build Coastguard Worker             (                                            \
119*ec779b8eSAndroid Build Coastguard Worker                 ((int32_t)(audio)) * ((int32_t)(coef))    \
120*ec779b8eSAndroid Build Coastguard Worker             )                                            \
121*ec779b8eSAndroid Build Coastguard Worker             >> NUM_PHASE_FRAC_BITS                        \
122*ec779b8eSAndroid Build Coastguard Worker                                         )                \
123*ec779b8eSAndroid Build Coastguard Worker                                         /* lint +704 <restore checking>*/
124*ec779b8eSAndroid Build Coastguard Worker 
125*ec779b8eSAndroid Build Coastguard Worker /* wet / dry calculation macros */
126*ec779b8eSAndroid Build Coastguard Worker #define NUM_WET_DRY_FRAC_BITS       7    // 15
127*ec779b8eSAndroid Build Coastguard Worker #define NUM_WET_DRY_INT_BITS        9    // 1
128*ec779b8eSAndroid Build Coastguard Worker 
129*ec779b8eSAndroid Build Coastguard Worker /* define a 1.0 */
130*ec779b8eSAndroid Build Coastguard Worker #define WET_DRY_ONE                 (int32_t) ((0x1L << NUM_WET_DRY_FRAC_BITS))
131*ec779b8eSAndroid Build Coastguard Worker #define WET_DRY_MINUS_ONE           (int32_t) (~WET_DRY_ONE)
132*ec779b8eSAndroid Build Coastguard Worker #define WET_DRY_FULL_SCALE          (int32_t) (WET_DRY_ONE - 1)
133*ec779b8eSAndroid Build Coastguard Worker 
134*ec779b8eSAndroid Build Coastguard Worker #define MULT_AUDIO_WET_DRY_COEF(audio,coef) /*lint -e(702) <avoid divide for performance>*/ \
135*ec779b8eSAndroid Build Coastguard Worker             (int32_t)(                                        \
136*ec779b8eSAndroid Build Coastguard Worker             (                                                \
137*ec779b8eSAndroid Build Coastguard Worker                 ((int32_t)(audio)) * ((int32_t)(coef))        \
138*ec779b8eSAndroid Build Coastguard Worker             )                                                \
139*ec779b8eSAndroid Build Coastguard Worker             >> NUM_WET_DRY_FRAC_BITS                        \
140*ec779b8eSAndroid Build Coastguard Worker                                                      )
141*ec779b8eSAndroid Build Coastguard Worker 
142*ec779b8eSAndroid Build Coastguard Worker /* Envelope 1 (EG1) calculation macros */
143*ec779b8eSAndroid Build Coastguard Worker #define    NUM_EG1_INT_BITS          1
144*ec779b8eSAndroid Build Coastguard Worker #define NUM_EG1_FRAC_BITS            15
145*ec779b8eSAndroid Build Coastguard Worker 
146*ec779b8eSAndroid Build Coastguard Worker /* the max positive gain used in the synth for EG1 */
147*ec779b8eSAndroid Build Coastguard Worker /* SYNTH_FULL_SCALE_EG1_GAIN must match the value in the dls2eas
148*ec779b8eSAndroid Build Coastguard Worker converter, otherwise, the values we read from the .eas file are bogus. */
149*ec779b8eSAndroid Build Coastguard Worker #define SYNTH_FULL_SCALE_EG1_GAIN    (int32_t) ((0x1L << NUM_EG1_FRAC_BITS) -1)
150*ec779b8eSAndroid Build Coastguard Worker 
151*ec779b8eSAndroid Build Coastguard Worker /* define a 1.0 */
152*ec779b8eSAndroid Build Coastguard Worker #define EG1_ONE                      (int32_t) ((0x1L << NUM_EG1_FRAC_BITS))
153*ec779b8eSAndroid Build Coastguard Worker #define EG1_MINUS_ONE                (int32_t) (~SYNTH_FULL_SCALE_EG1_GAIN)
154*ec779b8eSAndroid Build Coastguard Worker 
155*ec779b8eSAndroid Build Coastguard Worker #define EG1_HALF                     (int32_t) (EG1_ONE/2)
156*ec779b8eSAndroid Build Coastguard Worker #define EG1_MINUS_HALF               (int32_t) (EG1_MINUS_ONE/2)
157*ec779b8eSAndroid Build Coastguard Worker 
158*ec779b8eSAndroid Build Coastguard Worker /*
159*ec779b8eSAndroid Build Coastguard Worker We implement the EG1 using a linear gain value, which means that the
160*ec779b8eSAndroid Build Coastguard Worker attack segment is handled by incrementing (adding) the linear gain.
161*ec779b8eSAndroid Build Coastguard Worker However, EG1 treats the Decay, Sustain, and Release differently than
162*ec779b8eSAndroid Build Coastguard Worker the Attack portion. For Decay, Sustain, and Release, the gain is
163*ec779b8eSAndroid Build Coastguard Worker linear on dB scale, which is equivalent to exponential damping on
164*ec779b8eSAndroid Build Coastguard Worker a linear scale. Because we use a linear gain for EG1, we implement
165*ec779b8eSAndroid Build Coastguard Worker the Decay and Release as multiplication (instead of incrementing
166*ec779b8eSAndroid Build Coastguard Worker as we did for the attack segment).
167*ec779b8eSAndroid Build Coastguard Worker Therefore, we need the following macro to implement the multiplication
168*ec779b8eSAndroid Build Coastguard Worker (i.e., exponential damping) during the Decay and Release segments of
169*ec779b8eSAndroid Build Coastguard Worker the EG1
170*ec779b8eSAndroid Build Coastguard Worker */
171*ec779b8eSAndroid Build Coastguard Worker #define MULT_EG1_EG1(gain,damping)        /*lint -e(704) <avoid divide for performance>*/ \
172*ec779b8eSAndroid Build Coastguard Worker             (int32_t)(                                        \
173*ec779b8eSAndroid Build Coastguard Worker             (                                                \
174*ec779b8eSAndroid Build Coastguard Worker                 ((int32_t)(gain)) * ((int32_t)(damping))    \
175*ec779b8eSAndroid Build Coastguard Worker             )                                                \
176*ec779b8eSAndroid Build Coastguard Worker             >> NUM_EG1_FRAC_BITS                            \
177*ec779b8eSAndroid Build Coastguard Worker                                         )
178*ec779b8eSAndroid Build Coastguard Worker 
179*ec779b8eSAndroid Build Coastguard Worker // Use the following macro specifically for the filter, when multiplying
180*ec779b8eSAndroid Build Coastguard Worker // the b1 coefficient. The 0 <= |b1| < 2, which therefore might overflow
181*ec779b8eSAndroid Build Coastguard Worker // in certain conditions because we store b1 as a 1.15 value.
182*ec779b8eSAndroid Build Coastguard Worker // Instead, we could store b1 as b1p (b1' == b1 "prime") where
183*ec779b8eSAndroid Build Coastguard Worker // b1p == b1/2, thus ensuring no potential overflow for b1p because
184*ec779b8eSAndroid Build Coastguard Worker // 0 <= |b1p| < 1
185*ec779b8eSAndroid Build Coastguard Worker // However, during the filter calculation, we must account for the fact
186*ec779b8eSAndroid Build Coastguard Worker // that we are using b1p instead of b1, and thereby multiply by
187*ec779b8eSAndroid Build Coastguard Worker // an extra factor of 2. Rather than multiply by an extra factor of 2,
188*ec779b8eSAndroid Build Coastguard Worker // we can instead shift the result right by one less, hence the
189*ec779b8eSAndroid Build Coastguard Worker // modified shift right value of (NUM_EG1_FRAC_BITS -1)
190*ec779b8eSAndroid Build Coastguard Worker #define MULT_EG1_EG1_X2(gain,damping)         /*lint -e(702) <avoid divide for performance>*/ \
191*ec779b8eSAndroid Build Coastguard Worker             (int32_t)(                                        \
192*ec779b8eSAndroid Build Coastguard Worker             (                                                \
193*ec779b8eSAndroid Build Coastguard Worker                 ((int32_t)(gain)) * ((int32_t)(damping))    \
194*ec779b8eSAndroid Build Coastguard Worker             )                                                \
195*ec779b8eSAndroid Build Coastguard Worker             >> (NUM_EG1_FRAC_BITS -1)                        \
196*ec779b8eSAndroid Build Coastguard Worker                                         )
197*ec779b8eSAndroid Build Coastguard Worker 
198*ec779b8eSAndroid Build Coastguard Worker #define SATURATE_EG1(x)        /*lint -e{734} saturation operation */                \
199*ec779b8eSAndroid Build Coastguard Worker     ((int32_t)(x) > SYNTH_FULL_SCALE_EG1_GAIN)    ? (SYNTH_FULL_SCALE_EG1_GAIN) :    \
200*ec779b8eSAndroid Build Coastguard Worker     ((int32_t)(x) < EG1_MINUS_ONE)                ? (EG1_MINUS_ONE) :    (x);
201*ec779b8eSAndroid Build Coastguard Worker 
202*ec779b8eSAndroid Build Coastguard Worker 
203*ec779b8eSAndroid Build Coastguard Worker /* use "digital cents" == "dents" instead of cents */
204*ec779b8eSAndroid Build Coastguard Worker /* we coudl re-use the phase frac macros, but if we do,
205*ec779b8eSAndroid Build Coastguard Worker we must change the phase macros to cast to _I32 instead of _U32,
206*ec779b8eSAndroid Build Coastguard Worker because using a _U32 cast causes problems when shifting the exponent
207*ec779b8eSAndroid Build Coastguard Worker for the 2^x calculation, because right shift a negative values MUST
208*ec779b8eSAndroid Build Coastguard Worker be sign extended, or else the 2^x calculation is wrong */
209*ec779b8eSAndroid Build Coastguard Worker 
210*ec779b8eSAndroid Build Coastguard Worker /* use "digital cents" == "dents" instead of cents */
211*ec779b8eSAndroid Build Coastguard Worker #define NUM_DENTS_FRAC_BITS        12
212*ec779b8eSAndroid Build Coastguard Worker #define NUM_DENTS_INT_BITS         (HARDWARE_BIT_WIDTH - NUM_DENTS_FRAC_BITS)
213*ec779b8eSAndroid Build Coastguard Worker 
214*ec779b8eSAndroid Build Coastguard Worker #define DENTS_FRAC_MASK            (int32_t) ((0x1L << NUM_DENTS_FRAC_BITS) -1)
215*ec779b8eSAndroid Build Coastguard Worker 
216*ec779b8eSAndroid Build Coastguard Worker #define GET_DENTS_INT_PART(x)        /*lint -e(704) <avoid divide for performance>*/    \
217*ec779b8eSAndroid Build Coastguard Worker                             (int32_t)((int32_t)(x) >> NUM_DENTS_FRAC_BITS)
218*ec779b8eSAndroid Build Coastguard Worker 
219*ec779b8eSAndroid Build Coastguard Worker #define GET_DENTS_FRAC_PART(x)     (int32_t)((int32_t)(x) & DENTS_FRAC_MASK)
220*ec779b8eSAndroid Build Coastguard Worker 
221*ec779b8eSAndroid Build Coastguard Worker #define DENTS_ONE                  (int32_t) (0x1L << NUM_DENTS_FRAC_BITS)
222*ec779b8eSAndroid Build Coastguard Worker 
223*ec779b8eSAndroid Build Coastguard Worker /* use CENTS_TO_DENTS to convert a value in cents to dents */
224*ec779b8eSAndroid Build Coastguard Worker #define CENTS_TO_DENTS (int32_t) (DENTS_ONE * (0x1L << NUM_EG1_FRAC_BITS) / 1200L)                            \
225*ec779b8eSAndroid Build Coastguard Worker 
226*ec779b8eSAndroid Build Coastguard Worker 
227*ec779b8eSAndroid Build Coastguard Worker /*
228*ec779b8eSAndroid Build Coastguard Worker For gain, the LFO generates a value that modulates in terms
229*ec779b8eSAndroid Build Coastguard Worker of dB. However, we use a linear gain value, so we must convert
230*ec779b8eSAndroid Build Coastguard Worker the LFO value in dB to a linear gain. Normally, we would use
231*ec779b8eSAndroid Build Coastguard Worker linear gain = 10^x, where x = LFO value in dB / 20.
232*ec779b8eSAndroid Build Coastguard Worker Instead, we implement 10^x using our 2^x approximation.
233*ec779b8eSAndroid Build Coastguard Worker because
234*ec779b8eSAndroid Build Coastguard Worker 
235*ec779b8eSAndroid Build Coastguard Worker   10^x = 2^(log2(10^x)) = 2^(x * log2(10))
236*ec779b8eSAndroid Build Coastguard Worker 
237*ec779b8eSAndroid Build Coastguard Worker so we need to multiply by log2(10) which is just a constant.
238*ec779b8eSAndroid Build Coastguard Worker Ah, but just wait -- our 2^x actually doesn't exactly implement
239*ec779b8eSAndroid Build Coastguard Worker 2^x, but it actually assumes that the input is in cents, and within
240*ec779b8eSAndroid Build Coastguard Worker the 2^x approximation converts its input from cents to octaves
241*ec779b8eSAndroid Build Coastguard Worker by dividing its input by 1200.
242*ec779b8eSAndroid Build Coastguard Worker 
243*ec779b8eSAndroid Build Coastguard Worker So, in order to convert the LFO gain value in dB to something
244*ec779b8eSAndroid Build Coastguard Worker that our existing 2^x approximation can use, multiply the LFO gain
245*ec779b8eSAndroid Build Coastguard Worker by log2(10) * 1200 / 20
246*ec779b8eSAndroid Build Coastguard Worker 
247*ec779b8eSAndroid Build Coastguard Worker The divide by 20 helps convert dB to linear gain, and we might
248*ec779b8eSAndroid Build Coastguard Worker as well incorporate that operation into this conversion.
249*ec779b8eSAndroid Build Coastguard Worker Of course, we need to keep some fractional bits, so multiply
250*ec779b8eSAndroid Build Coastguard Worker the constant by NUM_EG1_FRAC_BITS
251*ec779b8eSAndroid Build Coastguard Worker */
252*ec779b8eSAndroid Build Coastguard Worker 
253*ec779b8eSAndroid Build Coastguard Worker /* use LFO_GAIN_TO_CENTS to convert the LFO gain value to cents */
254*ec779b8eSAndroid Build Coastguard Worker 
255*ec779b8eSAndroid Build Coastguard Worker #define LFO_GAIN_TO_CENTS (int32_t) (1671981156L >> (23 - NUM_EG1_FRAC_BITS))
256*ec779b8eSAndroid Build Coastguard Worker 
257*ec779b8eSAndroid Build Coastguard Worker 
258*ec779b8eSAndroid Build Coastguard Worker #define MULT_DENTS_COEF(dents,coef)     /*lint -e704 <avoid divide for performance>*/    \
259*ec779b8eSAndroid Build Coastguard Worker             (int32_t)(                                    \
260*ec779b8eSAndroid Build Coastguard Worker             (                                            \
261*ec779b8eSAndroid Build Coastguard Worker                 ((int32_t)(dents)) * ((int32_t)(coef))    \
262*ec779b8eSAndroid Build Coastguard Worker             )                                            \
263*ec779b8eSAndroid Build Coastguard Worker             >> NUM_DENTS_FRAC_BITS                        \
264*ec779b8eSAndroid Build Coastguard Worker                                         )                \
265*ec779b8eSAndroid Build Coastguard Worker                                         /* lint +e704 <restore checking>*/
266*ec779b8eSAndroid Build Coastguard Worker 
267*ec779b8eSAndroid Build Coastguard Worker 
268*ec779b8eSAndroid Build Coastguard Worker /* we use 16-bits in the PC per audio sample */
269*ec779b8eSAndroid Build Coastguard Worker #define BITS_PER_AUDIO_SAMPLE    16
270*ec779b8eSAndroid Build Coastguard Worker 
271*ec779b8eSAndroid Build Coastguard Worker /* we define 1 as 1.0 - 1 LSbit */
272*ec779b8eSAndroid Build Coastguard Worker #define DISTORTION_ONE           (int32_t)((0x1L << (BITS_PER_AUDIO_SAMPLE-1)) -1)
273*ec779b8eSAndroid Build Coastguard Worker #define DISTORTION_MINUS_ONE     (int32_t)(~DISTORTION_ONE)
274*ec779b8eSAndroid Build Coastguard Worker 
275*ec779b8eSAndroid Build Coastguard Worker /* drive coef is given as int.frac */
276*ec779b8eSAndroid Build Coastguard Worker #define NUM_DRIVE_COEF_INT_BITS  1
277*ec779b8eSAndroid Build Coastguard Worker #define NUM_DRIVE_COEF_FRAC_BITS 4
278*ec779b8eSAndroid Build Coastguard Worker 
279*ec779b8eSAndroid Build Coastguard Worker #define MULT_AUDIO_DRIVE(audio,drive)         /*lint -e(702) <avoid divide for performance>*/ \
280*ec779b8eSAndroid Build Coastguard Worker             (int32_t)    (                                \
281*ec779b8eSAndroid Build Coastguard Worker             (                                            \
282*ec779b8eSAndroid Build Coastguard Worker                 ((int32_t)(audio)) * ((int32_t)(drive))    \
283*ec779b8eSAndroid Build Coastguard Worker             )                                            \
284*ec779b8eSAndroid Build Coastguard Worker             >> NUM_DRIVE_COEF_FRAC_BITS                    \
285*ec779b8eSAndroid Build Coastguard Worker                                                 )
286*ec779b8eSAndroid Build Coastguard Worker 
287*ec779b8eSAndroid Build Coastguard Worker #define MULT_AUDIO_AUDIO(audio1,audio2)         /*lint -e(702) <avoid divide for performance>*/ \
288*ec779b8eSAndroid Build Coastguard Worker             (int32_t)    (                                    \
289*ec779b8eSAndroid Build Coastguard Worker             (                                                \
290*ec779b8eSAndroid Build Coastguard Worker                 ((int32_t)(audio1)) * ((int32_t)(audio2))    \
291*ec779b8eSAndroid Build Coastguard Worker             )                                                \
292*ec779b8eSAndroid Build Coastguard Worker             >> (BITS_PER_AUDIO_SAMPLE-1)                    \
293*ec779b8eSAndroid Build Coastguard Worker                                                     )
294*ec779b8eSAndroid Build Coastguard Worker 
295*ec779b8eSAndroid Build Coastguard Worker #define SATURATE(x)                                                            \
296*ec779b8eSAndroid Build Coastguard Worker     ((((int32_t)(x)) > DISTORTION_ONE)        ? (DISTORTION_ONE) :            \
297*ec779b8eSAndroid Build Coastguard Worker     (((int32_t)(x)) < DISTORTION_MINUS_ONE)    ? (DISTORTION_MINUS_ONE) :    ((int32_t)(x)));
298*ec779b8eSAndroid Build Coastguard Worker 
299*ec779b8eSAndroid Build Coastguard Worker 
300*ec779b8eSAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
301*ec779b8eSAndroid Build Coastguard Worker  * Effects_log2()
302*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
303*ec779b8eSAndroid Build Coastguard Worker  * Purpose:
304*ec779b8eSAndroid Build Coastguard Worker  * Fixed-point log2 function.
305*ec779b8eSAndroid Build Coastguard Worker  *
306*ec779b8eSAndroid Build Coastguard Worker  * Inputs:
307*ec779b8eSAndroid Build Coastguard Worker  * Input is interpreted as an integer (should not be 0).
308*ec779b8eSAndroid Build Coastguard Worker  *
309*ec779b8eSAndroid Build Coastguard Worker  * Outputs:
310*ec779b8eSAndroid Build Coastguard Worker  * Output is in 15-bit precision.
311*ec779b8eSAndroid Build Coastguard Worker  *
312*ec779b8eSAndroid Build Coastguard Worker  * Side Effects:
313*ec779b8eSAndroid Build Coastguard Worker  *
314*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
315*ec779b8eSAndroid Build Coastguard Worker */
316*ec779b8eSAndroid Build Coastguard Worker int32_t Effects_log2(uint32_t x);
317*ec779b8eSAndroid Build Coastguard Worker 
318*ec779b8eSAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
319*ec779b8eSAndroid Build Coastguard Worker  * Effects_exp2()
320*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
321*ec779b8eSAndroid Build Coastguard Worker  * Purpose:
322*ec779b8eSAndroid Build Coastguard Worker  * Fixed-point radix-2 exponent.
323*ec779b8eSAndroid Build Coastguard Worker  *
324*ec779b8eSAndroid Build Coastguard Worker  * Inputs:
325*ec779b8eSAndroid Build Coastguard Worker  * Input is in 15-bit precision. Must be non-negative and less than 32.
326*ec779b8eSAndroid Build Coastguard Worker  *
327*ec779b8eSAndroid Build Coastguard Worker  * Outputs:
328*ec779b8eSAndroid Build Coastguard Worker  * Output is an integer.
329*ec779b8eSAndroid Build Coastguard Worker  *
330*ec779b8eSAndroid Build Coastguard Worker  * Side Effects:
331*ec779b8eSAndroid Build Coastguard Worker  *
332*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
333*ec779b8eSAndroid Build Coastguard Worker */
334*ec779b8eSAndroid Build Coastguard Worker uint32_t Effects_exp2(int32_t x);
335*ec779b8eSAndroid Build Coastguard Worker 
336*ec779b8eSAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
337*ec779b8eSAndroid Build Coastguard Worker  * Effects_MillibelsToLinear16()
338*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
339*ec779b8eSAndroid Build Coastguard Worker  * Purpose:
340*ec779b8eSAndroid Build Coastguard Worker  * Transform gain in millibels to linear gain multiplier:
341*ec779b8eSAndroid Build Coastguard Worker  *
342*ec779b8eSAndroid Build Coastguard Worker  * mB = 2000*log(lin/32767)
343*ec779b8eSAndroid Build Coastguard Worker  *    => lin = 2^((mB+2000*log(32767))/2000*log(2))
344*ec779b8eSAndroid Build Coastguard Worker  *    => lin = Effects_exp2(((mB + K1) << 15) / K2)
345*ec779b8eSAndroid Build Coastguard Worker  * with:
346*ec779b8eSAndroid Build Coastguard Worker  *    K1 = 2000*log(32767) and K2 = 2000*log(2)
347*ec779b8eSAndroid Build Coastguard Worker  *
348*ec779b8eSAndroid Build Coastguard Worker  * Inputs:
349*ec779b8eSAndroid Build Coastguard Worker  * nGain - log scale value in millibels.
350*ec779b8eSAndroid Build Coastguard Worker  *
351*ec779b8eSAndroid Build Coastguard Worker  * Outputs:
352*ec779b8eSAndroid Build Coastguard Worker  * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
353*ec779b8eSAndroid Build Coastguard Worker  *
354*ec779b8eSAndroid Build Coastguard Worker  * Side Effects:
355*ec779b8eSAndroid Build Coastguard Worker  *
356*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
357*ec779b8eSAndroid Build Coastguard Worker */
358*ec779b8eSAndroid Build Coastguard Worker #define MB_TO_LIN_K1 9031
359*ec779b8eSAndroid Build Coastguard Worker #define MB_TO_LIN_K2 602
360*ec779b8eSAndroid Build Coastguard Worker int16_t Effects_MillibelsToLinear16 (int32_t nGain);
361*ec779b8eSAndroid Build Coastguard Worker 
362*ec779b8eSAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
363*ec779b8eSAndroid Build Coastguard Worker  * Effects_Linear16ToMillibels()
364*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
365*ec779b8eSAndroid Build Coastguard Worker  * Purpose:
366*ec779b8eSAndroid Build Coastguard Worker  * Transform linear gain multiplier to millibels
367*ec779b8eSAndroid Build Coastguard Worker  *  mB = 2000*log(lin/32767)
368*ec779b8eSAndroid Build Coastguard Worker  *     = 2000*log(2)*log2(lin)-2000*log(32767)
369*ec779b8eSAndroid Build Coastguard Worker  *    => mB = K1*Effects_log2(lin) + K2
370*ec779b8eSAndroid Build Coastguard Worker  * with:
371*ec779b8eSAndroid Build Coastguard Worker  *    K1 = 2000*log(2) and K2 = -2000*log(32767)
372*ec779b8eSAndroid Build Coastguard Worker  *
373*ec779b8eSAndroid Build Coastguard Worker  * Inputs:
374*ec779b8eSAndroid Build Coastguard Worker  * nGain - linear multiplier ranging form 0 to 32767 (corresponding to [0 1] gain range).
375*ec779b8eSAndroid Build Coastguard Worker  *
376*ec779b8eSAndroid Build Coastguard Worker  * Outputs:
377*ec779b8eSAndroid Build Coastguard Worker  * Returns a 16-bit log value expressed in milllibels.
378*ec779b8eSAndroid Build Coastguard Worker  *
379*ec779b8eSAndroid Build Coastguard Worker  * Side Effects:
380*ec779b8eSAndroid Build Coastguard Worker  *
381*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
382*ec779b8eSAndroid Build Coastguard Worker */
383*ec779b8eSAndroid Build Coastguard Worker int16_t Effects_Linear16ToMillibels (int32_t nGain);
384*ec779b8eSAndroid Build Coastguard Worker 
385*ec779b8eSAndroid Build Coastguard Worker /*----------------------------------------------------------------------------
386*ec779b8eSAndroid Build Coastguard Worker  * Effects_Sqrt()
387*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
388*ec779b8eSAndroid Build Coastguard Worker  * Purpose:
389*ec779b8eSAndroid Build Coastguard Worker  * Returns the square root of the argument given.
390*ec779b8eSAndroid Build Coastguard Worker  *
391*ec779b8eSAndroid Build Coastguard Worker  * Inputs:
392*ec779b8eSAndroid Build Coastguard Worker  * in - positive number in the range 0 - 2^28
393*ec779b8eSAndroid Build Coastguard Worker  *
394*ec779b8eSAndroid Build Coastguard Worker  * Outputs:
395*ec779b8eSAndroid Build Coastguard Worker  * Returned value: square root of in.
396*ec779b8eSAndroid Build Coastguard Worker  *
397*ec779b8eSAndroid Build Coastguard Worker  * Side Effects:
398*ec779b8eSAndroid Build Coastguard Worker  *
399*ec779b8eSAndroid Build Coastguard Worker  *----------------------------------------------------------------------------
400*ec779b8eSAndroid Build Coastguard Worker */
401*ec779b8eSAndroid Build Coastguard Worker int32_t Effects_Sqrt(int32_t in);
402*ec779b8eSAndroid Build Coastguard Worker 
403*ec779b8eSAndroid Build Coastguard Worker #if __cplusplus
404*ec779b8eSAndroid Build Coastguard Worker }  // extern "C"
405*ec779b8eSAndroid Build Coastguard Worker #endif
406*ec779b8eSAndroid Build Coastguard Worker 
407*ec779b8eSAndroid Build Coastguard Worker #endif /*ANDROID_EFFECTSMATH_H_*/
408*ec779b8eSAndroid Build Coastguard Worker 
409