1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2019 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 /**************************** SBR decoder library ******************************
96
97 Author(s): Oliver Moser, Manuel Jander, Matthias Hildenbrand
98
99 Description: QMF frequency pre-whitening for SBR.
100 In the documentation the terms "scale factor" and "exponent"
101 mean the same. Variables containing such information have
102 the suffix "_sf".
103
104 *******************************************************************************/
105
106 #include "HFgen_preFlat.h"
107
108 #define POLY_ORDER 3
109 #define MAXLOWBANDS 32
110 #define LOG10FAC 0.752574989159953f /* == 10/log2(10) * 2^-2 */
111 #define LOG10FAC_INV 0.664385618977472f /* == log2(10)/20 * 2^2 */
112
113 #define FIXP_CHB FIXP_SGL /* STB sinus Tab used in transformation */
114 #define CHC(a) (FX_DBL2FXCONST_SGL(a))
115 #define FX_CHB2FX_DBL(a) FX_SGL2FX_DBL(a)
116
117 typedef struct backsubst_data {
118 FIXP_CHB Lnorm1d[3]; /*!< Normalized L matrix */
119 SCHAR Lnorm1d_sf[3];
120 FIXP_CHB Lnormii
121 [3]; /*!< The diagonal data points [i][i] of the normalized L matrix */
122 SCHAR Lnormii_sf[3];
123 FIXP_CHB Bmul0
124 [4]; /*!< To normalize L*x=b, Bmul0 is what we need to multiply b with. */
125 SCHAR Bmul0_sf[4];
126 FIXP_CHB LnormInv1d[6]; /*!< Normalized inverted L matrix (L') */
127 SCHAR LnormInv1d_sf[6];
128 FIXP_CHB
129 Bmul1[4]; /*!< To normalize L'*x=b, Bmul1 is what we need to multiply b
130 with. */
131 SCHAR Bmul1_sf[4];
132 } backsubst_data;
133
134 /* for each element n do, f(n) = trunc(log2(n))+1 */
135 const UCHAR getLog2[32] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
136 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5};
137
138 /** \def BSD_IDX_OFFSET
139 *
140 * bsd[] begins at index 0 with data for numBands=5. The correct bsd[] is
141 * indexed like bsd[numBands-BSD_IDX_OFFSET].
142 */
143 #define BSD_IDX_OFFSET 5
144
145 #define N_NUMBANDS \
146 MAXLOWBANDS - BSD_IDX_OFFSET + \
147 1 /*!< Number of backsubst_data elements in bsd */
148
149 const backsubst_data bsd[N_NUMBANDS] = {
150 {
151 /* numBands=5 */
152 {CHC(0x66c85a52), CHC(0x4278e587), CHC(0x697dcaff)},
153 {-1, 0, 0},
154 {CHC(0x66a61789), CHC(0x5253b8e3), CHC(0x5addad81)},
155 {3, 4, 1},
156 {CHC(0x7525ee90), CHC(0x6e2a1210), CHC(0x6523bb40), CHC(0x59822ead)},
157 {-6, -4, -2, 0},
158 {CHC(0x609e4cad), CHC(0x59c7e312), CHC(0x681eecac), CHC(0x440ea893),
159 CHC(0x4a214bb3), CHC(0x53c345a1)},
160 {1, 0, -1, -1, -3, -5},
161 {CHC(0x7525ee90), CHC(0x58587936), CHC(0x410d0b38), CHC(0x7f1519d6)},
162 {-6, -1, 2, 0},
163 },
164 {
165 /* numBands=6 */
166 {CHC(0x68943285), CHC(0x4841d2c3), CHC(0x6a6214c7)},
167 {-1, 0, 0},
168 {CHC(0x63c5923e), CHC(0x4e906e18), CHC(0x6285af8a)},
169 {3, 4, 1},
170 {CHC(0x7263940b), CHC(0x424a69a5), CHC(0x4ae8383a), CHC(0x517b7730)},
171 {-7, -4, -2, 0},
172 {CHC(0x518aee5f), CHC(0x4823a096), CHC(0x43764a39), CHC(0x6e6faf23),
173 CHC(0x61bba44f), CHC(0x59d8b132)},
174 {1, 0, -1, -2, -4, -6},
175 {CHC(0x7263940b), CHC(0x6757bff2), CHC(0x5bf40fe0), CHC(0x7d6f4292)},
176 {-7, -2, 1, 0},
177 },
178 {
179 /* numBands=7 */
180 {CHC(0x699b4c3c), CHC(0x4b8b702f), CHC(0x6ae51a4f)},
181 {-1, 0, 0},
182 {CHC(0x623a7f49), CHC(0x4ccc91fc), CHC(0x68f048dd)},
183 {3, 4, 1},
184 {CHC(0x7e6ebe18), CHC(0x5701daf2), CHC(0x74a8198b), CHC(0x4b399aa1)},
185 {-8, -5, -3, 0},
186 {CHC(0x464a64a6), CHC(0x78e42633), CHC(0x5ee174ba), CHC(0x5d0008c8),
187 CHC(0x455cff0f), CHC(0x6b9100e7)},
188 {1, -1, -2, -2, -4, -7},
189 {CHC(0x7e6ebe18), CHC(0x42c52efe), CHC(0x45fe401f), CHC(0x7b5808ef)},
190 {-8, -2, 1, 0},
191 },
192 {
193 /* numBands=8 */
194 {CHC(0x6a3fd9b4), CHC(0x4d99823f), CHC(0x6b372a94)},
195 {-1, 0, 0},
196 {CHC(0x614c6ef7), CHC(0x4bd06699), CHC(0x6e59cfca)},
197 {3, 4, 1},
198 {CHC(0x4c389cc5), CHC(0x79686681), CHC(0x5e2544c2), CHC(0x46305b43)},
199 {-8, -6, -3, 0},
200 {CHC(0x7b4ca7c6), CHC(0x68270ac5), CHC(0x467c644c), CHC(0x505c1b0f),
201 CHC(0x67a14778), CHC(0x45801767)},
202 {0, -1, -2, -2, -5, -7},
203 {CHC(0x4c389cc5), CHC(0x5c499ceb), CHC(0x6f863c9f), CHC(0x79059bfc)},
204 {-8, -3, 0, 0},
205 },
206 {
207 /* numBands=9 */
208 {CHC(0x6aad9988), CHC(0x4ef8ac18), CHC(0x6b6df116)},
209 {-1, 0, 0},
210 {CHC(0x60b159b0), CHC(0x4b33f772), CHC(0x72f5573d)},
211 {3, 4, 1},
212 {CHC(0x6206cb18), CHC(0x58a7d8dc), CHC(0x4e0b2d0b), CHC(0x4207ad84)},
213 {-9, -6, -3, 0},
214 {CHC(0x6dadadae), CHC(0x5b8b2cfc), CHC(0x6cf61db2), CHC(0x46c3c90b),
215 CHC(0x506314ea), CHC(0x5f034acd)},
216 {0, -1, -3, -2, -5, -8},
217 {CHC(0x6206cb18), CHC(0x42f8b8de), CHC(0x5bb4776f), CHC(0x769acc79)},
218 {-9, -3, 0, 0},
219 },
220 {
221 /* numBands=10 */
222 {CHC(0x6afa7252), CHC(0x4feed3ed), CHC(0x6b94504d)},
223 {-1, 0, 0},
224 {CHC(0x60467899), CHC(0x4acbafba), CHC(0x76eb327f)},
225 {3, 4, 1},
226 {CHC(0x42415b15), CHC(0x431080da), CHC(0x420f1c32), CHC(0x7d0c1aeb)},
227 {-9, -6, -3, -1},
228 {CHC(0x62b2c7a4), CHC(0x51b040a6), CHC(0x56caddb4), CHC(0x7e74a2c8),
229 CHC(0x4030adf5), CHC(0x43d1dc4f)},
230 {0, -1, -3, -3, -5, -8},
231 {CHC(0x42415b15), CHC(0x64e299b3), CHC(0x4d33b5e8), CHC(0x742cee5f)},
232 {-9, -4, 0, 0},
233 },
234 {
235 /* numBands=11 */
236 {CHC(0x6b3258bb), CHC(0x50a21233), CHC(0x6bb03c19)},
237 {-1, 0, 0},
238 {CHC(0x5ff997c6), CHC(0x4a82706e), CHC(0x7a5aae36)},
239 {3, 4, 1},
240 {CHC(0x5d2fb4fb), CHC(0x685bddd8), CHC(0x71b5e983), CHC(0x7708c90b)},
241 {-10, -7, -4, -1},
242 {CHC(0x59aceea2), CHC(0x49c428a0), CHC(0x46ca5527), CHC(0x724be884),
243 CHC(0x68e586da), CHC(0x643485b6)},
244 {0, -1, -3, -3, -6, -9},
245 {CHC(0x5d2fb4fb), CHC(0x4e3fad1a), CHC(0x42310ba2), CHC(0x71c8b3ce)},
246 {-10, -4, 0, 0},
247 },
248 {
249 /* numBands=12 */
250 {CHC(0x6b5c4726), CHC(0x5128a4a8), CHC(0x6bc52ee1)},
251 {-1, 0, 0},
252 {CHC(0x5fc06618), CHC(0x4a4ce559), CHC(0x7d5c16e9)},
253 {3, 4, 1},
254 {CHC(0x43af8342), CHC(0x531533d3), CHC(0x633660a6), CHC(0x71ce6052)},
255 {-10, -7, -4, -1},
256 {CHC(0x522373d7), CHC(0x434150cb), CHC(0x75b58afc), CHC(0x68474f2d),
257 CHC(0x575348a5), CHC(0x4c20973f)},
258 {0, -1, -4, -3, -6, -9},
259 {CHC(0x43af8342), CHC(0x7c4d3d11), CHC(0x732e13db), CHC(0x6f756ac4)},
260 {-10, -5, -1, 0},
261 },
262 {
263 /* numBands=13 */
264 {CHC(0x6b7c8953), CHC(0x51903fcd), CHC(0x6bd54d2e)},
265 {-1, 0, 0},
266 {CHC(0x5f94abf0), CHC(0x4a2480fa), CHC(0x40013553)},
267 {3, 4, 2},
268 {CHC(0x6501236e), CHC(0x436b9c4e), CHC(0x578d7881), CHC(0x6d34f92e)},
269 {-11, -7, -4, -1},
270 {CHC(0x4bc0e2b2), CHC(0x7b9d12ac), CHC(0x636c1c1b), CHC(0x5fe15c2b),
271 CHC(0x49d54879), CHC(0x7662cfa5)},
272 {0, -2, -4, -3, -6, -10},
273 {CHC(0x6501236e), CHC(0x64b059fe), CHC(0x656d8359), CHC(0x6d370900)},
274 {-11, -5, -1, 0},
275 },
276 {
277 /* numBands=14 */
278 {CHC(0x6b95e276), CHC(0x51e1b637), CHC(0x6be1f7ed)},
279 {-1, 0, 0},
280 {CHC(0x5f727a1c), CHC(0x4a053e9c), CHC(0x412e528c)},
281 {3, 4, 2},
282 {CHC(0x4d178bd4), CHC(0x6f33b4e8), CHC(0x4e028f7f), CHC(0x691ee104)},
283 {-11, -8, -4, -1},
284 {CHC(0x46473d3f), CHC(0x725bd0a6), CHC(0x55199885), CHC(0x58bcc56b),
285 CHC(0x7e7e6288), CHC(0x5ddef6eb)},
286 {0, -2, -4, -3, -7, -10},
287 {CHC(0x4d178bd4), CHC(0x52ebd467), CHC(0x5a395a6e), CHC(0x6b0f724f)},
288 {-11, -5, -1, 0},
289 },
290 {
291 /* numBands=15 */
292 {CHC(0x6baa2a22), CHC(0x5222eb91), CHC(0x6bec1a86)},
293 {-1, 0, 0},
294 {CHC(0x5f57393b), CHC(0x49ec8934), CHC(0x423b5b58)},
295 {3, 4, 2},
296 {CHC(0x77fd2486), CHC(0x5cfbdf2c), CHC(0x46153bd1), CHC(0x65757ed9)},
297 {-12, -8, -4, -1},
298 {CHC(0x41888ee6), CHC(0x6a661db3), CHC(0x49abc8c8), CHC(0x52965848),
299 CHC(0x6d9301b7), CHC(0x4bb04721)},
300 {0, -2, -4, -3, -7, -10},
301 {CHC(0x77fd2486), CHC(0x45424c68), CHC(0x50f33cc6), CHC(0x68ff43f0)},
302 {-12, -5, -1, 0},
303 },
304 {
305 /* numBands=16 */
306 {CHC(0x6bbaa499), CHC(0x5257ed94), CHC(0x6bf456e4)},
307 {-1, 0, 0},
308 {CHC(0x5f412594), CHC(0x49d8a766), CHC(0x432d1dbd)},
309 {3, 4, 2},
310 {CHC(0x5ef5cfde), CHC(0x4eafcd2d), CHC(0x7ed36893), CHC(0x62274b45)},
311 {-12, -8, -5, -1},
312 {CHC(0x7ac438f5), CHC(0x637aab21), CHC(0x4067617a), CHC(0x4d3c6ec7),
313 CHC(0x5fd6e0dd), CHC(0x7bd5f024)},
314 {-1, -2, -4, -3, -7, -11},
315 {CHC(0x5ef5cfde), CHC(0x751d0d4f), CHC(0x492b3c41), CHC(0x67065409)},
316 {-12, -6, -1, 0},
317 },
318 {
319 /* numBands=17 */
320 {CHC(0x6bc836c9), CHC(0x5283997e), CHC(0x6bfb1f5e)},
321 {-1, 0, 0},
322 {CHC(0x5f2f02b6), CHC(0x49c868e9), CHC(0x44078151)},
323 {3, 4, 2},
324 {CHC(0x4c43b65a), CHC(0x4349dcf6), CHC(0x73799e2d), CHC(0x5f267274)},
325 {-12, -8, -5, -1},
326 {CHC(0x73726394), CHC(0x5d68511a), CHC(0x7191bbcc), CHC(0x48898c70),
327 CHC(0x548956e1), CHC(0x66981ce8)},
328 {-1, -2, -5, -3, -7, -11},
329 {CHC(0x4c43b65a), CHC(0x64131116), CHC(0x429028e2), CHC(0x65240211)},
330 {-12, -6, -1, 0},
331 },
332 {
333 /* numBands=18 */
334 {CHC(0x6bd3860d), CHC(0x52a80156), CHC(0x6c00c68d)},
335 {-1, 0, 0},
336 {CHC(0x5f1fed86), CHC(0x49baf636), CHC(0x44cdb9dc)},
337 {3, 4, 2},
338 {CHC(0x7c189389), CHC(0x742666d8), CHC(0x69b8c776), CHC(0x5c67e27d)},
339 {-13, -9, -5, -1},
340 {CHC(0x6cf1ea76), CHC(0x58095703), CHC(0x64e351a9), CHC(0x4460da90),
341 CHC(0x4b1f8083), CHC(0x55f2d3e1)},
342 {-1, -2, -5, -3, -7, -11},
343 {CHC(0x7c189389), CHC(0x5651792a), CHC(0x79cb9b3d), CHC(0x635769c0)},
344 {-13, -6, -2, 0},
345 },
346 {
347 /* numBands=19 */
348 {CHC(0x6bdd0c40), CHC(0x52c6abf6), CHC(0x6c058950)},
349 {-1, 0, 0},
350 {CHC(0x5f133f88), CHC(0x49afb305), CHC(0x45826d73)},
351 {3, 4, 2},
352 {CHC(0x6621a164), CHC(0x6512528e), CHC(0x61449fc8), CHC(0x59e2a0c0)},
353 {-13, -9, -5, -1},
354 {CHC(0x6721cadb), CHC(0x53404cd4), CHC(0x5a389e91), CHC(0x40abcbd2),
355 CHC(0x43332f01), CHC(0x48b82e46)},
356 {-1, -2, -5, -3, -7, -11},
357 {CHC(0x6621a164), CHC(0x4b12cc28), CHC(0x6ffd4df8), CHC(0x619f835e)},
358 {-13, -6, -2, 0},
359 },
360 {
361 /* numBands=20 */
362 {CHC(0x6be524c5), CHC(0x52e0beb3), CHC(0x6c099552)},
363 {-1, 0, 0},
364 {CHC(0x5f087c68), CHC(0x49a62bb5), CHC(0x4627d175)},
365 {3, 4, 2},
366 {CHC(0x54ec6afe), CHC(0x58991a42), CHC(0x59e23e8c), CHC(0x578f4ef4)},
367 {-13, -9, -5, -1},
368 {CHC(0x61e78f6f), CHC(0x4ef5e1e9), CHC(0x5129c3b8), CHC(0x7ab0f7b2),
369 CHC(0x78efb076), CHC(0x7c2567ea)},
370 {-1, -2, -5, -4, -8, -12},
371 {CHC(0x54ec6afe), CHC(0x41c7812c), CHC(0x676f6f8d), CHC(0x5ffb383f)},
372 {-13, -6, -2, 0},
373 },
374 {
375 /* numBands=21 */
376 {CHC(0x6bec1542), CHC(0x52f71929), CHC(0x6c0d0d5e)},
377 {-1, 0, 0},
378 {CHC(0x5eff45c5), CHC(0x499e092d), CHC(0x46bfc0c9)},
379 {3, 4, 2},
380 {CHC(0x47457a78), CHC(0x4e2d99b3), CHC(0x53637ea5), CHC(0x5567d0e9)},
381 {-13, -9, -5, -1},
382 {CHC(0x5d2dc61b), CHC(0x4b1760c8), CHC(0x4967cf39), CHC(0x74b113d8),
383 CHC(0x6d6676b6), CHC(0x6ad114e9)},
384 {-1, -2, -5, -4, -8, -12},
385 {CHC(0x47457a78), CHC(0x740accaa), CHC(0x5feb6609), CHC(0x5e696f95)},
386 {-13, -7, -2, 0},
387 },
388 {
389 /* numBands=22 */
390 {CHC(0x6bf21387), CHC(0x530a683c), CHC(0x6c100c59)},
391 {-1, 0, 0},
392 {CHC(0x5ef752ea), CHC(0x499708c6), CHC(0x474bcd1b)},
393 {3, 4, 2},
394 {CHC(0x78a21ab7), CHC(0x45658aec), CHC(0x4da3c4fe), CHC(0x5367094b)},
395 {-14, -9, -5, -1},
396 {CHC(0x58e2df6a), CHC(0x4795990e), CHC(0x42b5e0f7), CHC(0x6f408c64),
397 CHC(0x6370bebf), CHC(0x5c91ca85)},
398 {-1, -2, -5, -4, -8, -12},
399 {CHC(0x78a21ab7), CHC(0x66f951d6), CHC(0x594605bb), CHC(0x5ce91657)},
400 {-14, -7, -2, 0},
401 },
402 {
403 /* numBands=23 */
404 {CHC(0x6bf749b2), CHC(0x531b3348), CHC(0x6c12a750)},
405 {-1, 0, 0},
406 {CHC(0x5ef06b17), CHC(0x4990f6c9), CHC(0x47cd4c5b)},
407 {3, 4, 2},
408 {CHC(0x66dede36), CHC(0x7bdf90a9), CHC(0x4885b2b9), CHC(0x5188a6b7)},
409 {-14, -10, -5, -1},
410 {CHC(0x54f85812), CHC(0x446414ae), CHC(0x79c8d519), CHC(0x6a4c2f31),
411 CHC(0x5ac8325f), CHC(0x50bf9200)},
412 {-1, -2, -6, -4, -8, -12},
413 {CHC(0x66dede36), CHC(0x5be0d90e), CHC(0x535cc453), CHC(0x5b7923f0)},
414 {-14, -7, -2, 0},
415 },
416 {
417 /* numBands=24 */
418 {CHC(0x6bfbd91d), CHC(0x5329e580), CHC(0x6c14eeed)},
419 {-1, 0, 0},
420 {CHC(0x5eea6179), CHC(0x498baa90), CHC(0x4845635d)},
421 {3, 4, 2},
422 {CHC(0x58559b7e), CHC(0x6f1b231f), CHC(0x43f1789b), CHC(0x4fc8fcb8)},
423 {-14, -10, -5, -1},
424 {CHC(0x51621775), CHC(0x417881a3), CHC(0x6f9ba9b6), CHC(0x65c412b2),
425 CHC(0x53352c61), CHC(0x46db9caf)},
426 {-1, -2, -6, -4, -8, -12},
427 {CHC(0x58559b7e), CHC(0x52636003), CHC(0x4e13b316), CHC(0x5a189cdf)},
428 {-14, -7, -2, 0},
429 },
430 {
431 /* numBands=25 */
432 {CHC(0x6bffdc73), CHC(0x5336d4af), CHC(0x6c16f084)},
433 {-1, 0, 0},
434 {CHC(0x5ee51249), CHC(0x498703cc), CHC(0x48b50e4f)},
435 {3, 4, 2},
436 {CHC(0x4c5616cf), CHC(0x641b9fad), CHC(0x7fa735e0), CHC(0x4e24e57a)},
437 {-14, -10, -6, -1},
438 {CHC(0x4e15f47a), CHC(0x7d9481d6), CHC(0x66a82f8a), CHC(0x619ae971),
439 CHC(0x4c8b2f5f), CHC(0x7d09ec11)},
440 {-1, -3, -6, -4, -8, -13},
441 {CHC(0x4c5616cf), CHC(0x4a3770fb), CHC(0x495402de), CHC(0x58c693fa)},
442 {-14, -7, -2, 0},
443 },
444 {
445 /* numBands=26 */
446 {CHC(0x6c036943), CHC(0x53424625), CHC(0x6c18b6dc)},
447 {-1, 0, 0},
448 {CHC(0x5ee060aa), CHC(0x4982e88a), CHC(0x491d277f)},
449 {3, 4, 2},
450 {CHC(0x425ada5b), CHC(0x5a9368ac), CHC(0x78380a42), CHC(0x4c99aa05)},
451 {-14, -10, -6, -1},
452 {CHC(0x4b0b569c), CHC(0x78a420da), CHC(0x5ebdf203), CHC(0x5dc57e63),
453 CHC(0x46a650ff), CHC(0x6ee13fb8)},
454 {-1, -3, -6, -4, -8, -13},
455 {CHC(0x425ada5b), CHC(0x4323073c), CHC(0x450ae92b), CHC(0x57822ad5)},
456 {-14, -7, -2, 0},
457 },
458 {
459 /* numBands=27 */
460 {CHC(0x6c06911a), CHC(0x534c7261), CHC(0x6c1a4aba)},
461 {-1, 0, 0},
462 {CHC(0x5edc3524), CHC(0x497f43c0), CHC(0x497e6cd8)},
463 {3, 4, 2},
464 {CHC(0x73fb550e), CHC(0x5244894f), CHC(0x717aad78), CHC(0x4b24ef6c)},
465 {-15, -10, -6, -1},
466 {CHC(0x483aebe4), CHC(0x74139116), CHC(0x57b58037), CHC(0x5a3a4f3c),
467 CHC(0x416950fe), CHC(0x62c7f4f2)},
468 {-1, -3, -6, -4, -8, -13},
469 {CHC(0x73fb550e), CHC(0x79efb994), CHC(0x4128cab7), CHC(0x564a919a)},
470 {-15, -8, -2, 0},
471 },
472 {
473 /* numBands=28 */
474 {CHC(0x6c096264), CHC(0x535587cd), CHC(0x6c1bb355)},
475 {-1, 0, 0},
476 {CHC(0x5ed87c76), CHC(0x497c0439), CHC(0x49d98452)},
477 {3, 4, 2},
478 {CHC(0x65dec5bf), CHC(0x4afd1ba3), CHC(0x6b58b4b3), CHC(0x49c4a7b0)},
479 {-15, -10, -6, -1},
480 {CHC(0x459e6eb1), CHC(0x6fd850b7), CHC(0x516e7be9), CHC(0x56f13d05),
481 CHC(0x79785594), CHC(0x58617de7)},
482 {-1, -3, -6, -4, -9, -13},
483 {CHC(0x65dec5bf), CHC(0x6f2168aa), CHC(0x7b41310f), CHC(0x551f0692)},
484 {-15, -8, -3, 0},
485 },
486 {
487 /* numBands=29 */
488 {CHC(0x6c0be913), CHC(0x535dacd5), CHC(0x6c1cf6a3)},
489 {-1, 0, 0},
490 {CHC(0x5ed526b4), CHC(0x49791bc5), CHC(0x4a2eff99)},
491 {3, 4, 2},
492 {CHC(0x59e44afe), CHC(0x44949ada), CHC(0x65bf36f5), CHC(0x487705a0)},
493 {-15, -10, -6, -1},
494 {CHC(0x43307779), CHC(0x6be959c4), CHC(0x4bce2122), CHC(0x53e34d89),
495 CHC(0x7115ff82), CHC(0x4f6421a1)},
496 {-1, -3, -6, -4, -9, -13},
497 {CHC(0x59e44afe), CHC(0x659eab7d), CHC(0x74cea459), CHC(0x53fed574)},
498 {-15, -8, -3, 0},
499 },
500 {
501 /* numBands=30 */
502 {CHC(0x6c0e2f17), CHC(0x53650181), CHC(0x6c1e199d)},
503 {-1, 0, 0},
504 {CHC(0x5ed2269f), CHC(0x49767e9e), CHC(0x4a7f5f0b)},
505 {3, 4, 2},
506 {CHC(0x4faa4ae6), CHC(0x7dd3bf11), CHC(0x609e2732), CHC(0x473a72e9)},
507 {-15, -11, -6, -1},
508 {CHC(0x40ec57c6), CHC(0x683ee147), CHC(0x46be261d), CHC(0x510a7983),
509 CHC(0x698a84cb), CHC(0x4794a927)},
510 {-1, -3, -6, -4, -9, -13},
511 {CHC(0x4faa4ae6), CHC(0x5d3615ad), CHC(0x6ee74773), CHC(0x52e956a1)},
512 {-15, -8, -3, 0},
513 },
514 {
515 /* numBands=31 */
516 {CHC(0x6c103cc9), CHC(0x536ba0ac), CHC(0x6c1f2070)},
517 {-1, 0, 0},
518 {CHC(0x5ecf711e), CHC(0x497422ea), CHC(0x4acb1438)},
519 {3, 4, 2},
520 {CHC(0x46e322ad), CHC(0x73c32f3c), CHC(0x5be7d172), CHC(0x460d8800)},
521 {-15, -11, -6, -1},
522 {CHC(0x7d9bf8ad), CHC(0x64d22351), CHC(0x422bdc81), CHC(0x4e6184aa),
523 CHC(0x62ba2375), CHC(0x40c325de)},
524 {-2, -3, -6, -4, -9, -13},
525 {CHC(0x46e322ad), CHC(0x55bef2a3), CHC(0x697b3135), CHC(0x51ddee4d)},
526 {-15, -8, -3, 0},
527 },
528 {
529 // numBands=32
530 {CHC(0x6c121933), CHC(0x5371a104), CHC(0x6c200ea0)},
531 {-1, 0, 0},
532 {CHC(0x5eccfcd3), CHC(0x49720060), CHC(0x4b1283f0)},
533 {3, 4, 2},
534 {CHC(0x7ea12a52), CHC(0x6aca3303), CHC(0x579072bf), CHC(0x44ef056e)},
535 {-16, -11, -6, -1},
536 {CHC(0x79a3a9ab), CHC(0x619d38fc), CHC(0x7c0f0734), CHC(0x4be3dd5d),
537 CHC(0x5c8d7163), CHC(0x7591065f)},
538 {-2, -3, -7, -4, -9, -14},
539 {CHC(0x7ea12a52), CHC(0x4f1782a6), CHC(0x647cbcb2), CHC(0x50dc0bb1)},
540 {-16, -8, -3, 0},
541 },
542 };
543
544 /** \def SUM_SAFETY
545 *
546 * SUM_SAFTEY defines the bits needed to right-shift every summand in
547 * order to be overflow-safe. In the two backsubst functions we sum up 4
548 * values. Since one of which is definitely not MAXVAL_DBL (the L[x][y]),
549 * we spare just 2 safety bits instead of 3.
550 */
551 #define SUM_SAFETY 2
552
553 /**
554 * \brief Solves L*x=b via backsubstitution according to the following
555 * structure:
556 *
557 * x[0] = b[0];
558 * x[1] = (b[1] - x[0]) / L[1][1];
559 * x[2] = (b[2] - x[1]*L[2][1] - x[0]) / L[2][2];
560 * x[3] = (b[3] - x[2]*L[3][2] - x[1]*L[3][1] - x[0]) / L[3][3];
561 *
562 * \param[in] numBands SBR crossover band index
563 * \param[in] b the b in L*x=b (one-dimensional)
564 * \param[out] x output polynomial coefficients (mantissa)
565 * \param[out] x_sf exponents of x[]
566 */
backsubst_fw(const int numBands,const FIXP_DBL * const b,FIXP_DBL * RESTRICT x,int * RESTRICT x_sf)567 static void backsubst_fw(const int numBands, const FIXP_DBL *const b,
568 FIXP_DBL *RESTRICT x, int *RESTRICT x_sf) {
569 int i, k;
570 int m; /* the trip counter that indexes incrementally through Lnorm1d[] */
571
572 const FIXP_CHB *RESTRICT pLnorm1d = bsd[numBands - BSD_IDX_OFFSET].Lnorm1d;
573 const SCHAR *RESTRICT pLnorm1d_sf = bsd[numBands - BSD_IDX_OFFSET].Lnorm1d_sf;
574 const FIXP_CHB *RESTRICT pLnormii = bsd[numBands - BSD_IDX_OFFSET].Lnormii;
575 const SCHAR *RESTRICT pLnormii_sf = bsd[numBands - BSD_IDX_OFFSET].Lnormii_sf;
576
577 x[0] = b[0];
578
579 for (i = 1, m = 0; i <= POLY_ORDER; ++i) {
580 FIXP_DBL sum = b[i] >> SUM_SAFETY;
581 int sum_sf = x_sf[i];
582 for (k = i - 1; k > 0; --k, ++m) {
583 int e;
584 FIXP_DBL mult = fMultNorm(FX_CHB2FX_DBL(pLnorm1d[m]), x[k], &e);
585 int mult_sf = pLnorm1d_sf[m] + x_sf[k] + e;
586
587 /* check if the new summand mult has a different sf than the sum currently
588 * has */
589 int diff = mult_sf - sum_sf;
590
591 if (diff > 0) {
592 /* yes, and it requires the sum to be adjusted (scaled down) */
593 sum >>= diff;
594 sum_sf = mult_sf;
595 } else if (diff < 0) {
596 /* yes, but here mult needs to be scaled down */
597 mult >>= -diff;
598 }
599 sum -= (mult >> SUM_SAFETY);
600 }
601
602 /* - x[0] */
603 if (x_sf[0] > sum_sf) {
604 sum >>= (x_sf[0] - sum_sf);
605 sum_sf = x_sf[0];
606 }
607 sum -= (x[0] >> (sum_sf - x_sf[0] + SUM_SAFETY));
608
609 /* instead of the division /L[i][i], we multiply by the inverse */
610 int e;
611 x[i] = fMultNorm(sum, FX_CHB2FX_DBL(pLnormii[i - 1]), &e);
612 x_sf[i] = sum_sf + pLnormii_sf[i - 1] + e + SUM_SAFETY;
613 }
614 }
615
616 /**
617 * \brief Solves L*x=b via backsubstitution according to the following
618 * structure:
619 *
620 * x[3] = b[3];
621 * x[2] = b[2] - L[2][3]*x[3];
622 * x[1] = b[1] - L[1][2]*x[2] - L[1][3]*x[3];
623 * x[0] = b[0] - L[0][1]*x[1] - L[0][2]*x[2] - L[0][3]*x[3];
624 *
625 * \param[in] numBands SBR crossover band index
626 * \param[in] b the b in L*x=b (one-dimensional)
627 * \param[out] x solution vector
628 * \param[out] x_sf exponents of x[]
629 */
backsubst_bw(const int numBands,const FIXP_DBL * const b,FIXP_DBL * RESTRICT x,int * RESTRICT x_sf)630 static void backsubst_bw(const int numBands, const FIXP_DBL *const b,
631 FIXP_DBL *RESTRICT x, int *RESTRICT x_sf) {
632 int i, k;
633 int m; /* the trip counter that indexes incrementally through LnormInv1d[] */
634
635 const FIXP_CHB *RESTRICT pLnormInv1d =
636 bsd[numBands - BSD_IDX_OFFSET].LnormInv1d;
637 const SCHAR *RESTRICT pLnormInv1d_sf =
638 bsd[numBands - BSD_IDX_OFFSET].LnormInv1d_sf;
639
640 x[POLY_ORDER] = b[POLY_ORDER];
641
642 for (i = POLY_ORDER - 1, m = 0; i >= 0; i--) {
643 FIXP_DBL sum = b[i] >> SUM_SAFETY;
644 int sum_sf = x_sf[i]; /* sum's sf but disregarding SUM_SAFETY (added at the
645 iteration's end) */
646
647 for (k = i + 1; k <= POLY_ORDER; ++k, ++m) {
648 int e;
649 FIXP_DBL mult = fMultNorm(FX_CHB2FX_DBL(pLnormInv1d[m]), x[k], &e);
650 int mult_sf = pLnormInv1d_sf[m] + x_sf[k] + e;
651
652 /* check if the new summand mult has a different sf than sum currently has
653 */
654 int diff = mult_sf - sum_sf;
655
656 if (diff > 0) {
657 /* yes, and it requires the sum v to be adjusted (scaled down) */
658 sum >>= diff;
659 sum_sf = mult_sf;
660 } else if (diff < 0) {
661 /* yes, but here mult needs to be scaled down */
662 mult >>= -diff;
663 }
664
665 /* mult has now the same sf than what it is about to be added to. */
666 /* scale mult down additionally so that building the sum is overflow-safe.
667 */
668 sum -= (mult >> SUM_SAFETY);
669 }
670
671 x_sf[i] = sum_sf + SUM_SAFETY;
672 x[i] = sum;
673 }
674 }
675
676 /**
677 * \brief Solves a system of linear equations (L*x=b) with the Cholesky
678 * algorithm.
679 *
680 * \param[in] numBands SBR crossover band index
681 * \param[in,out] b input: vector b, output: solution vector p.
682 * \param[in,out] b_sf input: exponent of b; output: exponent of solution
683 * p.
684 */
choleskySolve(const int numBands,FIXP_DBL * RESTRICT b,int * RESTRICT b_sf)685 static void choleskySolve(const int numBands, FIXP_DBL *RESTRICT b,
686 int *RESTRICT b_sf) {
687 int i, e;
688
689 const FIXP_CHB *RESTRICT pBmul0 = bsd[numBands - BSD_IDX_OFFSET].Bmul0;
690 const SCHAR *RESTRICT pBmul0_sf = bsd[numBands - BSD_IDX_OFFSET].Bmul0_sf;
691 const FIXP_CHB *RESTRICT pBmul1 = bsd[numBands - BSD_IDX_OFFSET].Bmul1;
692 const SCHAR *RESTRICT pBmul1_sf = bsd[numBands - BSD_IDX_OFFSET].Bmul1_sf;
693
694 /* normalize b */
695 FIXP_DBL bnormed[POLY_ORDER + 1];
696 for (i = 0; i <= POLY_ORDER; ++i) {
697 bnormed[i] = fMultNorm(b[i], FX_CHB2FX_DBL(pBmul0[i]), &e);
698 b_sf[i] += pBmul0_sf[i] + e;
699 }
700
701 backsubst_fw(numBands, bnormed, b, b_sf);
702
703 /* normalize b again */
704 for (i = 0; i <= POLY_ORDER; ++i) {
705 bnormed[i] = fMultNorm(b[i], FX_CHB2FX_DBL(pBmul1[i]), &e);
706 b_sf[i] += pBmul1_sf[i] + e;
707 }
708
709 backsubst_bw(numBands, bnormed, b, b_sf);
710 }
711
712 /**
713 * \brief Find polynomial approximation of vector y with implicit abscisas
714 * x=0,1,2,3..n-1
715 *
716 * The problem (V^T * V * p = V^T * y) is solved with Cholesky.
717 * V is the Vandermode Matrix constructed with x = 0...n-1;
718 * A = V^T * V; b = V^T * y;
719 *
720 * \param[in] numBands SBR crossover band index (BSD_IDX_OFFSET <= numBands <=
721 * MAXLOWBANDS)
722 * \param[in] y input vector (mantissa)
723 * \param[in] y_sf exponents of y[]
724 * \param[out] p output polynomial coefficients (mantissa)
725 * \param[out] p_sf exponents of p[]
726 */
polyfit(const int numBands,const FIXP_DBL * const y,const int y_sf,FIXP_DBL * RESTRICT p,int * RESTRICT p_sf)727 static void polyfit(const int numBands, const FIXP_DBL *const y, const int y_sf,
728 FIXP_DBL *RESTRICT p, int *RESTRICT p_sf) {
729 int i, k;
730 LONG v[POLY_ORDER + 1];
731 int sum_saftey = getLog2[numBands - 1];
732
733 FDK_ASSERT((numBands >= BSD_IDX_OFFSET) && (numBands <= MAXLOWBANDS));
734
735 /* construct vector b[] temporarily stored in array p[] */
736 FDKmemclear(p, (POLY_ORDER + 1) * sizeof(FIXP_DBL));
737
738 /* p[] are the sums over n values and each p[i] has its own sf */
739 for (i = 0; i <= POLY_ORDER; ++i) p_sf[i] = 1 - DFRACT_BITS;
740
741 for (k = 0; k < numBands; k++) {
742 v[0] = (LONG)1;
743 for (i = 1; i <= POLY_ORDER; i++) {
744 v[i] = k * v[i - 1];
745 }
746
747 for (i = 0; i <= POLY_ORDER; i++) {
748 if (v[POLY_ORDER - i] != 0 && y[k] != FIXP_DBL(0)) {
749 int e;
750 FIXP_DBL mult = fMultNorm((FIXP_DBL)v[POLY_ORDER - i], y[k], &e);
751 int sf = DFRACT_BITS - 1 + y_sf + e;
752
753 /* check if the new summand has a different sf than the sum p[i]
754 * currently has */
755 int diff = sf - p_sf[i];
756
757 if (diff > 0) {
758 /* yes, and it requires the sum p[i] to be adjusted (scaled down) */
759 p[i] >>= fMin(DFRACT_BITS - 1, diff);
760 p_sf[i] = sf;
761 } else if (diff < 0) {
762 /* yes, but here mult needs to be scaled down */
763 mult >>= -diff;
764 }
765
766 /* mult has now the same sf than what it is about to be added to.
767 scale mult down additionally so that building the sum is
768 overflow-safe. */
769 p[i] += mult >> sum_saftey;
770 }
771 }
772 }
773
774 p_sf[0] += sum_saftey;
775 p_sf[1] += sum_saftey;
776 p_sf[2] += sum_saftey;
777 p_sf[3] += sum_saftey;
778
779 choleskySolve(numBands, p, p_sf);
780 }
781
782 /**
783 * \brief Calculates the output of a POLY_ORDER-degree polynomial function
784 * with Horner scheme:
785 *
786 * y(x) = p3 + p2*x + p1*x^2 + p0*x^3
787 * = p3 + x*(p2 + x*(p1 + x*p0))
788 *
789 * The for loop iterates through the mult/add parts in y(x) as above,
790 * during which regular upscaling ensures a stable exponent of the
791 * result.
792 *
793 * \param[in] p coefficients as in y(x)
794 * \param[in] p_sf exponents of p[]
795 * \param[in] x_int non-fractional integer representation of x as in y(x)
796 * \param[out] out_sf exponent of return value
797 *
798 * \return result y(x)
799 */
polyval(const FIXP_DBL * const p,const int * const p_sf,const int x_int,int * out_sf)800 static FIXP_DBL polyval(const FIXP_DBL *const p, const int *const p_sf,
801 const int x_int, int *out_sf) {
802 FDK_ASSERT(x_int <= 31); /* otherwise getLog2[] needs more elements */
803
804 int k, x_sf;
805 int result_sf; /* working space to compute return value *out_sf */
806 FIXP_DBL x; /* fractional value of x_int */
807 FIXP_DBL result; /* return value */
808
809 /* if x == 0, then y(x) is just p3 */
810 if (x_int != 0) {
811 x_sf = getLog2[x_int];
812 x = (FIXP_DBL)x_int << (DFRACT_BITS - 1 - x_sf);
813 } else {
814 *out_sf = p_sf[3];
815 return p[3];
816 }
817
818 result = p[0];
819 result_sf = p_sf[0];
820
821 for (k = 1; k <= POLY_ORDER; ++k) {
822 FIXP_DBL mult = fMult(x, result);
823 int mult_sf = x_sf + result_sf;
824
825 int room = CountLeadingBits(mult);
826 mult <<= room;
827 mult_sf -= room;
828
829 FIXP_DBL pp = p[k];
830 int pp_sf = p_sf[k];
831
832 /* equalize the shift factors of pp and mult so that we can sum them up */
833 int diff = pp_sf - mult_sf;
834
835 if (diff > 0) {
836 diff = fMin(diff, DFRACT_BITS - 1);
837 mult >>= diff;
838 } else if (diff < 0) {
839 diff = fMax(diff, 1 - DFRACT_BITS);
840 pp >>= -diff;
841 }
842
843 /* downshift by 1 to ensure safe summation */
844 mult >>= 1;
845 mult_sf++;
846 pp >>= 1;
847 pp_sf++;
848
849 result_sf = fMax(pp_sf, mult_sf);
850
851 result = mult + pp;
852 /* rarely, mult and pp happen to be almost equal except their sign,
853 and then upon summation, result becomes so small, that it is within
854 the inaccuracy range of a few bits, and then the relative error
855 produced by this function may become HUGE */
856 }
857
858 *out_sf = result_sf;
859 return result;
860 }
861
sbrDecoder_calculateGainVec(FIXP_DBL ** sourceBufferReal,FIXP_DBL ** sourceBufferImag,int sourceBuf_e_overlap,int sourceBuf_e_current,int overlap,FIXP_DBL * RESTRICT GainVec,int * GainVec_exp,int numBands,const int startSample,const int stopSample)862 void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal,
863 FIXP_DBL **sourceBufferImag,
864 int sourceBuf_e_overlap,
865 int sourceBuf_e_current, int overlap,
866 FIXP_DBL *RESTRICT GainVec, int *GainVec_exp,
867 int numBands, const int startSample,
868 const int stopSample) {
869 FIXP_DBL p[POLY_ORDER + 1];
870 FIXP_DBL meanNrg;
871 FIXP_DBL LowEnv[MAXLOWBANDS];
872 FIXP_DBL invNumBands = GetInvInt(numBands);
873 FIXP_DBL invNumSlots = GetInvInt(stopSample - startSample);
874 int i, loBand, exp, scale_nrg, scale_nrg_ov;
875 int sum_scale = 5, sum_scale_ov = 3;
876
877 if (overlap > 8) {
878 FDK_ASSERT(overlap <= 16);
879 sum_scale_ov += 1;
880 sum_scale += 1;
881 }
882
883 /* exponents of energy values */
884 sourceBuf_e_overlap = sourceBuf_e_overlap * 2 + sum_scale_ov;
885 sourceBuf_e_current = sourceBuf_e_current * 2 + sum_scale;
886 exp = fMax(sourceBuf_e_overlap, sourceBuf_e_current);
887 scale_nrg = sourceBuf_e_current - exp;
888 scale_nrg_ov = sourceBuf_e_overlap - exp;
889
890 meanNrg = (FIXP_DBL)0;
891 /* Calculate the spectral envelope in dB over the current copy-up frame. */
892 for (loBand = 0; loBand < numBands; loBand++) {
893 FIXP_DBL nrg_ov, nrg;
894 INT reserve = 0, exp_new;
895 FIXP_DBL maxVal = FL2FX_DBL(0.0f);
896
897 for (i = startSample; i < stopSample; i++) {
898 maxVal |=
899 (FIXP_DBL)((LONG)(sourceBufferReal[i][loBand]) ^
900 ((LONG)sourceBufferReal[i][loBand] >> (DFRACT_BITS - 1)));
901 maxVal |=
902 (FIXP_DBL)((LONG)(sourceBufferImag[i][loBand]) ^
903 ((LONG)sourceBufferImag[i][loBand] >> (DFRACT_BITS - 1)));
904 }
905
906 if (maxVal != FL2FX_DBL(0.0f)) {
907 reserve = CntLeadingZeros(maxVal) - 2;
908 }
909
910 nrg_ov = nrg = (FIXP_DBL)0;
911 if (scale_nrg_ov > -31) {
912 for (i = startSample; i < overlap; i++) {
913 nrg_ov +=
914 (fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) +
915 fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >>
916 sum_scale_ov;
917 }
918 } else {
919 scale_nrg_ov = 0;
920 }
921 if (scale_nrg > -31) {
922 for (i = overlap; i < stopSample; i++) {
923 nrg += (fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) +
924 fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >>
925 sum_scale;
926 }
927 } else {
928 scale_nrg = 0;
929 }
930
931 nrg = (scaleValue(nrg_ov, scale_nrg_ov) >> 1) +
932 (scaleValue(nrg, scale_nrg) >> 1);
933 nrg = fMult(nrg, invNumSlots);
934
935 exp_new =
936 exp - (2 * reserve) +
937 2; /* +1 for addition directly above, +1 for fPow2Div2 in loops above */
938
939 /* LowEnv = 10*log10(nrg) = log2(nrg) * 10/log2(10) */
940 /* exponent of logarithmic energy is 8 */
941 if (nrg > (FIXP_DBL)0) {
942 int exp_log2;
943 nrg = CalcLog2(nrg, exp_new, &exp_log2);
944 nrg = scaleValue(nrg, exp_log2 - 6);
945 nrg = fMult(FL2FXCONST_SGL(LOG10FAC), nrg);
946 } else {
947 nrg = (FIXP_DBL)0;
948 }
949 LowEnv[loBand] = nrg;
950 meanNrg += fMult(nrg, invNumBands);
951 }
952 exp = 6 + 2; /* exponent of LowEnv: +2 is exponent of LOG10FAC */
953
954 /* subtract mean before polynomial approximation to reduce dynamic of p[] */
955 for (loBand = 0; loBand < numBands; loBand++) {
956 LowEnv[loBand] = meanNrg - LowEnv[loBand];
957 }
958
959 /* For numBands < BSD_IDX_OFFSET (== POLY_ORDER+2) we dont get an
960 overdetermined equation system. The calculated polynomial will exactly fit
961 the input data and evaluating the polynomial will lead to the same vector
962 than the original input vector: lowEnvSlope[] == lowEnv[]
963 */
964 if (numBands > POLY_ORDER + 1) {
965 /* Find polynomial approximation of LowEnv */
966 int p_sf[POLY_ORDER + 1];
967
968 polyfit(numBands, LowEnv, exp, p, p_sf);
969
970 for (i = 0; i < numBands; i++) {
971 int sf;
972
973 /* lowBandEnvSlope[i] = tmp; */
974 FIXP_DBL tmp = polyval(p, p_sf, i, &sf);
975
976 /* GainVec = 10^((mean(y)-y)/20) = 2^( (mean(y)-y) * log2(10)/20 ) */
977 tmp = fMult(tmp, FL2FXCONST_SGL(LOG10FAC_INV));
978 GainVec[i] = f2Pow(tmp, sf - 2,
979 &GainVec_exp[i]); /* -2 is exponent of LOG10FAC_INV */
980 }
981 } else { /* numBands <= POLY_ORDER+1 */
982 for (i = 0; i < numBands; i++) {
983 int sf = exp; /* exponent of LowEnv[] */
984
985 /* lowBandEnvSlope[i] = LowEnv[i]; */
986 FIXP_DBL tmp = LowEnv[i];
987
988 /* GainVec = 10^((mean(y)-y)/20) = 2^( (mean(y)-y) * log2(10)/20 ) */
989 tmp = fMult(tmp, FL2FXCONST_SGL(LOG10FAC_INV));
990 GainVec[i] = f2Pow(tmp, sf - 2,
991 &GainVec_exp[i]); /* -2 is exponent of LOG10FAC_INV */
992 }
993 }
994 }
995