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 /*********************** 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,FIXP_DBL * RESTRICT slotAmp_wet,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(FIXP_DBL *RESTRICT slotAmp_dry,
245 FIXP_DBL *RESTRICT slotAmp_wet,
246 FIXP_DBL *RESTRICT pHybOutputRealDry,
247 FIXP_DBL *RESTRICT pHybOutputImagDry,
248 FIXP_DBL *RESTRICT pHybOutputRealWet,
249 FIXP_DBL *RESTRICT pHybOutputImagWet, INT cplxBands,
250 INT hybBands) {
251 INT qs;
252 FIXP_DBL dry, wet;
253
254 dry = wet = FL2FXCONST_DBL(0.0f);
255 for (qs = 0; qs < cplxBands; qs++) {
256 dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)) +
257 fPow2Div2(pHybOutputImagDry[qs] << (1)));
258 wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)) +
259 fPow2Div2(pHybOutputImagWet[qs] << (1)));
260 }
261 for (; qs < hybBands; qs++) {
262 dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)));
263 wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)));
264 }
265 *slotAmp_dry = dry >> (2 * (1));
266 *slotAmp_wet = wet >> (2 * (1));
267 }
268
269 #if defined(__aarch64__)
270 __attribute__((noinline))
271 #endif
272 static void
shapeBBEnv(FIXP_DBL * pHybOutputRealDry,FIXP_DBL * pHybOutputImagDry,FIXP_DBL dryFac,INT scale,INT cplxBands,INT hybBands)273 shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry,
274 FIXP_DBL dryFac, INT scale, INT cplxBands, INT hybBands) {
275 INT qs;
276
277 if (scale == 0) {
278 for (qs = 0; qs < cplxBands; qs++) {
279 pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
280 pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac);
281 }
282 for (; qs < hybBands; qs++) {
283 pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
284 }
285 } else {
286 for (qs = 0; qs < cplxBands; qs++) {
287 pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
288 fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
289 pHybOutputImagDry[qs] = SATURATE_LEFT_SHIFT(
290 fMultDiv2(pHybOutputImagDry[qs], dryFac), scale, DFRACT_BITS);
291 }
292 for (; qs < hybBands; qs++) {
293 pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
294 fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
295 }
296 }
297 }
298
extractBBEnv(spatialDec * self,INT inp,INT start,INT channels,FIXP_DBL * pEnv,const SPATIAL_BS_FRAME * frame)299 static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
300 FIXP_DBL *pEnv, const SPATIAL_BS_FRAME *frame) {
301 INT ch, pb, prevChOffs;
302 INT clz, scale, scale_min, envSF;
303 INT scaleCur, scalePrev, commonScale;
304 INT slotNrgSF, partNrgSF, frameNrgSF;
305 INT *pPartNrgPrevSF, *pFrameNrgPrevSF;
306 INT *pNormNrgPrevSF, *pPartNrgPrev2SF;
307
308 FIXP_DBL maxVal, env, frameNrg, normNrg;
309 FIXP_DBL *pReal, *pImag;
310 FIXP_DBL *partNrg, *partNrgPrev;
311
312 C_ALLOC_SCRATCH_START(pScratchBuffer, FIXP_DBL,
313 (2 * 42 + MAX_PARAMETER_BANDS));
314 C_ALLOC_SCRATCH_START(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
315 C_ALLOC_SCRATCH_START(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
316
317 FIXP_DBL *slotNrg = pScratchBuffer + (2 * 42);
318
319 RESHAPE_BBENV_STATE *pBBEnvState = self->reshapeBBEnvState;
320
321 FIXP_DBL alpha = pBBEnvState->alpha__FDK;
322 /*FIXP_DBL alpha1 = (FL2FXCONST_DBL(1.0f) - alpha) << SF_ALPHA1;*/
323 FIXP_DBL alpha1 = ((FIXP_DBL)MAXVAL_DBL - alpha) << SF_ALPHA1;
324 FIXP_DBL beta = pBBEnvState->beta__FDK;
325 /*FIXP_DBL beta1 = (FL2FXCONST_DBL(1.0f) - beta) << SF_BETA1;*/
326 FIXP_DBL beta1 = ((FIXP_DBL)MAXVAL_DBL - beta) << SF_BETA1;
327
328 INT shapeActiv = 1;
329 INT hybBands = fixMin(42, self->hybridBands);
330 INT staticScale = self->staticDecScale + (1);
331 INT cplxBands;
332 cplxBands = fixMin(42, self->hybridBands);
333
334 for (ch = start; ch < channels; ch++) {
335 if (inp == INP_DRY_WET) {
336 INT ch2 = row2channelGES[self->treeConfig][ch];
337 if (ch2 == -1) {
338 continue;
339 } else {
340 if (frame->tempShapeEnableChannelGES[ch2]) {
341 shapeActiv = 1;
342 } else {
343 shapeActiv = 0;
344 }
345 }
346 prevChOffs = ch;
347 pReal = pScratchBuffer;
348 pImag = pScratchBuffer + 42;
349 combineDryWet(pReal, pImag, self->hybOutputRealDry__FDK[ch],
350 self->hybOutputImagDry__FDK[ch],
351 self->hybOutputRealWet__FDK[ch],
352 self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
353 clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
354 getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
355 } else {
356 prevChOffs = ch + self->numOutputChannels;
357 pReal = self->hybInputReal__FDK[ch];
358 pImag = self->hybInputImag__FDK[ch];
359 clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
360 getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
361 }
362
363 partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
364 pPartNrgPrevSF = &pBBEnvState->partNrgPrevSF[prevChOffs];
365 pFrameNrgPrevSF = &pBBEnvState->frameNrgPrevSF[prevChOffs];
366 pNormNrgPrevSF = &pBBEnvState->normNrgPrevSF[prevChOffs];
367 pPartNrgPrev2SF = &pBBEnvState->partNrgPrev2SF[prevChOffs];
368
369 /* calculate slot energy */
370 {
371 getSlotNrgHQ(&pReal[12], &pImag[12], slotNrg, clz,
372 fixMin(42, self->hybridBands)); /* scale slotNrg:
373 2*(staticScale-clz) +
374 SF_FACTOR_SLOT */
375 }
376
377 slotNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
378 SF_FACTOR_SLOT;
379 frameNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
380 SF_FACTOR_SLOT;
381
382 partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
383 pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1);
384 scalePrev = fixMax(fixMin(partNrgSF - pPartNrgPrevSF[0], DFRACT_BITS - 1),
385 -(DFRACT_BITS - 1));
386 scaleCur =
387 fixMax(fixMin(partNrgSF - slotNrgSF + SF_ALPHA1, DFRACT_BITS - 1),
388 -(DFRACT_BITS - 1));
389
390 maxVal = FL2FXCONST_DBL(0.0f);
391 frameNrg = FL2FXCONST_DBL(0.0f);
392 if ((scaleCur < 0) && (scalePrev < 0)) {
393 scaleCur = -scaleCur;
394 scalePrev = -scalePrev;
395 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
396 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
397 (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
398 << 1;
399 maxVal |= partNrg[pb];
400 frameNrg += slotNrg[pb] >> 3;
401 }
402 } else if ((scaleCur >= 0) && (scalePrev >= 0)) {
403 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
404 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
405 (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
406 << 1;
407 maxVal |= partNrg[pb];
408 frameNrg += slotNrg[pb] >> 3;
409 }
410 } else if ((scaleCur < 0) && (scalePrev >= 0)) {
411 scaleCur = -scaleCur;
412 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
413 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
414 (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
415 << 1;
416 maxVal |= partNrg[pb];
417 frameNrg += slotNrg[pb] >> 3;
418 }
419 } else { /* if ( (scaleCur >= 0) && (scalePrev < 0) ) */
420 scalePrev = -scalePrev;
421 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
422 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
423 (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
424 << 1;
425 maxVal |= partNrg[pb];
426 frameNrg += slotNrg[pb] >> 3;
427 }
428 }
429
430 /* frameNrg /= (END_BB_ENV - START_BB_ENV); 0.88888888888f =
431 * (1/(END_BB_ENV-START_BB_ENV)<<3; shift with 3 is compensated in loop
432 * above */
433 frameNrg = fMult(frameNrg, FL2FXCONST_DBL(0.88888888888f));
434
435 /* store scalefactor and headroom for part nrg prev */
436 pPartNrgPrevSF[0] = partNrgSF;
437 pPartNrgPrev2SF[0] = fixMax(0, CntLeadingZeros(maxVal) - 1);
438
439 commonScale = fixMax(frameNrgSF - SF_ALPHA1 + 1, pFrameNrgPrevSF[0] + 1);
440 scalePrev = fixMin(commonScale - pFrameNrgPrevSF[0], DFRACT_BITS - 1);
441 scaleCur = fixMin(commonScale - frameNrgSF + SF_ALPHA1, DFRACT_BITS - 1);
442 frameNrgSF = commonScale;
443
444 frameNrg = ((fMultDiv2(alpha1, frameNrg) >> scaleCur) +
445 (fMultDiv2(alpha, pBBEnvState->frameNrgPrev__FDK[prevChOffs]) >>
446 scalePrev))
447 << 1;
448
449 clz = fixMax(0, CntLeadingZeros(frameNrg) - 1);
450 pBBEnvState->frameNrgPrev__FDK[prevChOffs] = frameNrg << clz;
451 pFrameNrgPrevSF[0] = frameNrgSF - clz;
452
453 env = FL2FXCONST_DBL(0.0f);
454 scale = clz + partNrgSF - frameNrgSF;
455 scale_min = DFRACT_BITS - 1;
456 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
457 if ((partNrg[pb] | slotNrg[pb]) != FL2FXCONST_DBL(0.0f)) {
458 INT s;
459 INT sc = 0;
460 INT sn = fixMax(0, CntLeadingZeros(slotNrg[pb]) - 1);
461 FIXP_DBL inv_sqrt = invSqrtNorm2(partNrg[pb], &sc);
462 FIXP_DBL res = fMult(slotNrg[pb] << sn, fPow2(inv_sqrt));
463
464 s = fixMax(0, CntLeadingZeros(res) - 1);
465 res = res << s;
466
467 sc = scale - (2 * sc - sn - s);
468 scale_min = fixMin(scale_min, sc);
469
470 resPb[pb] = res;
471 resPbSF[pb] = sc;
472 } else {
473 resPb[pb] = (FIXP_DBL)0;
474 resPbSF[pb] = 0;
475 }
476 }
477
478 scale_min = 4 - scale_min;
479
480 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
481 INT sc = fixMax(fixMin(resPbSF[pb] + scale_min, DFRACT_BITS - 1),
482 -(DFRACT_BITS - 1));
483
484 if (sc < 0) {
485 env += resPb[pb] << (-sc);
486 } else {
487 env += resPb[pb] >> (sc);
488 }
489 }
490
491 env = fMultDiv2(env, pBBEnvState->frameNrgPrev__FDK[prevChOffs]);
492 envSF = slotNrgSF + scale_min + 1;
493
494 commonScale = fixMax(envSF - SF_BETA1 + 1, pNormNrgPrevSF[0] + 1);
495 scalePrev = fixMin(commonScale - pNormNrgPrevSF[0], DFRACT_BITS - 1);
496 scaleCur = fixMin(commonScale - envSF + SF_BETA1, DFRACT_BITS - 1);
497
498 normNrg = ((fMultDiv2(beta1, env) >> scaleCur) +
499 (fMultDiv2(beta, pBBEnvState->normNrgPrev__FDK[prevChOffs]) >>
500 scalePrev))
501 << 1;
502
503 clz = fixMax(0, CntLeadingZeros(normNrg) - 1);
504 pBBEnvState->normNrgPrev__FDK[prevChOffs] = normNrg << clz;
505 pNormNrgPrevSF[0] = commonScale - clz;
506
507 if (shapeActiv) {
508 if ((env | normNrg) != FL2FXCONST_DBL(0.0f)) {
509 INT sc, se, sn;
510 se = fixMax(0, CntLeadingZeros(env) - 1);
511 sc = commonScale + SF_DIV32 - envSF + se;
512 env = fMult(sqrtFixp((env << se) >> (sc & 0x1)),
513 invSqrtNorm2(normNrg, &sn));
514
515 sc = fixMin((sc >> 1) - sn, DFRACT_BITS - 1);
516 if (sc < 0) {
517 env <<= (-sc);
518 } else {
519 env >>= (sc);
520 }
521 }
522 /* env is scaled by SF_DIV32/2 bits */
523 }
524 pEnv[ch] = env;
525 }
526
527 C_ALLOC_SCRATCH_END(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
528 C_ALLOC_SCRATCH_END(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
529 C_ALLOC_SCRATCH_END(pScratchBuffer, FIXP_DBL, (2 * 42 + MAX_PARAMETER_BANDS));
530 }
531
SpatialDecReshapeBBEnv(spatialDec * self,const SPATIAL_BS_FRAME * frame,INT ts)532 void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
533 INT ts) {
534 INT ch, scale;
535 INT dryFacSF, slotAmpSF;
536 FIXP_DBL tmp, dryFac, envShape;
537 FIXP_DBL slotAmp_dry, slotAmp_wet, slotAmp_ratio;
538 FIXP_DBL envDry[MAX_OUTPUT_CHANNELS], envDmx[2];
539
540 INT cplxBands;
541 INT hybBands = self->hybridBands - 6;
542
543 cplxBands = self->hybridBands - 6;
544
545 /* extract downmix envelope(s) */
546 switch (self->treeConfig) {
547 default:
548 extractBBEnv(self, INP_DMX, 0, fMin(self->numInputChannels, 2), envDmx,
549 frame);
550 }
551
552 /* extract dry and wet envelopes */
553 extractBBEnv(self, INP_DRY_WET, 0, self->numOutputChannels, envDry, frame);
554
555 for (ch = 0; ch < self->numOutputChannels; ch++) {
556 INT ch2;
557
558 ch2 = row2channelGES[self->treeConfig][ch];
559
560 if (ch2 == -1) continue;
561
562 if (frame->tempShapeEnableChannelGES[ch2]) {
563 INT sc;
564
565 /* reshape dry and wet signals according to transmitted envelope */
566
567 /* De-quantize GES data */
568 FDK_ASSERT((frame->bsEnvShapeData[ch2][ts] >= 0) &&
569 (frame->bsEnvShapeData[ch2][ts] <= 4));
570 FDK_ASSERT((self->envQuantMode == 0) || (self->envQuantMode == 1));
571 envShape =
572 FX_CFG2FX_DBL(envShapeDataTable__FDK[frame->bsEnvShapeData[ch2][ts]]
573 [self->envQuantMode]);
574
575 /* get downmix channel */
576 ch2 = self->row2channelDmxGES[ch];
577
578 /* multiply ratio with dmx envelope; tmp is scaled by SF_DIV32/2+SF_SHAPE
579 * bits */
580 if (ch2 == 2) {
581 tmp = fMultDiv2(envShape, envDmx[0]) + fMultDiv2(envShape, envDmx[1]);
582 } else {
583 tmp = fMult(envShape, envDmx[ch2]);
584 }
585
586 /* weighting factors */
587 dryFacSF = slotAmpSF = 0;
588 dryFac = slotAmp_ratio = FL2FXCONST_DBL(0.0f);
589
590 /* dryFac will be scaled by dryFacSF bits */
591 if (envDry[ch] != FL2FXCONST_DBL(0.0f)) {
592 envDry[ch] = invSqrtNorm2(envDry[ch], &dryFacSF);
593 dryFac = fMultDiv2(tmp, fPow2Div2(envDry[ch])) << 2;
594 dryFacSF = SF_SHAPE + 2 * dryFacSF;
595 }
596
597 /* calculate slotAmp_dry and slotAmp_wet */
598 slotAmp(&slotAmp_dry, &slotAmp_wet, &self->hybOutputRealDry__FDK[ch][6],
599 &self->hybOutputImagDry__FDK[ch][6],
600 &self->hybOutputRealWet__FDK[ch][6],
601 &self->hybOutputImagWet__FDK[ch][6], cplxBands, hybBands);
602
603 /* slotAmp_ratio will be scaled by slotAmpSF bits */
604 if (slotAmp_dry != FL2FXCONST_DBL(0.0f)) {
605 sc = fixMax(0, CntLeadingZeros(slotAmp_wet) - 1);
606 sc = sc - (sc & 1);
607
608 slotAmp_wet = sqrtFixp(slotAmp_wet << sc);
609 slotAmp_dry = invSqrtNorm2(slotAmp_dry, &slotAmpSF);
610
611 slotAmp_ratio = fMult(slotAmp_wet, slotAmp_dry);
612 slotAmpSF = slotAmpSF - (sc >> 1);
613 }
614
615 /* calculate common scale factor */
616 scale =
617 fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3
618 bits to avoid overflows
619 when calculating dryFac */
620 dryFac = dryFac >> fixMin(scale - dryFacSF, DFRACT_BITS - 1);
621 slotAmp_ratio =
622 slotAmp_ratio >> fixMin(scale - slotAmpSF, DFRACT_BITS - 1);
623
624 /* limit dryFac */
625 dryFac = fixMax(
626 FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1),
627 fMult(dryFac, slotAmp_ratio) -
628 (slotAmp_ratio >> fixMin(scale, DFRACT_BITS - 1)) +
629 (dryFac >> fixMin(scale, DFRACT_BITS - 1)));
630 dryFac = fixMin(
631 FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1),
632 dryFac); /* reduce shift bits by 3, because upper
633 limit 4.0 is scaled with 3 bits */
634 scale = 2 * scale + 1;
635
636 /* improve precision for dryFac */
637 sc = fixMax(0, CntLeadingZeros(dryFac) - 1);
638 dryFac = dryFac << (INT)fixMin(scale, sc);
639 scale = scale - fixMin(scale, sc);
640
641 /* shaping */
642 shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6],
643 &self->hybOutputImagDry__FDK[ch][6], dryFac,
644 fixMin(scale, DFRACT_BITS - 1), cplxBands, hybBands);
645 }
646 }
647 }
648