• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*----------------------------------------------------------------------------
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
11  
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.
23   *
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
36  
37  /*----------------------------------------------------------------------------
38   * EAS_Calculate2toX()
39   *----------------------------------------------------------------------------
40   * Purpose:
41   * Calculate 2^x
42   *
43   * Inputs:
44   * nCents -     measured in cents
45   * psEASData - pointer to overall EAS data structure
46   *
47   * Outputs:
48   * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
49   *
50   * Side Effects:
51   *
52   *----------------------------------------------------------------------------
53  */
EAS_Calculate2toX(EAS_I32 nCents)54  EAS_I32 EAS_Calculate2toX (EAS_I32 nCents)
55  {
56      EAS_I32 nDents;
57      EAS_I32 nExponentInt, nExponentFrac;
58      EAS_I32 nTemp1, nTemp2;
59      EAS_I32 nResult;
60  
61      /* check for minimum value */
62      if (nCents < MIN_CENTS)
63          return 0;
64  
65      /* for the time being, convert cents to dents */
66      nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
67  
68      nExponentInt = GET_DENTS_INT_PART(nDents);
69      nExponentFrac = GET_DENTS_FRAC_PART(nDents);
70  
71      /*
72      implement 2^(fracPart) as a power series
73      */
74      nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
75      nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
76      nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
77  
78      /*
79      implement 2^(intPart) as
80      a left shift for intPart >= 0 or
81      a left shift for intPart <  0
82      */
83      if (nExponentInt >= 0)
84      {
85          /* left shift for positive exponents */
86          /*lint -e{703} <avoid multiply for performance>*/
87          nResult = nTemp1 << nExponentInt;
88      }
89      else
90      {
91          /* right shift for negative exponents */
92          nExponentInt = -nExponentInt;
93          nResult = nTemp1 >> nExponentInt;
94      }
95  
96      return nResult;
97  }
98  
99  /*----------------------------------------------------------------------------
100   * EAS_LogToLinear16()
101   *----------------------------------------------------------------------------
102   * Purpose:
103   * Transform log value to linear gain multiplier using piece-wise linear
104   * approximation
105   *
106   * Inputs:
107   * nGain - log scale value in 20.10 format. Even though gain is normally
108   * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
109   * the need for saturation checking when combining gain values.
110   *
111   * Outputs:
112   * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
113   *
114   * Side Effects:
115   *
116   *----------------------------------------------------------------------------
117  */
EAS_LogToLinear16(EAS_I32 nGain)118  EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain)
119  {
120      EAS_INT nExp;
121      EAS_U16 nTemp;
122  
123      /* bias to positive */
124      nGain += 32767;
125  
126      /* check for infinite attenuation */
127      if (nGain < 0)
128          return 0;
129  
130      /* extract the exponent */
131      nExp = 31 - (nGain >> 10);
132  
133      /* check for maximum output */
134      if (nExp < 0)
135          return 0x7fff;
136  
137      /* extract mantissa and restore implied 1 bit */
138      nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp);
139  
140      /* use shift to approximate power-of-2 operation */
141      return nTemp;
142  }
143  
144  /*----------------------------------------------------------------------------
145   * EAS_VolumeToGain()
146   *----------------------------------------------------------------------------
147   * Purpose:
148   * Transform volume control in 1dB increments to gain multiplier
149   *
150   * Inputs:
151   * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
152   *
153   * Outputs:
154   * Returns a 16-bit linear value
155   *----------------------------------------------------------------------------
156  */
EAS_VolumeToGain(EAS_INT volume)157  EAS_I16 EAS_VolumeToGain (EAS_INT volume)
158  {
159      /* check for limits */
160      if (volume <= 0)
161          return 0;
162      if (volume >= 100)
163          return 0x7fff;
164  
165      /*lint -e{702} use shift instead of division */
166      return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1);
167  }
168  
169