• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6 
7  1.    INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18 
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28 
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33 
34 2.    COPYRIGHT LICENSE
35 
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39 
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42 
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48 
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51 
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54 
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60 
61 3.    NO PATENT LICENSE
62 
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67 
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70 
71 4.    DISCLAIMER
72 
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83 
84 5.    CONTACT INFORMATION
85 
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90 
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94 
95 /******************* Library for basic calculation routines ********************
96 
97    Author(s):   M. Gayer
98 
99    Description: Fixed point specific mathematical functions
100 
101 *******************************************************************************/
102 
103 #include "fixpoint_math.h"
104 
105 /*
106  * Hardware specific implementations
107  */
108 
109 /*
110  * Fallback implementations
111  */
112 
113 /*****************************************************************************
114   functionname: LdDataVector
115 *****************************************************************************/
116 LNK_SECTION_CODE_L1
LdDataVector(FIXP_DBL * srcVector,FIXP_DBL * destVector,INT n)117 void LdDataVector(FIXP_DBL *srcVector, FIXP_DBL *destVector, INT n) {
118   INT i;
119   for (i = 0; i < n; i++) {
120     destVector[i] = fLog2(srcVector[i], 0);
121   }
122 }
123 
124 #define MAX_POW2_PRECISION 8
125 #ifndef SINETABLE_16BIT
126 #define POW2_PRECISION MAX_POW2_PRECISION
127 #else
128 #define POW2_PRECISION 5
129 #endif
130 
131 /*
132   Taylor series coefficients of the function x^2. The first coefficient is
133   ommited (equal to 1.0).
134 
135   pow2Coeff[i-1] = (1/i!) d^i(2^x)/dx^i, i=1..MAX_POW2_PRECISION
136   To evaluate the taylor series around x = 0, the coefficients are: 1/!i *
137   ln(2)^i
138  */
139 #ifndef POW2COEFF_16BIT
140 RAM_ALIGN
141 LNK_SECTION_CONSTDATA_L1
142 static const FIXP_DBL pow2Coeff[MAX_POW2_PRECISION] = {
143     FL2FXCONST_DBL(0.693147180559945309417232121458177),   /* ln(2)^1 /1! */
144     FL2FXCONST_DBL(0.240226506959100712333551263163332),   /* ln(2)^2 /2! */
145     FL2FXCONST_DBL(0.0555041086648215799531422637686218),  /* ln(2)^3 /3! */
146     FL2FXCONST_DBL(0.00961812910762847716197907157365887), /* ln(2)^4 /4! */
147     FL2FXCONST_DBL(0.00133335581464284434234122219879962), /* ln(2)^5 /5! */
148     FL2FXCONST_DBL(1.54035303933816099544370973327423e-4), /* ln(2)^6 /6! */
149     FL2FXCONST_DBL(1.52527338040598402800254390120096e-5), /* ln(2)^7 /7! */
150     FL2FXCONST_DBL(1.32154867901443094884037582282884e-6)  /* ln(2)^8 /8! */
151 };
152 #else
153 RAM_ALIGN
154 LNK_SECTION_CONSTDATA_L1
155 static const FIXP_SGL pow2Coeff[MAX_POW2_PRECISION] = {
156     FL2FXCONST_SGL(0.693147180559945309417232121458177),   /* ln(2)^1 /1! */
157     FL2FXCONST_SGL(0.240226506959100712333551263163332),   /* ln(2)^2 /2! */
158     FL2FXCONST_SGL(0.0555041086648215799531422637686218),  /* ln(2)^3 /3! */
159     FL2FXCONST_SGL(0.00961812910762847716197907157365887), /* ln(2)^4 /4! */
160     FL2FXCONST_SGL(0.00133335581464284434234122219879962), /* ln(2)^5 /5! */
161     FL2FXCONST_SGL(1.54035303933816099544370973327423e-4), /* ln(2)^6 /6! */
162     FL2FXCONST_SGL(1.52527338040598402800254390120096e-5), /* ln(2)^7 /7! */
163     FL2FXCONST_SGL(1.32154867901443094884037582282884e-6)  /* ln(2)^8 /8! */
164 };
165 #endif
166 
167 /*****************************************************************************
168 
169   functionname: CalcInvLdData
170   description:  Delivers the inverse of function CalcLdData().
171                 Delivers 2^(op*LD_DATA_SCALING)
172   input:        Input op is assumed to be fractional -1.0 < op < 1.0
173   output:       For op == 0, the result is MAXVAL_DBL (almost 1.0).
174                 For negative input values the output should be treated as a
175 positive fractional value. For positive input values the output should be
176 treated as a positive integer value. This function does not output negative
177 values.
178 
179 *****************************************************************************/
180 /* Date: 06-JULY-2012 Arthur Tritthart, IIS Fraunhofer Erlangen */
181 /* Version with 3 table lookup and 1 linear interpolations      */
182 /* Algorithm: compute power of 2, argument x is in Q7.25 format */
183 /*  result = 2^(x/64)                                           */
184 /*  We split exponent (x/64) into 5 components:                 */
185 /*  integer part:      represented by b31..b25  (exp)           */
186 /*  fractional part 1: represented by b24..b20  (lookup1)       */
187 /*  fractional part 2: represented by b19..b15  (lookup2)       */
188 /*  fractional part 3: represented by b14..b10  (lookup3)       */
189 /*  fractional part 4: represented by b09..b00  (frac)          */
190 /*  => result = (lookup1*lookup2*(lookup3+C1*frac)<<3)>>exp     */
191 /* Due to the fact, that all lookup values contain a factor 0.5 */
192 /* the result has to be shifted by 3 to the right also.         */
193 /* Table exp2_tab_long contains the log2 for 0 to 1.0 in steps  */
194 /* of 1/32, table exp2w_tab_long the log2 for 0 to 1/32 in steps*/
195 /* of 1/1024, table exp2x_tab_long the log2 for 0 to 1/1024 in  */
196 /* steps of 1/32768. Since the 2-logarithm of very very small   */
197 /* negative value is rather linear, we can use interpolation.   */
198 /* Limitations:                                                 */
199 /* For x <= 0, the result is fractional positive                */
200 /* For x > 0, the result is integer in range 1...7FFF.FFFF      */
201 /* For x < -31/64, we have to clear the result                  */
202 /* For x = 0, the result is ~1.0 (0x7FFF.FFFF)                  */
203 /* For x >= 31/64, the result is 0x7FFF.FFFF                    */
204 
205 /* This table is used for lookup 2^x with   */
206 /* x in range [0...1.0[ in steps of 1/32 */
207 LNK_SECTION_DATA_L1
208 const UINT exp2_tab_long[32] = {
209     0x40000000, 0x4166C34C, 0x42D561B4, 0x444C0740, 0x45CAE0F2, 0x47521CC6,
210     0x48E1E9BA, 0x4A7A77D4, 0x4C1BF829, 0x4DC69CDD, 0x4F7A9930, 0x51382182,
211     0x52FF6B55, 0x54D0AD5A, 0x56AC1F75, 0x5891FAC1, 0x5A82799A, 0x5C7DD7A4,
212     0x5E8451D0, 0x60962665, 0x62B39509, 0x64DCDEC3, 0x6712460B, 0x69540EC9,
213     0x6BA27E65, 0x6DFDDBCC, 0x70666F76, 0x72DC8374, 0x75606374, 0x77F25CCE,
214     0x7A92BE8B, 0x7D41D96E
215     // 0x80000000
216 };
217 
218 /* This table is used for lookup 2^x with   */
219 /* x in range [0...1/32[ in steps of 1/1024 */
220 LNK_SECTION_DATA_L1
221 const UINT exp2w_tab_long[32] = {
222     0x40000000, 0x400B1818, 0x4016321B, 0x40214E0C, 0x402C6BE9, 0x40378BB4,
223     0x4042AD6D, 0x404DD113, 0x4058F6A8, 0x40641E2B, 0x406F479E, 0x407A7300,
224     0x4085A051, 0x4090CF92, 0x409C00C4, 0x40A733E6, 0x40B268FA, 0x40BD9FFF,
225     0x40C8D8F5, 0x40D413DD, 0x40DF50B8, 0x40EA8F86, 0x40F5D046, 0x410112FA,
226     0x410C57A2, 0x41179E3D, 0x4122E6CD, 0x412E3152, 0x41397DCC, 0x4144CC3B,
227     0x41501CA0, 0x415B6EFB,
228     // 0x4166C34C,
229 };
230 /* This table is used for lookup 2^x with   */
231 /* x in range [0...1/1024[ in steps of 1/32768 */
232 LNK_SECTION_DATA_L1
233 const UINT exp2x_tab_long[32] = {
234     0x40000000, 0x400058B9, 0x4000B173, 0x40010A2D, 0x400162E8, 0x4001BBA3,
235     0x4002145F, 0x40026D1B, 0x4002C5D8, 0x40031E95, 0x40037752, 0x4003D011,
236     0x400428CF, 0x4004818E, 0x4004DA4E, 0x4005330E, 0x40058BCE, 0x4005E48F,
237     0x40063D51, 0x40069613, 0x4006EED5, 0x40074798, 0x4007A05B, 0x4007F91F,
238     0x400851E4, 0x4008AAA8, 0x4009036E, 0x40095C33, 0x4009B4FA, 0x400A0DC0,
239     0x400A6688, 0x400ABF4F,
240     // 0x400B1818
241 };
242 
243 /*****************************************************************************
244     functionname: InitLdInt and CalcLdInt
245     description:  Create and access table with integer LdData (0 to
246 LD_INT_TAB_LEN)
247 *****************************************************************************/
248 #ifndef LD_INT_TAB_LEN
249 #define LD_INT_TAB_LEN \
250   193 /* Default tab length. Lower value should be set in fix.h */
251 #endif
252 
253 #if (LD_INT_TAB_LEN <= 120)
254 LNK_SECTION_CONSTDATA_L1
255 static const FIXP_DBL ldIntCoeff[] = {
256     (FIXP_DBL)0x80000001, (FIXP_DBL)0x00000000, (FIXP_DBL)0x02000000,
257     (FIXP_DBL)0x032b8034, (FIXP_DBL)0x04000000, (FIXP_DBL)0x04a4d3c2,
258     (FIXP_DBL)0x052b8034, (FIXP_DBL)0x059d5da0, (FIXP_DBL)0x06000000,
259     (FIXP_DBL)0x06570069, (FIXP_DBL)0x06a4d3c2, (FIXP_DBL)0x06eb3a9f,
260     (FIXP_DBL)0x072b8034, (FIXP_DBL)0x0766a009, (FIXP_DBL)0x079d5da0,
261     (FIXP_DBL)0x07d053f7, (FIXP_DBL)0x08000000, (FIXP_DBL)0x082cc7ee,
262     (FIXP_DBL)0x08570069, (FIXP_DBL)0x087ef05b, (FIXP_DBL)0x08a4d3c2,
263     (FIXP_DBL)0x08c8ddd4, (FIXP_DBL)0x08eb3a9f, (FIXP_DBL)0x090c1050,
264     (FIXP_DBL)0x092b8034, (FIXP_DBL)0x0949a785, (FIXP_DBL)0x0966a009,
265     (FIXP_DBL)0x0982809d, (FIXP_DBL)0x099d5da0, (FIXP_DBL)0x09b74949,
266     (FIXP_DBL)0x09d053f7, (FIXP_DBL)0x09e88c6b, (FIXP_DBL)0x0a000000,
267     (FIXP_DBL)0x0a16bad3, (FIXP_DBL)0x0a2cc7ee, (FIXP_DBL)0x0a423162,
268     (FIXP_DBL)0x0a570069, (FIXP_DBL)0x0a6b3d79, (FIXP_DBL)0x0a7ef05b,
269     (FIXP_DBL)0x0a92203d, (FIXP_DBL)0x0aa4d3c2, (FIXP_DBL)0x0ab7110e,
270     (FIXP_DBL)0x0ac8ddd4, (FIXP_DBL)0x0ada3f60, (FIXP_DBL)0x0aeb3a9f,
271     (FIXP_DBL)0x0afbd42b, (FIXP_DBL)0x0b0c1050, (FIXP_DBL)0x0b1bf312,
272     (FIXP_DBL)0x0b2b8034, (FIXP_DBL)0x0b3abb40, (FIXP_DBL)0x0b49a785,
273     (FIXP_DBL)0x0b584822, (FIXP_DBL)0x0b66a009, (FIXP_DBL)0x0b74b1fd,
274     (FIXP_DBL)0x0b82809d, (FIXP_DBL)0x0b900e61, (FIXP_DBL)0x0b9d5da0,
275     (FIXP_DBL)0x0baa708f, (FIXP_DBL)0x0bb74949, (FIXP_DBL)0x0bc3e9ca,
276     (FIXP_DBL)0x0bd053f7, (FIXP_DBL)0x0bdc899b, (FIXP_DBL)0x0be88c6b,
277     (FIXP_DBL)0x0bf45e09, (FIXP_DBL)0x0c000000, (FIXP_DBL)0x0c0b73cb,
278     (FIXP_DBL)0x0c16bad3, (FIXP_DBL)0x0c21d671, (FIXP_DBL)0x0c2cc7ee,
279     (FIXP_DBL)0x0c379085, (FIXP_DBL)0x0c423162, (FIXP_DBL)0x0c4caba8,
280     (FIXP_DBL)0x0c570069, (FIXP_DBL)0x0c6130af, (FIXP_DBL)0x0c6b3d79,
281     (FIXP_DBL)0x0c7527b9, (FIXP_DBL)0x0c7ef05b, (FIXP_DBL)0x0c88983f,
282     (FIXP_DBL)0x0c92203d, (FIXP_DBL)0x0c9b8926, (FIXP_DBL)0x0ca4d3c2,
283     (FIXP_DBL)0x0cae00d2, (FIXP_DBL)0x0cb7110e, (FIXP_DBL)0x0cc0052b,
284     (FIXP_DBL)0x0cc8ddd4, (FIXP_DBL)0x0cd19bb0, (FIXP_DBL)0x0cda3f60,
285     (FIXP_DBL)0x0ce2c97d, (FIXP_DBL)0x0ceb3a9f, (FIXP_DBL)0x0cf39355,
286     (FIXP_DBL)0x0cfbd42b, (FIXP_DBL)0x0d03fda9, (FIXP_DBL)0x0d0c1050,
287     (FIXP_DBL)0x0d140ca0, (FIXP_DBL)0x0d1bf312, (FIXP_DBL)0x0d23c41d,
288     (FIXP_DBL)0x0d2b8034, (FIXP_DBL)0x0d3327c7, (FIXP_DBL)0x0d3abb40,
289     (FIXP_DBL)0x0d423b08, (FIXP_DBL)0x0d49a785, (FIXP_DBL)0x0d510118,
290     (FIXP_DBL)0x0d584822, (FIXP_DBL)0x0d5f7cff, (FIXP_DBL)0x0d66a009,
291     (FIXP_DBL)0x0d6db197, (FIXP_DBL)0x0d74b1fd, (FIXP_DBL)0x0d7ba190,
292     (FIXP_DBL)0x0d82809d, (FIXP_DBL)0x0d894f75, (FIXP_DBL)0x0d900e61,
293     (FIXP_DBL)0x0d96bdad, (FIXP_DBL)0x0d9d5da0, (FIXP_DBL)0x0da3ee7f,
294     (FIXP_DBL)0x0daa708f, (FIXP_DBL)0x0db0e412, (FIXP_DBL)0x0db74949,
295     (FIXP_DBL)0x0dbda072, (FIXP_DBL)0x0dc3e9ca, (FIXP_DBL)0x0dca258e};
296 
297 #elif (LD_INT_TAB_LEN <= 193)
298 LNK_SECTION_CONSTDATA_L1
299 static const FIXP_DBL ldIntCoeff[] = {
300     (FIXP_DBL)0x80000001, (FIXP_DBL)0x00000000, (FIXP_DBL)0x02000000,
301     (FIXP_DBL)0x032b8034, (FIXP_DBL)0x04000000, (FIXP_DBL)0x04a4d3c2,
302     (FIXP_DBL)0x052b8034, (FIXP_DBL)0x059d5da0, (FIXP_DBL)0x06000000,
303     (FIXP_DBL)0x06570069, (FIXP_DBL)0x06a4d3c2, (FIXP_DBL)0x06eb3a9f,
304     (FIXP_DBL)0x072b8034, (FIXP_DBL)0x0766a009, (FIXP_DBL)0x079d5da0,
305     (FIXP_DBL)0x07d053f7, (FIXP_DBL)0x08000000, (FIXP_DBL)0x082cc7ee,
306     (FIXP_DBL)0x08570069, (FIXP_DBL)0x087ef05b, (FIXP_DBL)0x08a4d3c2,
307     (FIXP_DBL)0x08c8ddd4, (FIXP_DBL)0x08eb3a9f, (FIXP_DBL)0x090c1050,
308     (FIXP_DBL)0x092b8034, (FIXP_DBL)0x0949a785, (FIXP_DBL)0x0966a009,
309     (FIXP_DBL)0x0982809d, (FIXP_DBL)0x099d5da0, (FIXP_DBL)0x09b74949,
310     (FIXP_DBL)0x09d053f7, (FIXP_DBL)0x09e88c6b, (FIXP_DBL)0x0a000000,
311     (FIXP_DBL)0x0a16bad3, (FIXP_DBL)0x0a2cc7ee, (FIXP_DBL)0x0a423162,
312     (FIXP_DBL)0x0a570069, (FIXP_DBL)0x0a6b3d79, (FIXP_DBL)0x0a7ef05b,
313     (FIXP_DBL)0x0a92203d, (FIXP_DBL)0x0aa4d3c2, (FIXP_DBL)0x0ab7110e,
314     (FIXP_DBL)0x0ac8ddd4, (FIXP_DBL)0x0ada3f60, (FIXP_DBL)0x0aeb3a9f,
315     (FIXP_DBL)0x0afbd42b, (FIXP_DBL)0x0b0c1050, (FIXP_DBL)0x0b1bf312,
316     (FIXP_DBL)0x0b2b8034, (FIXP_DBL)0x0b3abb40, (FIXP_DBL)0x0b49a785,
317     (FIXP_DBL)0x0b584822, (FIXP_DBL)0x0b66a009, (FIXP_DBL)0x0b74b1fd,
318     (FIXP_DBL)0x0b82809d, (FIXP_DBL)0x0b900e61, (FIXP_DBL)0x0b9d5da0,
319     (FIXP_DBL)0x0baa708f, (FIXP_DBL)0x0bb74949, (FIXP_DBL)0x0bc3e9ca,
320     (FIXP_DBL)0x0bd053f7, (FIXP_DBL)0x0bdc899b, (FIXP_DBL)0x0be88c6b,
321     (FIXP_DBL)0x0bf45e09, (FIXP_DBL)0x0c000000, (FIXP_DBL)0x0c0b73cb,
322     (FIXP_DBL)0x0c16bad3, (FIXP_DBL)0x0c21d671, (FIXP_DBL)0x0c2cc7ee,
323     (FIXP_DBL)0x0c379085, (FIXP_DBL)0x0c423162, (FIXP_DBL)0x0c4caba8,
324     (FIXP_DBL)0x0c570069, (FIXP_DBL)0x0c6130af, (FIXP_DBL)0x0c6b3d79,
325     (FIXP_DBL)0x0c7527b9, (FIXP_DBL)0x0c7ef05b, (FIXP_DBL)0x0c88983f,
326     (FIXP_DBL)0x0c92203d, (FIXP_DBL)0x0c9b8926, (FIXP_DBL)0x0ca4d3c2,
327     (FIXP_DBL)0x0cae00d2, (FIXP_DBL)0x0cb7110e, (FIXP_DBL)0x0cc0052b,
328     (FIXP_DBL)0x0cc8ddd4, (FIXP_DBL)0x0cd19bb0, (FIXP_DBL)0x0cda3f60,
329     (FIXP_DBL)0x0ce2c97d, (FIXP_DBL)0x0ceb3a9f, (FIXP_DBL)0x0cf39355,
330     (FIXP_DBL)0x0cfbd42b, (FIXP_DBL)0x0d03fda9, (FIXP_DBL)0x0d0c1050,
331     (FIXP_DBL)0x0d140ca0, (FIXP_DBL)0x0d1bf312, (FIXP_DBL)0x0d23c41d,
332     (FIXP_DBL)0x0d2b8034, (FIXP_DBL)0x0d3327c7, (FIXP_DBL)0x0d3abb40,
333     (FIXP_DBL)0x0d423b08, (FIXP_DBL)0x0d49a785, (FIXP_DBL)0x0d510118,
334     (FIXP_DBL)0x0d584822, (FIXP_DBL)0x0d5f7cff, (FIXP_DBL)0x0d66a009,
335     (FIXP_DBL)0x0d6db197, (FIXP_DBL)0x0d74b1fd, (FIXP_DBL)0x0d7ba190,
336     (FIXP_DBL)0x0d82809d, (FIXP_DBL)0x0d894f75, (FIXP_DBL)0x0d900e61,
337     (FIXP_DBL)0x0d96bdad, (FIXP_DBL)0x0d9d5da0, (FIXP_DBL)0x0da3ee7f,
338     (FIXP_DBL)0x0daa708f, (FIXP_DBL)0x0db0e412, (FIXP_DBL)0x0db74949,
339     (FIXP_DBL)0x0dbda072, (FIXP_DBL)0x0dc3e9ca, (FIXP_DBL)0x0dca258e,
340     (FIXP_DBL)0x0dd053f7, (FIXP_DBL)0x0dd6753e, (FIXP_DBL)0x0ddc899b,
341     (FIXP_DBL)0x0de29143, (FIXP_DBL)0x0de88c6b, (FIXP_DBL)0x0dee7b47,
342     (FIXP_DBL)0x0df45e09, (FIXP_DBL)0x0dfa34e1, (FIXP_DBL)0x0e000000,
343     (FIXP_DBL)0x0e05bf94, (FIXP_DBL)0x0e0b73cb, (FIXP_DBL)0x0e111cd2,
344     (FIXP_DBL)0x0e16bad3, (FIXP_DBL)0x0e1c4dfb, (FIXP_DBL)0x0e21d671,
345     (FIXP_DBL)0x0e275460, (FIXP_DBL)0x0e2cc7ee, (FIXP_DBL)0x0e323143,
346     (FIXP_DBL)0x0e379085, (FIXP_DBL)0x0e3ce5d8, (FIXP_DBL)0x0e423162,
347     (FIXP_DBL)0x0e477346, (FIXP_DBL)0x0e4caba8, (FIXP_DBL)0x0e51daa8,
348     (FIXP_DBL)0x0e570069, (FIXP_DBL)0x0e5c1d0b, (FIXP_DBL)0x0e6130af,
349     (FIXP_DBL)0x0e663b74, (FIXP_DBL)0x0e6b3d79, (FIXP_DBL)0x0e7036db,
350     (FIXP_DBL)0x0e7527b9, (FIXP_DBL)0x0e7a1030, (FIXP_DBL)0x0e7ef05b,
351     (FIXP_DBL)0x0e83c857, (FIXP_DBL)0x0e88983f, (FIXP_DBL)0x0e8d602e,
352     (FIXP_DBL)0x0e92203d, (FIXP_DBL)0x0e96d888, (FIXP_DBL)0x0e9b8926,
353     (FIXP_DBL)0x0ea03232, (FIXP_DBL)0x0ea4d3c2, (FIXP_DBL)0x0ea96df0,
354     (FIXP_DBL)0x0eae00d2, (FIXP_DBL)0x0eb28c7f, (FIXP_DBL)0x0eb7110e,
355     (FIXP_DBL)0x0ebb8e96, (FIXP_DBL)0x0ec0052b, (FIXP_DBL)0x0ec474e4,
356     (FIXP_DBL)0x0ec8ddd4, (FIXP_DBL)0x0ecd4012, (FIXP_DBL)0x0ed19bb0,
357     (FIXP_DBL)0x0ed5f0c4, (FIXP_DBL)0x0eda3f60, (FIXP_DBL)0x0ede8797,
358     (FIXP_DBL)0x0ee2c97d, (FIXP_DBL)0x0ee70525, (FIXP_DBL)0x0eeb3a9f,
359     (FIXP_DBL)0x0eef69ff, (FIXP_DBL)0x0ef39355, (FIXP_DBL)0x0ef7b6b4,
360     (FIXP_DBL)0x0efbd42b, (FIXP_DBL)0x0effebcd, (FIXP_DBL)0x0f03fda9,
361     (FIXP_DBL)0x0f0809cf, (FIXP_DBL)0x0f0c1050, (FIXP_DBL)0x0f10113b,
362     (FIXP_DBL)0x0f140ca0, (FIXP_DBL)0x0f18028d, (FIXP_DBL)0x0f1bf312,
363     (FIXP_DBL)0x0f1fde3d, (FIXP_DBL)0x0f23c41d, (FIXP_DBL)0x0f27a4c0,
364     (FIXP_DBL)0x0f2b8034};
365 
366 #else
367 #error "ldInt table size too small"
368 
369 #endif
370 
371 LNK_SECTION_INITCODE
InitLdInt()372 void InitLdInt() { /* nothing to do! Use preinitialized logarithm table */
373 }
374 
375 #if (LD_INT_TAB_LEN != 0)
376 
377 LNK_SECTION_CODE_L1
CalcLdInt(INT i)378 FIXP_DBL CalcLdInt(INT i) {
379   /* calculates ld(op)/LD_DATA_SCALING */
380   /* op is assumed to be an integer value between 1 and LD_INT_TAB_LEN */
381 
382   FDK_ASSERT((LD_INT_TAB_LEN > 0) &&
383              ((FIXP_DBL)ldIntCoeff[0] ==
384               (FIXP_DBL)0x80000001)); /* tab has to be initialized */
385 
386   if ((i > 0) && (i < LD_INT_TAB_LEN))
387     return ldIntCoeff[i];
388   else {
389     return (0);
390   }
391 }
392 #endif /* (LD_INT_TAB_LEN!=0)  */
393 
394 #if !defined(FUNCTION_schur_div)
395 /*****************************************************************************
396 
397     functionname: schur_div
398     description:  delivers op1/op2 with op3-bit accuracy
399 
400 *****************************************************************************/
401 
schur_div(FIXP_DBL num,FIXP_DBL denum,INT count)402 FIXP_DBL schur_div(FIXP_DBL num, FIXP_DBL denum, INT count) {
403   INT L_num = (LONG)num >> 1;
404   INT L_denum = (LONG)denum >> 1;
405   INT div = 0;
406   INT k = count;
407 
408   FDK_ASSERT(num >= (FIXP_DBL)0);
409   FDK_ASSERT(denum > (FIXP_DBL)0);
410   FDK_ASSERT(num <= denum);
411 
412   if (L_num != 0)
413     while (--k) {
414       div <<= 1;
415       L_num <<= 1;
416       if (L_num >= L_denum) {
417         L_num -= L_denum;
418         div++;
419       }
420     }
421   return (FIXP_DBL)(div << (DFRACT_BITS - count));
422 }
423 
424 #endif /* !defined(FUNCTION_schur_div) */
425 
426 #ifndef FUNCTION_fMultNorm
fMultNorm(FIXP_DBL f1,FIXP_DBL f2,INT * result_e)427 FIXP_DBL fMultNorm(FIXP_DBL f1, FIXP_DBL f2, INT *result_e) {
428   INT product = 0;
429   INT norm_f1, norm_f2;
430 
431   if ((f1 == (FIXP_DBL)0) || (f2 == (FIXP_DBL)0)) {
432     *result_e = 0;
433     return (FIXP_DBL)0;
434   }
435   norm_f1 = CountLeadingBits(f1);
436   f1 = f1 << norm_f1;
437   norm_f2 = CountLeadingBits(f2);
438   f2 = f2 << norm_f2;
439 
440   if ((f1 == (FIXP_DBL)MINVAL_DBL) && (f2 == (FIXP_DBL)MINVAL_DBL)) {
441     product = -((FIXP_DBL)MINVAL_DBL >> 1);
442     *result_e = -(norm_f1 + norm_f2 - 1);
443   } else {
444     product = fMult(f1, f2);
445     *result_e = -(norm_f1 + norm_f2);
446   }
447 
448   return (FIXP_DBL)product;
449 }
450 #endif
451 
452 #ifndef FUNCTION_fDivNorm
fDivNorm(FIXP_DBL L_num,FIXP_DBL L_denum,INT * result_e)453 FIXP_DBL fDivNorm(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e) {
454   FIXP_DBL div;
455   INT norm_num, norm_den;
456 
457   FDK_ASSERT(L_num >= (FIXP_DBL)0);
458   FDK_ASSERT(L_denum > (FIXP_DBL)0);
459 
460   if (L_num == (FIXP_DBL)0) {
461     *result_e = 0;
462     return ((FIXP_DBL)0);
463   }
464 
465   norm_num = CountLeadingBits(L_num);
466   L_num = L_num << norm_num;
467   L_num = L_num >> 1;
468   *result_e = -norm_num + 1;
469 
470   norm_den = CountLeadingBits(L_denum);
471   L_denum = L_denum << norm_den;
472   *result_e -= -norm_den;
473 
474   div = schur_div(L_num, L_denum, FRACT_BITS);
475 
476   return div;
477 }
478 #endif /* !FUNCTION_fDivNorm */
479 
480 #ifndef FUNCTION_fDivNorm
fDivNorm(FIXP_DBL num,FIXP_DBL denom)481 FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom) {
482   INT e;
483   FIXP_DBL res;
484 
485   FDK_ASSERT(denom >= num);
486 
487   res = fDivNorm(num, denom, &e);
488 
489   /* Avoid overflow since we must output a value with exponent 0
490      there is no other choice than saturating to almost 1.0f */
491   if (res == (FIXP_DBL)(1 << (DFRACT_BITS - 2)) && e == 1) {
492     res = (FIXP_DBL)MAXVAL_DBL;
493   } else {
494     res = scaleValue(res, e);
495   }
496 
497   return res;
498 }
499 #endif /* !FUNCTION_fDivNorm */
500 
501 #ifndef FUNCTION_fDivNormSigned
fDivNormSigned(FIXP_DBL num,FIXP_DBL denom)502 FIXP_DBL fDivNormSigned(FIXP_DBL num, FIXP_DBL denom) {
503   INT e;
504   FIXP_DBL res;
505   int sign;
506 
507   if (denom == (FIXP_DBL)0) {
508     return (FIXP_DBL)MAXVAL_DBL;
509   }
510 
511   sign = ((num >= (FIXP_DBL)0) != (denom >= (FIXP_DBL)0));
512   res = fDivNormSigned(num, denom, &e);
513 
514   /* Saturate since we must output a value with exponent 0 */
515   if ((e > 0) && (fAbs(res) >= FL2FXCONST_DBL(0.5))) {
516     if (sign) {
517       res = (FIXP_DBL)MINVAL_DBL;
518     } else {
519       res = (FIXP_DBL)MAXVAL_DBL;
520     }
521   } else {
522     res = scaleValue(res, e);
523   }
524 
525   return res;
526 }
fDivNormSigned(FIXP_DBL L_num,FIXP_DBL L_denum,INT * result_e)527 FIXP_DBL fDivNormSigned(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e) {
528   FIXP_DBL div;
529   INT norm_num, norm_den;
530   int sign;
531 
532   sign = ((L_num >= (FIXP_DBL)0) != (L_denum >= (FIXP_DBL)0));
533 
534   if (L_num == (FIXP_DBL)0) {
535     *result_e = 0;
536     return ((FIXP_DBL)0);
537   }
538   if (L_denum == (FIXP_DBL)0) {
539     *result_e = 14;
540     return ((FIXP_DBL)MAXVAL_DBL);
541   }
542 
543   norm_num = CountLeadingBits(L_num);
544   L_num = L_num << norm_num;
545   L_num = L_num >> 2;
546   L_num = fAbs(L_num);
547   *result_e = -norm_num + 1;
548 
549   norm_den = CountLeadingBits(L_denum);
550   L_denum = L_denum << norm_den;
551   L_denum = L_denum >> 1;
552   L_denum = fAbs(L_denum);
553   *result_e -= -norm_den;
554 
555   div = schur_div(L_num, L_denum, FRACT_BITS);
556 
557   if (sign) {
558     div = -div;
559   }
560 
561   return div;
562 }
563 #endif /* FUNCTION_fDivNormSigned */
564 
565 #ifndef FUNCTION_fDivNormHighPrec
fDivNormHighPrec(FIXP_DBL num,FIXP_DBL denom,INT * result_e)566 FIXP_DBL fDivNormHighPrec(FIXP_DBL num, FIXP_DBL denom, INT *result_e) {
567   FIXP_DBL div;
568   INT norm_num, norm_den;
569 
570   FDK_ASSERT(num >= (FIXP_DBL)0);
571   FDK_ASSERT(denom > (FIXP_DBL)0);
572 
573   if (num == (FIXP_DBL)0) {
574     *result_e = 0;
575     return ((FIXP_DBL)0);
576   }
577 
578   norm_num = CountLeadingBits(num);
579   num = num << norm_num;
580   num = num >> 1;
581   *result_e = -norm_num + 1;
582 
583   norm_den = CountLeadingBits(denom);
584   denom = denom << norm_den;
585   *result_e -= -norm_den;
586 
587   div = schur_div(num, denom, 31);
588   return div;
589 }
590 #endif /* !FUNCTION_fDivNormHighPrec */
591 
592 #ifndef FUNCTION_fPow
f2Pow(const FIXP_DBL exp_m,const INT exp_e,INT * result_e)593 FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e, INT *result_e) {
594   FIXP_DBL frac_part, result_m;
595   INT int_part;
596 
597   if (exp_e > 0) {
598     INT exp_bits = DFRACT_BITS - 1 - exp_e;
599     int_part = exp_m >> exp_bits;
600     frac_part = exp_m - (FIXP_DBL)(int_part << exp_bits);
601     frac_part = frac_part << exp_e;
602   } else {
603     int_part = 0;
604     frac_part = exp_m >> -exp_e;
605   }
606 
607   /* Best accuracy is around 0, so try to get there with the fractional part. */
608   if (frac_part > FL2FXCONST_DBL(0.5f)) {
609     int_part = int_part + 1;
610     frac_part = frac_part + FL2FXCONST_DBL(-1.0f);
611   }
612   if (frac_part < FL2FXCONST_DBL(-0.5f)) {
613     int_part = int_part - 1;
614     frac_part = -(FL2FXCONST_DBL(-1.0f) - frac_part);
615   }
616 
617   /* "+ 1" compensates fMultAddDiv2() of the polynomial evaluation below. */
618   *result_e = int_part + 1;
619 
620   /* Evaluate taylor polynomial which approximates 2^x */
621   {
622     FIXP_DBL p;
623 
624     /* result_m ~= 2^frac_part */
625     p = frac_part;
626     /* First taylor series coefficient a_0 = 1.0, scaled by 0.5 due to
627      * fMultDiv2(). */
628     result_m = FL2FXCONST_DBL(1.0f / 2.0f);
629     for (INT i = 0; i < POW2_PRECISION; i++) {
630       /* next taylor series term: a_i * x^i, x=0 */
631       result_m = fMultAddDiv2(result_m, pow2Coeff[i], p);
632       p = fMult(p, frac_part);
633     }
634   }
635   return result_m;
636 }
637 
f2Pow(const FIXP_DBL exp_m,const INT exp_e)638 FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e) {
639   FIXP_DBL result_m;
640   INT result_e;
641 
642   result_m = f2Pow(exp_m, exp_e, &result_e);
643   result_e = fixMin(DFRACT_BITS - 1, fixMax(-(DFRACT_BITS - 1), result_e));
644 
645   return scaleValue(result_m, result_e);
646 }
647 
fPow(FIXP_DBL base_m,INT base_e,FIXP_DBL exp_m,INT exp_e,INT * result_e)648 FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
649               INT *result_e) {
650   INT ans_lg2_e, baselg2_e;
651   FIXP_DBL base_lg2, ans_lg2, result;
652 
653   /* Calc log2 of base */
654   base_lg2 = fLog2(base_m, base_e, &baselg2_e);
655 
656   /* Prepare exp */
657   {
658     INT leadingBits;
659 
660     leadingBits = CountLeadingBits(fAbs(exp_m));
661     exp_m = exp_m << leadingBits;
662     exp_e -= leadingBits;
663   }
664 
665   /* Calc base pow exp */
666   ans_lg2 = fMult(base_lg2, exp_m);
667   ans_lg2_e = exp_e + baselg2_e;
668 
669   /* Calc antilog */
670   result = f2Pow(ans_lg2, ans_lg2_e, result_e);
671 
672   return result;
673 }
674 
fLdPow(FIXP_DBL baseLd_m,INT baseLd_e,FIXP_DBL exp_m,INT exp_e,INT * result_e)675 FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e,
676                 INT *result_e) {
677   INT ans_lg2_e;
678   FIXP_DBL ans_lg2, result;
679 
680   /* Prepare exp */
681   {
682     INT leadingBits;
683 
684     leadingBits = CountLeadingBits(fAbs(exp_m));
685     exp_m = exp_m << leadingBits;
686     exp_e -= leadingBits;
687   }
688 
689   /* Calc base pow exp */
690   ans_lg2 = fMult(baseLd_m, exp_m);
691   ans_lg2_e = exp_e + baseLd_e;
692 
693   /* Calc antilog */
694   result = f2Pow(ans_lg2, ans_lg2_e, result_e);
695 
696   return result;
697 }
698 
fLdPow(FIXP_DBL baseLd_m,INT baseLd_e,FIXP_DBL exp_m,INT exp_e)699 FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e) {
700   FIXP_DBL result_m;
701   int result_e;
702 
703   result_m = fLdPow(baseLd_m, baseLd_e, exp_m, exp_e, &result_e);
704 
705   return SATURATE_SHIFT(result_m, -result_e, DFRACT_BITS);
706 }
707 
fPowInt(FIXP_DBL base_m,INT base_e,INT exp,INT * pResult_e)708 FIXP_DBL fPowInt(FIXP_DBL base_m, INT base_e, INT exp, INT *pResult_e) {
709   FIXP_DBL result;
710 
711   if (exp != 0) {
712     INT result_e = 0;
713 
714     if (base_m != (FIXP_DBL)0) {
715       {
716         INT leadingBits;
717         leadingBits = CountLeadingBits(base_m);
718         base_m <<= leadingBits;
719         base_e -= leadingBits;
720       }
721 
722       result = base_m;
723 
724       {
725         int i;
726         for (i = 1; i < fAbs(exp); i++) {
727           result = fMult(result, base_m);
728         }
729       }
730 
731       if (exp < 0) {
732         /* 1.0 / ans */
733         result = fDivNorm(FL2FXCONST_DBL(0.5f), result, &result_e);
734         result_e++;
735       } else {
736         int ansScale = CountLeadingBits(result);
737         result <<= ansScale;
738         result_e -= ansScale;
739       }
740 
741       result_e += exp * base_e;
742 
743     } else {
744       result = (FIXP_DBL)0;
745     }
746     *pResult_e = result_e;
747   } else {
748     result = FL2FXCONST_DBL(0.5f);
749     *pResult_e = 1;
750   }
751 
752   return result;
753 }
754 #endif /* FUNCTION_fPow */
755 
756 #ifndef FUNCTION_fLog2
CalcLog2(FIXP_DBL base_m,INT base_e,INT * result_e)757 FIXP_DBL CalcLog2(FIXP_DBL base_m, INT base_e, INT *result_e) {
758   return fLog2(base_m, base_e, result_e);
759 }
760 #endif /* FUNCTION_fLog2 */
761 
fixp_floorToInt(FIXP_DBL f_inp,INT sf)762 INT fixp_floorToInt(FIXP_DBL f_inp, INT sf) {
763   FDK_ASSERT(sf >= 0);
764   INT floorInt = (INT)(f_inp >> ((DFRACT_BITS - 1) - sf));
765   return floorInt;
766 }
767 
fixp_floor(FIXP_DBL f_inp,INT sf)768 FIXP_DBL fixp_floor(FIXP_DBL f_inp, INT sf) {
769   FDK_ASSERT(sf >= 0);
770   INT floorInt = fixp_floorToInt(f_inp, sf);
771   FIXP_DBL f_floor = (FIXP_DBL)(floorInt << ((DFRACT_BITS - 1) - sf));
772   return f_floor;
773 }
774 
fixp_ceilToInt(FIXP_DBL f_inp,INT sf)775 INT fixp_ceilToInt(FIXP_DBL f_inp, INT sf)  // sf  mantissaBits left of dot
776 {
777   FDK_ASSERT(sf >= 0);
778   INT sx = (DFRACT_BITS - 1) - sf;  // sx  mantissaBits right of dot
779   INT inpINT = (INT)f_inp;
780 
781   INT mask = (0x1 << sx) - 1;
782   INT ceilInt = (INT)(f_inp >> sx);
783 
784   if (inpINT & mask) {
785     ceilInt++;  // increment only, if there is at least one set mantissaBit
786                 // right of dot [in inpINT]
787   }
788 
789   return ceilInt;
790 }
791 
fixp_ceil(FIXP_DBL f_inp,INT sf)792 FIXP_DBL fixp_ceil(FIXP_DBL f_inp, INT sf) {
793   FDK_ASSERT(sf >= 0);
794   INT sx = (DFRACT_BITS - 1) - sf;
795   INT ceilInt = fixp_ceilToInt(f_inp, sf);
796   ULONG mask = (ULONG)0x1 << (DFRACT_BITS - 1);  // 0x80000000
797   ceilInt = ceilInt
798             << sx;  // no fract warn bec. shift into saturation done on int side
799 
800   if ((f_inp > FL2FXCONST_DBL(0.0f)) && (ceilInt & mask)) {
801     --ceilInt;
802   }
803   FIXP_DBL f_ceil = (FIXP_DBL)ceilInt;
804 
805   return f_ceil;
806 }
807 
808 /*****************************************************************************
809    fixp_truncateToInt()
810      Just remove the fractional part which is located right of decimal point
811      Same as which is done when a float is casted to (INT) :
812      result_INTtype = (INT)b_floatTypeInput;
813 
814    returns INT
815 *****************************************************************************/
fixp_truncateToInt(FIXP_DBL f_inp,INT sf)816 INT fixp_truncateToInt(FIXP_DBL f_inp, INT sf)  // sf  mantissaBits left  of dot
817                                                 // (without sign)  e.g. at width
818                                                 // 32 this would be [sign]7.
819                                                 // supposed sf equals 8.
820 {
821   FDK_ASSERT(sf >= 0);
822   INT sx = (DFRACT_BITS - 1) - sf;  // sx  mantissaBits right of dot
823                                     // at width 32 this would be        .24
824                                     // supposed sf equals 8.
825   INT fbaccu = (INT)f_inp;
826   INT mask = (0x1 << sx);
827 
828   if ((fbaccu < 0) && (fbaccu & (mask - 1))) {
829     fbaccu = fbaccu + mask;
830   }
831 
832   fbaccu = fbaccu >> sx;
833   return fbaccu;
834 }
835 
836 /*****************************************************************************
837    fixp_truncate()
838      Just remove the fractional part which is located right of decimal point
839 
840    returns FIXP_DBL
841 *****************************************************************************/
fixp_truncate(FIXP_DBL f_inp,INT sf)842 FIXP_DBL fixp_truncate(FIXP_DBL f_inp, INT sf) {
843   FDK_ASSERT(sf >= 0);
844   INT truncateInt = fixp_truncateToInt(f_inp, sf);
845   FIXP_DBL f_truncate = (FIXP_DBL)(truncateInt << ((DFRACT_BITS - 1) - sf));
846   return f_truncate;
847 }
848 
849 /*****************************************************************************
850   fixp_roundToInt()
851     round [typical rounding]
852 
853     See fct roundRef() [which is the reference]
854   returns INT
855 *****************************************************************************/
fixp_roundToInt(FIXP_DBL f_inp,INT sf)856 INT fixp_roundToInt(FIXP_DBL f_inp, INT sf) {
857   FDK_ASSERT(sf >= 0);
858   INT sx = DFRACT_BITS - 1 - sf;
859   INT inp = (INT)f_inp;
860   INT mask1 = (0x1 << (sx - 1));
861   INT mask2 = (0x1 << (sx)) - 1;
862   INT mask3 = 0x7FFFFFFF;
863   INT iam = inp & mask2;
864   INT rnd;
865 
866   if ((inp < 0) && !(iam == mask1))
867     rnd = inp + mask1;
868   else if ((inp > 0) && !(inp == mask3))
869     rnd = inp + mask1;
870   else
871     rnd = inp;
872 
873   rnd = rnd >> sx;
874 
875   if (inp == mask3) rnd++;
876 
877   return rnd;
878 }
879 
880 /*****************************************************************************
881   fixp_round()
882     round [typical rounding]
883 
884     See fct roundRef() [which is the reference]
885   returns FIXP_DBL
886 *****************************************************************************/
fixp_round(FIXP_DBL f_inp,INT sf)887 FIXP_DBL fixp_round(FIXP_DBL f_inp, INT sf) {
888   FDK_ASSERT(sf >= 0);
889   INT sx = DFRACT_BITS - 1 - sf;
890   INT r = fixp_roundToInt(f_inp, sf);
891   ULONG mask = (ULONG)0x1 << (DFRACT_BITS - 1);  // 0x80000000
892   r = r << sx;
893 
894   if ((f_inp > FL2FXCONST_DBL(0.0f)) && (r & mask)) {
895     --r;
896   }
897 
898   FIXP_DBL f_round = (FIXP_DBL)r;
899   return f_round;
900 }
901