1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2021 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 /*********************** MPEG surround decoder library *************************
96
97 Author(s):
98
99 Description: SAC Dec subband processing
100
101 *******************************************************************************/
102
103 #include "sac_stp.h"
104 #include "sac_calcM1andM2.h"
105 #include "sac_bitdec.h"
106 #include "FDK_matrixCalloc.h"
107 #include "sac_rom.h"
108
109 #define SF_FREQ_DOMAIN_HEADROOM (2 * (1))
110
111 #define BP_GF_START 6
112 #define BP_GF_SIZE 25
113 #define HP_SIZE 9
114 #define STP_UPDATE_ENERGY_RATE 32
115
116 #define SF_WET 5
117 #define SF_DRY \
118 3 /* SF_DRY == 2 would produce good conformance test results as well */
119 #define SF_DRY_NRG \
120 (4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
121 i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
122 calculation needs 4 bits headroom, headroom can be reduced by 1 \
123 bit due to fPow2Div2() usage */
124 #define SF_WET_NRG \
125 (4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
126 i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
127 calculation needs 4 bits headroom, headroom can be reduced by 1 \
128 bit due to fPow2Div2() usage */
129 #define SF_PRODUCT_BP_GF 13
130 #define SF_PRODUCT_BP_GF_GF 26
131 #define SF_SCALE 2
132
133 #define SF_SCALE_LD64 FL2FXCONST_DBL(0.03125) /* LD64((1<<SF_SCALE))*/
134 #define STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.950f) /* 0.95 */
135 #define ONE_MINUS_STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.05f) /* 1.0 - 0.95 */
136 #define STP_LPF_COEFF2__FDK FL2FXCONST_DBL(0.450f) /* 0.45 */
137 #define ONE_MINUS_STP_LPF_COEFF2__FDK \
138 FL2FXCONST_DBL(1.0f - 0.450f) /* 1.0 - 0.45 */
139 #define STP_SCALE_LIMIT__FDK \
140 FL2FXCONST_DBL(2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE */
141 #define ONE_DIV_STP_SCALE_LIMIT__FDK \
142 FL2FXCONST_DBL(1.0f / 2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE \
143 */
144 #define ABS_THR__FDK \
145 FL2FXCONST_DBL(ABS_THR / \
146 ((float)(1 << (22 + 22 - 26)))) /* scaled by 18 bits */
147 #define ABS_THR2__FDK \
148 FL2FXCONST_DBL(ABS_THR * 32.0f * 32.0f / \
149 ((float)(1 << (22 + 22 - 26)))) /* scaled by 10 bits */
150 #define STP_SCALE_LIMIT_HI \
151 FL2FXCONST_DBL(3.02222222222 / (1 << SF_SCALE)) /* see 4. below */
152 #define STP_SCALE_LIMIT_LO \
153 FL2FXCONST_DBL(0.28289992119 / (1 << SF_SCALE)) /* see 4. below */
154 #define STP_SCALE_LIMIT_HI_LD64 \
155 FL2FXCONST_DBL(0.04986280452) /* see 4. below \
156 */
157 #define STP_SCALE_LIMIT_LO_LD64 \
158 FL2FXCONST_DBL(0.05692613500) /* see 4. below \
159 */
160
161 /* Scale factor calculation for the diffuse signal needs adapted thresholds
162 for STP_SCALE_LIMIT and 1/STP_SCALE_LIMIT:
163
164 1. scale = sqrt(DryNrg/WetNrg)
165
166 2. Damping of scale factor
167 scale2 = 0.1 + 0.9 * scale
168
169 3. Limiting of scale factor
170 STP_SCALE_LIMIT >= scale2 >= 1/STP_SCALE_LIMIT
171 => STP_SCALE_LIMIT >= (0.1 + 0.9 * scale) >= 1/STP_SCALE_LIMIT
172 => (STP_SCALE_LIMIT-0.1)/0.9 >= scale >=
173 (1/STP_SCALE_LIMIT-0.1)/0.9
174
175 3. Limiting of scale factor before sqrt calculation
176 ((STP_SCALE_LIMIT-0.1)/0.9)^2 >= (scale^2) >=
177 ((1/STP_SCALE_LIMIT-0.1)/0.9)^2 (STP_SCALE_LIMIT_HI)^2 >= (scale^2) >=
178 (STP_SCALE_LIMIT_LO)^2
179
180 4. Thresholds for limiting of scale factor
181 STP_SCALE_LIMIT_HI = ((2.82-0.1)/0.9)
182 STP_SCALE_LIMIT_LO = (((1.0/2.82)-0.1)/0.9)
183 STP_SCALE_LIMIT_HI_LD64 = LD64(STP_SCALE_LIMIT_HI*STP_SCALE_LIMIT_HI)
184 STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO)
185 */
186
187 #define CALC_WET_SCALE(dryIdx, wetIdx) \
188 if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \
189 scale[wetIdx] = STP_SCALE_LIMIT_HI; \
190 } else if (DryEnerLD64[dryIdx] < \
191 (WetEnerLD64[wetIdx] - STP_SCALE_LIMIT_LO_LD64)) { \
192 scale[wetIdx] = STP_SCALE_LIMIT_LO; \
193 } else { \
194 tmp = ((DryEnerLD64[dryIdx] - WetEnerLD64[wetIdx]) >> 1) - SF_SCALE_LD64; \
195 scale[wetIdx] = CalcInvLdData(tmp); \
196 }
197
198 struct STP_DEC {
199 FIXP_DBL runDryEner[MAX_INPUT_CHANNELS];
200 FIXP_DBL runWetEner[MAX_OUTPUT_CHANNELS];
201 FIXP_DBL oldDryEnerLD64[MAX_INPUT_CHANNELS];
202 FIXP_DBL oldWetEnerLD64[MAX_OUTPUT_CHANNELS];
203 FIXP_DBL prev_tp_scale[MAX_OUTPUT_CHANNELS];
204 const FIXP_CFG *BP;
205 const FIXP_CFG *BP_GF;
206 int update_old_ener;
207 };
208
combineSignalCplx(FIXP_DBL * hybOutputRealDry,FIXP_DBL * hybOutputImagDry,FIXP_DBL * hybOutputRealWet,FIXP_DBL * hybOutputImagWet,int bands)209 inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
210 FIXP_DBL *hybOutputImagDry,
211 FIXP_DBL *hybOutputRealWet,
212 FIXP_DBL *hybOutputImagWet, int bands) {
213 int n;
214
215 for (n = bands - 1; n >= 0; n--) {
216 *hybOutputRealDry = fAddSaturate(*hybOutputRealDry, *hybOutputRealWet);
217 *hybOutputImagDry = fAddSaturate(*hybOutputImagDry, *hybOutputImagWet);
218 hybOutputRealDry++, hybOutputRealWet++;
219 hybOutputImagDry++, hybOutputImagWet++;
220 }
221 }
222
combineSignalCplxScale1(FIXP_DBL * hybOutputRealDry,FIXP_DBL * hybOutputImagDry,FIXP_DBL * hybOutputRealWet,FIXP_DBL * hybOutputImagWet,const FIXP_CFG * pBP,FIXP_DBL scaleX,int bands)223 inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry,
224 FIXP_DBL *hybOutputImagDry,
225 FIXP_DBL *hybOutputRealWet,
226 FIXP_DBL *hybOutputImagWet,
227 const FIXP_CFG *pBP, FIXP_DBL scaleX,
228 int bands) {
229 int n;
230 FIXP_DBL scaleY;
231 for (n = bands - 1; n >= 0; n--) {
232 scaleY = fMult(scaleX, *pBP);
233 *hybOutputRealDry = SATURATE_LEFT_SHIFT(
234 (*hybOutputRealDry >> SF_SCALE) + fMult(*hybOutputRealWet, scaleY),
235 SF_SCALE, DFRACT_BITS);
236 *hybOutputImagDry = SATURATE_LEFT_SHIFT(
237 (*hybOutputImagDry >> SF_SCALE) + fMult(*hybOutputImagWet, scaleY),
238 SF_SCALE, DFRACT_BITS);
239 hybOutputRealDry++, hybOutputRealWet++;
240 hybOutputImagDry++, hybOutputImagWet++;
241 pBP++;
242 }
243 }
244
combineSignalCplxScale2(FIXP_DBL * hybOutputRealDry,FIXP_DBL * hybOutputImagDry,FIXP_DBL * hybOutputRealWet,FIXP_DBL * hybOutputImagWet,FIXP_DBL scaleX,int bands)245 inline void combineSignalCplxScale2(FIXP_DBL *hybOutputRealDry,
246 FIXP_DBL *hybOutputImagDry,
247 FIXP_DBL *hybOutputRealWet,
248 FIXP_DBL *hybOutputImagWet, FIXP_DBL scaleX,
249 int bands) {
250 int n;
251
252 for (n = bands - 1; n >= 0; n--) {
253 *hybOutputRealDry = SATURATE_LEFT_SHIFT(
254 (*hybOutputRealDry >> SF_SCALE) + fMult(*hybOutputRealWet, scaleX),
255 SF_SCALE, DFRACT_BITS);
256 *hybOutputImagDry = SATURATE_LEFT_SHIFT(
257 (*hybOutputImagDry >> SF_SCALE) + fMult(*hybOutputImagWet, scaleX),
258 SF_SCALE, DFRACT_BITS);
259 hybOutputRealDry++, hybOutputRealWet++;
260 hybOutputImagDry++, hybOutputImagWet++;
261 }
262 }
263
264 /*******************************************************************************
265 Functionname: subbandTPCreate
266 ******************************************************************************/
subbandTPCreate(HANDLE_STP_DEC * hStpDec)267 SACDEC_ERROR subbandTPCreate(HANDLE_STP_DEC *hStpDec) {
268 HANDLE_STP_DEC self = NULL;
269 FDK_ALLOCATE_MEMORY_1D(self, 1, struct STP_DEC)
270 if (hStpDec != NULL) {
271 *hStpDec = self;
272 }
273
274 return MPS_OK;
275 bail:
276 return MPS_OUTOFMEMORY;
277 }
278
subbandTPInit(HANDLE_STP_DEC self)279 SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) {
280 SACDEC_ERROR err = MPS_OK;
281 int ch;
282
283 for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
284 self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
285 self->oldWetEnerLD64[ch] = FL2FXCONST_DBL(0.0);
286 }
287 for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
288 self->oldDryEnerLD64[ch] = FL2FXCONST_DBL(0.0);
289 }
290
291 self->BP = BP__FDK;
292 self->BP_GF = BP_GF__FDK;
293
294 self->update_old_ener = 0;
295
296 return err;
297 }
298
299 /*******************************************************************************
300 Functionname: subbandTPDestroy
301 ******************************************************************************/
subbandTPDestroy(HANDLE_STP_DEC * hStpDec)302 void subbandTPDestroy(HANDLE_STP_DEC *hStpDec) {
303 if (hStpDec != NULL) {
304 FDK_FREE_MEMORY_1D(*hStpDec);
305 }
306 }
307
308 /*******************************************************************************
309 Functionname: subbandTPApply
310 ******************************************************************************/
subbandTPApply(spatialDec * self,const SPATIAL_BS_FRAME * frame)311 SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
312 FIXP_DBL *qmfOutputRealDry[MAX_OUTPUT_CHANNELS];
313 FIXP_DBL *qmfOutputImagDry[MAX_OUTPUT_CHANNELS];
314 FIXP_DBL *qmfOutputRealWet[MAX_OUTPUT_CHANNELS];
315 FIXP_DBL *qmfOutputImagWet[MAX_OUTPUT_CHANNELS];
316
317 FIXP_DBL DryEner[MAX_INPUT_CHANNELS];
318 FIXP_DBL scale[MAX_OUTPUT_CHANNELS];
319
320 FIXP_DBL DryEnerLD64[MAX_INPUT_CHANNELS];
321 FIXP_DBL WetEnerLD64[MAX_OUTPUT_CHANNELS];
322
323 FIXP_DBL DryEner0 = FL2FXCONST_DBL(0.0f);
324 FIXP_DBL WetEnerX, damp, tmp;
325 FIXP_DBL dmxReal0, dmxImag0;
326 int skipChannels[MAX_OUTPUT_CHANNELS];
327 int n, ch, cplxBands, cplxHybBands;
328 int dry_scale_dmx, wet_scale_dmx;
329 int i_LF, i_RF;
330 HANDLE_STP_DEC hStpDec;
331 const FIXP_CFG *pBP;
332
333 int nrgScale = (2 * self->clipProtectGainSF__FDK);
334
335 hStpDec = self->hStpDec;
336
337 /* set scalefactor and loop counter */
338 FDK_ASSERT(SF_DRY >= 1);
339 {
340 cplxBands = BP_GF_SIZE;
341 cplxHybBands = self->hybridBands;
342 if (self->treeConfig == TREE_212) {
343 dry_scale_dmx = 2; /* 2 bits to compensate fMultDiv2() and fPow2Div2()
344 used in energy calculation */
345 } else {
346 dry_scale_dmx = (2 * SF_DRY) - 2;
347 }
348 wet_scale_dmx = 2;
349 }
350
351 /* setup pointer for forming the direct downmix signal */
352 for (ch = 0; ch < self->numOutputChannels; ch++) {
353 qmfOutputRealDry[ch] = &self->hybOutputRealDry__FDK[ch][7];
354 qmfOutputRealWet[ch] = &self->hybOutputRealWet__FDK[ch][7];
355 qmfOutputImagDry[ch] = &self->hybOutputImagDry__FDK[ch][7];
356 qmfOutputImagWet[ch] = &self->hybOutputImagWet__FDK[ch][7];
357 }
358
359 /* clear skipping flag for all output channels */
360 FDKmemset(skipChannels, 0, self->numOutputChannels * sizeof(int));
361
362 /* set scale values to zero */
363 FDKmemset(scale, 0, self->numOutputChannels * sizeof(FIXP_DBL));
364
365 /* update normalisation energy with latest smoothed energy */
366 if (hStpDec->update_old_ener == STP_UPDATE_ENERGY_RATE) {
367 hStpDec->update_old_ener = 1;
368 for (ch = 0; ch < self->numInputChannels; ch++) {
369 hStpDec->oldDryEnerLD64[ch] =
370 CalcLdData(fAddSaturate(hStpDec->runDryEner[ch], ABS_THR__FDK));
371 }
372 for (ch = 0; ch < self->numOutputChannels; ch++) {
373 if (self->treeConfig == TREE_212)
374 hStpDec->oldWetEnerLD64[ch] =
375 CalcLdData(fAddSaturate(hStpDec->runWetEner[ch], ABS_THR__FDK));
376 else
377 hStpDec->oldWetEnerLD64[ch] =
378 CalcLdData(fAddSaturate(hStpDec->runWetEner[ch], ABS_THR2__FDK));
379 }
380 } else {
381 hStpDec->update_old_ener++;
382 }
383
384 /* get channel configuration */
385 switch (self->treeConfig) {
386 case TREE_212:
387 i_LF = 0;
388 i_RF = 1;
389 break;
390 default:
391 return MPS_WRONG_TREECONFIG;
392 }
393
394 /* form the 'direct' downmix signal */
395 pBP = hStpDec->BP_GF - BP_GF_START;
396 switch (self->treeConfig) {
397 case TREE_212:
398 INT sMin, sNorm, sReal, sImag;
399
400 sReal = fMin(getScalefactor(&qmfOutputRealDry[i_LF][BP_GF_START],
401 cplxBands - BP_GF_START),
402 getScalefactor(&qmfOutputRealDry[i_RF][BP_GF_START],
403 cplxBands - BP_GF_START));
404 sImag = fMin(getScalefactor(&qmfOutputImagDry[i_LF][BP_GF_START],
405 cplxBands - BP_GF_START),
406 getScalefactor(&qmfOutputImagDry[i_RF][BP_GF_START],
407 cplxBands - BP_GF_START));
408 sMin = fMin(sReal, sImag) - 1;
409
410 for (n = BP_GF_START; n < cplxBands; n++) {
411 dmxReal0 = scaleValue(qmfOutputRealDry[i_LF][n], sMin) +
412 scaleValue(qmfOutputRealDry[i_RF][n], sMin);
413 dmxImag0 = scaleValue(qmfOutputImagDry[i_LF][n], sMin) +
414 scaleValue(qmfOutputImagDry[i_RF][n], sMin);
415
416 DryEner0 += (fMultDiv2(fPow2Div2(dmxReal0), pBP[n]) +
417 fMultDiv2(fPow2Div2(dmxImag0), pBP[n])) >>
418 SF_DRY_NRG;
419 }
420
421 sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_DRY_NRG + dry_scale_dmx -
422 (2 * sMin) + nrgScale;
423 DryEner0 = scaleValueSaturate(
424 DryEner0, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
425 break;
426 default:;
427 }
428 DryEner[0] = DryEner0;
429
430 /* normalise the 'direct' signals */
431 for (ch = 0; ch < self->numInputChannels; ch++) {
432 if (self->treeConfig != TREE_212) DryEner[ch] = DryEner[ch] << nrgScale;
433 hStpDec->runDryEner[ch] =
434 fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
435 fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
436 if (DryEner[ch] != FL2FXCONST_DBL(0.0f)) {
437 DryEnerLD64[ch] =
438 fixMax((CalcLdData(DryEner[ch]) - hStpDec->oldDryEnerLD64[ch]),
439 FL2FXCONST_DBL(-0.484375f));
440 } else {
441 DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
442 }
443 }
444 for (; ch < MAX_INPUT_CHANNELS; ch++) {
445 DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
446 }
447
448 /* normalise the 'diffuse' signals */
449 pBP = hStpDec->BP_GF - BP_GF_START;
450 for (ch = 0; ch < self->numOutputChannels; ch++) {
451 if (skipChannels[ch]) {
452 continue;
453 }
454
455 WetEnerX = FL2FXCONST_DBL(0.0f);
456
457 if (self->treeConfig == TREE_212) {
458 INT sMin, sNorm;
459
460 sMin = fMin(getScalefactor(&qmfOutputRealWet[ch][BP_GF_START],
461 cplxBands - BP_GF_START),
462 getScalefactor(&qmfOutputImagWet[ch][BP_GF_START],
463 cplxBands - BP_GF_START));
464
465 for (n = BP_GF_START; n < cplxBands; n++) {
466 WetEnerX +=
467 (fMultDiv2(fPow2Div2(scaleValue(qmfOutputRealWet[ch][n], sMin)),
468 pBP[n]) +
469 fMultDiv2(fPow2Div2(scaleValue(qmfOutputImagWet[ch][n], sMin)),
470 pBP[n])) >>
471 SF_WET_NRG;
472 }
473 sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_WET_NRG + wet_scale_dmx -
474 (2 * sMin) + nrgScale;
475 WetEnerX = scaleValueSaturate(
476 WetEnerX, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
477 } else
478 FDK_ASSERT(self->treeConfig == TREE_212);
479
480 hStpDec->runWetEner[ch] =
481 fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
482 fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);
483
484 if (WetEnerX == FL2FXCONST_DBL(0.0f)) {
485 WetEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
486 } else {
487 WetEnerLD64[ch] =
488 fixMax((CalcLdData(WetEnerX) - hStpDec->oldWetEnerLD64[ch]),
489 FL2FXCONST_DBL(-0.484375f));
490 }
491 }
492
493 /* compute scale factor for the 'diffuse' signals */
494 switch (self->treeConfig) {
495 case TREE_212:
496 if (DryEner[0] != FL2FXCONST_DBL(0.0f)) {
497 CALC_WET_SCALE(0, i_LF);
498 CALC_WET_SCALE(0, i_RF);
499 }
500 break;
501 default:;
502 }
503
504 damp = FL2FXCONST_DBL(0.1f / (1 << SF_SCALE));
505 for (ch = 0; ch < self->numOutputChannels; ch++) {
506 /* damp the scaling factor */
507 scale[ch] = damp + fMult(FL2FXCONST_DBL(0.9f), scale[ch]);
508
509 /* limiting the scale factor */
510 if (scale[ch] > STP_SCALE_LIMIT__FDK) {
511 scale[ch] = STP_SCALE_LIMIT__FDK;
512 }
513 if (scale[ch] < ONE_DIV_STP_SCALE_LIMIT__FDK) {
514 scale[ch] = ONE_DIV_STP_SCALE_LIMIT__FDK;
515 }
516
517 /* low pass filter the scaling factor */
518 scale[ch] =
519 fMult(STP_LPF_COEFF2__FDK, scale[ch]) +
520 fMult(ONE_MINUS_STP_LPF_COEFF2__FDK, hStpDec->prev_tp_scale[ch]);
521 hStpDec->prev_tp_scale[ch] = scale[ch];
522 }
523
524 /* combine 'direct' and scaled 'diffuse' signal */
525 FDK_ASSERT((HP_SIZE - 3 + 10 - 1) == PC_NUM_HYB_BANDS);
526 const SCHAR *channlIndex = row2channelSTP[self->treeConfig];
527
528 for (ch = 0; ch < self->numOutputChannels; ch++) {
529 int no_scaling;
530
531 no_scaling = !frame->tempShapeEnableChannelSTP[channlIndex[ch]];
532 if (no_scaling) {
533 combineSignalCplx(
534 &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
535 &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
536 &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
537 &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
538 cplxHybBands - self->tp_hybBandBorder);
539
540 } else {
541 FIXP_DBL scaleX;
542 scaleX = scale[ch];
543 pBP = hStpDec->BP - self->tp_hybBandBorder;
544 /* Band[HP_SIZE-3+10-1] needs not to be processed in
545 combineSignalCplxScale1(), because pB[HP_SIZE-3+10-1] would be 1.0 */
546 combineSignalCplxScale1(
547 &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
548 &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
549 &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
550 &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
551 &pBP[self->tp_hybBandBorder], scaleX,
552 (HP_SIZE - 3 + 10 - 1) - self->tp_hybBandBorder);
553
554 {
555 combineSignalCplxScale2(
556 &self->hybOutputRealDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
557 &self->hybOutputImagDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
558 &self->hybOutputRealWet__FDK[ch][HP_SIZE - 3 + 10 - 1],
559 &self->hybOutputImagWet__FDK[ch][HP_SIZE - 3 + 10 - 1], scaleX,
560 cplxHybBands - (HP_SIZE - 3 + 10 - 1));
561 }
562 }
563 }
564
565 return (SACDEC_ERROR)MPS_OK;
566 ;
567 }
568