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