diff options
Diffstat (limited to 'libFDK/src/fixpoint_math.cpp')
-rw-r--r-- | libFDK/src/fixpoint_math.cpp | 82 |
1 files changed, 62 insertions, 20 deletions
diff --git a/libFDK/src/fixpoint_math.cpp b/libFDK/src/fixpoint_math.cpp index 78cae2b..30283ff 100644 --- a/libFDK/src/fixpoint_math.cpp +++ b/libFDK/src/fixpoint_math.cpp @@ -242,30 +242,72 @@ FIXP_DBL mul_dbl_sgl_rnd (const FIXP_DBL op1, const FIXP_SGL op2) *****************************************************************************/ LNK_SECTION_CODE_L1 -FIXP_DBL CalcInvLdData(FIXP_DBL op) +/* This table is used for lookup 2^x with */ +/* x in range [0...1.0[ in steps of 1/32 */ +LNK_SECTION_DATA_L1 static const UINT exp2_tab_long[32]={ +0x40000000,0x4166C34C,0x42D561B4,0x444C0740, +0x45CAE0F2,0x47521CC6,0x48E1E9BA,0x4A7A77D4, +0x4C1BF829,0x4DC69CDD,0x4F7A9930,0x51382182, +0x52FF6B55,0x54D0AD5A,0x56AC1F75,0x5891FAC1, +0x5A82799A,0x5C7DD7A4,0x5E8451D0,0x60962665, +0x62B39509,0x64DCDEC3,0x6712460B,0x69540EC9, +0x6BA27E65,0x6DFDDBCC,0x70666F76,0x72DC8374, +0x75606374,0x77F25CCE,0x7A92BE8B,0x7D41D96E +// 0x80000000 +}; + +/* This table is used for lookup 2^x with */ +/* x in range [0...1/32[ in steps of 1/1024 */ +LNK_SECTION_DATA_L1 static const UINT exp2w_tab_long[32]={ +0x40000000,0x400B1818,0x4016321B,0x40214E0C, +0x402C6BE9,0x40378BB4,0x4042AD6D,0x404DD113, +0x4058F6A8,0x40641E2B,0x406F479E,0x407A7300, +0x4085A051,0x4090CF92,0x409C00C4,0x40A733E6, +0x40B268FA,0x40BD9FFF,0x40C8D8F5,0x40D413DD, +0x40DF50B8,0x40EA8F86,0x40F5D046,0x410112FA, +0x410C57A2,0x41179E3D,0x4122E6CD,0x412E3152, +0x41397DCC,0x4144CC3B,0x41501CA0,0x415B6EFB, +// 0x4166C34C, +}; +/* This table is used for lookup 2^x with */ +/* x in range [0...1/1024[ in steps of 1/32768 */ +LNK_SECTION_DATA_L1 static const UINT exp2x_tab_long[32]={ +0x40000000,0x400058B9,0x4000B173,0x40010A2D, +0x400162E8,0x4001BBA3,0x4002145F,0x40026D1B, +0x4002C5D8,0x40031E95,0x40037752,0x4003D011, +0x400428CF,0x4004818E,0x4004DA4E,0x4005330E, +0x40058BCE,0x4005E48F,0x40063D51,0x40069613, +0x4006EED5,0x40074798,0x4007A05B,0x4007F91F, +0x400851E4,0x4008AAA8,0x4009036E,0x40095C33, +0x4009B4FA,0x400A0DC0,0x400A6688,0x400ABF4F, +//0x400B1818 +}; + +LNK_SECTION_CODE_L1 FIXP_DBL CalcInvLdData(FIXP_DBL x) { - FIXP_DBL result_m; + int set_zero = (x < FL2FXCONST_DBL(-31.0/64.0))? 0 : 1; + int set_max = (x >= FL2FXCONST_DBL( 31.0/64.0)) | (x == FL2FXCONST_DBL(0.0)); - if ( op == FL2FXCONST_DBL(0.0f) ) { - result_m = (FIXP_DBL)MAXVAL_DBL; - } - else if ( op < FL2FXCONST_DBL(0.0f) ) { - result_m = f2Pow(op, LD_DATA_SHIFT); - } - else { - int result_e; + FIXP_SGL frac = (FIXP_SGL)(LONG)(x & 0x3FF); + UINT index3 = (UINT)(LONG)(x >> 10) & 0x1F; + UINT index2 = (UINT)(LONG)(x >> 15) & 0x1F; + UINT index1 = (UINT)(LONG)(x >> 20) & 0x1F; + int exp = (x > FL2FXCONST_DBL(0.0f)) ? (31 - (int)(x>>25)) : (int)(-(x>>25)); - result_m = f2Pow(op, LD_DATA_SHIFT, &result_e); - result_e = fixMin(fixMax(result_e+1-(DFRACT_BITS-1), -(DFRACT_BITS-1)), (DFRACT_BITS-1)); /* rounding and saturation */ + UINT lookup1 = exp2_tab_long[index1]*set_zero; + UINT lookup2 = exp2w_tab_long[index2]; + UINT lookup3 = exp2x_tab_long[index3]; + UINT lookup3f = lookup3 + (UINT)(LONG)fMultDiv2((FIXP_DBL)(0x0016302F),(FIXP_SGL)frac); + + UINT lookup12 = (UINT)(LONG)fMult((FIXP_DBL)lookup1, (FIXP_DBL) lookup2); + UINT lookup = (UINT)(LONG)fMult((FIXP_DBL)lookup12, (FIXP_DBL) lookup3f); - if ( (result_e>0) && ( result_m > (((FIXP_DBL)MAXVAL_DBL)>>result_e) ) ) { - result_m = (FIXP_DBL)MAXVAL_DBL; /* saturate to max representable value */ - } - else { - result_m = (scaleValue(result_m, result_e)+(FIXP_DBL)1)>>1; /* descale result + rounding */ - } - } - return result_m; + FIXP_DBL retVal = (lookup<<3) >> exp; + + if (set_max) + retVal=FL2FXCONST_DBL(1.0f); + + return retVal; } |