AAX SDK 2.8.0
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-2024 Avid Technology, Inc.
4 * All rights reserved.
5 *
6 * This file is part of the Avid AAX SDK.
7 *
8 * The AAX SDK is subject to commercial or open-source licensing.
9 *
10 * By using the AAX SDK, you agree to the terms of both the Avid AAX SDK License
11 * Agreement and Avid Privacy Policy.
12 *
13 * AAX SDK License: https://developer.avid.com/aax
14 * Privacy Policy: https://www.avid.com/legal/privacy-policy-statement
15 *
16 * Or: You may also use this code under the terms of the GPL v3 (see
17 * www.gnu.org/licenses).
18 *
19 * THE AAX SDK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 * EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 * DISCLAIMED.
22 */
23
42/*================================================================================================*/
43
44
45
46
47#pragma once
48
49#ifndef _AAX_FASTPOW_H_
50#define _AAX_FASTPOW_H_
51
52#include <cmath>
53#if defined(MAC_VERSION) || defined(LINUX_VERSION)
54namespace std {using ::powf;using ::log10f;using ::fabsf;}
55#endif
56#include "AAX.h" // For AAX_RESTRICT
57
58namespace AAX
59{
60static const float _2p23 = 8388608.0f;
61const unsigned int kPowExtent = 9; // 9 results in ~-80dB cancellation
62const unsigned int kPowTableSize = 1 << kPowExtent;
63
78static inline void PowFastSetTable(
79 float* const AAX_RESTRICT pTable,
80 const unsigned int precision,
81 const unsigned int extent,
82 const bool isRound)
83{
84 // step along table elements and x-axis positions
85 float zeroToOne = !isRound ?
86 0.0f : (1.0f / (static_cast<float>(1 << precision) * 2.0f));
87 for( int i = 0; i < (1 << extent); ++i )
88 {
89 // make y-axis value for table element
90 pTable[i] = std::powf( 2.0f, zeroToOne );
91
92 zeroToOne += 1.0f / static_cast<float>(1 << precision);
93 }
94}
95
141static inline float PowFastLookup(
142 const float val,
143 const float ilog2,
144 const float* const AAX_RESTRICT tableH,
145 const float* const AAX_RESTRICT tableL)
146{
147
148 // build float bits
149 const int i = static_cast<int>( (val * (_2p23 * ilog2)) + (127.0f * _2p23) );
150
151 // replace mantissa with combined lookups
152 const float t = tableH[(i >> 14) & 0x1FF] * tableL[(i >> 5) & 0x1FF];
153 const int it = (i & 0xFF800000) |
154 (*reinterpret_cast<const int*>( &t ) & 0x7FFFFF);
155
156 // convert bits to float
157 return *reinterpret_cast<const float*>( &it );
158
159}
160
172static inline float Pow2FastLookup(
173 const float val,
174 const float* const AAX_RESTRICT tableH,
175 const float* const AAX_RESTRICT tableL)
176{
177
178 // build float bits
179 const int i = static_cast<int>((val + 127.0f) * _2p23);
180
181 // replace mantissa with combined lookups
182 const float t = tableH[(i >> 14) & 0x1FF] * tableL[(i >> 5) & 0x1FF];
183 const int it = (i & 0xFF800000) |
184 (*reinterpret_cast<const int*>( &t ) & 0x007FFFFF);
185
186 // convert bits to float
187 return *reinterpret_cast<const float*>( &it );
188
189}
191
192
193static const int kMantissaBitSize = 23;
194static const int kExpBias = 127;
195static const int kLogMantissaMSBs = 9;
196static const int kLogTableSize = (1 << kLogMantissaMSBs) + 1;// 513;
197
208static inline void LogFastSetTable(
209 float* const AAX_RESTRICT logTable,
210 int tableSize = kLogTableSize)
211{
212 const float kInv = 1.0f/float(tableSize - 1); // 0.001953125
213 float mantissaVal = 1.0f; //Start here.
214 const float invLog10Base2 = 1.0f / std::log10f(2.0f);
215 for (int j = 0; j < tableSize; j++)
216 {
217 logTable[j] = std::log10f(mantissaVal) * invLog10Base2; //By log equivalency: log2(x) = log10(x)/log10(2)
218 mantissaVal += kInv;
219
220 }
221
222 return;
223}
224
243template <int kMantMSBs>
244static inline void LogFloatToExpMantissa(
245 float number,
246 int * const AAX_RESTRICT outExp,
247 int * const AAX_RESTRICT outMant,
248 float* const AAX_RESTRICT fract)
249{
250 const int mantissaSize = 1 << (kMantissaBitSize - kMantMSBs);
251 const float invMantissaSize = 1.0f/(float)mantissaSize;
252 const int intEquiv = *reinterpret_cast<const int*>(&number);
253
254 //bool isNegative = (result & 0x80000000) != 0; //Sign bit
255 const int exponent = (intEquiv & 0x7f800000) >> 23; //Exponent bits
256 const int mantissa = intEquiv & 0x007fffff; //Mantissa bits.
257
258 // 0 000|0 000|0 1 010| 0000 0000 0000 0000 0000
259 // 0111 1111 1000 0000 0000 0000 0000 0000 = 7f800000 (Exp)
260 // 0000 0000 0111 1111 1111 1111 1111 1111 = 007fffff (Mant)
261
262 *outExp = exponent - kExpBias; //Compensate for exponent bias for caller.
263 //To do: add halfLSBShifted to mantissa before shifting; *outMant = (mantissa + halfLSBShifted) >> (kMantissaBitSize - mantMSBs)
264 *outMant = mantissa >> (kMantissaBitSize - kMantMSBs); //Shift to provide only mantMSBs for log LUT.
265 // Provide a linear interpolation fraction
266 *fract = (float)(mantissa & (mantissaSize - 1)) * invMantissaSize;
267
268 return;
269}
270
284template <int kPrecision>
285static inline float LogFastLookup(
286 float num,
287 const float* const AAX_RESTRICT logTable)
288{
289
290 int exponent, mantissa;
291 float fract;
292
293 AAX::LogFloatToExpMantissa<kPrecision>(num, &exponent, &mantissa, &fract);
294
295 const float mantLog1 = logTable[mantissa];
296 const float mantLog2 = logTable[mantissa+1];
297
298 const float logOfNum = (mantLog1 * (1.0f - fract) + fract * mantLog2) + exponent;
299 return logOfNum;
300}
301
302
303
304} // namespace AAX
305
306#endif // #ifndef _AAX_FASTPOW_H_
Various utility definitions for AAX.
Definition: AAX_EnvironmentUtilities.h:72
const unsigned int kPowExtent
Definition: AAX_FastPow.h:61
const unsigned int kPowTableSize
Definition: AAX_FastPow.h:62