12228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
22228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* -----------------------------------------------------------------------------------------------------------
32228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectSoftware License for The Fraunhofer FDK AAC Codec Library for Android
42228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
54f0d97057c5c640b25518358886f8c47da9fc052Jean-Michel Trivi� Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
62228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  All rights reserved.
72228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
82228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1.    INTRODUCTION
92228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
112228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is intended to be used on a wide variety of Android devices.
122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
132228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectaudio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindependent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof the MPEG specifications.
172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
182228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPatent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmay be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindividually for the purpose of encoding or decoding bit streams in products that are compliant with
212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthese patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware may already be covered under those patent licenses when it is used for those licensed purposes only.
242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
252228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCommercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectare also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectapplications information and documentation.
282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project2.    COPYRIGHT LICENSE
302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
312228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectRedistribution and use in source and binary forms, with or without modification, are permitted without
322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectpayment of copyright license fees provided that you satisfy the following conditions:
332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
342228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in redistributions of the FDK AAC Codec or
352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectyour modifications thereto in source code form.
362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
372228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in the documentation and/or other materials
382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprovided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
392228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must make available free of charge copies of the complete source code of the FDK AAC Codec and your
402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmodifications thereto to recipients of copies in binary form.
412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
422228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe name of Fraunhofer may not be used to endorse or promote products derived from this library without
432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprior written permission.
442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
452228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware or your modifications thereto.
472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
482228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYour modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectand the date of any change. For modified versions of the FDK AAC Codec, the term
502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project3.    NO PATENT LICENSE
542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
552228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectNO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
562228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectrespect to this software.
582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
592228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectby appropriate patent licenses.
612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project4.    DISCLAIMER
632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
642228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
672228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectincluding but not limited to procurement of substitute goods or services; loss of use, data, or profits,
692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projector business interruption, however caused and on any theory of liability, whether in contract, strict
702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectliability, or tort (including negligence), arising in any way out of the use of this software, even if
712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectadvised of the possibility of such damage.
722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project5.    CONTACT INFORMATION
742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
752228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFraunhofer Institute for Integrated Circuits IIS
762228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAttention: Audio and Multimedia Departments - FDK AAC LL
772228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAm Wolfsmantel 33
782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project91058 Erlangen, Germany
792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectwww.iis.fraunhofer.de/amm
812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectamm-info@iis.fraunhofer.de
822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project----------------------------------------------------------------------------------------------------------- */
832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/***************************  Fraunhofer IIS FDK Tools  **********************
852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   Author(s):   M. Gayer
872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   Description: Fixed point specific mathematical functions
882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project******************************************************************************/
902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "fixpoint_math.h"
922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define MAX_LD_PRECISION 10
952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define LD_PRECISION     10
962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* Taylor series coeffcients for ln(1-x), centered at 0 (MacLaurin polinomial). */
982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef LDCOEFF_16BIT
992228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLNK_SECTION_CONSTDATA_L1
1002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic const FIXP_DBL ldCoeff[MAX_LD_PRECISION] = {
1012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(-1.0),
1022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(-1.0/2.0),
1032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(-1.0/3.0),
1042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(-1.0/4.0),
1052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(-1.0/5.0),
1062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(-1.0/6.0),
1072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(-1.0/7.0),
1082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(-1.0/8.0),
1092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(-1.0/9.0),
1102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(-1.0/10.0)
1112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project};
1122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else
1132228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLNK_SECTION_CONSTDATA_L1
1142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic const FIXP_SGL ldCoeff[MAX_LD_PRECISION] = {
1152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(-1.0),
1162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(-1.0/2.0),
1172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(-1.0/3.0),
1182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(-1.0/4.0),
1192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(-1.0/5.0),
1202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(-1.0/6.0),
1212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(-1.0/7.0),
1222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(-1.0/8.0),
1232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(-1.0/9.0),
1242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(-1.0/10.0)
1252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project};
1262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
1272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
1292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  functionname: CalcLdData
1312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  description:  Delivers the Logarithm Dualis ld(op)/LD_DATA_SCALING with polynomial approximation.
1322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  input:        Input op is assumed to be double precision fractional 0 < op < 1.0
1332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                This function does not accept negative values.
1342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  output:       For op == 0, the result is saturated to -1.0
1352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                This function does not return positive values since input values are treated as fractional values.
1362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                It does not make sense to input an integer value into this function (and expect a positive output value)
1372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                since input values are treated as fractional values.
1382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
1402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1412228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLNK_SECTION_CODE_L1
1422228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL CalcLdData(FIXP_DBL op)
1432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return fLog2(op, 0);
1452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
1492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  functionname: LdDataVector
1502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
1512228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLNK_SECTION_CODE_L1
1522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid LdDataVector(  FIXP_DBL    *srcVector,
1532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    FIXP_DBL    *destVector,
1542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    INT         n)
1552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT i;
1572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for ( i=0; i<n; i++) {
1582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        destVector[i] = CalcLdData(srcVector[i]);
1592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
1602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define MAX_POW2_PRECISION 8
1652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef SINETABLE_16BIT
1662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project	#define POW2_PRECISION MAX_POW2_PRECISION
1672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else
1682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project	#define POW2_PRECISION 5
1692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
1702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*
1722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Taylor series coefficients of the function x^2. The first coefficient is
1732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  ommited (equal to 1.0).
1742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pow2Coeff[i-1] = (1/i!) d^i(2^x)/dx^i, i=1..MAX_POW2_PRECISION
1762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  To evaluate the taylor series around x = 0, the coefficients are: 1/!i * ln(2)^i
1772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
1782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef POW2COEFF_16BIT
1792228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLNK_SECTION_CONSTDATA_L1
1802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic const FIXP_DBL pow2Coeff[MAX_POW2_PRECISION] = {
1812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(0.693147180559945309417232121458177),    /* ln(2)^1 /1! */
1822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(0.240226506959100712333551263163332),    /* ln(2)^2 /2! */
1832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(0.0555041086648215799531422637686218),   /* ln(2)^3 /3! */
1842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(0.00961812910762847716197907157365887),  /* ln(2)^4 /4! */
1852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(0.00133335581464284434234122219879962),  /* ln(2)^5 /5! */
1862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(1.54035303933816099544370973327423e-4),  /* ln(2)^6 /6! */
1872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(1.52527338040598402800254390120096e-5),  /* ln(2)^7 /7! */
1882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_DBL(1.32154867901443094884037582282884e-6)   /* ln(2)^8 /8! */
1892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project};
1902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else
1912228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLNK_SECTION_CONSTDATA_L1
1922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic const FIXP_SGL pow2Coeff[MAX_POW2_PRECISION] = {
1932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.693147180559945309417232121458177),    /* ln(2)^1 /1! */
1942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.240226506959100712333551263163332),    /* ln(2)^2 /2! */
1952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.0555041086648215799531422637686218),   /* ln(2)^3 /3! */
1962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.00961812910762847716197907157365887),  /* ln(2)^4 /4! */
1972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.00133335581464284434234122219879962),  /* ln(2)^5 /5! */
1982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(1.54035303933816099544370973327423e-4),  /* ln(2)^6 /6! */
1992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(1.52527338040598402800254390120096e-5),  /* ln(2)^7 /7! */
2002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(1.32154867901443094884037582282884e-6)   /* ln(2)^8 /8! */
2012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project};
2022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
2032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
2072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    functionname: mul_dbl_sgl_rnd
2092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    description:  Multiply with round.
2102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
2112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* for rounding a dfract to fract */
2132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define ACCU_R (LONG) 0x00008000
2142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2152228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLNK_SECTION_CODE_L1
2162228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL mul_dbl_sgl_rnd (const FIXP_DBL op1, const FIXP_SGL op2)
2172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
2182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL prod;
2192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  LONG v = (LONG)(op1);
2202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  SHORT u = (SHORT)(op2);
2212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  LONG low = u*(v&SGL_MASK);
2232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  low = (low+(ACCU_R>>1)) >> (FRACT_BITS-1);  /* round */
2242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  LONG high = u * ((v>>FRACT_BITS)<<1);
2252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  prod = (LONG)(high+low);
2272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return((FIXP_DBL)prod);
2292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
2302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
2332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  functionname: CalcInvLdData
2352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  description:  Delivers the inverse of function CalcLdData().
2362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                Delivers 2^(op*LD_DATA_SCALING)
2372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  input:        Input op is assumed to be fractional -1.0 < op < 1.0
2382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  output:       For op == 0, the result is MAXVAL_DBL (almost 1.0).
2392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                For negative input values the output should be treated as a positive fractional value.
2402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                For positive input values the output should be treated as a positive integer value.
2412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                This function does not output negative values.
2422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
2442228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLNK_SECTION_CODE_L1
2457ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi/* This table is used for lookup 2^x with   */
2467ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi/* x in range [0...1.0[ in steps of 1/32 */
2477ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel TriviLNK_SECTION_DATA_L1 static const UINT exp2_tab_long[32]={
2487ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x40000000,0x4166C34C,0x42D561B4,0x444C0740,
2497ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x45CAE0F2,0x47521CC6,0x48E1E9BA,0x4A7A77D4,
2507ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x4C1BF829,0x4DC69CDD,0x4F7A9930,0x51382182,
2517ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x52FF6B55,0x54D0AD5A,0x56AC1F75,0x5891FAC1,
2527ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x5A82799A,0x5C7DD7A4,0x5E8451D0,0x60962665,
2537ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x62B39509,0x64DCDEC3,0x6712460B,0x69540EC9,
2547ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x6BA27E65,0x6DFDDBCC,0x70666F76,0x72DC8374,
2557ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x75606374,0x77F25CCE,0x7A92BE8B,0x7D41D96E
2567ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi// 0x80000000
2577ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi};
2587ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi
2597ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi/* This table is used for lookup 2^x with   */
2607ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi/* x in range [0...1/32[ in steps of 1/1024 */
2617ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel TriviLNK_SECTION_DATA_L1 static const UINT exp2w_tab_long[32]={
2627ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x40000000,0x400B1818,0x4016321B,0x40214E0C,
2637ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x402C6BE9,0x40378BB4,0x4042AD6D,0x404DD113,
2647ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x4058F6A8,0x40641E2B,0x406F479E,0x407A7300,
2657ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x4085A051,0x4090CF92,0x409C00C4,0x40A733E6,
2667ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x40B268FA,0x40BD9FFF,0x40C8D8F5,0x40D413DD,
2677ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x40DF50B8,0x40EA8F86,0x40F5D046,0x410112FA,
2687ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x410C57A2,0x41179E3D,0x4122E6CD,0x412E3152,
2697ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x41397DCC,0x4144CC3B,0x41501CA0,0x415B6EFB,
2707ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi// 0x4166C34C,
2717ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi};
2727ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi/* This table is used for lookup 2^x with   */
2737ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi/* x in range [0...1/1024[ in steps of 1/32768 */
2747ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel TriviLNK_SECTION_DATA_L1 static const UINT exp2x_tab_long[32]={
2757ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x40000000,0x400058B9,0x4000B173,0x40010A2D,
2767ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x400162E8,0x4001BBA3,0x4002145F,0x40026D1B,
2777ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x4002C5D8,0x40031E95,0x40037752,0x4003D011,
2787ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x400428CF,0x4004818E,0x4004DA4E,0x4005330E,
2797ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x40058BCE,0x4005E48F,0x40063D51,0x40069613,
2807ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x4006EED5,0x40074798,0x4007A05B,0x4007F91F,
2817ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x400851E4,0x4008AAA8,0x4009036E,0x40095C33,
2827ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi0x4009B4FA,0x400A0DC0,0x400A6688,0x400ABF4F,
2837ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi//0x400B1818
2847ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi};
2857ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi
2867ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel TriviLNK_SECTION_CODE_L1 FIXP_DBL CalcInvLdData(FIXP_DBL x)
2872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
2887ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  int set_zero = (x <  FL2FXCONST_DBL(-31.0/64.0))? 0 : 1;
2897ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  int set_max  = (x >= FL2FXCONST_DBL( 31.0/64.0)) | (x == FL2FXCONST_DBL(0.0));
2907ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi
2917ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  FIXP_SGL frac = (FIXP_SGL)(LONG)(x & 0x3FF);
2927ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  UINT index3 = (UINT)(LONG)(x >> 10) & 0x1F;
2937ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  UINT index2 = (UINT)(LONG)(x >> 15) & 0x1F;
2947ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  UINT index1 = (UINT)(LONG)(x >> 20) & 0x1F;
2957ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  int exp  = (x >  FL2FXCONST_DBL(0.0f)) ? (31 - (int)(x>>25)) : (int)(-(x>>25));
2967ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi
2977ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  UINT lookup1 = exp2_tab_long[index1]*set_zero;
2987ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  UINT lookup2 = exp2w_tab_long[index2];
2997ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  UINT lookup3 = exp2x_tab_long[index3];
3007ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  UINT lookup3f = lookup3 + (UINT)(LONG)fMultDiv2((FIXP_DBL)(0x0016302F),(FIXP_SGL)frac);
3017ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi
3027ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  UINT lookup12 = (UINT)(LONG)fMult((FIXP_DBL)lookup1,  (FIXP_DBL) lookup2);
3037ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  UINT lookup   = (UINT)(LONG)fMult((FIXP_DBL)lookup12, (FIXP_DBL) lookup3f);
3047ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi
3057ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  FIXP_DBL retVal = (lookup<<3) >> exp;
3067ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi
3077ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  if (set_max)
3087ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi    retVal=FL2FXCONST_DBL(1.0f);
3097ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi
3107ad97579f8ccb843afdb5b184c4b209253839fe3Jean-Michel Trivi  return retVal;
3112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
3122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
3182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    functionname: InitLdInt and CalcLdInt
3192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    description:  Create and access table with integer LdData (0 to 193)
3202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
3212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    LNK_SECTION_CONSTDATA_L1
3242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    static const FIXP_DBL ldIntCoeff[] = {
3252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x80000001, 0x00000000, 0x02000000, 0x032b8034, 0x04000000, 0x04a4d3c2, 0x052b8034, 0x059d5da0,
3262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x06000000, 0x06570069, 0x06a4d3c2, 0x06eb3a9f, 0x072b8034, 0x0766a009, 0x079d5da0, 0x07d053f7,
3272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x08000000, 0x082cc7ee, 0x08570069, 0x087ef05b, 0x08a4d3c2, 0x08c8ddd4, 0x08eb3a9f, 0x090c1050,
3282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x092b8034, 0x0949a785, 0x0966a009, 0x0982809d, 0x099d5da0, 0x09b74949, 0x09d053f7, 0x09e88c6b,
3292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0a000000, 0x0a16bad3, 0x0a2cc7ee, 0x0a423162, 0x0a570069, 0x0a6b3d79, 0x0a7ef05b, 0x0a92203d,
3302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0aa4d3c2, 0x0ab7110e, 0x0ac8ddd4, 0x0ada3f60, 0x0aeb3a9f, 0x0afbd42b, 0x0b0c1050, 0x0b1bf312,
3312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0b2b8034, 0x0b3abb40, 0x0b49a785, 0x0b584822, 0x0b66a009, 0x0b74b1fd, 0x0b82809d, 0x0b900e61,
3322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0b9d5da0, 0x0baa708f, 0x0bb74949, 0x0bc3e9ca, 0x0bd053f7, 0x0bdc899b, 0x0be88c6b, 0x0bf45e09,
3332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0c000000, 0x0c0b73cb, 0x0c16bad3, 0x0c21d671, 0x0c2cc7ee, 0x0c379085, 0x0c423162, 0x0c4caba8,
3342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0c570069, 0x0c6130af, 0x0c6b3d79, 0x0c7527b9, 0x0c7ef05b, 0x0c88983f, 0x0c92203d, 0x0c9b8926,
3352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0ca4d3c2, 0x0cae00d2, 0x0cb7110e, 0x0cc0052b, 0x0cc8ddd4, 0x0cd19bb0, 0x0cda3f60, 0x0ce2c97d,
3362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0ceb3a9f, 0x0cf39355, 0x0cfbd42b, 0x0d03fda9, 0x0d0c1050, 0x0d140ca0, 0x0d1bf312, 0x0d23c41d,
3372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0d2b8034, 0x0d3327c7, 0x0d3abb40, 0x0d423b08, 0x0d49a785, 0x0d510118, 0x0d584822, 0x0d5f7cff,
3382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0d66a009, 0x0d6db197, 0x0d74b1fd, 0x0d7ba190, 0x0d82809d, 0x0d894f75, 0x0d900e61, 0x0d96bdad,
3392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0d9d5da0, 0x0da3ee7f, 0x0daa708f, 0x0db0e412, 0x0db74949, 0x0dbda072, 0x0dc3e9ca, 0x0dca258e,
3402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0dd053f7, 0x0dd6753e, 0x0ddc899b, 0x0de29143, 0x0de88c6b, 0x0dee7b47, 0x0df45e09, 0x0dfa34e1,
3412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0e000000, 0x0e05bf94, 0x0e0b73cb, 0x0e111cd2, 0x0e16bad3, 0x0e1c4dfb, 0x0e21d671, 0x0e275460,
3422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0e2cc7ee, 0x0e323143, 0x0e379085, 0x0e3ce5d8, 0x0e423162, 0x0e477346, 0x0e4caba8, 0x0e51daa8,
3432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0e570069, 0x0e5c1d0b, 0x0e6130af, 0x0e663b74, 0x0e6b3d79, 0x0e7036db, 0x0e7527b9, 0x0e7a1030,
3442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0e7ef05b, 0x0e83c857, 0x0e88983f, 0x0e8d602e, 0x0e92203d, 0x0e96d888, 0x0e9b8926, 0x0ea03232,
3452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0ea4d3c2, 0x0ea96df0, 0x0eae00d2, 0x0eb28c7f, 0x0eb7110e, 0x0ebb8e96, 0x0ec0052b, 0x0ec474e4,
3462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0ec8ddd4, 0x0ecd4012, 0x0ed19bb0, 0x0ed5f0c4, 0x0eda3f60, 0x0ede8797, 0x0ee2c97d, 0x0ee70525,
3472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0eeb3a9f, 0x0eef69ff, 0x0ef39355, 0x0ef7b6b4, 0x0efbd42b, 0x0effebcd, 0x0f03fda9, 0x0f0809cf,
3482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0f0c1050, 0x0f10113b, 0x0f140ca0, 0x0f18028d, 0x0f1bf312, 0x0f1fde3d, 0x0f23c41d, 0x0f27a4c0,
3492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      0x0f2b8034
3502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    };
3512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  LNK_SECTION_INITCODE
3542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  void InitLdInt()
3552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
3562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* nothing to do! Use preinitialized logarithm table */
3572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
3582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3612228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLNK_SECTION_CODE_L1
3622228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL CalcLdInt(INT i)
3632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
3642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* calculates ld(op)/LD_DATA_SCALING */
3652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* op is assumed to be an integer value between 1 and 193 */
3662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDK_ASSERT((193>0) && ((FIXP_DBL)ldIntCoeff[0]==(FIXP_DBL)0x80000001)); /* tab has to be initialized */
3682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ((i>0)&&(i<193))
3702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return ldIntCoeff[i];
3712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  else
3722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
3732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return (0);
3742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
3752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
3762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
3792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    functionname: invSqrtNorm2
3812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    description:  delivers 1/sqrt(op) normalized to .5...1 and the shift value of the OUTPUT
3822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
3842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define SQRT_BITS           7
3852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define SQRT_VALUES       128
3862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define SQRT_BITS_MASK   0x7f
3872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3882228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLNK_SECTION_CONSTDATA_L1
3892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic const FIXP_DBL invSqrtTab[SQRT_VALUES] = {
3902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x5a827999, 0x5a287e03, 0x59cf8cbb, 0x5977a0ab, 0x5920b4de, 0x58cac480, 0x5875cade, 0x5821c364,
3912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x57cea99c, 0x577c792f, 0x572b2ddf, 0x56dac38d, 0x568b3631, 0x563c81df, 0x55eea2c3, 0x55a19521,
3922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x55555555, 0x5509dfd0, 0x54bf311a, 0x547545d0, 0x542c1aa3, 0x53e3ac5a, 0x539bf7cc, 0x5354f9e6,
3932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x530eafa4, 0x52c91617, 0x52842a5e, 0x523fe9ab, 0x51fc513f, 0x51b95e6b, 0x51770e8e, 0x51355f19,
3942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x50f44d88, 0x50b3d768, 0x5073fa4f, 0x5034b3e6, 0x4ff601df, 0x4fb7e1f9, 0x4f7a5201, 0x4f3d4fce,
3952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x4f00d943, 0x4ec4ec4e, 0x4e8986e9, 0x4e4ea718, 0x4e144ae8, 0x4dda7072, 0x4da115d9, 0x4d683948,
3962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x4d2fd8f4, 0x4cf7f31b, 0x4cc08604, 0x4c898fff, 0x4c530f64, 0x4c1d0293, 0x4be767f5, 0x4bb23df9,
3972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x4b7d8317, 0x4b4935ce, 0x4b1554a6, 0x4ae1de2a, 0x4aaed0f0, 0x4a7c2b92, 0x4a49ecb3, 0x4a1812fa,
3982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x49e69d16, 0x49b589bb, 0x4984d7a4, 0x49548591, 0x49249249, 0x48f4fc96, 0x48c5c34a, 0x4896e53c,
3992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x48686147, 0x483a364c, 0x480c6331, 0x47dee6e0, 0x47b1c049, 0x4784ee5f, 0x4758701c, 0x472c447c,
4002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x47006a80, 0x46d4e130, 0x46a9a793, 0x467ebcb9, 0x46541fb3, 0x4629cf98, 0x45ffcb80, 0x45d61289,
4012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x45aca3d5, 0x45837e88, 0x455aa1ca, 0x45320cc8, 0x4509beb0, 0x44e1b6b4, 0x44b9f40b, 0x449275ec,
4022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x446b3b95, 0x44444444, 0x441d8f3b, 0x43f71bbe, 0x43d0e917, 0x43aaf68e, 0x43854373, 0x435fcf14,
4032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x433a98c5, 0x43159fdb, 0x42f0e3ae, 0x42cc6397, 0x42a81ef5, 0x42841527, 0x4260458d, 0x423caf8c,
4042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x4219528b, 0x41f62df1, 0x41d3412a, 0x41b08ba1, 0x418e0cc7, 0x416bc40d, 0x4149b0e4, 0x4127d2c3,
4052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  0x41062920, 0x40e4b374, 0x40c3713a, 0x40a261ef, 0x40818511, 0x4060da21, 0x404060a1, 0x40201814
4062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project};
4072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4082228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectLNK_SECTION_INITCODE
4092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid InitInvSqrtTab()
4102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
4112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* nothing to do !
4122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project     use preinitialized square root table
4132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  */
4142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
4152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if !defined(FUNCTION_invSqrtNorm2)
4192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
4202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  delivers 1/sqrt(op) normalized to .5...1 and the shift value of the OUTPUT,
4212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  i.e. the denormalized result is 1/sqrt(op) = invSqrtNorm(op) * 2^(shift)
4222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  uses Newton-iteration for approximation
4232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      Q(n+1) = Q(n) + Q(n) * (0.5 - 2 * V * Q(n)^2)
4242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      with Q = 0.5* V ^-0.5; 0.5 <= V < 1.0
4252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
4262228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL invSqrtNorm2(FIXP_DBL op, INT *shift)
4272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
4282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL val = op ;
4302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL reg1, reg2, regtmp ;
4312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (val == FL2FXCONST_DBL(0.0)) {
4332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *shift = 1 ;
4342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return((LONG)1);  /* minimum positive value */
4352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
4362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* normalize input, calculate shift value */
4392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDK_ASSERT(val > FL2FXCONST_DBL(0.0));
4402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  *shift = fNormz(val) - 1;  /* CountLeadingBits() is not necessary here since test value is always > 0 */
4412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  val <<=*shift ;  /* normalized input V */
4422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  *shift+=2 ;      /* bias for exponent */
4432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Newton iteration of 1/sqrt(V) */
4452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  reg1 = invSqrtTab[ (INT)(val>>(DFRACT_BITS-1-(SQRT_BITS+1))) & SQRT_BITS_MASK ];
4462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  reg2 = FL2FXCONST_DBL(0.0625f);   /* 0.5 >> 3 */
4472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  regtmp= fPow2Div2(reg1);              /* a = Q^2 */
4492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  regtmp= reg2 - fMultDiv2(regtmp, val);      /* b = 0.5 - 2 * V * Q^2 */
4502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  reg1 += (fMultDiv2(regtmp, reg1)<<4);       /* Q = Q + Q*b */
4512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* calculate the output exponent = input exp/2 */
4532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (*shift & 0x00000001) { /* odd shift values ? */
4542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    reg2 = FL2FXCONST_DBL(0.707106781186547524400844362104849f); /* 1/sqrt(2); */
4552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    reg1 = fMultDiv2(reg1, reg2) << 2;
4562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
4572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  *shift = *shift>>1;
4592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return(reg1);
4612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
4622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* !defined(FUNCTION_invSqrtNorm2) */
4632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
4652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    functionname: sqrtFixp
4672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    description:  delivers sqrt(op)
4682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
4702228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL sqrtFixp(FIXP_DBL op)
4712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
4722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  INT tmp_exp = 0;
4732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL tmp_inv = invSqrtNorm2(op, &tmp_exp);
4742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDK_ASSERT(tmp_exp > 0) ;
4762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return( (FIXP_DBL) ( fMultDiv2( (op<<(tmp_exp-1)), tmp_inv ) << 2 ));
4772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
4782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if !defined(FUNCTION_schur_div)
4812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
4822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    functionname: schur_div
4842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    description:  delivers op1/op2 with op3-bit accuracy
4852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
4872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4892228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL schur_div(FIXP_DBL num, FIXP_DBL denum, INT count)
4902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
4912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT L_num   = (LONG)num>>1;
4922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT L_denum = (LONG)denum>>1;
4932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT div     = 0;
4942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT k       = count;
4952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_ASSERT (num>=(FIXP_DBL)0);
4972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_ASSERT (denum>(FIXP_DBL)0);
4982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_ASSERT (num <= denum);
4992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (L_num != 0)
5012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        while (--k)
5022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
5032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            div   <<= 1;
5042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            L_num <<= 1;
5052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (L_num >= L_denum)
5062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            {
5072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                L_num -= L_denum;
5082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                div++;
5092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
5102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
5112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return (FIXP_DBL)(div << (DFRACT_BITS - count));
5122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
5132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* !defined(FUNCTION_schur_div) */
5162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef FUNCTION_fMultNorm
5192228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL fMultNorm(FIXP_DBL f1, FIXP_DBL f2, INT *result_e)
5202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
5212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT    product = 0;
5222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT    norm_f1, norm_f2;
5232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (  (f1 == (FIXP_DBL)0) || (f2 == (FIXP_DBL)0) ) {
5252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *result_e = 0;
5262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return (FIXP_DBL)0;
5272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    norm_f1 = CountLeadingBits(f1);
5292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    f1 = f1 << norm_f1;
5302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    norm_f2 = CountLeadingBits(f2);
5312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    f2 = f2 << norm_f2;
5322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    product = fMult(f1, f2);
5342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *result_e  = - (norm_f1 + norm_f2);
5352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return (FIXP_DBL)product;
5372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
5382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
5392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef FUNCTION_fDivNorm
5412228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL fDivNorm(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e)
5422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
5432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL div;
5442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT norm_num, norm_den;
5452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_ASSERT (L_num   >= (FIXP_DBL)0);
5472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_ASSERT (L_denum >  (FIXP_DBL)0);
5482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if(L_num == (FIXP_DBL)0)
5502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
5512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *result_e = 0;
5522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return ((FIXP_DBL)0);
5532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    norm_num = CountLeadingBits(L_num);
5562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    L_num = L_num << norm_num;
5572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    L_num = L_num >> 1;
5582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *result_e = - norm_num + 1;
5592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    norm_den = CountLeadingBits(L_denum);
5612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    L_denum = L_denum << norm_den;
5622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *result_e -= - norm_den;
5632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    div = schur_div(L_num, L_denum, FRACT_BITS);
5652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return div;
5672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
5682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* !FUNCTION_fDivNorm */
5692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef FUNCTION_fDivNorm
5712228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom)
5722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
5732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT e;
5742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL res;
5752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_ASSERT (denom >= num);
5772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    res = fDivNorm(num, denom, &e);
5792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Avoid overflow since we must output a value with exponent 0
5812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project       there is no other choice than saturating to almost 1.0f */
5822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if(res == (FIXP_DBL)(1<<(DFRACT_BITS-2)) && e == 1)
5832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
5842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        res = (FIXP_DBL)MAXVAL_DBL;
5852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    else
5872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
5882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        res = scaleValue(res, e);
5892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return res;
5922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
5932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* !FUNCTION_fDivNorm */
5942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef FUNCTION_fDivNormHighPrec
5962228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL fDivNormHighPrec(FIXP_DBL num, FIXP_DBL denom, INT *result_e)
5972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
5982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL div;
5992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT norm_num, norm_den;
6002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_ASSERT (num   >= (FIXP_DBL)0);
6022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_ASSERT (denom >  (FIXP_DBL)0);
6032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if(num == (FIXP_DBL)0)
6052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
6062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *result_e = 0;
6072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return ((FIXP_DBL)0);
6082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
6092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    norm_num = CountLeadingBits(num);
6112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    num = num << norm_num;
6122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    num = num >> 1;
6132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *result_e = - norm_num + 1;
6142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    norm_den = CountLeadingBits(denom);
6162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    denom = denom << norm_den;
6172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *result_e -=  - norm_den;
6182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    div = schur_div(num, denom, 31);
6202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return div;
6212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
6222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* !FUNCTION_fDivNormHighPrec */
6232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6262228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL CalcLog2(FIXP_DBL base_m, INT base_e, INT *result_e)
6272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
6282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return fLog2(base_m, base_e, result_e);
6292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
6302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6312228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL f2Pow(
6322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        const FIXP_DBL exp_m, const INT exp_e,
6332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT *result_e
6342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        )
6352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
6362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL frac_part, result_m;
6372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  INT int_part;
6382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (exp_e > 0)
6402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
6412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      INT exp_bits = DFRACT_BITS-1 - exp_e;
6422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      int_part = exp_m >> exp_bits;
6432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      frac_part = exp_m - (FIXP_DBL)(int_part << exp_bits);
6442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      frac_part = frac_part << exp_e;
6452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
6462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  else
6472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
6482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      int_part = 0;
6492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      frac_part = exp_m >> -exp_e;
6502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
6512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Best accuracy is around 0, so try to get there with the fractional part. */
6532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if( frac_part > FL2FXCONST_DBL(0.5f) )
6542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
6552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      int_part = int_part + 1;
6562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      frac_part = frac_part + FL2FXCONST_DBL(-1.0f);
6572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
6582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if( frac_part < FL2FXCONST_DBL(-0.5f) )
6592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
6602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      int_part = int_part - 1;
6612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      frac_part = -(FL2FXCONST_DBL(-1.0f) - frac_part);
6622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
6632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Evaluate taylor polynomial which approximates 2^x */
6652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
6662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL p;
6672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* result_m ~= 2^frac_part */
6692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    p = frac_part;
6702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* First taylor series coefficient a_0 = 1.0, scaled by 0.5 due to fMultDiv2(). */
6712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    result_m = FL2FXCONST_DBL(1.0f/2.0f);
6722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (INT i = 0; i < POW2_PRECISION; i++) {
6732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* next taylor series term: a_i * x^i, x=0 */
6742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      result_m = fMultAddDiv2(result_m, pow2Coeff[i], p);
6752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      p  = fMult(p, frac_part);
6762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
6772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
6782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* "+ 1" compensates fMultAddDiv2() of the polynomial evaluation above. */
6802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  *result_e = int_part + 1;
6812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return result_m;
6832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
6842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6852228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL f2Pow(
6862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        const FIXP_DBL exp_m, const INT exp_e
6872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        )
6882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
6892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL result_m;
6902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  INT result_e;
6912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  result_m = f2Pow(exp_m, exp_e, &result_e);
6932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  result_e = fixMin(DFRACT_BITS-1,fixMax(-(DFRACT_BITS-1),result_e));
6942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return scaleValue(result_m, result_e);
6962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
6972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6982228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL fPow(
6992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL base_m, INT base_e,
7002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL exp_m, INT exp_e,
7012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT *result_e
7022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        )
7032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
7042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT ans_lg2_e, baselg2_e;
7052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL base_lg2, ans_lg2, result;
7062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Calc log2 of base */
7082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    base_lg2 = fLog2(base_m, base_e, &baselg2_e);
7092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Prepare exp */
7112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
7122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      INT leadingBits;
7132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      leadingBits = CountLeadingBits(fAbs(exp_m));
7152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      exp_m = exp_m << leadingBits;
7162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      exp_e -= leadingBits;
7172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
7182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Calc base pow exp */
7202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    ans_lg2 = fMult(base_lg2, exp_m);
7212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    ans_lg2_e = exp_e + baselg2_e;
7222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Calc antilog */
7242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    result = f2Pow(ans_lg2, ans_lg2_e, result_e);
7252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return result;
7272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
7282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7292228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL fLdPow(
7302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL baseLd_m,
7312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT baseLd_e,
7322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL exp_m, INT exp_e,
7332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT *result_e
7342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        )
7352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
7362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT ans_lg2_e;
7372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL ans_lg2, result;
7382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Prepare exp */
7402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
7412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      INT leadingBits;
7422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      leadingBits = CountLeadingBits(fAbs(exp_m));
7442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      exp_m = exp_m << leadingBits;
7452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      exp_e -= leadingBits;
7462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
7472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Calc base pow exp */
7492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    ans_lg2 = fMult(baseLd_m, exp_m);
7502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    ans_lg2_e = exp_e + baseLd_e;
7512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Calc antilog */
7532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    result = f2Pow(ans_lg2, ans_lg2_e, result_e);
7542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return result;
7562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
7572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7582228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL fLdPow(
7592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL baseLd_m, INT baseLd_e,
7602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL exp_m, INT exp_e
7612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        )
7622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
7632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL result_m;
7642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int result_e;
7652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  result_m = fLdPow(baseLd_m, baseLd_e, exp_m, exp_e, &result_e);
7672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return SATURATE_SHIFT(result_m, -result_e, DFRACT_BITS);
7692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
7702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7712228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL fPowInt(
7722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL base_m, INT base_e,
7732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT exp,
7742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT *pResult_e
7752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        )
7762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
7772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL result;
7782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (exp != 0) {
7802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT result_e = 0;
7812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (base_m != (FIXP_DBL)0) {
7832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      {
7842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT leadingBits;
7852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        leadingBits = CountLeadingBits( base_m );
7862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        base_m <<= leadingBits;
7872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        base_e -= leadingBits;
7882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
7892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      result = base_m;
7912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      {
7932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        int i;
7942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (i = 1; i < fAbs(exp); i++) {
7952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          result = fMult(result, base_m);
7962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
7972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
7982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (exp < 0) {
8002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* 1.0 / ans */
8012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        result = fDivNorm( FL2FXCONST_DBL(0.5f), result, &result_e );
8022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        result_e++;
8032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      } else {
8042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        int ansScale = CountLeadingBits( result );
8052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        result <<= ansScale;
8062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        result_e -= ansScale;
8072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
8082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      result_e += exp * base_e;
8102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else {
8122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      result = (FIXP_DBL)0;
8132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *pResult_e = result_e;
8152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  else {
8172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    result =  FL2FXCONST_DBL(0.5f);
8182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *pResult_e = 1;
8192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return result;
8222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
8232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8242228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL fLog2(FIXP_DBL x_m, INT x_e, INT *result_e)
8252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
8262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL result_m;
8272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Short cut for zero and negative numbers. */
8292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ( x_m <= FL2FXCONST_DBL(0.0f) ) {
8302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *result_e = DFRACT_BITS-1;
8312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return FL2FXCONST_DBL(-1.0f);
8322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Calculate log2() */
8352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
8362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL px2_m, x2_m;
8372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Move input value x_m * 2^x_e toward 1.0, where the taylor approximation
8392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project       of the function log(1-x) centered at 0 is most accurate. */
8402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
8412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      INT b_norm;
8422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      b_norm = fNormz(x_m)-1;
8442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      x2_m = x_m << b_norm;
8452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      x_e = x_e - b_norm;
8462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* map x from log(x) domain to log(1-x) domain. */
8492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    x2_m = - (x2_m + FL2FXCONST_DBL(-1.0) );
8502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Taylor polinomial approximation of ln(1-x) */
8522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    result_m  = FL2FXCONST_DBL(0.0);
8532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    px2_m = x2_m;
8542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (int i=0; i<LD_PRECISION; i++) {
8552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      result_m = fMultAddDiv2(result_m, ldCoeff[i], px2_m);
8562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      px2_m = fMult(px2_m, x2_m);
8572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Multiply result with 1/ln(2) = 1.0 + 0.442695040888 (get log2(x) from ln(x) result). */
8592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    result_m = fMultAddDiv2(result_m, result_m, FL2FXCONST_DBL(2.0*0.4426950408889634073599246810019));
8602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Add exponent part. log2(x_m * 2^x_e) = log2(x_m) + x_e */
8622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (x_e != 0)
8632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
8642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      int enorm;
8652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      enorm = DFRACT_BITS - fNorm((FIXP_DBL)x_e);
8672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* The -1 in the right shift of result_m compensates the fMultDiv2() above in the taylor polinomial evaluation loop.*/
8682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      result_m = (result_m >> (enorm-1)) + ((FIXP_DBL)x_e << (DFRACT_BITS-1-enorm));
8692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      *result_e = enorm;
8712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else {
8722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* 1 compensates the fMultDiv2() above in the taylor polinomial evaluation loop.*/
8732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      *result_e = 1;
8742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return result_m;
8782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
8792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8802228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL fLog2(FIXP_DBL x_m, INT x_e)
8812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
8822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ( x_m <= FL2FXCONST_DBL(0.0f) ) {
8832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    x_m = FL2FXCONST_DBL(-1.0f);
8842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  else {
8862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT result_e;
8872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    x_m = fLog2(x_m, x_e, &result_e);
8882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    x_m = scaleValue(x_m, result_e-LD_DATA_SHIFT);
8892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return  x_m;
8912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
8922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
896