macros.h
来自「AMLOGIC DPF source code」· C头文件 代码 · 共 781 行 · 第 1/2 页
H
781 行
// Difference of two random numbers gives a triangle distribution and a range of (-2.5, 2.5)
// it also gives a serial correlation of -0.5 at lag 1. But all the other lags have normally small correlations.
iTemp1 = iTemp - ptRandState->iPrior;
// Save first term of this difference for next time.
ptRandState->iPrior = iTemp;
//return -2.5 to 2.5 with Binary Point = 3 with a triangle distribution
return iTemp1;
}
static INLINE void RandStateClear(tRandState* ptRandState) {
ptRandState->iPrior = 0;
ptRandState->uiRand = 0;
}
// protect encoder from having these defined by mistake
# ifdef REFERENCE_RAND_24
# undef REFERENCE_RAND_24
# endif
# ifdef REFERENCE_RAND_16
# undef REFERENCE_RAND_16
# endif
#elif defined(REFERENCE_RAND_24)
//****************************************************************************
// Quick and dirty 24-bit rand generator.
// Simulates 24-bits on a 32-bit reference machine.
// Note this is the 24-bit referenced generator which can be used for compliance
// comparisions with 24-bit implementations by defining REFERENCE_RAN_24
//****************************************************************************
typedef struct tagRandState {
I32 iPrior; // prior value (only top 24-bits used)
U32 uiRand; // current value (only top 24-bits used)
} tRandState;
static INLINE I32 quickRand(tRandState* ptRandState)
{
// OK to 512 lags, then ChiSquare is suspect at 1024 and rejects at 2048 (length 1024000)
const U32 uLCa = 69857; // 0x000110E1
const U32 uLCc = 3546581; // 0x00361DD5
I32 iTemp, iTemp1;
//a*x + c has to be done with unsigned 32 bit - but we similate a 24x24
ptRandState->uiRand = (uLCa * ((ptRandState->uiRand)>>8) + uLCc)<<8;
// uiRand values starting from a 0 seed are: 0x361dd500, 0x78a60a00, 0xaaac9f00, 0xa0c59400, 0x7104e900, 0xc2fe9e00, 0x1fc6b300
// do not change the above - see comment in 32-bit generator
// cast and shift to make the range (-1, 1) with Binary Point 3.
iTemp = (((I32)(ptRandState->uiRand)) >> 2) & 0xFFFFFF00;
// *1.25 to make the range (-1.25, 1.25)
iTemp += ((iTemp>>2) & 0xFFFFFF00);
// Difference of two random numbers gives a triangle distribution and a range of (-2.5, 2.5)
// it also gives a serial correlation of -0.5 at lag 1. But all the other lags have normally small correlations.
iTemp1 = iTemp - ptRandState->iPrior;
// Save first term of this difference for next time.
ptRandState->iPrior = iTemp;
//return -2.5 to 2.5 with Binary Point = 3 with a triangle distribution
return iTemp1;
}
static INLINE void RandStateClear(tRandState* ptRandState) {
ptRandState->iPrior = 0;
ptRandState->uiRand = 0;
}
#elif defined(REFERENCE_RAND_16)
//****************************************************************************
// Quick and dirty 16-bit rand generator.
// Simulates 16-bits on a 32-bit reference machine.
// Note this is the 16-bit referenced generator for compliance comparisions
// with 16-bit implementations by defining REFERENCE_RAN_16.
// The function actually returns 21 random bits at the top of the 32
// so is not a pure 16-bit generator, but does limit itself to a 16x16=>32 multiply
//****************************************************************************
// Background
// A pure 16-bit Linear Congruent generator has limited sequence length.
// Use 13 A's and 3 C's choosen from good values in the middle of the range.
// Tested OK up to lag 1024 (length 32768) and pretty good at 2048 and 2049.
// Sequence length quite long.
// these two arrays are defined once in dectables.c
# define LCA_SET 13
# define LCC_SET 3
extern const unsigned int g_uWMALCA[LCA_SET]; // {1637,1033,1825,1621, 1657,1861,1229,1549, 2017,941,1409,1777, 1153};
extern const unsigned int g_uWMALCC[LCC_SET]; // {13849,13841,13859};
typedef struct tagRandState {
I32 iPrior; // prior value
U16 uiRand; // current value
char bIdxLCA; // index for uLCA
char bIdxLCC; // index for uLCC
} tRandState;
static INLINE I32 quickRand(tRandState* ptRandState)
{
// This 16-bit implementation returns a 32-bit result with the top 21 bits random.
// But it base implementation is 16x16=>32, e.g. it requires only a single precision 16-bit multiply.
I32 iTemp, iTemp1;
U32 uTemp;
//a*x + c is with unsigned 32 bit - but we similate a 16x16+16 =32
uTemp = (g_uWMALCA[ptRandState->bIdxLCA++] * (ptRandState->uiRand)) + g_uWMALCC[ptRandState->bIdxLCC++];
// save bottom 16 bits
ptRandState->uiRand = (unsigned short)uTemp;
// uiRand values starting from a 0 seed are: 0x3623, 0x259c, 0x5add, 0x5698, 0xb511, 0x78ae, 0x6af9, 0x09f2, 0xc49b, 0x4f3e, 0x4377, 0x1108
// wrap indexes
if (ptRandState->bIdxLCA>=LCA_SET)
ptRandState->bIdxLCA = 0;
if (ptRandState->bIdxLCC>=LCC_SET)
ptRandState->bIdxLCC = 0;
// get best 19 bits into top
uTemp <<= 13;
// do not change the above - see comment in 32-bit generator
// cast and shift to make the range (-1, 1) with Binary Point 3.
iTemp = (((I32)(uTemp)) >> 2);
// *1.25 to make the range (-1.25, 1.25)
iTemp += (iTemp>>2);
// Difference of two random numbers gives a triangle distribution and a range of (-2.5, 2.5)
// it also gives a serial correlation of -0.5 at lag 1. But all the other lags have normally small correlations.
iTemp1 = iTemp - ptRandState->iPrior;
// Save first term of this difference for next time.
ptRandState->iPrior = iTemp;
//return -2.5 to 2.5 with Binary Point = 3 with a triangle distribution
return iTemp1;
}
static INLINE void RandStateClear(tRandState* ptRandState) {
ptRandState->iPrior = 0;
ptRandState->uiRand = 0;
ptRandState->bIdxLCA = 1;
ptRandState->bIdxLCC = 2;
}
#endif
//****************************************************************************
// log base 2 of a number which is a power of 2
//****************************************************************************
static INLINE I32 LOG2(U32 i)
{ // returns n where n = log2(2^n) = log2(2^(n+1)-1)
U32 iLog2 = 0;
assert (i != 0);
while ((i >> iLog2) > 1)
iLog2++;
return iLog2;
}
#define log2 LOG2
//****************************************************************************
// Normalize a dynamically scaled unsigned int
//****************************************************************************
static INLINE void NormUInt( UInt* puiValue, Int* pcFracBits, const UInt uiTarget ){
const UInt uiTarget2 = uiTarget>>1;
register UInt uiV = *puiValue;
register Int cFB = *pcFracBits;
assert( uiV > 0 );
if (uiV == 0) return; // useful if asserts are disabled
while ( uiV < uiTarget2 )
{
uiV <<= 2;
cFB += 2;
}
if ( uiV < uiTarget )
{
uiV <<= 1;
cFB += 1;
}
*puiValue = uiV;
*pcFracBits = cFB;
}
//****************************************************************************
// Align a dynamically scaled int to a particular binary point position
//****************************************************************************
static INLINE Int Align2FracBits( const Int iValue, const Int cFracBits, const Int cAlignFracBits )
{
const Int iShift = cFracBits-cAlignFracBits;
if (iShift < 0) {
return (iValue << -iShift);
} else if (iShift < 32) {
return (iValue >> iShift);
} else {
return 0;
}
}
// V4 Compatibility Mode: This mode allows us to compare V5 encoder with V4 encoder
#ifdef V4V5_COMPARE_MODE
#define V4V5COMPARE_SNAPTOZERO(x) if (fabs(x) <= 1.0e-15) {(x) = 0;}
#define ROUNDF_V4V5COMPARE(x) ROUNDD(x)
typedef double V4V5COMPARE;
#else // V4V5_COMPARE_MODE
#define V4V5COMPARE_SNAPTOZERO(x)
#define ROUNDF_V4V5COMPARE(x) ROUNDF(x)
typedef float V4V5COMPARE;
#endif // V4V5_COMPARE_MODE
typedef I32 FLOATORI32;
typedef U32 FLOATORU32;
typedef U16 FLOATORU16;
#define FLOATORU32_CONST(flop,fb) ((U32)((flop)*(1 << (fb))))
#define FLOATORINT_TOFLOAT(x,fb) ((Float)(x)/(Float)(1 << (fb)))
#define FLOATORINT_SELECTTOFLOAT(f,i,fb) ((Float)(i)/(Float)(1 << (fb)))
#define FLOATORINT_ASSERT(x) assert(x)
#define FLOATORINT_AB(a,b) (a)
// The following is used to allow non-integerized code to convert a FLOP
// result to a bit-discarded integer result
#define FLOATORU32_DISCARDBITSFROMFLT(x,fb) ((U32)((x)/(float)(1 << (fb))))
#define FLOATORU32_DISCARDBITSFROMU32(x,fb) ((U32)(x) >> (fb))
#define FLOATORU32_DISCARDBITSFROMI64(x,fb) ((I64)(x) >> (fb))
#define FLOATORU32_ADDFRACTBITS(i,fb) ((i) << (fb))
#define FLOATORI32_DISCARDBITSFROMI32(x,fb) ((I32)(x) >> (fb))
// **************************************************************************
// Bring in platform-specific macros
// **************************************************************************
// Include them here because some of them use the global macros above
#include "wmaOS.h"
// Output target
#ifdef COMMONMACROS_OUTPUT_TARGET
#pragma COMPILER_MESSAGE("-----MACROS.H: Compiling for ANSI-C Target")
#endif // COMMONMACROS_OUTPUT_TARGET
// Bring in platform-independent macros
#define MULT_HI_DWORD_DOWN(a,b) (I32)((((I64)(a))*((I64)(b)))>>30)
#define MULT_HI_DWORD(a,b) (I32)((((I64)(a))*((I64)(b)))>>32)
// Unsigned version of multiply
#define MULT_HI_UDWORD(a,b) (U32)((((U64)(a))*((U64)(b)))>>32)
// **************************************************************************
// Overridable Macros (optimized for some platforms, but not all)
// **************************************************************************
// The following can be overridden within a particular platform macro file
static INLINE I32 ROUNDF(float f) {
if (f < 0.0f)
return (I32) (f - 0.5f);
else
return (I32) (f + 0.5f);
}
//---------------------------------------------------------------------------
static INLINE I32 ROUNDD(double f) {
if (f < 0)
return (I32) (f - 0.5);
else
return (I32) (f + 0.5);
}
//---------------------------------------------------------------------------
#ifndef PLATFORM_SPECIFIC_FNPTR
#define PLATFORM_SPECIFIC_FNPTR //nothing for non-x86
#endif // PLATFORM_SPECIFIC_FNPTR
//**********************************************************************
// Support for FastFloat
//**********************************************************************
// FastFloat
// FastFloat is a quick way of handling values that exceed I32 range without incurring
// the expense of floating point emulation on integer only platforms.
// real value = iFraction * pow( 2, -iFracBits )
// In debugger, iFraction*1.0F/(1<<iFracBits) works if 0<=iFracBits<31
// Normalize a FastFloat
INLINE static void Norm4FastFloat( FastFloat* pfflt )
{ // use the faster Norm4FastFloatU when you know the value is positive
register UInt uiF = abs(pfflt->iFraction);
register Int iFB = 0;
if ( uiF == 0 )
{
pfflt->iFracBits = 0;
return;
}
while ( uiF < 0x1FFFFFFF )
{
uiF <<= 2;
iFB += 2;
}
if ( uiF < 0x3FFFFFFF )
{
iFB += 1;
}
pfflt->iFraction <<= iFB;
pfflt->iFracBits += iFB;
}
INLINE static void Norm4FastFloatU( FastFloat* pfflt )
{ // same as above when we know value is positive (which we often do)
register UInt uiF = pfflt->iFraction;
register Int iFB = 0;
assert( uiF > 0 );
while ( uiF < 0x1FFFFFFF )
{
uiF <<= 2;
iFB += 2;
}
if ( uiF < 0x3FFFFFFF )
{
uiF <<= 1;
iFB += 1;
}
pfflt->iFraction = uiF;
pfflt->iFracBits += iFB;
}
INLINE static FastFloat FastFloatFromFloat(Float flt) {
FastFloat fflt;
Float fltScale = (Float)(1<<(31-24));
fflt.iFracBits = 24;
while( flt < -fltScale || fltScale < flt )
{
flt /= 2;
fflt.iFracBits -= 1;
fltScale *= 2;
}
fflt.iFraction = (I32)(flt*(1<<fflt.iFracBits));
Norm4FastFloat( &fflt );
return fflt;
}
INLINE static Float FloatFromFastFloat( FastFloat fflt )
{
assert( 0<= fflt.iFracBits && fflt.iFracBits <= 50 );
if ( fflt.iFracBits > 30 )
return fflt.iFraction/(1048576.0F*(1<<(fflt.iFracBits-20)));
else
return fflt.iFraction/((Float)(1<<fflt.iFracBits));
}
# define FASTFLOAT_FROM_FLOAT(flt) FastFloatFromFloat(flt)
# define FLOAT_FROM_FASTFLOAT(fflt) FloatFromFastFloat(fflt)
# define DOUBLE_FROM_FASTFLOAT(fflt) ((double)fflt.iFraction/(1<<fflt.iFracBits))
typedef FastFloat QuantStepType;
#define DOUBLE_FROM_QUANTSTEPTYPE(qst) DOUBLE_FROM_FASTFLOAT(qst)
#define FLOAT_FROM_QUANTSTEPTYPE(qst) FLOAT_FROM_FASTFLOAT(qst)
#define FASTFLOAT_FROM_QUANTSTEPTYPE(qst) (qst)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Define Macros to switch auReconMono and auSaveHistoryMono between Integer and Float
#define ROUND_SATURATE_STORE(piDst,cf,mn,mx,iTmp) \
*piDst = (I16) checkRange (cf, mn, mx); \
iTmp = cf;
#endif // __COMMON_MACROS_H
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?