mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 05:44:12 +02:00
Fast fixed-point log2 approximation
This commit is contained in:
parent
cad9eeb8ba
commit
106dd6ce6a
1 changed files with 63 additions and 0 deletions
|
@ -252,6 +252,69 @@ static inline int32_t peaklog2(float* input0, float* input1, float* input2, floa
|
|||
return (e << LOG2_FRACBITS) - (c2 >> 3);
|
||||
}
|
||||
|
||||
//
|
||||
// Count Leading Zeros
|
||||
// Emulates the CLZ (ARM) and LZCNT (x86) instruction
|
||||
//
|
||||
static inline int CLZ(uint32_t x) {
|
||||
|
||||
if (x == 0) {
|
||||
return 32;
|
||||
}
|
||||
|
||||
int e = 0;
|
||||
if (x < 0x00010000) {
|
||||
x <<= 16;
|
||||
e += 16;
|
||||
}
|
||||
if (x < 0x01000000) {
|
||||
x <<= 8;
|
||||
e += 8;
|
||||
}
|
||||
if (x < 0x10000000) {
|
||||
x <<= 4;
|
||||
e += 4;
|
||||
}
|
||||
if (x < 0x40000000) {
|
||||
x <<= 2;
|
||||
e += 2;
|
||||
}
|
||||
if (x < 0x80000000) {
|
||||
e += 1;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
//
|
||||
// Compute -log2(x) for x=[0,1] in Q31, result in Q26
|
||||
// x = 0 returns 0x7fffffff
|
||||
// x < 0 undefined
|
||||
//
|
||||
static inline int32_t fixlog2(int32_t x) {
|
||||
|
||||
if (x == 0) {
|
||||
return 0x7fffffff;
|
||||
}
|
||||
|
||||
// split into e and x - 1.0
|
||||
int e = CLZ((uint32_t)x);
|
||||
x <<= e; // normalize to [0x80000000, 0xffffffff]
|
||||
x &= 0x7fffffff; // x - 1.0
|
||||
|
||||
int k = x >> (31 - LOG2_TABBITS);
|
||||
|
||||
// polynomial for log2(1+x) over x=[0,1]
|
||||
int32_t c0 = log2Table[k][0];
|
||||
int32_t c1 = log2Table[k][1];
|
||||
int32_t c2 = log2Table[k][2];
|
||||
|
||||
c1 += MULHI(c0, x);
|
||||
c2 += MULHI(c1, x);
|
||||
|
||||
// reconstruct result in Q26
|
||||
return (e << LOG2_FRACBITS) - (c2 >> 3);
|
||||
}
|
||||
|
||||
//
|
||||
// Compute exp2(-x) for x=[0,32] in Q26, result in Q31
|
||||
// x < 0 undefined
|
||||
|
|
Loading…
Reference in a new issue