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