/*----------------------------------------------------------------------------
 *
 * File: 
 * eas_math.c
 *
 * Contents and purpose:
 * Contains common math routines for the various audio engines.
 *
 *
 * Copyright Sonic Network Inc. 2005

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *----------------------------------------------------------------------------
 * Revision Control:
 *   $Revision: 586 $
 *   $Date: 2007-03-08 20:33:04 -0800 (Thu, 08 Mar 2007) $
 *----------------------------------------------------------------------------
*/

#include "eas.h"
#include "eas_math.h"

/* anything less than this converts to a fraction too small to represent in 32-bits */
#define MIN_CENTS	-18000

/*----------------------------------------------------------------------------
 * EAS_Calculate2toX()
 *----------------------------------------------------------------------------
 * Purpose:
 * Calculate 2^x
 *
 * Inputs:
 * nCents - 	measured in cents
 * psEASData - pointer to overall EAS data structure
 *
 * Outputs:
 * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
 *
 * Side Effects:
 *
 *----------------------------------------------------------------------------
*/
EAS_I32 EAS_Calculate2toX (EAS_I32 nCents)
{
	EAS_I32 nDents;
	EAS_I32 nExponentInt, nExponentFrac;
	EAS_I32 nTemp1, nTemp2;
	EAS_I32 nResult;

	/* check for minimum value */
	if (nCents < MIN_CENTS)
		return 0;

	/* for the time being, convert cents to dents */
	nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);

	nExponentInt = GET_DENTS_INT_PART(nDents);
	nExponentFrac = GET_DENTS_FRAC_PART(nDents);

	/*
	implement 2^(fracPart) as a power series
	*/
	nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
	nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
	nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);

	/*
	implement 2^(intPart) as 
	a left shift for intPart >= 0 or
	a left shift for intPart <  0
	*/
	if (nExponentInt >= 0)
	{
		/* left shift for positive exponents */
		/*lint -e{703} <avoid multiply for performance>*/
		nResult = nTemp1 << nExponentInt;
	}
	else
	{
		/* right shift for negative exponents */
		nExponentInt = -nExponentInt;
		nResult = nTemp1 >> nExponentInt;
	}

	return nResult;
}

/*----------------------------------------------------------------------------
 * EAS_LogToLinear16()
 *----------------------------------------------------------------------------
 * Purpose:
 * Transform log value to linear gain multiplier using piece-wise linear
 * approximation
 *
 * Inputs:
 * nGain - log scale value in 20.10 format. Even though gain is normally
 * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
 * the need for saturation checking when combining gain values.
 *
 * Outputs:
 * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
 *
 * Side Effects:
 *
 *----------------------------------------------------------------------------
*/
EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain)
{
	EAS_INT nExp;
	EAS_U16 nTemp;

	/* bias to positive */
	nGain += 32767;

	/* check for infinite attenuation */
	if (nGain < 0)
		return 0;

	/* extract the exponent */
	nExp = 31 - (nGain >> 10);

	/* check for maximum output */
	if (nExp < 0)
		return 0x7fff;

	/* extract mantissa and restore implied 1 bit */
	nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp);

	/* use shift to approximate power-of-2 operation */
	return nTemp;
}

/*----------------------------------------------------------------------------
 * EAS_VolumeToGain()
 *----------------------------------------------------------------------------
 * Purpose:
 * Transform volume control in 1dB increments to gain multiplier
 *
 * Inputs:
 * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
 *
 * Outputs:
 * Returns a 16-bit linear value 
 *----------------------------------------------------------------------------
*/
EAS_I16 EAS_VolumeToGain (EAS_INT volume)
{
	/* check for limits */
	if (volume <= 0)
		return 0;
	if (volume >= 100)
		return 0x7fff;
	
	/*lint -e{702} use shift instead of division */
	return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1);
}

