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 guided envelope shaping
100
101 *******************************************************************************/
102
103 #include "sac_reshapeBBEnv.h"
104
105 #include "sac_dec.h"
106 #include "sac_bitdec.h"
107 #include "sac_calcM1andM2.h"
108 #include "sac_reshapeBBEnv.h"
109 #include "sac_rom.h"
110
111 #define INP_DRY_WET 0
112 #define INP_DMX 1
113
114 #define SF_SHAPE 1
115 #define SF_DIV32 6
116 #define SF_FACTOR_SLOT 5
117
118 #define START_BB_ENV 0 /* 10 */
119 #define END_BB_ENV 9 /* 18 */
120
121 #define SF_ALPHA1 8
122 #define SF_BETA1 4
123
initBBEnv(spatialDec * self,int initStatesFlag)124 void initBBEnv(spatialDec *self, int initStatesFlag) {
125 INT ch, k;
126
127 for (ch = 0; ch < self->numOutputChannels; ch++) {
128 k = row2channelGES[self->treeConfig][ch];
129 self->row2channelDmxGES[ch] = k;
130 if (k == -1) continue;
131
132 switch (self->treeConfig) {
133 case TREE_212:
134 self->row2channelDmxGES[ch] = 0;
135 break;
136 default:;
137 }
138 }
139
140 if (initStatesFlag) {
141 for (k = 0; k < 2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS; k++) {
142 self->reshapeBBEnvState->normNrgPrev__FDK[k] =
143 FL2FXCONST_DBL(0.5f); /* 32768.f*32768.f */
144 self->reshapeBBEnvState->normNrgPrevSF[k] = DFRACT_BITS - 1;
145 self->reshapeBBEnvState->partNrgPrevSF[k] = 0;
146 self->reshapeBBEnvState->partNrgPrev2SF[k] = 0;
147 self->reshapeBBEnvState->frameNrgPrevSF[k] = 0;
148 }
149 }
150
151 self->reshapeBBEnvState->alpha__FDK =
152 FL2FXCONST_DBL(0.99637845575f); /* FDKexp(-64 / (0.4f * 44100)) */
153 self->reshapeBBEnvState->beta__FDK =
154 FL2FXCONST_DBL(0.96436909488f); /* FDKexp(-64 / (0.04f * 44100)) */
155 }
156
getSlotNrgHQ(FIXP_DBL * RESTRICT pReal,FIXP_DBL * RESTRICT pImag,FIXP_DBL * RESTRICT slotNrg,INT maxValSF,INT hybBands)157 static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
158 FIXP_DBL *RESTRICT pImag,
159 FIXP_DBL *RESTRICT slotNrg, INT maxValSF,
160 INT hybBands) {
161 INT qs;
162 FIXP_DBL nrg;
163
164 /* qs = 12, 13, 14 */
165 slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
166 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
167 slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
168 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
169 slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
170 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
171 /* qs = 15 */
172 slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
173 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
174 /* qs = 16, 17 */
175 nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
176 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
177 slotNrg[4] =
178 nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
179 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
180 /* qs = 18, 19, 20 */
181 nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
182 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
183 nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
184 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
185 slotNrg[5] =
186 nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
187 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
188 /* qs = 21, 22 */
189 nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
190 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
191 slotNrg[6] =
192 nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
193 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
194 /* qs = 23, 24 */
195 if (hybBands > 23) {
196 slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
197 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
198 slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
199 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
200 /* qs = 25, 26, 29, 28, 29 */
201 nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
202 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
203 nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
204 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
205 nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
206 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
207 nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
208 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
209 slotNrg[7] =
210 nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
211 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
212 /* qs = 30 ... min(41,hybBands-1) */
213 nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
214 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
215 for (qs = 31; qs < hybBands; qs++) {
216 nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
217 (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
218 }
219 slotNrg[8] = nrg;
220 } else {
221 slotNrg[7] = (FIXP_DBL)0;
222 slotNrg[8] = (FIXP_DBL)0;
223 }
224 }
225
combineDryWet(FIXP_DBL * RESTRICT pReal,FIXP_DBL * RESTRICT pImag,FIXP_DBL * RESTRICT pHybOutputRealDry,FIXP_DBL * RESTRICT pHybOutputImagDry,FIXP_DBL * RESTRICT pHybOutputRealWet,FIXP_DBL * RESTRICT pHybOutputImagWet,INT cplxBands,INT hybBands)226 static inline void combineDryWet(FIXP_DBL *RESTRICT pReal,
227 FIXP_DBL *RESTRICT pImag,
228 FIXP_DBL *RESTRICT pHybOutputRealDry,
229 FIXP_DBL *RESTRICT pHybOutputImagDry,
230 FIXP_DBL *RESTRICT pHybOutputRealWet,
231 FIXP_DBL *RESTRICT pHybOutputImagWet,
232 INT cplxBands, INT hybBands) {
233 INT qs;
234
235 for (qs = 12; qs < cplxBands; qs++) {
236 pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
237 pImag[qs] = (pHybOutputImagDry[qs] >> 1) + (pHybOutputImagWet[qs] >> 1);
238 }
239 for (; qs < hybBands; qs++) {
240 pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
241 }
242 }
243
slotAmp(FIXP_DBL * RESTRICT slotAmp_dry,INT * RESTRICT slotAmp_dry_e,FIXP_DBL * RESTRICT slotAmp_wet,INT * RESTRICT slotAmp_wet_e,FIXP_DBL * RESTRICT pHybOutputRealDry,FIXP_DBL * RESTRICT pHybOutputImagDry,FIXP_DBL * RESTRICT pHybOutputRealWet,FIXP_DBL * RESTRICT pHybOutputImagWet,INT cplxBands,INT hybBands)244 static inline void slotAmp(
245 FIXP_DBL *RESTRICT slotAmp_dry, INT *RESTRICT slotAmp_dry_e,
246 FIXP_DBL *RESTRICT slotAmp_wet, INT *RESTRICT slotAmp_wet_e,
247 FIXP_DBL *RESTRICT pHybOutputRealDry, FIXP_DBL *RESTRICT pHybOutputImagDry,
248 FIXP_DBL *RESTRICT pHybOutputRealWet, FIXP_DBL *RESTRICT pHybOutputImagWet,
249 INT cplxBands, INT hybBands) {
250 INT qs, s1, s2, headroom_dry, headroom_wet;
251 FIXP_DBL dry, wet;
252
253 /* headroom can be reduced by 1 bit due to use of fPow2Div2 */
254 s1 = DFRACT_BITS - 1 - CntLeadingZeros(hybBands + cplxBands);
255 headroom_dry = fMin(getScalefactor(pHybOutputRealDry, hybBands),
256 getScalefactor(pHybOutputImagDry, cplxBands));
257 headroom_wet = fMin(getScalefactor(pHybOutputRealWet, hybBands),
258 getScalefactor(pHybOutputImagWet, cplxBands));
259
260 dry = wet = FL2FXCONST_DBL(0.0f);
261 for (qs = 0; qs < cplxBands; qs++) {
262 /* sum up dry part */
263 dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
264 dry += (fPow2Div2(pHybOutputImagDry[qs] << headroom_dry) >> s1);
265 /* sum up wet part */
266 wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
267 wet += (fPow2Div2(pHybOutputImagWet[qs] << headroom_wet) >> s1);
268 }
269 for (; qs < hybBands; qs++) {
270 dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
271 wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
272 }
273
274 /* consider fPow2Div2() */
275 s1 += 1;
276
277 /* normalize dry part, ensure that exponent is even */
278 s2 = fixMax(0, CntLeadingZeros(dry) - 1);
279 *slotAmp_dry = dry << s2;
280 *slotAmp_dry_e = s1 - s2 - 2 * headroom_dry;
281 if (*slotAmp_dry_e & 1) {
282 *slotAmp_dry = *slotAmp_dry >> 1;
283 *slotAmp_dry_e += 1;
284 }
285
286 /* normalize wet part, ensure that exponent is even */
287 s2 = fixMax(0, CntLeadingZeros(wet) - 1);
288 *slotAmp_wet = wet << s2;
289 *slotAmp_wet_e = s1 - s2 - 2 * headroom_wet;
290 if (*slotAmp_wet_e & 1) {
291 *slotAmp_wet = *slotAmp_wet >> 1;
292 *slotAmp_wet_e += 1;
293 }
294 }
295
296 #if defined(__aarch64__)
297 __attribute__((noinline))
298 #endif
299 static void
shapeBBEnv(FIXP_DBL * pHybOutputRealDry,FIXP_DBL * pHybOutputImagDry,FIXP_DBL dryFac,INT scale,INT cplxBands,INT hybBands)300 shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry,
301 FIXP_DBL dryFac, INT scale, INT cplxBands, INT hybBands) {
302 INT qs;
303
304 if (scale == 0) {
305 for (qs = 0; qs < cplxBands; qs++) {
306 pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
307 pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac);
308 }
309 for (; qs < hybBands; qs++) {
310 pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
311 }
312 } else {
313 for (qs = 0; qs < cplxBands; qs++) {
314 pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
315 fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
316 pHybOutputImagDry[qs] = SATURATE_LEFT_SHIFT(
317 fMultDiv2(pHybOutputImagDry[qs], dryFac), scale, DFRACT_BITS);
318 }
319 for (; qs < hybBands; qs++) {
320 pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
321 fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
322 }
323 }
324 }
325
extractBBEnv(spatialDec * self,INT inp,INT start,INT channels,FIXP_DBL * pEnv,const SPATIAL_BS_FRAME * frame)326 static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
327 FIXP_DBL *pEnv, const SPATIAL_BS_FRAME *frame) {
328 INT ch, pb, prevChOffs;
329 INT clz, scale, scale_min, envSF;
330 INT scaleCur, scalePrev, commonScale;
331 INT slotNrgSF, partNrgSF, frameNrgSF;
332 INT *pPartNrgPrevSF, *pFrameNrgPrevSF;
333 INT *pNormNrgPrevSF, *pPartNrgPrev2SF;
334
335 FIXP_DBL maxVal, env, frameNrg, normNrg;
336 FIXP_DBL *pReal, *pImag;
337 FIXP_DBL *partNrg, *partNrgPrev;
338
339 C_ALLOC_SCRATCH_START(pScratchBuffer, FIXP_DBL,
340 (2 * 42 + MAX_PARAMETER_BANDS));
341 C_ALLOC_SCRATCH_START(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
342 C_ALLOC_SCRATCH_START(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
343
344 FIXP_DBL *slotNrg = pScratchBuffer + (2 * 42);
345
346 RESHAPE_BBENV_STATE *pBBEnvState = self->reshapeBBEnvState;
347
348 FIXP_DBL alpha = pBBEnvState->alpha__FDK;
349 /*FIXP_DBL alpha1 = (FL2FXCONST_DBL(1.0f) - alpha) << SF_ALPHA1;*/
350 FIXP_DBL alpha1 = ((FIXP_DBL)MAXVAL_DBL - alpha) << SF_ALPHA1;
351 FIXP_DBL beta = pBBEnvState->beta__FDK;
352 /*FIXP_DBL beta1 = (FL2FXCONST_DBL(1.0f) - beta) << SF_BETA1;*/
353 FIXP_DBL beta1 = ((FIXP_DBL)MAXVAL_DBL - beta) << SF_BETA1;
354
355 INT shapeActiv = 1;
356 INT hybBands = fixMin(42, self->hybridBands);
357 INT staticScale = self->staticDecScale + (1);
358 INT cplxBands;
359 cplxBands = fixMin(42, self->hybridBands);
360
361 for (ch = start; ch < channels; ch++) {
362 if (inp == INP_DRY_WET) {
363 INT ch2 = row2channelGES[self->treeConfig][ch];
364 if (ch2 == -1) {
365 continue;
366 } else {
367 if (frame->tempShapeEnableChannelGES[ch2]) {
368 shapeActiv = 1;
369 } else {
370 shapeActiv = 0;
371 }
372 }
373 prevChOffs = ch;
374 pReal = pScratchBuffer;
375 pImag = pScratchBuffer + 42;
376 combineDryWet(pReal, pImag, self->hybOutputRealDry__FDK[ch],
377 self->hybOutputImagDry__FDK[ch],
378 self->hybOutputRealWet__FDK[ch],
379 self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
380 clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
381 getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
382 } else {
383 prevChOffs = ch + self->numOutputChannels;
384 pReal = self->hybInputReal__FDK[ch];
385 pImag = self->hybInputImag__FDK[ch];
386 clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
387 getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
388 }
389
390 partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
391 pPartNrgPrevSF = &pBBEnvState->partNrgPrevSF[prevChOffs];
392 pFrameNrgPrevSF = &pBBEnvState->frameNrgPrevSF[prevChOffs];
393 pNormNrgPrevSF = &pBBEnvState->normNrgPrevSF[prevChOffs];
394 pPartNrgPrev2SF = &pBBEnvState->partNrgPrev2SF[prevChOffs];
395
396 /* calculate slot energy */
397 {
398 getSlotNrgHQ(&pReal[12], &pImag[12], slotNrg, clz,
399 fixMin(42, self->hybridBands)); /* scale slotNrg:
400 2*(staticScale-clz) +
401 SF_FACTOR_SLOT */
402 }
403
404 slotNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
405 SF_FACTOR_SLOT;
406 frameNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
407 SF_FACTOR_SLOT;
408
409 partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
410 pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1);
411 scalePrev = fixMax(fixMin(partNrgSF - pPartNrgPrevSF[0], DFRACT_BITS - 1),
412 -(DFRACT_BITS - 1));
413 scaleCur =
414 fixMax(fixMin(partNrgSF - slotNrgSF + SF_ALPHA1, DFRACT_BITS - 1),
415 -(DFRACT_BITS - 1));
416
417 maxVal = FL2FXCONST_DBL(0.0f);
418 frameNrg = FL2FXCONST_DBL(0.0f);
419 if ((scaleCur < 0) && (scalePrev < 0)) {
420 scaleCur = -scaleCur;
421 scalePrev = -scalePrev;
422 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
423 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
424 (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
425 << 1;
426 maxVal |= partNrg[pb];
427 frameNrg += slotNrg[pb] >> 3;
428 }
429 } else if ((scaleCur >= 0) && (scalePrev >= 0)) {
430 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
431 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
432 (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
433 << 1;
434 maxVal |= partNrg[pb];
435 frameNrg += slotNrg[pb] >> 3;
436 }
437 } else if ((scaleCur < 0) && (scalePrev >= 0)) {
438 scaleCur = -scaleCur;
439 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
440 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
441 (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
442 << 1;
443 maxVal |= partNrg[pb];
444 frameNrg += slotNrg[pb] >> 3;
445 }
446 } else { /* if ( (scaleCur >= 0) && (scalePrev < 0) ) */
447 scalePrev = -scalePrev;
448 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
449 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
450 (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
451 << 1;
452 maxVal |= partNrg[pb];
453 frameNrg += slotNrg[pb] >> 3;
454 }
455 }
456
457 /* frameNrg /= (END_BB_ENV - START_BB_ENV); 0.88888888888f =
458 * (1/(END_BB_ENV-START_BB_ENV)<<3; shift with 3 is compensated in loop
459 * above */
460 frameNrg = fMult(frameNrg, FL2FXCONST_DBL(0.88888888888f));
461
462 /* store scalefactor and headroom for part nrg prev */
463 pPartNrgPrevSF[0] = partNrgSF;
464 pPartNrgPrev2SF[0] = fixMax(0, CntLeadingZeros(maxVal) - 1);
465
466 commonScale = fixMax(frameNrgSF - SF_ALPHA1 + 1, pFrameNrgPrevSF[0] + 1);
467 scalePrev = fixMin(commonScale - pFrameNrgPrevSF[0], DFRACT_BITS - 1);
468 scaleCur = fixMin(commonScale - frameNrgSF + SF_ALPHA1, DFRACT_BITS - 1);
469 frameNrgSF = commonScale;
470
471 frameNrg = ((fMultDiv2(alpha1, frameNrg) >> scaleCur) +
472 (fMultDiv2(alpha, pBBEnvState->frameNrgPrev__FDK[prevChOffs]) >>
473 scalePrev))
474 << 1;
475
476 clz = fixMax(0, CntLeadingZeros(frameNrg) - 1);
477 pBBEnvState->frameNrgPrev__FDK[prevChOffs] = frameNrg << clz;
478 pFrameNrgPrevSF[0] = frameNrgSF - clz;
479
480 env = FL2FXCONST_DBL(0.0f);
481 scale = clz + partNrgSF - frameNrgSF;
482 scale_min = DFRACT_BITS - 1;
483 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
484 if ((partNrg[pb] | slotNrg[pb]) != FL2FXCONST_DBL(0.0f)) {
485 INT s;
486 INT sc = 0;
487 INT sn = fixMax(0, CntLeadingZeros(slotNrg[pb]) - 1);
488 FIXP_DBL inv_sqrt = invSqrtNorm2(partNrg[pb], &sc);
489 FIXP_DBL res = fMult(slotNrg[pb] << sn, fPow2(inv_sqrt));
490
491 s = fixMax(0, CntLeadingZeros(res) - 1);
492 res = res << s;
493
494 sc = scale - (2 * sc - sn - s);
495 scale_min = fixMin(scale_min, sc);
496
497 resPb[pb] = res;
498 resPbSF[pb] = sc;
499 } else {
500 resPb[pb] = (FIXP_DBL)0;
501 resPbSF[pb] = 0;
502 }
503 }
504
505 scale_min = 4 - scale_min;
506
507 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
508 INT sc = fixMax(fixMin(resPbSF[pb] + scale_min, DFRACT_BITS - 1),
509 -(DFRACT_BITS - 1));
510
511 if (sc < 0) {
512 env += resPb[pb] << (-sc);
513 } else {
514 env += resPb[pb] >> (sc);
515 }
516 }
517
518 env = fMultDiv2(env, pBBEnvState->frameNrgPrev__FDK[prevChOffs]);
519 envSF = slotNrgSF + scale_min + 1;
520
521 commonScale = fixMax(envSF - SF_BETA1 + 1, pNormNrgPrevSF[0] + 1);
522 scalePrev = fixMin(commonScale - pNormNrgPrevSF[0], DFRACT_BITS - 1);
523 scaleCur = fixMin(commonScale - envSF + SF_BETA1, DFRACT_BITS - 1);
524
525 normNrg = ((fMultDiv2(beta1, env) >> scaleCur) +
526 (fMultDiv2(beta, pBBEnvState->normNrgPrev__FDK[prevChOffs]) >>
527 scalePrev))
528 << 1;
529
530 clz = fixMax(0, CntLeadingZeros(normNrg) - 1);
531 pBBEnvState->normNrgPrev__FDK[prevChOffs] = normNrg << clz;
532 pNormNrgPrevSF[0] = commonScale - clz;
533
534 if (shapeActiv) {
535 if ((env | normNrg) != FL2FXCONST_DBL(0.0f)) {
536 INT sc, se, sn;
537 se = fixMax(0, CntLeadingZeros(env) - 1);
538 sc = commonScale + SF_DIV32 - envSF + se;
539 env = fMult(sqrtFixp((env << se) >> (sc & 0x1)),
540 invSqrtNorm2(normNrg, &sn));
541
542 sc = fixMin((sc >> 1) - sn, DFRACT_BITS - 1);
543 if (sc < 0) {
544 env <<= (-sc);
545 } else {
546 env >>= (sc);
547 }
548 }
549 /* env is scaled by SF_DIV32/2 bits */
550 }
551 pEnv[ch] = env;
552 }
553
554 C_ALLOC_SCRATCH_END(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
555 C_ALLOC_SCRATCH_END(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
556 C_ALLOC_SCRATCH_END(pScratchBuffer, FIXP_DBL, (2 * 42 + MAX_PARAMETER_BANDS));
557 }
558
SpatialDecReshapeBBEnv(spatialDec * self,const SPATIAL_BS_FRAME * frame,INT ts)559 void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
560 INT ts) {
561 INT ch, scale;
562 INT dryFacSF, slotAmpSF;
563 INT slotAmp_dry_e, slotAmp_wet_e;
564 FIXP_DBL tmp, dryFac, envShape;
565 FIXP_DBL slotAmp_dry, slotAmp_wet, slotAmp_ratio;
566 FIXP_DBL envDry[MAX_OUTPUT_CHANNELS], envDmx[2];
567
568 INT cplxBands;
569 INT hybBands = self->hybridBands - 6;
570
571 cplxBands = self->hybridBands - 6;
572
573 /* extract downmix envelope(s) */
574 switch (self->treeConfig) {
575 default:
576 extractBBEnv(self, INP_DMX, 0, fMin(self->numInputChannels, 2), envDmx,
577 frame);
578 }
579
580 /* extract dry and wet envelopes */
581 extractBBEnv(self, INP_DRY_WET, 0, self->numOutputChannels, envDry, frame);
582
583 for (ch = 0; ch < self->numOutputChannels; ch++) {
584 INT ch2;
585
586 ch2 = row2channelGES[self->treeConfig][ch];
587
588 if (ch2 == -1) continue;
589
590 if (frame->tempShapeEnableChannelGES[ch2]) {
591 INT sc;
592
593 /* reshape dry and wet signals according to transmitted envelope */
594
595 /* De-quantize GES data */
596 FDK_ASSERT((frame->bsEnvShapeData[ch2][ts] >= 0) &&
597 (frame->bsEnvShapeData[ch2][ts] <= 4));
598 FDK_ASSERT((self->envQuantMode == 0) || (self->envQuantMode == 1));
599 envShape =
600 FX_CFG2FX_DBL(envShapeDataTable__FDK[frame->bsEnvShapeData[ch2][ts]]
601 [self->envQuantMode]);
602
603 /* get downmix channel */
604 ch2 = self->row2channelDmxGES[ch];
605
606 /* multiply ratio with dmx envelope; tmp is scaled by SF_DIV32/2+SF_SHAPE
607 * bits */
608 if (ch2 == 2) {
609 tmp = fMultDiv2(envShape, envDmx[0]) + fMultDiv2(envShape, envDmx[1]);
610 } else {
611 tmp = fMult(envShape, envDmx[ch2]);
612 }
613
614 /* weighting factors */
615 dryFacSF = slotAmpSF = 0;
616 dryFac = slotAmp_ratio = FL2FXCONST_DBL(0.0f);
617
618 /* dryFac will be scaled by dryFacSF bits */
619 if (envDry[ch] != FL2FXCONST_DBL(0.0f)) {
620 envDry[ch] = invSqrtNorm2(envDry[ch], &dryFacSF);
621 dryFac = fMultDiv2(tmp, fPow2Div2(envDry[ch])) << 2;
622 dryFacSF = SF_SHAPE + 2 * dryFacSF;
623 }
624
625 slotAmp_dry_e = slotAmp_wet_e = 0;
626
627 /* calculate slotAmp_dry and slotAmp_wet */
628 slotAmp(&slotAmp_dry, &slotAmp_dry_e, &slotAmp_wet, &slotAmp_wet_e,
629 &self->hybOutputRealDry__FDK[ch][6],
630 &self->hybOutputImagDry__FDK[ch][6],
631 &self->hybOutputRealWet__FDK[ch][6],
632 &self->hybOutputImagWet__FDK[ch][6], cplxBands, hybBands);
633
634 /* exponents must be even due to subsequent square root calculation */
635 FDK_ASSERT(((slotAmp_dry_e & 1) == 0) && ((slotAmp_wet_e & 1) == 0));
636
637 /* slotAmp_ratio will be scaled by slotAmpSF bits */
638 if (slotAmp_dry != FL2FXCONST_DBL(0.0f)) {
639 slotAmp_wet = sqrtFixp(slotAmp_wet);
640 slotAmp_dry = invSqrtNorm2(slotAmp_dry, &slotAmpSF);
641
642 slotAmp_ratio = fMult(slotAmp_wet, slotAmp_dry);
643 slotAmpSF = slotAmpSF + (slotAmp_wet_e >> 1) - (slotAmp_dry_e >> 1);
644 }
645
646 /* calculate common scale factor */
647 scale =
648 fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3
649 bits to avoid overflows
650 when calculating dryFac */
651 dryFac = dryFac >> fixMin(scale - dryFacSF, DFRACT_BITS - 1);
652 slotAmp_ratio =
653 slotAmp_ratio >> fixMin(scale - slotAmpSF, DFRACT_BITS - 1);
654
655 /* limit dryFac */
656 dryFac = fixMax(
657 FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1),
658 fMult(dryFac, slotAmp_ratio) -
659 (slotAmp_ratio >> fixMin(scale, DFRACT_BITS - 1)) +
660 (dryFac >> fixMin(scale, DFRACT_BITS - 1)));
661 dryFac = fixMin(
662 FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1),
663 dryFac); /* reduce shift bits by 3, because upper
664 limit 4.0 is scaled with 3 bits */
665 scale = 2 * scale + 1;
666
667 /* improve precision for dryFac */
668 sc = fixMax(0, CntLeadingZeros(dryFac) - 1);
669 dryFac = dryFac << (INT)fixMin(scale, sc);
670 scale = scale - fixMin(scale, sc);
671
672 /* shaping */
673 shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6],
674 &self->hybOutputImagDry__FDK[ch][6], dryFac,
675 fixMin(scale, DFRACT_BITS - 1), cplxBands, hybBands);
676 }
677 }
678 }
679