blob: 18f27e9d5c412313a861603359887e6e2d818a25 [file] [log] [blame]
Dave Sparks56c99cd2009-08-24 17:35:45 -07001/*----------------------------------------------------------------------------
2 *
3 * File:
4 * eas_math.c
5 *
6 * Contents and purpose:
7 * Contains common math routines for the various audio engines.
8 *
9 *
10 * Copyright Sonic Network Inc. 2005
The Android Open Source Project7df30102009-03-03 19:30:38 -080011
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
Dave Sparks56c99cd2009-08-24 17:35:45 -070023 *
24 *----------------------------------------------------------------------------
25 * Revision Control:
26 * $Revision: 586 $
27 * $Date: 2007-03-08 20:33:04 -0800 (Thu, 08 Mar 2007) $
28 *----------------------------------------------------------------------------
29*/
30
31#include "eas.h"
32#include "eas_math.h"
33
34/* anything less than this converts to a fraction too small to represent in 32-bits */
35#define MIN_CENTS -18000
Marco Nelissen699753c2020-04-30 19:54:37 -070036/* anything greater than this converts to a fraction too large to represent in 32-bits */
37#define MAX_CENTS 19200
Dave Sparks56c99cd2009-08-24 17:35:45 -070038
39/*----------------------------------------------------------------------------
40 * EAS_Calculate2toX()
41 *----------------------------------------------------------------------------
42 * Purpose:
43 * Calculate 2^x
44 *
45 * Inputs:
46 * nCents - measured in cents
47 * psEASData - pointer to overall EAS data structure
48 *
49 * Outputs:
50 * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
51 *
52 * Side Effects:
53 *
54 *----------------------------------------------------------------------------
55*/
Marco Nelissen699753c2020-04-30 19:54:37 -070056
Dave Sparks56c99cd2009-08-24 17:35:45 -070057EAS_I32 EAS_Calculate2toX (EAS_I32 nCents)
58{
59 EAS_I32 nDents;
60 EAS_I32 nExponentInt, nExponentFrac;
61 EAS_I32 nTemp1, nTemp2;
62 EAS_I32 nResult;
63
64 /* check for minimum value */
65 if (nCents < MIN_CENTS)
66 return 0;
67
Marco Nelissen699753c2020-04-30 19:54:37 -070068 if (nCents > MAX_CENTS) {
69 nCents = MAX_CENTS;
70 }
71
Dave Sparks56c99cd2009-08-24 17:35:45 -070072 /* for the time being, convert cents to dents */
73 nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
74
75 nExponentInt = GET_DENTS_INT_PART(nDents);
76 nExponentFrac = GET_DENTS_FRAC_PART(nDents);
77
78 /*
79 implement 2^(fracPart) as a power series
80 */
81 nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
82 nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
83 nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
84
85 /*
86 implement 2^(intPart) as
87 a left shift for intPart >= 0 or
88 a left shift for intPart < 0
89 */
90 if (nExponentInt >= 0)
91 {
92 /* left shift for positive exponents */
93 /*lint -e{703} <avoid multiply for performance>*/
94 nResult = nTemp1 << nExponentInt;
95 }
96 else
97 {
98 /* right shift for negative exponents */
99 nExponentInt = -nExponentInt;
100 nResult = nTemp1 >> nExponentInt;
101 }
102
103 return nResult;
104}
105
106/*----------------------------------------------------------------------------
107 * EAS_LogToLinear16()
108 *----------------------------------------------------------------------------
109 * Purpose:
110 * Transform log value to linear gain multiplier using piece-wise linear
111 * approximation
112 *
113 * Inputs:
114 * nGain - log scale value in 20.10 format. Even though gain is normally
115 * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
116 * the need for saturation checking when combining gain values.
117 *
118 * Outputs:
119 * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
120 *
121 * Side Effects:
122 *
123 *----------------------------------------------------------------------------
124*/
125EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain)
126{
127 EAS_INT nExp;
128 EAS_U16 nTemp;
129
130 /* bias to positive */
131 nGain += 32767;
132
133 /* check for infinite attenuation */
134 if (nGain < 0)
135 return 0;
136
137 /* extract the exponent */
138 nExp = 31 - (nGain >> 10);
139
140 /* check for maximum output */
141 if (nExp < 0)
142 return 0x7fff;
143
144 /* extract mantissa and restore implied 1 bit */
145 nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp);
146
147 /* use shift to approximate power-of-2 operation */
148 return nTemp;
149}
150
151/*----------------------------------------------------------------------------
152 * EAS_VolumeToGain()
153 *----------------------------------------------------------------------------
154 * Purpose:
155 * Transform volume control in 1dB increments to gain multiplier
156 *
157 * Inputs:
158 * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
159 *
160 * Outputs:
161 * Returns a 16-bit linear value
162 *----------------------------------------------------------------------------
163*/
164EAS_I16 EAS_VolumeToGain (EAS_INT volume)
165{
166 /* check for limits */
167 if (volume <= 0)
168 return 0;
169 if (volume >= 100)
170 return 0x7fff;
171
172 /*lint -e{702} use shift instead of division */
173 return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1);
174}
175