Coverage Report

Created: 2025-10-28 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aac/libFDK/src/fixpoint_math.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4
© Copyright  1995 - 2020 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
117
0
void LdDataVector(FIXP_DBL *srcVector, FIXP_DBL *destVector, INT n) {
118
0
  INT i;
119
0
  for (i = 0; i < n; i++) {
120
0
    destVector[i] = fLog2(srcVector[i], 0);
121
0
  }
122
0
}
123
124
#define MAX_POW2_PRECISION 8
125
#ifndef SINETABLE_16BIT
126
#define POW2_PRECISION MAX_POW2_PRECISION
127
#else
128
84.1M
#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
1.37M
  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
372
0
void InitLdInt() { /* nothing to do! Use preinitialized logarithm table */
373
0
}
374
375
#if (LD_INT_TAB_LEN != 0)
376
377
LNK_SECTION_CODE_L1
378
1.37M
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
1.37M
  FDK_ASSERT((LD_INT_TAB_LEN > 0) &&
383
1.37M
             ((FIXP_DBL)ldIntCoeff[0] ==
384
1.37M
              (FIXP_DBL)0x80000001)); /* tab has to be initialized */
385
386
1.37M
  if ((i > 0) && (i < LD_INT_TAB_LEN))
387
1.37M
    return ldIntCoeff[i];
388
0
  else {
389
0
    return (0);
390
0
  }
