AAX SDK 2.6.1
Avid Audio Extensions Development Kit
Loading...
Searching...
No Matches
AAX_FastPow.h
Go to the documentation of this file.
1/*================================================================================================*/
2/*
3 * Copyright 2009-2015, 2023 Avid Technology, Inc.
4 * All rights reserved.
5 *
6 * CONFIDENTIAL: this document contains confidential information of Avid. Do
7 * not disclose to any third party. Use of the information contained in this
8 * document is subject to an Avid SDK license.
9 */
10
29/*================================================================================================*/
30
31
32
33
34#pragma once
35
36#ifndef _AAX_FASTPOW_H_
37#define _AAX_FASTPOW_H_
38
39#include <cmath>
40#if defined(MAC_VERSION) || defined(LINUX_VERSION)
41namespace std {using ::powf;using ::log10f;using ::fabsf;}
42#endif
43#include "AAX.h" // For AAX_RESTRICT
44
45namespace AAX
46{
47static const float _2p23 = 8388608.0f;
48const unsigned int kPowExtent = 9; // 9 results in ~-80dB cancellation
49const unsigned int kPowTableSize = 1 << kPowExtent;
50
65static inline void PowFastSetTable(
66 float* const AAX_RESTRICT pTable,
67 const unsigned int precision,
68 const unsigned int extent,
69 const bool isRound)
70{
71 // step along table elements and x-axis positions
72 float zeroToOne = !isRound ?
73 0.0f : (1.0f / (static_cast<float>(1 << precision) * 2.0f));
74 for( int i = 0; i < (1 << extent); ++i )
75 {
76 // make y-axis value for table element
77 pTable[i] = std::powf( 2.0f, zeroToOne );
78
79 zeroToOne += 1.0f / static_cast<float>(1 << precision);
80 }
81}
82
128static inline float PowFastLookup(
129 const float val,
130 const float ilog2,
131 const float* const AAX_RESTRICT tableH,
132 const float* const AAX_RESTRICT tableL)
133{
134
135 // build float bits
136 const int i = static_cast<int>( (val * (_2p23 * ilog2)) + (127.0f * _2p23) );
137
138 // replace mantissa with combined lookups
139 const float t = tableH[(i >> 14) & 0x1FF] * tableL[(i >> 5) & 0x1FF];
140 const int it = (i & 0xFF800000) |
141 (*reinterpret_cast<const int*>( &t ) & 0x7FFFFF);
142
143 // convert bits to float
144 return *reinterpret_cast<const float*>( &it );
145
146}
147
159static inline float Pow2FastLookup(
160 const float val,
161 const float* const AAX_RESTRICT tableH,
162 const float* const AAX_RESTRICT tableL)
163{
164
165 // build float bits
166 const int i = static_cast<int>((val + 127.0f) * _2p23);
167
168 // replace mantissa with combined lookups
169 const float t = tableH[(i >> 14) & 0x1FF] * tableL[(i >> 5) & 0x1FF];
170 const int it = (i & 0xFF800000) |
171 (*reinterpret_cast<const int*>( &t ) & 0x007FFFFF);
172
173 // convert bits to float
174 return *reinterpret_cast<const float*>( &it );
175
176}
178
179
180static const int kMantissaBitSize = 23;
181static const int kExpBias = 127;
182static const int kLogMantissaMSBs = 9;
183static const int kLogTableSize = (1 << kLogMantissaMSBs) + 1;// 513;
184
195static inline void LogFastSetTable(
196 float* const AAX_RESTRICT logTable,
197 int tableSize = kLogTableSize)
198{
199 const float kInv = 1.0f/float(tableSize - 1); // 0.001953125
200 float mantissaVal = 1.0f; //Start here.
201 const float invLog10Base2 = 1.0f / std::log10f(2.0f);
202 for (int j = 0; j < tableSize; j++)
203 {
204 logTable[j] = std::log10f(mantissaVal) * invLog10Base2; //By log equivalency: log2(x) = log10(x)/log10(2)
205 mantissaVal += kInv;
206
207 }
208
209 return;
210}
211
230template <int kMantMSBs>
231static inline void LogFloatToExpMantissa(
232 float number,
233 int * const AAX_RESTRICT outExp,
234 int * const AAX_RESTRICT outMant,
235 float* const AAX_RESTRICT fract)
236{
237 const int mantissaSize = 1 << (kMantissaBitSize - kMantMSBs);
238 const float invMantissaSize = 1.0f/(float)mantissaSize;
239 const int intEquiv = *reinterpret_cast<const int*>(&number);
240
241 //bool isNegative = (result & 0x80000000) != 0; //Sign bit
242 const int exponent = (intEquiv & 0x7f800000) >> 23; //Exponent bits
243 const int mantissa = intEquiv & 0x007fffff; //Mantissa bits.
244
245 // 0 000|0 000|0 1 010| 0000 0000 0000 0000 0000
246 // 0111 1111 1000 0000 0000 0000 0000 0000 = 7f800000 (Exp)
247 // 0000 0000 0111 1111 1111 1111 1111 1111 = 007fffff (Mant)
248
249 *outExp = exponent - kExpBias; //Compensate for exponent bias for caller.
250 //To do: add halfLSBShifted to mantissa before shifting; *outMant = (mantissa + halfLSBShifted) >> (kMantissaBitSize - mantMSBs)
251 *outMant = mantissa >> (kMantissaBitSize - kMantMSBs); //Shift to provide only mantMSBs for log LUT.
252 // Provide a linear interpolation fraction
253 *fract = (float)(mantissa & (mantissaSize - 1)) * invMantissaSize;
254
255 return;
256}
257
271template <int kPrecision>
272static inline float LogFastLookup(
273 float num,
274 const float* const AAX_RESTRICT logTable)
275{
276
277 int exponent, mantissa;
278 float fract;
279
280 AAX::LogFloatToExpMantissa<kPrecision>(num, &exponent, &mantissa, &fract);
281
282 const float mantLog1 = logTable[mantissa];
283 const float mantLog2 = logTable[mantissa+1];
284
285 const float logOfNum = (mantLog1 * (1.0f - fract) + fract * mantLog2) + exponent;
286 return logOfNum;
287}
288
289
290
291} // namespace AAX
292
293#endif // #ifndef _AAX_FASTPOW_H_
Various utility definitions for AAX.
Definition: AAX_EnvironmentUtilities.h:59
const unsigned int kPowExtent
Definition: AAX_FastPow.h:48
const unsigned int kPowTableSize
Definition: AAX_FastPow.h:49