/**************************************************************************** (C) Copyright Fraunhofer IIS (2004) All Rights Reserved Please be advised that this software and/or program delivery is Confidential Information of Fraunhofer and subject to and covered by the Fraunhofer IIS Software Evaluation Agreement between Google Inc. and Fraunhofer effective and in full force since March 1, 2012. You may use this software and/or program only under the terms and conditions described in the above mentioned Fraunhofer IIS Software Evaluation Agreement. Any other and/or further use requires a separate agreement. This software and/or program is protected by copyright law and international treaties. Any reproduction or distribution of this software and/or program, or any portion of it, may result in severe civil and criminal penalties, and will be prosecuted to the maximum extent possible under law. $Id$ *******************************************************************************/ /*! \file \brief FDK Fixed Point Arithmetic Library Interface $Revision: 36841 $ */ /*! \mainpage Fixed Point Arithmetic Library Documentation Information in this SDK is subject to change without notice. Companies, names, and data used in examples herein are fictitious unless otherwise noted. Product and corporate names may be trademarks or registered trademarks of other companies. They are used for explanation only, with no intent to infringe. No part of this publication may be reproduced or utilized in any form or by any means, electronic or mechanical, including photocopying and microfilm, without permission in writing from the publisher. */ #ifndef __TRANSCENDENT_H #define __TRANSCENDENT_H #include "sbrdecoder.h" #include "sbr_rom.h" /************************************************************************/ /*! \brief Get number of octaves between frequencies a and b The Result is scaled with 1/8. The valid range for a and b is 1 to LOG_DUALIS_TABLE_SIZE. \return ld(a/b) / 8 */ /************************************************************************/ static inline FIXP_SGL FDK_getNumOctavesDiv8(INT a, /*!< lower band */ INT b) /*!< upper band */ { return ( (SHORT)((LONG)(CalcLdInt(b) - CalcLdInt(a))>>(FRACT_BITS-3)) ); } /************************************************************************/ /*! \brief Add two values given by mantissa and exponent. Mantissas are in fract format with values between 0 and 1.
The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
*/ /************************************************************************/ inline void FDK_add_MantExp(FIXP_SGL a_m, /*!< Mantissa of 1st operand a */ SCHAR a_e, /*!< Exponent of 1st operand a */ FIXP_SGL b_m, /*!< Mantissa of 2nd operand b */ SCHAR b_e, /*!< Exponent of 2nd operand b */ FIXP_SGL *ptrSum_m, /*!< Mantissa of result */ SCHAR *ptrSum_e) /*!< Exponent of result */ { FIXP_DBL accu; int shift; int shiftAbs; FIXP_DBL shiftedMantissa; FIXP_DBL otherMantissa; /* Equalize exponents of the summands. For the smaller summand, the exponent is adapted and for compensation, the mantissa is shifted right. */ shift = (int)(a_e - b_e); shiftAbs = (shift>0)? shift : -shift; shiftAbs = (shiftAbs < DFRACT_BITS-1)? shiftAbs : DFRACT_BITS-1; shiftedMantissa = (shift>0)? (FX_SGL2FX_DBL(b_m) >> shiftAbs) : (FX_SGL2FX_DBL(a_m) >> shiftAbs); otherMantissa = (shift>0)? FX_SGL2FX_DBL(a_m) : FX_SGL2FX_DBL(b_m); *ptrSum_e = (shift>0)? a_e : b_e; accu = (shiftedMantissa >> 1) + (otherMantissa >> 1); /* shift by 1 bit to avoid overflow */ if ( (accu >= (FL2FXCONST_DBL(0.5f) - (FIXP_DBL)1)) || (accu <= FL2FXCONST_DBL(-0.5f)) ) *ptrSum_e += 1; else accu = (shiftedMantissa + otherMantissa); *ptrSum_m = FX_DBL2FX_SGL(accu); } inline void FDK_add_MantExp(FIXP_DBL a, /*!< Mantissa of 1st operand a */ SCHAR a_e, /*!< Exponent of 1st operand a */ FIXP_DBL b, /*!< Mantissa of 2nd operand b */ SCHAR b_e, /*!< Exponent of 2nd operand b */ FIXP_DBL *ptrSum, /*!< Mantissa of result */ SCHAR *ptrSum_e) /*!< Exponent of result */ { FIXP_DBL accu; int shift; int shiftAbs; FIXP_DBL shiftedMantissa; FIXP_DBL otherMantissa; /* Equalize exponents of the summands. For the smaller summand, the exponent is adapted and for compensation, the mantissa is shifted right. */ shift = (int)(a_e - b_e); shiftAbs = (shift>0)? shift : -shift; shiftAbs = (shiftAbs < DFRACT_BITS-1)? shiftAbs : DFRACT_BITS-1; shiftedMantissa = (shift>0)? (b >> shiftAbs) : (a >> shiftAbs); otherMantissa = (shift>0)? a : b; *ptrSum_e = (shift>0)? a_e : b_e; accu = (shiftedMantissa >> 1) + (otherMantissa >> 1); /* shift by 1 bit to avoid overflow */ if ( (accu >= (FL2FXCONST_DBL(0.5f) - (FIXP_DBL)1)) || (accu <= FL2FXCONST_DBL(-0.5f)) ) *ptrSum_e += 1; else accu = (shiftedMantissa + otherMantissa); *ptrSum = accu; } /************************************************************************/ /*! \brief Divide two values given by mantissa and exponent. Mantissas are in fract format with values between 0 and 1.
The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
For performance reasons, the division is based on a table lookup which limits accuracy. */ /************************************************************************/ static inline void FDK_divide_MantExp(FIXP_SGL a_m, /*!< Mantissa of dividend a */ SCHAR a_e, /*!< Exponent of dividend a */ FIXP_SGL b_m, /*!< Mantissa of divisor b */ SCHAR b_e, /*!< Exponent of divisor b */ FIXP_SGL *ptrResult_m, /*!< Mantissa of quotient a/b */ SCHAR *ptrResult_e) /*!< Exponent of quotient a/b */ { int preShift, postShift, index, shift; FIXP_DBL ratio_m; FIXP_SGL bInv_m = FL2FXCONST_SGL(0.0f); preShift = CntLeadingZeros(FX_SGL2FX_DBL(b_m)); /* Shift b into the range from 0..INV_TABLE_SIZE-1, E.g. 10 bits must be skipped for INV_TABLE_BITS 8: - leave 8 bits as index for table - skip sign bit, - skip first bit of mantissa, because this is always the same (>0.5) We are dealing with energies, so we need not care about negative numbers */ /* The first interval has half width so the lowest bit of the index is needed for a doubled resolution. */ shift = (FRACT_BITS - 2 - INV_TABLE_BITS - preShift); index = (shift<0)? (LONG)b_m << (-shift) : (LONG)b_m >> shift; /* The index has INV_TABLE_BITS +1 valid bits here. Clear the other bits. */ index &= (1 << (INV_TABLE_BITS+1)) - 1; /* Remove offset of half an interval */ index--; /* Now the lowest bit is shifted out */ index = index >> 1; /* Fetch inversed mantissa from table: */ bInv_m = (index<0)? bInv_m : FDK_sbrDecoder_invTable[index]; /* Multiply a with the inverse of b: */ ratio_m = (index<0)? FX_SGL2FX_DBL(a_m >> 1) : fMultDiv2(bInv_m,a_m); postShift = CntLeadingZeros(ratio_m)-1; *ptrResult_m = FX_DBL2FX_SGL(ratio_m << postShift); *ptrResult_e = a_e - b_e + 1 + preShift - postShift; } static inline void FDK_divide_MantExp(FIXP_DBL a_m, /*!< Mantissa of dividend a */ SCHAR a_e, /*!< Exponent of dividend a */ FIXP_DBL b_m, /*!< Mantissa of divisor b */ SCHAR b_e, /*!< Exponent of divisor b */ FIXP_DBL *ptrResult_m, /*!< Mantissa of quotient a/b */ SCHAR *ptrResult_e) /*!< Exponent of quotient a/b */ { int preShift, postShift, index, shift; FIXP_DBL ratio_m; FIXP_SGL bInv_m = FL2FXCONST_SGL(0.0f); preShift = CntLeadingZeros(b_m); /* Shift b into the range from 0..INV_TABLE_SIZE-1, E.g. 10 bits must be skipped for INV_TABLE_BITS 8: - leave 8 bits as index for table - skip sign bit, - skip first bit of mantissa, because this is always the same (>0.5) We are dealing with energies, so we need not care about negative numbers */ /* The first interval has half width so the lowest bit of the index is needed for a doubled resolution. */ shift = (DFRACT_BITS - 2 - INV_TABLE_BITS - preShift); index = (shift<0)? (LONG)b_m << (-shift) : (LONG)b_m >> shift; /* The index has INV_TABLE_BITS +1 valid bits here. Clear the other bits. */ index &= (1 << (INV_TABLE_BITS+1)) - 1; /* Remove offset of half an interval */ index--; /* Now the lowest bit is shifted out */ index = index >> 1; /* Fetch inversed mantissa from table: */ bInv_m = (index<0)? bInv_m : FDK_sbrDecoder_invTable[index]; /* Multiply a with the inverse of b: */ ratio_m = (index<0)? (a_m >> 1) : fMultDiv2(bInv_m,a_m); postShift = CntLeadingZeros(ratio_m)-1; *ptrResult_m = ratio_m << postShift; *ptrResult_e = a_e - b_e + 1 + preShift - postShift; } /*! \brief Calculate the squareroot of a number given by mantissa and exponent Mantissa is in fract format with values between 0 and 1.
The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
The operand is addressed via pointers and will be overwritten with the result. For performance reasons, the square root is based on a table lookup which limits accuracy. */ static inline void FDK_sqrt_MantExp(FIXP_DBL *mantissa, /*!< Pointer to mantissa */ SCHAR *exponent, const SCHAR *destScale) { FIXP_DBL input_m = *mantissa; int input_e = (int) *exponent; FIXP_DBL result = FL2FXCONST_DBL(0.0f); int result_e = -FRACT_BITS; /* Call lookup square root, which does internally normalization. */ result = sqrtFixp_lookup(input_m, &input_e); result_e = input_e; /* Write result */ if (exponent==destScale) { *mantissa = result; *exponent = result_e; } else { int shift = result_e - *destScale; *mantissa = (shift>=0) ? result << (INT)fixMin(DFRACT_BITS-1,shift) : result >> (INT)fixMin(DFRACT_BITS-1,-shift); *exponent = *destScale; } } #endif