391
1.37M
}
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
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
427
12.5M
FIXP_DBL fMultNorm(FIXP_DBL f1, FIXP_DBL f2, INT *result_e) {
428
12.5M
  INT product = 0;
429
12.5M
  INT norm_f1, norm_f2;
430
431
12.5M
  if ((f1 == (FIXP_DBL)0) || (f2 == (FIXP_DBL)0)) {
432
1.66M
    *result_e = 0;
433
1.66M
    return (FIXP_DBL)0;
434
1.66M
  }
435
10.9M
  norm_f1 = CountLeadingBits(f1);
436
10.9M
  f1 = f1 << norm_f1;
437
10.9M
  norm_f2 = CountLeadingBits(f2);
438
10.9M
  f2 = f2 << norm_f2;
439
440
10.9M
  if ((f1 == (FIXP_DBL)MINVAL_DBL) && (f2 == (FIXP_DBL)MINVAL_DBL)) {
441
0
    product = -((FIXP_DBL)MINVAL_DBL >> 1);
442
0
    *result_e = -(norm_f1 + norm_f2 - 1);
443
10.9M
  } else {
444
10.9M
    product = fMult(f1, f2);
445
10.9M
    *result_e = -(norm_f1 + norm_f2);
446
10.9M
  }
447
448
10.9M
  return (FIXP_DBL)product;
449
12.5M
}
450
#endif
451
452
#ifndef FUNCTION_fDivNorm
453
314M
FIXP_DBL fDivNorm(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e) {
454
314M
  FIXP_DBL div;
455
314M
  INT norm_num, norm_den;
456
457
314M
  FDK_ASSERT(L_num >= (FIXP_DBL)0);
458
314M
  FDK_ASSERT(L_denum > (FIXP_DBL)0);
459
460
314M
  if (L_num == (FIXP_DBL)0) {
461
707k
    *result_e = 0;
462
707k
    return ((FIXP_DBL)0);
463
707k
  }
464
465
314M
  norm_num = CountLeadingBits(L_num);
466
314M
  L_num = L_num << norm_num;
467
314M
  L_num = L_num >> 1;
468
314M
  *result_e = -norm_num + 1;
469
470
314M
  norm_den = CountLeadingBits(L_denum);
471
314M
  L_denum = L_denum << norm_den;
472
314M
  *result_e -= -norm_den;
473
474
314M
  div = schur_div(L_num, L_denum, FRACT_BITS);
475
476
314M
  return div;
477
314M
}
478
#endif /* !FUNCTION_fDivNorm */
479
480
#ifndef FUNCTION_fDivNorm
481
235M
FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom) {
482
235M
  INT e;
483
235M
  FIXP_DBL res;
484
485
235M
  FDK_ASSERT(denom >= num);
486
487
235M
  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
235M
  if (res == (FIXP_DBL)(1 << (DFRACT_BITS - 2)) && e == 1) {
492
255k
    res = (FIXP_DBL)MAXVAL_DBL;
493
235M
  } else {
494
235M
    res = scaleValue(res, e);
495
235M
  }
496
497
235M
  return res;
498
235M
}
499
#endif /* !FUNCTION_fDivNorm */
500
501
#ifndef FUNCTION_fDivNormSigned
502
0
FIXP_DBL fDivNormSigned(FIXP_DBL num, FIXP_DBL denom) {
503
0
  INT e;
504
0
  FIXP_DBL res;
505
0
  int sign;
506
507
0
  if (denom == (FIXP_DBL)0) {
508
0
    return (FIXP_DBL)MAXVAL_DBL;
509
0
  }
510
511
0
  sign = ((num >= (FIXP_DBL)0) != (denom >= (FIXP_DBL)0));
512
0
  res = fDivNormSigned(num, denom, &e);
513
514
  /* Saturate since we must output a value with exponent 0 */
515
0
  if ((e > 0) && (fAbs(res) >= FL2FXCONST_DBL(0.5))) {
516
0
    if (sign) {
517
0
      res = (FIXP_DBL)MINVAL_DBL;
518
0
    } else {
519
0
      res = (FIXP_DBL)MAXVAL_DBL;
520
0
    }
521
0
  } else {
522
0
    res = scaleValue(res, e);
523
0
  }
524
525
0
  return res;
526
0
}
527
281k
FIXP_DBL fDivNormSigned(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e) {
528
281k
  FIXP_DBL div;
529
281k
  INT norm_num, norm_den;
530
281k
  int sign;
531
532
281k
  sign = ((L_num >= (FIXP_DBL)0) != (L_denum >= (FIXP_DBL)0));
533
534
281k
  if (L_num == (FIXP_DBL)0) {
535
8.08k
    *result_e = 0;
536
8.08k
    return ((FIXP_DBL)0);
537
8.08k
  }
538
273k
  if (L_denum == (FIXP_DBL)0) {
539
0
    *result_e = 14;
540
0
    return ((FIXP_DBL)MAXVAL_DBL);
541
0
  }
542
543
273k
  norm_num = CountLeadingBits(L_num);
544
273k
  L_num = L_num << norm_num;
545
273k
  L_num = L_num >> 2;
546
273k
  L_num = fAbs(L_num);
547
273k
  *result_e = -norm_num + 1;
548
549
273k
  norm_den = CountLeadingBits(L_denum);
550
273k
  L_denum = L_denum << norm_den;
551
273k
  L_denum = L_denum >> 1;
552
273k
  L_denum = fAbs(L_denum);
553
273k
  *result_e -= -norm_den;
554
555
273k
  div = schur_div(L_num, L_denum, FRACT_BITS);
556
557
273k
  if (sign) {
558
73.8k
    div = -div;
559
73.8k
  }
560
561
273k
  return div;
562
273k
}
563
#endif /* FUNCTION_fDivNormSigned */
564
565
#ifndef FUNCTION_fDivNormHighPrec
566
393k
FIXP_DBL fDivNormHighPrec(FIXP_DBL num, FIXP_DBL denom, INT *result_e) {
567
393k
  FIXP_DBL div;
568
393k
  INT norm_num, norm_den;
569
570
393k
  FDK_ASSERT(num >= (FIXP_DBL)0);
571
393k
  FDK_ASSERT(denom > (FIXP_DBL)0);
572
573
393k
  if (num == (FIXP_DBL)0) {
574
0
    *result_e = 0;
575
0
    return ((FIXP_DBL)0);
576
0
  }
577
578
393k
  norm_num = CountLeadingBits(num);
579
393k
  num = num << norm_num;
580
393k
  num = num >> 1;
581
393k
  *result_e = -norm_num + 1;
582
583
393k
  norm_den = CountLeadingBits(denom);
584
393k
  denom = denom << norm_den;
585
393k
  *result_e -= -norm_den;
586
587
393k
  div = schur_div(num, denom, 31);
588
393k
  return div;
589
393k
}
590
#endif /* !FUNCTION_fDivNormHighPrec */
591
592
#ifndef FUNCTION_fPow
593
14.0M
FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e, INT *result_e) {
594
14.0M
  FIXP_DBL frac_part, result_m;
595
14.0M
  INT int_part;
596
597
14.0M
  if (exp_e > 0) {
598
12.9M
    INT exp_bits = DFRACT_BITS - 1 - exp_e;
599
12.9M
    int_part = exp_m >> exp_bits;
600
12.9M
    frac_part = exp_m - (FIXP_DBL)(int_part << exp_bits);
601
12.9M
    frac_part = frac_part << exp_e;
602
12.9M
  } else {
603
1.11M
    int_part = 0;
604
1.11M
    frac_part = exp_m >> -exp_e;
605
1.11M
  }
606
607
  /* Best accuracy is around 0, so try to get there with the fractional part. */
608
14.0M
  if (frac_part > FL2FXCONST_DBL(0.5f)) {
609
7.05M
    int_part = int_part + 1;
610
7.05M
    frac_part = frac_part + FL2FXCONST_DBL(-1.0f);
611
7.05M
  }
612
14.0M
  if (frac_part < FL2FXCONST_DBL(-0.5f)) {
613
4.00k
    int_part = int_part - 1;
614
4.00k
    frac_part = -(FL2FXCONST_DBL(-1.0f) - frac_part);
615
4.00k
  }
616
617
  /* "+ 1" compensates fMultAddDiv2() of the polynomial evaluation below. */
618
14.0M
  *result_e = int_part + 1;
619
620
  /* Evaluate taylor polynomial which approximates 2^x */
621
14.0M
  {
622
14.0M
    FIXP_DBL p;
623
624
    /* result_m ~= 2^frac_part */
625
14.0M
    p = frac_part;
626
    /* First taylor series coefficient a_0 = 1.0, scaled by 0.5 due to
627
     * fMultDiv2(). */
628
14.0M
    result_m = FL2FXCONST_DBL(1.0f / 2.0f);
629
84.1M
    for (INT i = 0; i < POW2_PRECISION; i++) {
630
      /* next taylor series term: a_i * x^i, x=0 */
631
70.0M
      result_m = fMultAddDiv2(result_m, pow2Coeff[i], p);
632
70.0M
      p = fMult(p, frac_part);
633
70.0M
    }
634
14.0M
  }
635
14.0M
  return result_m;
636
14.0M
}
637
638
0
FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e) {
639
0
  FIXP_DBL result_m;
640
0
  INT result_e;
641
642
0
  result_m = f2Pow(exp_m, exp_e, &result_e);
643
0
  result_e = fixMin(DFRACT_BITS - 1, fixMax(-(DFRACT_BITS - 1), result_e));
644
645
0
  return scaleValue(result_m, result_e);
646
0
}
647
648
FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
649
821k
              INT *result_e) {
650
821k
  INT ans_lg2_e, baselg2_e;
651
821k
  FIXP_DBL base_lg2, ans_lg2, result;
652
653
821k
  if (base_m <= (FIXP_DBL)0) {
654
0
    result = (FIXP_DBL)0;
655
0
    *result_e = 0;
656
0
    return result;
657
0
  }
658
659
  /* Calc log2 of base */
660
821k
  base_lg2 = fLog2(base_m, base_e, &baselg2_e);
661
662
  /* Prepare exp */
663
821k
  {
664
821k
    INT leadingBits;
665
666
821k
    leadingBits = CountLeadingBits(fAbs(exp_m));
667
821k
    exp_m = exp_m << leadingBits;
668
821k
    exp_e -= leadingBits;
669
821k
  }
670
671
  /* Calc base pow exp */
672
821k
  ans_lg2 = fMult(base_lg2, exp_m);
673
821k
  ans_lg2_e = exp_e + baselg2_e;
674
675
  /* Calc antilog */
676
821k
  result = f2Pow(ans_lg2, ans_lg2_e, result_e);
677
678
821k
  return result;
679
821k
}
680
681
FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e,
682
488k
                INT *result_e) {
683
488k
  INT ans_lg2_e;
684
488k
  FIXP_DBL ans_lg2, result;
685
686
  /* Prepare exp */
687
488k
  {
688
488k
    INT leadingBits;
689
690
488k
    leadingBits = CountLeadingBits(fAbs(exp_m));
691
488k
    exp_m = exp_m << leadingBits;
692
488k
    exp_e -= leadingBits;
693
488k
  }
694
695
  /* Calc base pow exp */
696
488k
  ans_lg2 = fMult(baseLd_m, exp_m);
697
488k
  ans_lg2_e = exp_e + baseLd_e;
698
699
  /* Calc antilog */
700
488k
  result = f2Pow(ans_lg2, ans_lg2_e, result_e);
701
702
488k
  return result;
703
488k
}
704
705
0
FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e) {
706
0
  FIXP_DBL result_m;
707
0
  int result_e;
708
709
0
  result_m = fLdPow(baseLd_m, baseLd_e, exp_m, exp_e, &result_e);
710
711
0
  return SATURATE_SHIFT(result_m, -result_e, DFRACT_BITS);
712
0
}
713
714
4.13k
FIXP_DBL fPowInt(FIXP_DBL base_m, INT base_e, INT exp, INT *pResult_e) {
715
4.13k
  FIXP_DBL result;
716
717
4.13k
  if (exp != 0) {
718
1.00k
    INT result_e = 0;
719
720
1.00k
    if (base_m != (FIXP_DBL)0) {
721
1.00k
      {
722
1.00k
        INT leadingBits;
723
1.00k
        leadingBits = CountLeadingBits(base_m);
724
1.00k
        base_m <<= leadingBits;
725
1.00k
        base_e -= leadingBits;
726
1.00k
      }
727
728
1.00k
      result = base_m;
729
730
1.00k
      {
731
1.00k
        int i;
732
5.76k
        for (i = 1; i < fAbs(exp); i++) {
733
4.76k
          result = fMult(result, base_m);
734
4.76k
        }
735
1.00k
      }
736
737
1.00k
      if (exp < 0) {
738
        /* 1.0 / ans */
739
0
        result = fDivNorm(FL2FXCONST_DBL(0.5f), result, &result_e);
740
0
        result_e++;
741
1.00k
      } else {
742
1.00k
        int ansScale = CountLeadingBits(result);
743
1.00k
        result <<= ansScale;
744
1.00k
        result_e -= ansScale;
745
1.00k
      }
746
747
1.00k
      result_e += exp * base_e;
748
749
1.00k
    } else {
750
0
      result = (FIXP_DBL)0;
751
0
    }
752
1.00k
    *pResult_e = result_e;
753
3.12k
  } else {
754
3.12k
    result = FL2FXCONST_DBL(0.5f);
755
3.12k
    *pResult_e = 1;
756
3.12k
  }
757
758
4.13k
  return result;
759
4.13k
}
760
#endif /* FUNCTION_fPow */
761
762
#ifndef FUNCTION_fLog2
763
4.13M
FIXP_DBL CalcLog2(FIXP_DBL base_m, INT base_e, INT *result_e) {
764
4.13M
  return fLog2(base_m, base_e, result_e);
765
4.13M
}
766
#endif /* FUNCTION_fLog2 */
767
768
0
INT fixp_floorToInt(FIXP_DBL f_inp, INT sf) {
769
0
  FDK_ASSERT(sf >= 0);
770
0
  INT floorInt = (INT)(f_inp >> ((DFRACT_BITS - 1) - sf));
771
0
  return floorInt;
772
0
}
773
774
0
FIXP_DBL fixp_floor(FIXP_DBL f_inp, INT sf) {
775
0
  FDK_ASSERT(sf >= 0);
776
0
  INT floorInt = fixp_floorToInt(f_inp, sf);
777
0
  FIXP_DBL f_floor = (FIXP_DBL)(floorInt << ((DFRACT_BITS - 1) - sf));
778
0
  return f_floor;
779
0
}
780
781
INT fixp_ceilToInt(FIXP_DBL f_inp, INT sf)  // sf  mantissaBits left of dot
782
0
{
783
0
  FDK_ASSERT(sf >= 0);
784
0
  INT sx = (DFRACT_BITS - 1) - sf;  // sx  mantissaBits right of dot
785
0
  INT inpINT = (INT)f_inp;
786
787
0
  INT mask = (0x1 << sx) - 1;
788
0
  INT ceilInt = (INT)(f_inp >> sx);
789
790
0
  if (inpINT & mask) {
791
0
    ceilInt++;  // increment only, if there is at least one set mantissaBit
792
                // right of dot [in inpINT]
793
0
  }
794
795
0
  return ceilInt;
796
0
}
797
798
0
FIXP_DBL fixp_ceil(FIXP_DBL f_inp, INT sf) {
799
0
  FDK_ASSERT(sf >= 0);
800
0
  INT sx = (DFRACT_BITS - 1) - sf;
801
0
  INT ceilInt = fixp_ceilToInt(f_inp, sf);
802
0
  ULONG mask = (ULONG)0x1 << (DFRACT_BITS - 1);  // 0x80000000
803
0
  ceilInt = ceilInt
804
0
            << sx;  // no fract warn bec. shift into saturation done on int side
805
806
0
  if ((f_inp > FL2FXCONST_DBL(0.0f)) && (ceilInt & mask)) {
807
0
    --ceilInt;
808
0
  }
809
0
  FIXP_DBL f_ceil = (FIXP_DBL)ceilInt;
810
811
0
  return f_ceil;
812
0
}
813
814
/*****************************************************************************
815
   fixp_truncateToInt()
816
     Just remove the fractional part which is located right of decimal point
817
     Same as which is done when a float is casted to (INT) :
818
     result_INTtype = (INT)b_floatTypeInput;
819
820
   returns INT
821
*****************************************************************************/
822
INT fixp_truncateToInt(FIXP_DBL f_inp, INT sf)  // sf  mantissaBits left  of dot
823
                                                // (without sign)  e.g. at width
