156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*---------------------------------------------------------------------------- 256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * File: 456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * eas_math.c 556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Contents and purpose: 756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Contains common math routines for the various audio engines. 856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 1056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Copyright Sonic Network Inc. 2005 117df30109963092559d3760c0661a020f9daf1030The Android Open Source Project 127df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 137df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * you may not use this file except in compliance with the License. 147df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * You may obtain a copy of the License at 157df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * 167df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 177df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * 187df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 197df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 207df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 217df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * See the License for the specific language governing permissions and 227df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * limitations under the License. 2356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 2456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *---------------------------------------------------------------------------- 2556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Revision Control: 2656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * $Revision: 586 $ 2756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * $Date: 2007-03-08 20:33:04 -0800 (Thu, 08 Mar 2007) $ 2856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *---------------------------------------------------------------------------- 2956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/ 3056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 3156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas.h" 3256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_math.h" 3356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 3456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/* anything less than this converts to a fraction too small to represent in 32-bits */ 3556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#define MIN_CENTS -18000 3656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 3756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*---------------------------------------------------------------------------- 3856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * EAS_Calculate2toX() 3956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *---------------------------------------------------------------------------- 4056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose: 4156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Calculate 2^x 4256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 4356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs: 4456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * nCents - measured in cents 4556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * psEASData - pointer to overall EAS data structure 4656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 4756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs: 4856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS) 4956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 5056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects: 5156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 5256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *---------------------------------------------------------------------------- 5356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/ 5456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksEAS_I32 EAS_Calculate2toX (EAS_I32 nCents) 5556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{ 5656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EAS_I32 nDents; 5756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EAS_I32 nExponentInt, nExponentFrac; 5856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EAS_I32 nTemp1, nTemp2; 5956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EAS_I32 nResult; 6056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 6156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* check for minimum value */ 6256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks if (nCents < MIN_CENTS) 6356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks return 0; 6456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 6556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* for the time being, convert cents to dents */ 6656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nDents = FMUL_15x15(nCents, CENTS_TO_DENTS); 6756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 6856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nExponentInt = GET_DENTS_INT_PART(nDents); 6956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nExponentFrac = GET_DENTS_FRAC_PART(nDents); 7056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 7156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* 7256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks implement 2^(fracPart) as a power series 7356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks */ 7456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3); 7556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1); 7656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2); 7756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 7856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* 7956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks implement 2^(intPart) as 8056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks a left shift for intPart >= 0 or 8156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks a left shift for intPart < 0 8256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks */ 8356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks if (nExponentInt >= 0) 8456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks { 8556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* left shift for positive exponents */ 8656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /*lint -e{703} <avoid multiply for performance>*/ 8756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nResult = nTemp1 << nExponentInt; 8856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 8956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks else 9056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks { 9156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* right shift for negative exponents */ 9256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nExponentInt = -nExponentInt; 9356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nResult = nTemp1 >> nExponentInt; 9456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 9556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 9656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks return nResult; 9756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} 9856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 9956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*---------------------------------------------------------------------------- 10056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * EAS_LogToLinear16() 10156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *---------------------------------------------------------------------------- 10256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose: 10356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Transform log value to linear gain multiplier using piece-wise linear 10456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * approximation 10556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 10656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs: 10756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * nGain - log scale value in 20.10 format. Even though gain is normally 10856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate 10956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * the need for saturation checking when combining gain values. 11056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 11156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs: 11256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Returns a 16-bit linear value approximately equal to 2^(nGain/1024) 11356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 11456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects: 11556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 11656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *---------------------------------------------------------------------------- 11756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/ 11856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksEAS_U16 EAS_LogToLinear16 (EAS_I32 nGain) 11956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{ 12056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EAS_INT nExp; 12156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks EAS_U16 nTemp; 12256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 12356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* bias to positive */ 12456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nGain += 32767; 12556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 12656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* check for infinite attenuation */ 12756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks if (nGain < 0) 12856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks return 0; 12956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 13056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* extract the exponent */ 13156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nExp = 31 - (nGain >> 10); 13256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 13356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* check for maximum output */ 13456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks if (nExp < 0) 13556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks return 0x7fff; 13656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 13756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* extract mantissa and restore implied 1 bit */ 13856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp); 13956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 14056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* use shift to approximate power-of-2 operation */ 14156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks return nTemp; 14256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} 14356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 14456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*---------------------------------------------------------------------------- 14556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * EAS_VolumeToGain() 14656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *---------------------------------------------------------------------------- 14756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose: 14856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Transform volume control in 1dB increments to gain multiplier 14956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 15056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs: 15156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * volume - 100 = 0dB, 99 = -1dB, 0 = -inf 15256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * 15356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs: 15456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Returns a 16-bit linear value 15556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *---------------------------------------------------------------------------- 15656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/ 15756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksEAS_I16 EAS_VolumeToGain (EAS_INT volume) 15856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{ 15956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /* check for limits */ 16056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks if (volume <= 0) 16156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks return 0; 16256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks if (volume >= 100) 16356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks return 0x7fff; 16456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 16556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /*lint -e{702} use shift instead of division */ 16656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1); 16756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} 16856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 169