1
0
Fork 0
forked from len0rd/rockbox

Libfaad pow2/log2 improvements:

Correct pow2_* to calculate correct output for input < 0.0 or between 0.0 and 1.0 instead of returning 0. This will change output, but the float version of this codec uses pow(2.0,x) in place of these functions, so this behavior was probably a bug
Replace 64-bit multiply in pow2_* with left or right shift by whole part of input, rounding if shifting right. An ARM-specific optimized version is provided as a C inline function, other targets use a C macro.
Increase constant size of table for pow2 to improve accuracy, also avoid early truncation in linear interpolation of result.
Move constant tables for pow2 and log2 to iram.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23967 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Andrew Mahone 2009-12-13 03:45:40 +00:00
parent 7668e3fe51
commit af5bad46d8
3 changed files with 105 additions and 64 deletions

View file

@ -49,10 +49,11 @@ extern "C" {
typedef int32_t real_t;
#define REAL_CONST(A) (((A) >= 0) ? ((real_t)((A)*(REAL_PRECISION)+0.5)) : ((real_t)((A)*(REAL_PRECISION)-0.5)))
#define COEF_CONST(A) (((A) >= 0) ? ((real_t)((A)*(COEF_PRECISION)+0.5)) : ((real_t)((A)*(COEF_PRECISION)-0.5)))
#define FRAC_CONST(A) (((A) == 1.00) ? ((real_t)FRAC_MAX) : (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5))))
#define UFIX_CONST(A,PRECISION) ((uint32_t)((A)*(PRECISION)+0.5))
#define FIX_CONST(A,PRECISION) (((A) >= 0) ? ((real_t)((A)*(PRECISION)+0.5)) : ((real_t)((A)*(PRECISION)-0.5)))
#define REAL_CONST(A) FIX_CONST((A),(REAL_PRECISION))
#define COEF_CONST(A) FIX_CONST((A),(COEF_PRECISION))
#define FRAC_CONST(A) (((A) == 1.00) ? ((real_t)FRAC_MAX) : FIX_CONST((A),(FRAC_PRECISION)))
//#define FRAC_CONST(A) (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5)))
#define Q2_BITS 22
@ -128,6 +129,8 @@ static INLINE void ComplexMult(real_t *y1, real_t *y2,
#define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS)
#define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6)
#define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23)
#define DESCALE(A,S) ((S)>0?(((A)>>((S)-1))+1)>>1:(A)<<-(S))
#define DESCALE_SHIFT(A,SH,SC) DESCALE((A),(SC)-(SH)
#elif defined(__GNUC__) && defined (__arm__)
@ -205,6 +208,18 @@ static INLINE void ComplexMult(real_t *y1, real_t *y2,
*y2 = yt2 << (FRAC_SIZE-FRAC_BITS);
}
static inline real_t DESCALE_SHIFT(unsigned val, int shift, int scale)
{
unsigned out;
if ((out = val >> (scale - shift - 1)))
{
out++;
out >>= 1;
} else
out = val << (shift - scale);
return out;
}
#else
/* multiply with real shift */
@ -225,6 +240,8 @@ static INLINE void ComplexMult(real_t *y1, real_t *y2,
#define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS)
#define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6)
#define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23)
#define DESCALE(A,S) ((S)>0?(((A)>>((S)-1))+1)>>1:(A)<<-(S))
#define DESCALE_SHIFT(A,SH,SC) DESCALE((A),(SC)-(SH)
/* Complex multiplication */
static INLINE void ComplexMult(real_t *y1, real_t *y2,