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