1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6
7 1. INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33
34 2. COPYRIGHT LICENSE
35
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60
61 3. NO PATENT LICENSE
62
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70
71 4. DISCLAIMER
72
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83
84 5. CONTACT INFORMATION
85
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94
95 /*********************** 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 BP_GF_START 6
110 #define BP_GF_SIZE 25
111 #define HP_SIZE 9
112 #define STP_UPDATE_ENERGY_RATE 32
113
114 #define SF_WET 5
115 #define SF_DRY \
116 3 /* SF_DRY == 2 would produce good conformance test results as well */
117 #define SF_PRODUCT_BP_GF 13
118 #define SF_PRODUCT_BP_GF_GF 26
119 #define SF_SCALE 2
120
121 #define SF_SCALE_LD64 FL2FXCONST_DBL(0.03125) /* LD64((1<<SF_SCALE))*/
122 #define STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.950f) /* 0.95 */
123 #define ONE_MINUS_STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.05f) /* 1.0 - 0.95 */
124 #define STP_LPF_COEFF2__FDK FL2FXCONST_DBL(0.450f) /* 0.45 */
125 #define ONE_MINUS_STP_LPF_COEFF2__FDK \
126 FL2FXCONST_DBL(1.0f - 0.450f) /* 1.0 - 0.45 */
127 #define STP_SCALE_LIMIT__FDK \
128 FL2FXCONST_DBL(2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE */
129 #define ONE_DIV_STP_SCALE_LIMIT__FDK \
130 FL2FXCONST_DBL(1.0f / 2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE \
131 */
132 #define ABS_THR__FDK \
133 FL2FXCONST_DBL(ABS_THR / \
134 ((float)(1 << (22 + 22 - 26)))) /* scaled by 18 bits */
135 #define ABS_THR2__FDK \
136 FL2FXCONST_DBL(ABS_THR * 32.0f * 32.0f / \
137 ((float)(1 << (22 + 22 - 26)))) /* scaled by 10 bits */
138 #define STP_SCALE_LIMIT_HI \
139 FL2FXCONST_DBL(3.02222222222 / (1 << SF_SCALE)) /* see 4. below */
140 #define STP_SCALE_LIMIT_LO \
141 FL2FXCONST_DBL(0.28289992119 / (1 << SF_SCALE)) /* see 4. below */
142 #define STP_SCALE_LIMIT_HI_LD64 \
143 FL2FXCONST_DBL(0.04986280452) /* see 4. below \
144 */
145 #define STP_SCALE_LIMIT_LO_LD64 \
146 FL2FXCONST_DBL(0.05692613500) /* see 4. below \
147 */
148
149 /* Scale factor calculation for the diffuse signal needs adapted thresholds
150 for STP_SCALE_LIMIT and 1/STP_SCALE_LIMIT:
151
152 1. scale = sqrt(DryNrg/WetNrg)
153
154 2. Damping of scale factor
155 scale2 = 0.1 + 0.9 * scale
156
157 3. Limiting of scale factor
158 STP_SCALE_LIMIT >= scale2 >= 1/STP_SCALE_LIMIT
159 => STP_SCALE_LIMIT >= (0.1 + 0.9 * scale) >= 1/STP_SCALE_LIMIT
160 => (STP_SCALE_LIMIT-0.1)/0.9 >= scale >=
161 (1/STP_SCALE_LIMIT-0.1)/0.9
162
163 3. Limiting of scale factor before sqrt calculation
164 ((STP_SCALE_LIMIT-0.1)/0.9)^2 >= (scale^2) >=
165 ((1/STP_SCALE_LIMIT-0.1)/0.9)^2 (STP_SCALE_LIMIT_HI)^2 >= (scale^2) >=
166 (STP_SCALE_LIMIT_LO)^2
167
168 4. Thresholds for limiting of scale factor
169 STP_SCALE_LIMIT_HI = ((2.82-0.1)/0.9)
170 STP_SCALE_LIMIT_LO = (((1.0/2.82)-0.1)/0.9)
171 STP_SCALE_LIMIT_HI_LD64 = LD64(STP_SCALE_LIMIT_HI*STP_SCALE_LIMIT_HI)
172 STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO)
173 */
174
175 #define DRY_ENER_WEIGHT(DryEner) DryEner = DryEner >> dry_scale_dmx
176
177 #define WET_ENER_WEIGHT(WetEner) WetEner = WetEner << wet_scale_dmx
178
179 #define DRY_ENER_SUM_REAL(DryEner, dmxReal, n) \
180 DryEner += \
181 fMultDiv2(fPow2Div2(dmxReal << SF_DRY), pBP[n]) >> ((2 * SF_DRY) - 2)
182
183 #define DRY_ENER_SUM_CPLX(DryEner, dmxReal, dmxImag, n) \
184 DryEner += fMultDiv2( \
185 fPow2Div2(dmxReal << SF_DRY) + fPow2Div2(dmxImag << SF_DRY), pBP[n])
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
combineSignalReal(FIXP_DBL * hybOutputRealDry,FIXP_DBL * hybOutputRealWet,int bands)209 inline void combineSignalReal(FIXP_DBL *hybOutputRealDry,
210 FIXP_DBL *hybOutputRealWet, int bands) {
211 int n;
212
213 for (n = bands - 1; n >= 0; n--) {
214 *hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet;
215 hybOutputRealDry++, hybOutputRealWet++;
216 }
217 }
218
combineSignalRealScale1(FIXP_DBL * hybOutputRealDry,FIXP_DBL * hybOutputRealWet,FIXP_DBL scaleX,int bands)219 inline void combineSignalRealScale1(FIXP_DBL *hybOutputRealDry,
220 FIXP_DBL *hybOutputRealWet, FIXP_DBL scaleX,
221 int bands) {
222 int n;
223
224 for (n = bands - 1; n >= 0; n--) {
225 *hybOutputRealDry =
226 *hybOutputRealDry +
227 (fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1));
228 hybOutputRealDry++, hybOutputRealWet++;
229 }
230 }
231
combineSignalCplx(FIXP_DBL * hybOutputRealDry,FIXP_DBL * hybOutputImagDry,FIXP_DBL * hybOutputRealWet,FIXP_DBL * hybOutputImagWet,int bands)232 inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
233 FIXP_DBL *hybOutputImagDry,
234 FIXP_DBL *hybOutputRealWet,
235 FIXP_DBL *hybOutputImagWet, int bands) {
236 int n;
237
238 for (n = bands - 1; n >= 0; n--) {
239 *hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet;
240 *hybOutputImagDry = *hybOutputImagDry + *hybOutputImagWet;
241 hybOutputRealDry++, hybOutputRealWet++;
242 hybOutputImagDry++, hybOutputImagWet++;
243 }
244 }
245
combineSignalCplxScale1(FIXP_DBL * hybOutputRealDry,FIXP_DBL * hybOutputImagDry,FIXP_DBL * hybOutputRealWet,FIXP_DBL * hybOutputImagWet,const FIXP_CFG * pBP,FIXP_DBL scaleX,int bands)246 inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry,
247 FIXP_DBL *hybOutputImagDry,
248 FIXP_DBL *hybOutputRealWet,
249 FIXP_DBL *hybOutputImagWet,
250 const FIXP_CFG *pBP, FIXP_DBL scaleX,
251 int bands) {
252 int n;
253 FIXP_DBL scaleY;
254 for (n = bands - 1; n >= 0; n--) {
255 scaleY = fMultDiv2(scaleX, *pBP);
256 *hybOutputRealDry =
257 *hybOutputRealDry +
258 (fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 2));
259 *hybOutputImagDry =
260 *hybOutputImagDry +
261 (fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 2));
262 hybOutputRealDry++, hybOutputRealWet++;
263 hybOutputImagDry++, hybOutputImagWet++;
264 pBP++;
265 }
266 }
267
combineSignalCplxScale2(FIXP_DBL * hybOutputRealDry,FIXP_DBL * hybOutputImagDry,FIXP_DBL * hybOutputRealWet,FIXP_DBL * hybOutputImagWet,FIXP_DBL scaleX,int bands)268 inline void combineSignalCplxScale2(FIXP_DBL *hybOutputRealDry,
269 FIXP_DBL *hybOutputImagDry,
270 FIXP_DBL *hybOutputRealWet,
271 FIXP_DBL *hybOutputImagWet, FIXP_DBL scaleX,
272 int bands) {
273 int n;
274
275 for (n = bands - 1; n >= 0; n--) {
276 *hybOutputRealDry =
277 *hybOutputRealDry +
278 (fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1));
279 *hybOutputImagDry =
280 *hybOutputImagDry +
281 (fMultDiv2(*hybOutputImagWet, scaleX) << (SF_SCALE + 1));
282 hybOutputRealDry++, hybOutputRealWet++;
283 hybOutputImagDry++, hybOutputImagWet++;
284 }
285 }
286
287 /*******************************************************************************
288 Functionname: subbandTPCreate
289 ******************************************************************************/
subbandTPCreate(HANDLE_STP_DEC * hStpDec)290 SACDEC_ERROR subbandTPCreate(HANDLE_STP_DEC *hStpDec) {
291 HANDLE_STP_DEC self = NULL;
292 FDK_ALLOCATE_MEMORY_1D(self, 1, struct STP_DEC)
293 if (hStpDec != NULL) {
294 *hStpDec = self;
295 }
296
297 return MPS_OK;
298 bail:
299 return MPS_OUTOFMEMORY;
300 }
301
subbandTPInit(HANDLE_STP_DEC self)302 SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) {
303 SACDEC_ERROR err = MPS_OK;
304 int ch;
305
306 for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
307 self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
308 self->oldWetEnerLD64[ch] =
309 FL2FXCONST_DBL(0.34375f); /* 32768.0*32768.0/2^(44-26-10) */
310 }
311 for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
312 self->oldDryEnerLD64[ch] =
313 FL2FXCONST_DBL(0.1875f); /* 32768.0*32768.0/2^(44-26) */
314 }
315
316 self->BP = BP__FDK;
317 self->BP_GF = BP_GF__FDK;
318
319 self->update_old_ener = 0;
320
321 return err;
322 }
323
324 /*******************************************************************************
325 Functionname: subbandTPDestroy
326 ******************************************************************************/
subbandTPDestroy(HANDLE_STP_DEC * hStpDec)327 void subbandTPDestroy(HANDLE_STP_DEC *hStpDec) {
328 if (hStpDec != NULL) {
329 FDK_FREE_MEMORY_1D(*hStpDec);
330 }
331 }
332
333 /*******************************************************************************
334 Functionname: subbandTPApply
335 ******************************************************************************/
subbandTPApply(spatialDec * self,const SPATIAL_BS_FRAME * frame)336 SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
337 FIXP_DBL *qmfOutputRealDry[MAX_OUTPUT_CHANNELS];
338 FIXP_DBL *qmfOutputImagDry[MAX_OUTPUT_CHANNELS];
339 FIXP_DBL *qmfOutputRealWet[MAX_OUTPUT_CHANNELS];
340 FIXP_DBL *qmfOutputImagWet[MAX_OUTPUT_CHANNELS];
341
342 FIXP_DBL DryEner[MAX_INPUT_CHANNELS];
343 FIXP_DBL scale[MAX_OUTPUT_CHANNELS];
344
345 FIXP_DBL DryEnerLD64[MAX_INPUT_CHANNELS];
346 FIXP_DBL WetEnerLD64[MAX_OUTPUT_CHANNELS];
347
348 FIXP_DBL DryEner0 = FL2FXCONST_DBL(0.0f);
349 FIXP_DBL WetEnerX, damp, tmp;
350 FIXP_DBL dmxReal0, dmxImag0;
351 int skipChannels[MAX_OUTPUT_CHANNELS];
352 int n, ch, cplxBands, cplxHybBands;
353 int dry_scale_dmx, wet_scale_dmx;
354 int i_LF, i_RF;
355 HANDLE_STP_DEC hStpDec;
356 const FIXP_CFG *pBP;
357
358 int nrgScale = (2 * self->clipProtectGainSF__FDK);
359
360 hStpDec = self->hStpDec;
361
362 /* set scalefactor and loop counter */
363 FDK_ASSERT(SF_DRY >= 1);
364 {
365 cplxBands = BP_GF_SIZE;
366 cplxHybBands = self->hybridBands;
367 dry_scale_dmx = (2 * SF_DRY) - 2;
368 wet_scale_dmx = 2;
369 }
370
371 /* setup pointer for forming the direct downmix signal */
372 for (ch = 0; ch < self->numOutputChannels; ch++) {
373 qmfOutputRealDry[ch] = &self->hybOutputRealDry__FDK[ch][7];
374 qmfOutputRealWet[ch] = &self->hybOutputRealWet__FDK[ch][7];
375 qmfOutputImagDry[ch] = &self->hybOutputImagDry__FDK[ch][7];
376 qmfOutputImagWet[ch] = &self->hybOutputImagWet__FDK[ch][7];
377 }
378
379 /* clear skipping flag for all output channels */
380 FDKmemset(skipChannels, 0, self->numOutputChannels * sizeof(int));
381
382 /* set scale values to zero */
383 FDKmemset(scale, 0, self->numOutputChannels * sizeof(FIXP_DBL));
384
385 /* update normalisation energy with latest smoothed energy */
386 if (hStpDec->update_old_ener == STP_UPDATE_ENERGY_RATE) {
387 hStpDec->update_old_ener = 1;
388 for (ch = 0; ch < self->numInputChannels; ch++) {
389 hStpDec->oldDryEnerLD64[ch] =
390 CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK);
391 }
392 for (ch = 0; ch < self->numOutputChannels; ch++) {
393 hStpDec->oldWetEnerLD64[ch] =
394 CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
395 }
396 } else {
397 hStpDec->update_old_ener++;
398 }
399
400 /* get channel configuration */
401 switch (self->treeConfig) {
402 case TREE_212:
403 i_LF = 0;
404 i_RF = 1;
405 break;
406 default:
407 return MPS_WRONG_TREECONFIG;
408 }
409
410 /* form the 'direct' downmix signal */
411 pBP = hStpDec->BP_GF - BP_GF_START;
412 switch (self->treeConfig) {
413 case TREE_212:
414 for (n = BP_GF_START; n < cplxBands; n++) {
415 dmxReal0 = qmfOutputRealDry[i_LF][n] + qmfOutputRealDry[i_RF][n];
416 dmxImag0 = qmfOutputImagDry[i_LF][n] + qmfOutputImagDry[i_RF][n];
417 DRY_ENER_SUM_CPLX(DryEner0, dmxReal0, dmxImag0, n);
418 }
419 DRY_ENER_WEIGHT(DryEner0);
420 break;
421 default:;
422 }
423 DryEner[0] = DryEner0;
424
425 /* normalise the 'direct' signals */
426 for (ch = 0; ch < self->numInputChannels; ch++) {
427 DryEner[ch] = DryEner[ch] << (nrgScale);
428 hStpDec->runDryEner[ch] =
429 fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
430 fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
431 if (DryEner[ch] != FL2FXCONST_DBL(0.0f)) {
432 DryEnerLD64[ch] =
433 fixMax((CalcLdData(DryEner[ch]) - hStpDec->oldDryEnerLD64[ch]),
434 FL2FXCONST_DBL(-0.484375f));
435 } else {
436 DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
437 }
438 }
439 if (self->treeConfig == TREE_212) {
440 for (; ch < MAX_INPUT_CHANNELS; ch++) {
441 DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
442 }
443 }
444
445 /* normalise the 'diffuse' signals */
446 pBP = hStpDec->BP_GF - BP_GF_START;
447 for (ch = 0; ch < self->numOutputChannels; ch++) {
448 if (skipChannels[ch]) {
449 continue;
450 }
451
452 WetEnerX = FL2FXCONST_DBL(0.0f);
453 for (n = BP_GF_START; n < cplxBands; n++) {
454 tmp = fPow2Div2(qmfOutputRealWet[ch][n] << SF_WET);
455 tmp += fPow2Div2(qmfOutputImagWet[ch][n] << SF_WET);
456 WetEnerX += fMultDiv2(tmp, pBP[n]);
457 }
458 WET_ENER_WEIGHT(WetEnerX);
459
460 WetEnerX = WetEnerX << (nrgScale);
461 hStpDec->runWetEner[ch] =
462 fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
463 fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);
464
465 if (WetEnerX == FL2FXCONST_DBL(0.0f)) {
466 WetEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
467 } else {
468 WetEnerLD64[ch] =
469 fixMax((CalcLdData(WetEnerX) - hStpDec->oldWetEnerLD64[ch]),
470 FL2FXCONST_DBL(-0.484375f));
471 }
472 }
473
474 /* compute scale factor for the 'diffuse' signals */
475 switch (self->treeConfig) {
476 case TREE_212:
477 if (DryEner[0] != FL2FXCONST_DBL(0.0f)) {
478 CALC_WET_SCALE(0, i_LF);
479 CALC_WET_SCALE(0, i_RF);
480 }
481 break;
482 default:;
483 }
484
485 damp = FL2FXCONST_DBL(0.1f / (1 << SF_SCALE));
486 for (ch = 0; ch < self->numOutputChannels; ch++) {
487 /* damp the scaling factor */
488 scale[ch] = damp + fMult(FL2FXCONST_DBL(0.9f), scale[ch]);
489
490 /* limiting the scale factor */
491 if (scale[ch] > STP_SCALE_LIMIT__FDK) {
492 scale[ch] = STP_SCALE_LIMIT__FDK;
493 }
494 if (scale[ch] < ONE_DIV_STP_SCALE_LIMIT__FDK) {
495 scale[ch] = ONE_DIV_STP_SCALE_LIMIT__FDK;
496 }
497
498 /* low pass filter the scaling factor */
499 scale[ch] =
500 fMult(STP_LPF_COEFF2__FDK, scale[ch]) +
501 fMult(ONE_MINUS_STP_LPF_COEFF2__FDK, hStpDec->prev_tp_scale[ch]);
502 hStpDec->prev_tp_scale[ch] = scale[ch];
503 }
504
505 /* combine 'direct' and scaled 'diffuse' signal */
506 FDK_ASSERT((HP_SIZE - 3 + 10 - 1) == PC_NUM_HYB_BANDS);
507 const SCHAR *channlIndex = row2channelSTP[self->treeConfig];
508
509 for (ch = 0; ch < self->numOutputChannels; ch++) {
510 int no_scaling;
511
512 no_scaling = !frame->tempShapeEnableChannelSTP[channlIndex[ch]];
513 if (no_scaling) {
514 combineSignalCplx(
515 &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
516 &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
517 &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
518 &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
519 cplxHybBands - self->tp_hybBandBorder);
520
521 } else {
522 FIXP_DBL scaleX;
523 scaleX = scale[ch];
524 pBP = hStpDec->BP - self->tp_hybBandBorder;
525 /* Band[HP_SIZE-3+10-1] needs not to be processed in
526 combineSignalCplxScale1(), because pB[HP_SIZE-3+10-1] would be 1.0 */
527 combineSignalCplxScale1(
528 &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
529 &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
530 &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
531 &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
532 &pBP[self->tp_hybBandBorder], scaleX,
533 (HP_SIZE - 3 + 10 - 1) - self->tp_hybBandBorder);
534
535 {
536 combineSignalCplxScale2(
537 &self->hybOutputRealDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
538 &self->hybOutputImagDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
539 &self->hybOutputRealWet__FDK[ch][HP_SIZE - 3 + 10 - 1],
540 &self->hybOutputImagWet__FDK[ch][HP_SIZE - 3 + 10 - 1], scaleX,
541 cplxHybBands - (HP_SIZE - 3 + 10 - 1));
542 }
543 }
544 }
545
546 return (SACDEC_ERROR)MPS_OK;
547 ;
548 }
549