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