824
                                                // 32 this would be [sign]7.
825
                                                // supposed sf equals 8.
826
0
{
827
0
  FDK_ASSERT(sf >= 0);
828
0
  INT sx = (DFRACT_BITS - 1) - sf;  // sx  mantissaBits right of dot
829
                                    // at width 32 this would be        .24
830
                                    // supposed sf equals 8.
831
0
  INT fbaccu = (INT)f_inp;
832
0
  INT mask = (0x1 << sx);
833
834
0
  if ((fbaccu < 0) && (fbaccu & (mask - 1))) {
835
0
    fbaccu = fbaccu + mask;
836
0
  }
837
838
0
  fbaccu = fbaccu >> sx;
839
0
  return fbaccu;
840
0
}
841
842
/*****************************************************************************
843
   fixp_truncate()
844
     Just remove the fractional part which is located right of decimal point
845
846
   returns FIXP_DBL
847
*****************************************************************************/
848
0
FIXP_DBL fixp_truncate(FIXP_DBL f_inp, INT sf) {
849
0
  FDK_ASSERT(sf >= 0);
850
0
  INT truncateInt = fixp_truncateToInt(f_inp, sf);
851
0
  FIXP_DBL f_truncate = (FIXP_DBL)(truncateInt << ((DFRACT_BITS - 1) - sf));
852
0
  return f_truncate;
853
0
}
854
855
/*****************************************************************************
856
  fixp_roundToInt()
857
    round [typical rounding]
858
859
    See fct roundRef() [which is the reference]
860
  returns INT
861
*****************************************************************************/
862
0
INT fixp_roundToInt(FIXP_DBL f_inp, INT sf) {
863
0
  FDK_ASSERT(sf >= 0);
864
0
  INT sx = DFRACT_BITS - 1 - sf;
865
0
  INT inp = (INT)f_inp;
866
0
  INT mask1 = (0x1 << (sx - 1));
867
0
  INT mask2 = (0x1 << (sx)) - 1;
868
0
  INT mask3 = 0x7FFFFFFF;
869
0
  INT iam = inp & mask2;
870
0
  INT rnd;
871
872
0
  if ((inp < 0) && !(iam == mask1))
873
0
    rnd = inp + mask1;
874
0
  else if ((inp > 0) && !(inp == mask3))
875
0
    rnd = inp + mask1;
876
0
  else
877
0
    rnd = inp;
878
879
0
  rnd = rnd >> sx;
880
881
0
  if (inp == mask3) rnd++;
882
883
0
  return rnd;
884
0
}
885
886
/*****************************************************************************
887
  fixp_round()
888
    round [typical rounding]
889
890
    See fct roundRef() [which is the reference]
891
  returns FIXP_DBL
892
*****************************************************************************/
893
0
FIXP_DBL fixp_round(FIXP_DBL f_inp, INT sf) {
894
0
  FDK_ASSERT(sf >= 0);
895
0
  INT sx = DFRACT_BITS - 1 - sf;
896
0
  INT r = fixp_roundToInt(f_inp, sf);
897
0
  ULONG mask = (ULONG)0x1 << (DFRACT_BITS - 1);  // 0x80000000
898
0
  r = r << sx;
899
900
0
  if ((f_inp > FL2FXCONST_DBL(0.0f)) && (r & mask)) {
901
0
    --r;
902
0
  }
903
904
0
  FIXP_DBL f_round = (FIXP_DBL)r;
905
0
  return f_round;
906
0
}