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