From f260c2ac3661143bfdfbcc4c7a3574acdd831894 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Tue, 30 Dec 2003 02:00:10 +0000 Subject: - update to libfaad 2.0 rc3 - some fixes to xine_decoder.c CVS patchset: 5959 CVS date: 2003/12/30 02:00:10 --- src/libfaad/fixed.h | 151 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 113 insertions(+), 38 deletions(-) (limited to 'src/libfaad/fixed.h') diff --git a/src/libfaad/fixed.h b/src/libfaad/fixed.h index 5fae855ab..65897d166 100644 --- a/src/libfaad/fixed.h +++ b/src/libfaad/fixed.h @@ -1,6 +1,6 @@ /* -** FAAD - Freeware Advanced Audio Decoder -** Copyright (C) 2002 M. Bakker +** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding +** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by @@ -16,7 +16,13 @@ ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** -** $Id: fixed.h,v 1.2 2003/04/12 14:58:47 miguelfreitas Exp $ +** Any non-GPL usage of this software or parts of this software is strictly +** forbidden. +** +** Commercial non-GPL licensing of this software is possible. +** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. +** +** $Id: fixed.h,v 1.3 2003/12/30 02:00:10 miguelfreitas Exp $ **/ #ifndef __FIXED_H__ @@ -26,23 +32,32 @@ extern "C" { #endif +#ifdef _WIN32_WCE +#include +#endif #define COEF_BITS 28 #define COEF_PRECISION (1 << COEF_BITS) -#define REAL_BITS 7 +#define REAL_BITS 14 // MAXIMUM OF 14 FOR FIXED POINT SBR #define REAL_PRECISION (1 << REAL_BITS) +/* FRAC is the fractional only part of the fixed point number [0.0..1.0) */ +#define FRAC_SIZE 32 /* frac is a 32 bit integer */ +#define FRAC_BITS 31 +#define FRAC_PRECISION ((uint32_t)(1 << FRAC_BITS)) +#define FRAC_MAX 0x7FFFFFFF typedef int32_t real_t; -#define REAL_CONST(A) ((real_t)(A*(REAL_PRECISION))) -#define COEF_CONST(A) ((real_t)(A*(COEF_PRECISION))) +#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)))) #if defined(_WIN32) && !defined(_WIN32_WCE) -/* multiply real with real */ -static INLINE MUL(real_t A, real_t B) +/* multiply with real shift */ +static INLINE real_t MUL_R(real_t A, real_t B) { _asm { mov eax,A @@ -51,8 +66,8 @@ static INLINE MUL(real_t A, real_t B) } } -/* multiply coef with coef */ -static INLINE MUL_C_C(real_t A, real_t B) +/* multiply with coef shift */ +static INLINE real_t MUL_C(real_t A, real_t B) { _asm { mov eax,A @@ -61,60 +76,120 @@ static INLINE MUL_C_C(real_t A, real_t B) } } -/* multiply real with coef */ -static INLINE MUL_R_C(real_t A, real_t B) +static INLINE real_t _MulHigh(real_t A, real_t B) { _asm { mov eax,A imul B - shrd eax,edx,COEF_BITS + mov eax,edx } } +/* multiply with fractional shift */ +static INLINE real_t MUL_F(real_t A, real_t B) +{ + return _MulHigh(A,B) << (FRAC_SIZE-FRAC_BITS); +} + +/* Complex multiplication */ +static INLINE void ComplexMult(real_t *y1, real_t *y2, + real_t x1, real_t x2, real_t c1, real_t c2) +{ + *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS); + *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS); +} + #elif defined(__GNUC__) && defined (__arm__) /* taken from MAD */ #define arm_mul(x, y, SCALEBITS) \ - ({ uint32_t __hi; \ - uint32_t __lo; \ - uint32_t __result; \ - asm ("smull %0, %1, %3, %4\n\t" \ - "movs %0, %0, lsr %5\n\t" \ - "adc %2, %0, %1, lsl %6" \ - : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ - : "%r" (x), "r" (y), \ - "M" (SCALEBITS), "M" (32 - (SCALEBITS)) \ - : "cc"); \ - __result; \ - }) - -static INLINE real_t MUL(real_t A, real_t B) +({ \ + uint32_t __hi; \ + uint32_t __lo; \ + uint32_t __result; \ + asm("smull %0, %1, %3, %4\n\t" \ + "movs %0, %0, lsr %5\n\t" \ + "adc %2, %0, %1, lsl %6" \ + : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ + : "%r" (x), "r" (y), \ + "M" (SCALEBITS), "M" (32 - (SCALEBITS)) \ + : "cc"); \ + __result; \ +}) + +static INLINE real_t MUL_R(real_t A, real_t B) +{ + return arm_mul(A, B, REAL_BITS); +} + +static INLINE real_t MUL_C(real_t A, real_t B) +{ + return arm_mul(A, B, COEF_BITS); +} + +static INLINE real_t _MulHigh(real_t x, real_t y) { - return arm_mul( A, B, REAL_BITS); + uint32_t __lo; + uint32_t __hi; + asm("smull\t%0, %1, %2, %3" + : "=&r"(__lo),"=&r"(__hi) + : "%r"(x),"r"(y) + : "cc"); + return __hi; } -static INLINE real_t MUL_C_C(real_t A, real_t B) +static INLINE real_t MUL_F(real_t A, real_t B) { - return arm_mul( A, B, COEF_BITS); + return _MulHigh(A, B) << (FRAC_SIZE-FRAC_BITS); } -static INLINE real_t MUL_R_C(real_t A, real_t B) +/* Complex multiplication */ +static INLINE void ComplexMult(real_t *y1, real_t *y2, + real_t x1, real_t x2, real_t c1, real_t c2) { - return arm_mul( A, B, COEF_BITS); + int32_t tmp, yt1, yt2; + asm("smull %0, %1, %4, %6\n\t" + "smlal %0, %1, %5, %7\n\t" + "rsb %3, %4, #0\n\t" + "smull %0, %2, %5, %6\n\t" + "smlal %0, %2, %3, %7" + : "=&r" (tmp), "=&r" (yt1), "=&r" (yt2), "=r" (x1) + : "3" (x1), "r" (x2), "r" (c1), "r" (c2) + : "cc" ); + *y1 = yt1 << (FRAC_SIZE-FRAC_BITS); + *y2 = yt2 << (FRAC_SIZE-FRAC_BITS); } #else - /* multiply real with real */ - #define MUL(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (REAL_BITS-1))) >> REAL_BITS) - /* multiply coef with coef */ - #define MUL_C_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS) - /* multiply real with coef */ - #define MUL_R_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS) + /* multiply with real shift */ + #define MUL_R(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (REAL_BITS-1))) >> REAL_BITS) + /* multiply with coef shift */ + #define MUL_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS) + /* multiply with fractional shift */ +#ifndef _WIN32_WCE + #define _MulHigh(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_SIZE-1))) >> FRAC_SIZE) + #define MUL_F(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_BITS-1))) >> FRAC_BITS) +#else + /* eVC for PocketPC has an intrinsic function that returns only the high 32 bits of a 32x32 bit multiply */ + static INLINE real_t MUL_F(real_t A, real_t B) + { + return _MulHigh(A,B) << (32-FRAC_BITS); + } +#endif + +/* Complex multiplication */ +static INLINE void ComplexMult(real_t *y1, real_t *y2, + real_t x1, real_t x2, real_t c1, real_t c2) +{ + *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS); + *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS); +} #endif + #ifdef __cplusplus } #endif -- cgit v1.2.3