AAX SDK  2.4.1
Avid Audio Extensions Development Kit
AAX_FastPow.h
Go to the documentation of this file.
1 /*================================================================================================*/
2 /*
3  * Copyright 2009-2015 by Avid Technology, Inc.
4  * All rights reserved.
5  *
6  * CONFIDENTIAL: This document contains confidential information. Do not
7  * read or examine this document unless you are an Avid Technology employee
8  * or have signed a non-disclosure agreement with Avid Technology which protects
9  * the confidentiality of this document. DO NOT DISCLOSE ANY INFORMATION
10  * CONTAINED IN THIS DOCUMENT TO ANY THIRD-PARTY WITHOUT THE PRIOR WRITTEN CONSENT
11  * OF Avid Technology, INC.
12  */
13 
32 /*================================================================================================*/
33 
34 
35 
36 
37 #pragma once
38 
39 #ifndef _AAX_FASTPOW_H_
40 #define _AAX_FASTPOW_H_
41 
42 #include <cmath>
43 #if defined(MAC_VERSION) || defined(LINUX_VERSION)
44 namespace std {using ::powf;using ::log10f;using ::fabsf;}
45 #endif
46 #include "AAX.h" // For AAX_RESTRICT
47 
48 namespace AAX
49 {
50 static const float _2p23 = 8388608.0f;
51 const unsigned int kPowExtent = 9; // 9 results in ~-80dB cancellation
52 const unsigned int kPowTableSize = 1 << kPowExtent;
53 
68 static inline void PowFastSetTable(
69  float* const AAX_RESTRICT pTable,
70  const unsigned int precision,
71  const unsigned int extent,
72  const bool isRound)
73 {
74  // step along table elements and x-axis positions
75  float zeroToOne = !isRound ?
76  0.0f : (1.0f / (static_cast<float>(1 << precision) * 2.0f));
77  for( int i = 0; i < (1 << extent); ++i )
78  {
79  // make y-axis value for table element
80  pTable[i] = std::powf( 2.0f, zeroToOne );
81 
82  zeroToOne += 1.0f / static_cast<float>(1 << precision);
83  }
84 }
85 
131 static inline float PowFastLookup(
132  const float val,
133  const float ilog2,
134  const float* const AAX_RESTRICT tableH,
135  const float* const AAX_RESTRICT tableL)
136 {
137 
138  // build float bits
139  const int i = static_cast<int>( (val * (_2p23 * ilog2)) + (127.0f * _2p23) );
140 
141  // replace mantissa with combined lookups
142  const float t = tableH[(i >> 14) & 0x1FF] * tableL[(i >> 5) & 0x1FF];
143  const int it = (i & 0xFF800000) |
144  (*reinterpret_cast<const int*>( &t ) & 0x7FFFFF);
145 
146  // convert bits to float
147  return *reinterpret_cast<const float*>( &it );
148 
149 }
150 
162 static inline float Pow2FastLookup(
163  const float val,
164  const float* const AAX_RESTRICT tableH,
165  const float* const AAX_RESTRICT tableL)
166 {
167 
168  // build float bits
169  const int i = static_cast<int>((val + 127.0f) * _2p23);
170 
171  // replace mantissa with combined lookups
172  const float t = tableH[(i >> 14) & 0x1FF] * tableL[(i >> 5) & 0x1FF];
173  const int it = (i & 0xFF800000) |
174  (*reinterpret_cast<const int*>( &t ) & 0x007FFFFF);
175 
176  // convert bits to float
177  return *reinterpret_cast<const float*>( &it );
178 
179 }
181 
182 
183 static const int kMantissaBitSize = 23;
184 static const int kExpBias = 127;
185 static const int kLogMantissaMSBs = 9;
186 static const int kLogTableSize = (1 << kLogMantissaMSBs) + 1;// 513;
187 
198 static inline void LogFastSetTable(
199  float* const AAX_RESTRICT logTable,
200  int tableSize = kLogTableSize)
201 {
202  const float kInv = 1.0f/float(tableSize - 1); // 0.001953125
203  float mantissaVal = 1.0f; //Start here.
204  const float invLog10Base2 = 1.0f / std::log10f(2.0f);
205  for (int j = 0; j < tableSize; j++)
206  {
207  logTable[j] = std::log10f(mantissaVal) * invLog10Base2; //By log equivalency: log2(x) = log10(x)/log10(2)
208  mantissaVal += kInv;
209 
210  }
211 
212  return;
213 }
214 
233 template <int kMantMSBs>
234 static inline void LogFloatToExpMantissa(
235  float number,
236  int * const AAX_RESTRICT outExp,
237  int * const AAX_RESTRICT outMant,
238  float* const AAX_RESTRICT fract)
239 {
240  const int mantissaSize = 1 << (kMantissaBitSize - kMantMSBs);
241  const float invMantissaSize = 1.0f/(float)mantissaSize;
242  const int intEquiv = *reinterpret_cast<const int*>(&number);
243 
244  //bool isNegative = (result & 0x80000000) != 0; //Sign bit
245  const int exponent = (intEquiv & 0x7f800000) >> 23; //Exponent bits
246  const int mantissa = intEquiv & 0x007fffff; //Mantissa bits.
247 
248  // 0 000|0 000|0 1 010| 0000 0000 0000 0000 0000
249  // 0111 1111 1000 0000 0000 0000 0000 0000 = 7f800000 (Exp)
250  // 0000 0000 0111 1111 1111 1111 1111 1111 = 007fffff (Mant)
251 
252  *outExp = exponent - kExpBias; //Compensate for exponent bias for caller.
253  //To do: add halfLSBShifted to mantissa before shifting; *outMant = (mantissa + halfLSBShifted) >> (kMantissaBitSize - mantMSBs)
254  *outMant = mantissa >> (kMantissaBitSize - kMantMSBs); //Shift to provide only mantMSBs for log LUT.
255  // Provide a linear interpolation fraction
256  *fract = (float)(mantissa & (mantissaSize - 1)) * invMantissaSize;
257 
258  return;
259 }
260 
274 template <int kPrecision>
275 static inline float LogFastLookup(
276  float num,
277  const float* const AAX_RESTRICT logTable)
278 {
279 
280  int exponent, mantissa;
281  float fract;
282 
283  AAX::LogFloatToExpMantissa<kPrecision>(num, &exponent, &mantissa, &fract);
284 
285  const float mantLog1 = logTable[mantissa];
286  const float mantLog2 = logTable[mantissa+1];
287 
288  const float logOfNum = (mantLog1 * (1.0f - fract) + fract * mantLog2) + exponent;
289  return logOfNum;
290 }
291 
292 
293 
294 } // namespace AAX
295 
296 #endif // #ifndef _AAX_FASTPOW_H_
Various utility definitions for AAX.
Definition: AAX_Exception.h:42
const unsigned int kPowExtent
Definition: AAX_FastPow.h:51
const unsigned int kPowTableSize
Definition: AAX_FastPow.h:52
float fabsf(float iVal)
Definition: AAX_MiscUtils.h:185