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