summaryrefslogtreecommitdiffstats
path: root/arm-fm-22k/lib_src/eas_math.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm-fm-22k/lib_src/eas_math.c')
-rw-r--r--arm-fm-22k/lib_src/eas_math.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/arm-fm-22k/lib_src/eas_math.c b/arm-fm-22k/lib_src/eas_math.c
new file mode 100644
index 0000000..12d788e
--- /dev/null
+++ b/arm-fm-22k/lib_src/eas_math.c
@@ -0,0 +1,168 @@
+/*----------------------------------------------------------------------------
+ *
+ * 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);
+}
+