/src/aac/libAACenc/src/aacenc_pns.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 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten |
5 | | Forschung e.V. All rights reserved. |
6 | | |
7 | | 1. INTRODUCTION |
8 | | The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software |
9 | | that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding |
10 | | scheme for digital audio. This FDK AAC Codec software is intended to be used on |
11 | | a wide variety of Android devices. |
12 | | |
13 | | AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient |
14 | | general perceptual audio codecs. AAC-ELD is considered the best-performing |
15 | | full-bandwidth communications codec by independent studies and is widely |
16 | | deployed. AAC has been standardized by ISO and IEC as part of the MPEG |
17 | | specifications. |
18 | | |
19 | | Patent licenses for necessary patent claims for the FDK AAC Codec (including |
20 | | those of Fraunhofer) may be obtained through Via Licensing |
21 | | (www.vialicensing.com) or through the respective patent owners individually for |
22 | | the purpose of encoding or decoding bit streams in products that are compliant |
23 | | with the ISO/IEC MPEG audio standards. Please note that most manufacturers of |
24 | | Android devices already license these patent claims through Via Licensing or |
25 | | directly from the patent owners, and therefore FDK AAC Codec software may |
26 | | already be covered under those patent licenses when it is used for those |
27 | | licensed purposes only. |
28 | | |
29 | | Commercially-licensed AAC software libraries, including floating-point versions |
30 | | with enhanced sound quality, are also available from Fraunhofer. Users are |
31 | | encouraged to check the Fraunhofer website for additional applications |
32 | | information and documentation. |
33 | | |
34 | | 2. COPYRIGHT LICENSE |
35 | | |
36 | | Redistribution and use in source and binary forms, with or without modification, |
37 | | are permitted without payment of copyright license fees provided that you |
38 | | satisfy the following conditions: |
39 | | |
40 | | You must retain the complete text of this software license in redistributions of |
41 | | the FDK AAC Codec or your modifications thereto in source code form. |
42 | | |
43 | | You must retain the complete text of this software license in the documentation |
44 | | and/or other materials provided with redistributions of the FDK AAC Codec or |
45 | | your modifications thereto in binary form. You must make available free of |
46 | | charge copies of the complete source code of the FDK AAC Codec and your |
47 | | modifications thereto to recipients of copies in binary form. |
48 | | |
49 | | The name of Fraunhofer may not be used to endorse or promote products derived |
50 | | from this library without prior written permission. |
51 | | |
52 | | You may not charge copyright license fees for anyone to use, copy or distribute |
53 | | the FDK AAC Codec software or your modifications thereto. |
54 | | |
55 | | Your modified versions of the FDK AAC Codec must carry prominent notices stating |
56 | | that you changed the software and the date of any change. For modified versions |
57 | | of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" |
58 | | must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK |
59 | | AAC Codec Library for Android." |
60 | | |
61 | | 3. NO PATENT LICENSE |
62 | | |
63 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without |
64 | | limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. |
65 | | Fraunhofer provides no warranty of patent non-infringement with respect to this |
66 | | software. |
67 | | |
68 | | You may use this FDK AAC Codec software or modifications thereto only for |
69 | | purposes that are authorized by appropriate patent licenses. |
70 | | |
71 | | 4. DISCLAIMER |
72 | | |
73 | | This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright |
74 | | holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, |
75 | | including but not limited to the implied warranties of merchantability and |
76 | | fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
77 | | CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, |
78 | | or consequential damages, including but not limited to procurement of substitute |
79 | | goods or services; loss of use, data, or profits, or business interruption, |
80 | | however caused and on any theory of liability, whether in contract, strict |
81 | | liability, or tort (including negligence), arising in any way out of the use of |
82 | | this software, even if advised of the possibility of such damage. |
83 | | |
84 | | 5. CONTACT INFORMATION |
85 | | |
86 | | Fraunhofer Institute for Integrated Circuits IIS |
87 | | Attention: Audio and Multimedia Departments - FDK AAC LL |
88 | | Am Wolfsmantel 33 |
89 | | 91058 Erlangen, Germany |
90 | | |
91 | | www.iis.fraunhofer.de/amm |
92 | | amm-info@iis.fraunhofer.de |
93 | | ----------------------------------------------------------------------------- */ |
94 | | |
95 | | /**************************** AAC encoder library ****************************** |
96 | | |
97 | | Author(s): M. Lohwasser |
98 | | |
99 | | Description: pns.c |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | #include "aacenc_pns.h" |
104 | | |
105 | | #include "psy_data.h" |
106 | | #include "pnsparam.h" |
107 | | #include "noisedet.h" |
108 | | #include "bit_cnt.h" |
109 | | #include "interface.h" |
110 | | |
111 | | /* minCorrelationEnergy = (1.0e-10f)^2 ~ 2^-67 = 2^-47 * 2^-20 */ |
112 | | static const FIXP_DBL minCorrelationEnergy = |
113 | | FL2FXCONST_DBL(0.0); /* FL2FXCONST_DBL((float)FDKpow(2.0,-47)); */ |
114 | | /* noiseCorrelationThresh = 0.6^2 */ |
115 | | static const FIXP_DBL noiseCorrelationThresh = FL2FXCONST_DBL(0.36); |
116 | | |
117 | | static void FDKaacEnc_FDKaacEnc_noiseDetection( |
118 | | PNS_CONFIG *pnsConf, PNS_DATA *pnsData, const INT sfbActive, |
119 | | const INT *sfbOffset, INT tnsOrder, INT tnsPredictionGain, INT tnsActive, |
120 | | FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality); |
121 | | |
122 | | static void FDKaacEnc_CalcNoiseNrgs(const INT sfbActive, INT *pnsFlag, |
123 | | FIXP_DBL *sfbEnergyLdData, INT *noiseNrg); |
124 | | |
125 | | /***************************************************************************** |
126 | | |
127 | | functionname: initPnsConfiguration |
128 | | description: fill pnsConf with pns parameters |
129 | | returns: error status |
130 | | input: PNS Config struct (modified) |
131 | | bitrate, samplerate, usePns, |
132 | | number of sfb's, pointer to sfb offset |
133 | | output: error code |
134 | | |
135 | | *****************************************************************************/ |
136 | | |
137 | | AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration( |
138 | | PNS_CONFIG *pnsConf, INT bitRate, INT sampleRate, INT usePns, INT sfbCnt, |
139 | 0 | const INT *sfbOffset, const INT numChan, const INT isLC) { |
140 | 0 | AAC_ENCODER_ERROR ErrorStatus; |
141 | | |
142 | | /* init noise detection */ |
143 | 0 | ErrorStatus = FDKaacEnc_GetPnsParam(&pnsConf->np, bitRate, sampleRate, sfbCnt, |
144 | 0 | sfbOffset, &usePns, numChan, isLC); |
145 | 0 | if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; |
146 | | |
147 | 0 | pnsConf->minCorrelationEnergy = minCorrelationEnergy; |
148 | 0 | pnsConf->noiseCorrelationThresh = noiseCorrelationThresh; |
149 | |
|
150 | 0 | pnsConf->usePns = usePns; |
151 | |
|
152 | 0 | return AAC_ENC_OK; |
153 | 0 | } |
154 | | |
155 | | /***************************************************************************** |
156 | | |
157 | | functionname: FDKaacEnc_PnsDetect |
158 | | description: do decision, if PNS shall used or not |
159 | | returns: |
160 | | input: pns config structure |
161 | | pns data structure (modified), |
162 | | lastWindowSequence (long or short blocks) |
163 | | sfbActive |
164 | | pointer to Sfb Energy, Threshold, Offset |
165 | | pointer to mdct Spectrum |
166 | | length of each group |
167 | | pointer to tonality calculated in chaosmeasure |
168 | | tns order and prediction gain |
169 | | calculated noiseNrg at active PNS |
170 | | output: pnsFlag in pns data structure |
171 | | |
172 | | *****************************************************************************/ |
173 | | void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, PNS_DATA *pnsData, |
174 | | const INT lastWindowSequence, const INT sfbActive, |
175 | | const INT maxSfbPerGroup, FIXP_DBL *sfbThresholdLdData, |
176 | | const INT *sfbOffset, FIXP_DBL *mdctSpectrum, |
177 | | INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality, |
178 | | INT tnsOrder, INT tnsPredictionGain, INT tnsActive, |
179 | | FIXP_DBL *sfbEnergyLdData, INT *noiseNrg) |
180 | | |
181 | 0 | { |
182 | 0 | int sfb; |
183 | 0 | int startNoiseSfb; |
184 | | |
185 | | /* Reset pns info. */ |
186 | 0 | FDKmemclear(pnsData->pnsFlag, sizeof(pnsData->pnsFlag)); |
187 | 0 | for (sfb = 0; sfb < MAX_GROUPED_SFB; sfb++) { |
188 | 0 | noiseNrg[sfb] = NO_NOISE_PNS; |
189 | 0 | } |
190 | | |
191 | | /* Disable PNS and skip detection in certain cases. */ |
192 | 0 | if (pnsConf->usePns == 0) { |
193 | 0 | return; |
194 | 0 | } else { |
195 | | /* AAC - LC core encoder */ |
196 | 0 | if ((pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) && |
197 | 0 | (lastWindowSequence == SHORT_WINDOW)) { |
198 | 0 | return; |
199 | 0 | } |
200 | | /* AAC - (E)LD core encoder */ |
201 | 0 | if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) && |
202 | 0 | (pnsConf->np.detectionAlgorithmFlags & JUST_LONG_WINDOW) && |
203 | 0 | (lastWindowSequence != LONG_WINDOW)) { |
204 | 0 | return; |
205 | 0 | } |
206 | 0 | } |
207 | | |
208 | | /* |
209 | | call noise detection |
210 | | */ |
211 | 0 | FDKaacEnc_FDKaacEnc_noiseDetection( |
212 | 0 | pnsConf, pnsData, sfbActive, sfbOffset, tnsOrder, tnsPredictionGain, |
213 | 0 | tnsActive, mdctSpectrum, sfbMaxScaleSpec, sfbtonality); |
214 | | |
215 | | /* set startNoiseSfb (long) */ |
216 | 0 | startNoiseSfb = pnsConf->np.startSfb; |
217 | | |
218 | | /* Set noise substitution status */ |
219 | 0 | for (sfb = 0; sfb < sfbActive; sfb++) { |
220 | | /* No PNS below startNoiseSfb */ |
221 | 0 | if (sfb < startNoiseSfb) { |
222 | 0 | pnsData->pnsFlag[sfb] = 0; |
223 | 0 | continue; |
224 | 0 | } |
225 | | |
226 | | /* |
227 | | do noise substitution if |
228 | | fuzzy measure is high enough |
229 | | sfb freq > minimum sfb freq |
230 | | signal in coder band is not masked |
231 | | */ |
232 | | |
233 | 0 | if ((pnsData->noiseFuzzyMeasure[sfb] > FL2FXCONST_SGL(0.5)) && |
234 | 0 | ((sfbThresholdLdData[sfb] + |
235 | 0 | FL2FXCONST_DBL(0.5849625f / |
236 | 0 | 64.0f)) /* thr * 1.5 = thrLd +ld(1.5)/64 */ |
237 | 0 | < sfbEnergyLdData[sfb])) { |
238 | | /* |
239 | | mark in psyout flag array that we will code |
240 | | this band with PNS |
241 | | */ |
242 | 0 | pnsData->pnsFlag[sfb] = 1; /* PNS_ON */ |
243 | 0 | } else { |
244 | 0 | pnsData->pnsFlag[sfb] = 0; /* PNS_OFF */ |
245 | 0 | } |
246 | | |
247 | | /* no PNS if LTP is active */ |
248 | 0 | } |
249 | | |
250 | | /* avoid PNS holes */ |
251 | 0 | if ((pnsData->noiseFuzzyMeasure[0] > FL2FXCONST_SGL(0.5f)) && |
252 | 0 | (pnsData->pnsFlag[1])) { |
253 | 0 | pnsData->pnsFlag[0] = 1; |
254 | 0 | } |
255 | |
|
256 | 0 | for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) { |
257 | 0 | if ((pnsData->noiseFuzzyMeasure[sfb] > pnsConf->np.gapFillThr) && |
258 | 0 | (pnsData->pnsFlag[sfb - 1]) && (pnsData->pnsFlag[sfb + 1])) { |
259 | 0 | pnsData->pnsFlag[sfb] = 1; |
260 | 0 | } |
261 | 0 | } |
262 | |
|
263 | 0 | if (maxSfbPerGroup > 0) { |
264 | | /* avoid PNS hole */ |
265 | 0 | if ((pnsData->noiseFuzzyMeasure[maxSfbPerGroup - 1] > |
266 | 0 | pnsConf->np.gapFillThr) && |
267 | 0 | (pnsData->pnsFlag[maxSfbPerGroup - 2])) { |
268 | 0 | pnsData->pnsFlag[maxSfbPerGroup - 1] = 1; |
269 | 0 | } |
270 | | /* avoid single PNS band */ |
271 | 0 | if (pnsData->pnsFlag[maxSfbPerGroup - 2] == 0) { |
272 | 0 | pnsData->pnsFlag[maxSfbPerGroup - 1] = 0; |
273 | 0 | } |
274 | 0 | } |
275 | | |
276 | | /* avoid single PNS bands */ |
277 | 0 | if (pnsData->pnsFlag[1] == 0) { |
278 | 0 | pnsData->pnsFlag[0] = 0; |
279 | 0 | } |
280 | |
|
281 | 0 | for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) { |
282 | 0 | if ((pnsData->pnsFlag[sfb - 1] == 0) && (pnsData->pnsFlag[sfb + 1] == 0)) { |
283 | 0 | pnsData->pnsFlag[sfb] = 0; |
284 | 0 | } |
285 | 0 | } |
286 | | |
287 | | /* |
288 | | calculate noiseNrg's |
289 | | */ |
290 | 0 | FDKaacEnc_CalcNoiseNrgs(sfbActive, pnsData->pnsFlag, sfbEnergyLdData, |
291 | 0 | noiseNrg); |
292 | 0 | } |
293 | | |
294 | | /***************************************************************************** |
295 | | |
296 | | functionname:FDKaacEnc_FDKaacEnc_noiseDetection |
297 | | description: wrapper for noisedet.c |
298 | | returns: |
299 | | input: pns config structure |
300 | | pns data structure (modified), |
301 | | sfbActive |
302 | | tns order and prediction gain |
303 | | pointer to mdct Spectrumand Sfb Energy |
304 | | pointer to Sfb tonality |
305 | | output: noiseFuzzyMeasure in structure pnsData |
306 | | flags tonal / nontonal |
307 | | |
308 | | *****************************************************************************/ |
309 | | static void FDKaacEnc_FDKaacEnc_noiseDetection( |
310 | | PNS_CONFIG *pnsConf, PNS_DATA *pnsData, const INT sfbActive, |
311 | | const INT *sfbOffset, int tnsOrder, INT tnsPredictionGain, INT tnsActive, |
312 | 0 | FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality) { |
313 | 0 | INT condition = TRUE; |
314 | 0 | if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY)) { |
315 | 0 | condition = (tnsOrder > 3); |
316 | 0 | } |
317 | | /* |
318 | | no PNS if heavy TNS activity |
319 | | clear pnsData->noiseFuzzyMeasure |
320 | | */ |
321 | 0 | if ((pnsConf->np.detectionAlgorithmFlags & USE_TNS_GAIN_THR) && |
322 | 0 | (tnsPredictionGain >= pnsConf->np.tnsGainThreshold) && condition && |
323 | 0 | !((pnsConf->np.detectionAlgorithmFlags & USE_TNS_PNS) && |
324 | 0 | (tnsPredictionGain >= pnsConf->np.tnsPNSGainThreshold) && |
325 | 0 | (tnsActive))) { |
326 | | /* clear all noiseFuzzyMeasure */ |
327 | 0 | FDKmemclear(pnsData->noiseFuzzyMeasure, sfbActive * sizeof(FIXP_SGL)); |
328 | 0 | } else { |
329 | | /* |
330 | | call noise detection, output in pnsData->noiseFuzzyMeasure, |
331 | | use real mdct spectral data |
332 | | */ |
333 | 0 | FDKaacEnc_noiseDetect(mdctSpectrum, sfbMaxScaleSpec, sfbActive, sfbOffset, |
334 | 0 | pnsData->noiseFuzzyMeasure, &pnsConf->np, |
335 | 0 | sfbtonality); |
336 | 0 | } |
337 | 0 | } |
338 | | |
339 | | /***************************************************************************** |
340 | | |
341 | | functionname:FDKaacEnc_CalcNoiseNrgs |
342 | | description: Calculate the NoiseNrg's |
343 | | returns: |
344 | | input: sfbActive |
345 | | if pnsFlag calculate NoiseNrg |
346 | | pointer to sfbEnergy and groupLen |
347 | | pointer to noiseNrg (modified) |
348 | | output: noiseNrg's in pnsFlaged sfb's |
349 | | |
350 | | *****************************************************************************/ |
351 | | |
352 | | static void FDKaacEnc_CalcNoiseNrgs(const INT sfbActive, INT *RESTRICT pnsFlag, |
353 | | FIXP_DBL *RESTRICT sfbEnergyLdData, |
354 | 0 | INT *RESTRICT noiseNrg) { |
355 | 0 | int sfb; |
356 | 0 | INT tmp = (-LOG_NORM_PCM) << 2; |
357 | |
|
358 | 0 | for (sfb = 0; sfb < sfbActive; sfb++) { |
359 | 0 | if (pnsFlag[sfb]) { |
360 | 0 | INT nrg = (-sfbEnergyLdData[sfb] + FL2FXCONST_DBL(0.5f / 64.0f)) >> |
361 | 0 | (DFRACT_BITS - 1 - 7); |
362 | 0 | noiseNrg[sfb] = tmp - nrg; |
363 | 0 | } |
364 | 0 | } |
365 | 0 | } |
366 | | |
367 | | /***************************************************************************** |
368 | | |
369 | | functionname:FDKaacEnc_CodePnsChannel |
370 | | description: Execute pns decission |
371 | | returns: |
372 | | input: sfbActive |
373 | | pns config structure |
374 | | use PNS if pnsFlag |
375 | | pointer to Sfb Energy, noiseNrg, Threshold |
376 | | output: set sfbThreshold high to code pe with 0, |
377 | | noiseNrg marks flag for pns coding |
378 | | |
379 | | *****************************************************************************/ |
380 | | |
381 | | void FDKaacEnc_CodePnsChannel(const INT sfbActive, PNS_CONFIG *pnsConf, |
382 | | INT *RESTRICT pnsFlag, |
383 | | FIXP_DBL *RESTRICT sfbEnergyLdData, |
384 | | INT *RESTRICT noiseNrg, |
385 | 0 | FIXP_DBL *RESTRICT sfbThresholdLdData) { |
386 | 0 | INT sfb; |
387 | 0 | INT lastiNoiseEnergy = 0; |
388 | 0 | INT firstPNSband = 1; /* TRUE for first PNS-coded band */ |
389 | | |
390 | | /* no PNS */ |
391 | 0 | if (!pnsConf->usePns) { |
392 | 0 | for (sfb = 0; sfb < sfbActive; sfb++) { |
393 | | /* no PNS coding */ |
394 | 0 | noiseNrg[sfb] = NO_NOISE_PNS; |
395 | 0 | } |
396 | 0 | return; |
397 | 0 | } |
398 | | |
399 | | /* code PNS */ |
400 | 0 | for (sfb = 0; sfb < sfbActive; sfb++) { |
401 | 0 | if (pnsFlag[sfb]) { |
402 | | /* high sfbThreshold causes pe = 0 */ |
403 | 0 | if (noiseNrg[sfb] != NO_NOISE_PNS) |
404 | 0 | sfbThresholdLdData[sfb] = |
405 | 0 | sfbEnergyLdData[sfb] + FL2FXCONST_DBL(1.0f / LD_DATA_SCALING); |
406 | | |
407 | | /* set noiseNrg in valid region */ |
408 | 0 | if (!firstPNSband) { |
409 | 0 | INT deltaiNoiseEnergy = noiseNrg[sfb] - lastiNoiseEnergy; |
410 | |
|
411 | 0 | if (deltaiNoiseEnergy > CODE_BOOK_PNS_LAV) |
412 | 0 | noiseNrg[sfb] -= deltaiNoiseEnergy - CODE_BOOK_PNS_LAV; |
413 | 0 | else if (deltaiNoiseEnergy < -CODE_BOOK_PNS_LAV) |
414 | 0 | noiseNrg[sfb] -= deltaiNoiseEnergy + CODE_BOOK_PNS_LAV; |
415 | 0 | } else { |
416 | 0 | firstPNSband = 0; |
417 | 0 | } |
418 | 0 | lastiNoiseEnergy = noiseNrg[sfb]; |
419 | 0 | } else { |
420 | | /* no PNS coding */ |
421 | 0 | noiseNrg[sfb] = NO_NOISE_PNS; |
422 | 0 | } |
423 | 0 | } |
424 | 0 | } |
425 | | |
426 | | /***************************************************************************** |
427 | | |
428 | | functionname:FDKaacEnc_PreProcessPnsChannelPair |
429 | | description: Calculate the correlation of noise in a channel pair |
430 | | |
431 | | returns: |
432 | | input: sfbActive |
433 | | pointer to sfb energies left, right and mid channel |
434 | | pns config structure |
435 | | pns data structure left and right (modified) |
436 | | |
437 | | output: noiseEnergyCorrelation in pns data structure |
438 | | |
439 | | *****************************************************************************/ |
440 | | |
441 | | void FDKaacEnc_PreProcessPnsChannelPair( |
442 | | const INT sfbActive, FIXP_DBL *RESTRICT sfbEnergyLeft, |
443 | | FIXP_DBL *RESTRICT sfbEnergyRight, FIXP_DBL *RESTRICT sfbEnergyLeftLD, |
444 | | FIXP_DBL *RESTRICT sfbEnergyRightLD, FIXP_DBL *RESTRICT sfbEnergyMid, |
445 | | PNS_CONFIG *RESTRICT pnsConf, PNS_DATA *pnsDataLeft, |
446 | 0 | PNS_DATA *pnsDataRight) { |
447 | 0 | INT sfb; |
448 | 0 | FIXP_DBL ccf; |
449 | |
|
450 | 0 | if (!pnsConf->usePns) return; |
451 | | |
452 | 0 | FIXP_DBL *RESTRICT pNoiseEnergyCorrelationL = |
453 | 0 | pnsDataLeft->noiseEnergyCorrelation; |
454 | 0 | FIXP_DBL *RESTRICT pNoiseEnergyCorrelationR = |
455 | 0 | pnsDataRight->noiseEnergyCorrelation; |
456 | |
|
457 | 0 | for (sfb = 0; sfb < sfbActive; sfb++) { |
458 | 0 | FIXP_DBL quot = (sfbEnergyLeftLD[sfb] >> 1) + (sfbEnergyRightLD[sfb] >> 1); |
459 | |
|
460 | 0 | if (quot < FL2FXCONST_DBL(-32.0f / (float)LD_DATA_SCALING)) |
461 | 0 | ccf = FL2FXCONST_DBL(0.0f); |
462 | 0 | else { |
463 | 0 | FIXP_DBL accu = |
464 | 0 | sfbEnergyMid[sfb] - |
465 | 0 | (((sfbEnergyLeft[sfb] >> 1) + (sfbEnergyRight[sfb] >> 1)) >> 1); |
466 | 0 | INT sign = (accu < FL2FXCONST_DBL(0.0f)) ? 1 : 0; |
467 | 0 | accu = fixp_abs(accu); |
468 | |
|
469 | 0 | ccf = CalcLdData(accu) + |
470 | 0 | FL2FXCONST_DBL((float)1.0f / (float)LD_DATA_SCALING) - |
471 | 0 | quot; /* ld(accu*2) = ld(accu) + 1 */ |
472 | 0 | ccf = (ccf >= FL2FXCONST_DBL(0.0)) |
473 | 0 | ? ((FIXP_DBL)MAXVAL_DBL) |
474 | 0 | : (sign) ? -CalcInvLdData(ccf) : CalcInvLdData(ccf); |
475 | 0 | } |
476 | |
|
477 | 0 | pNoiseEnergyCorrelationL[sfb] = ccf; |
478 | 0 | pNoiseEnergyCorrelationR[sfb] = ccf; |
479 | 0 | } |
480 | 0 | } |
481 | | |
482 | | /***************************************************************************** |
483 | | |
484 | | functionname:FDKaacEnc_PostProcessPnsChannelPair |
485 | | description: if PNS used at left and right channel, |
486 | | use msMask to flag correlation |
487 | | returns: |
488 | | input: sfbActive |
489 | | pns config structure |
490 | | pns data structure left and right (modified) |
491 | | pointer to msMask, flags correlation by pns coding (modified) |
492 | | Digest of MS coding |
493 | | output: pnsFlag in pns data structure, |
494 | | msFlag in msMask (flags correlation) |
495 | | |
496 | | *****************************************************************************/ |
497 | | |
498 | | void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive, |
499 | | PNS_CONFIG *pnsConf, |
500 | | PNS_DATA *pnsDataLeft, |
501 | | PNS_DATA *pnsDataRight, |
502 | 0 | INT *RESTRICT msMask, INT *msDigest) { |
503 | 0 | INT sfb; |
504 | |
|
505 | 0 | if (!pnsConf->usePns) return; |
506 | | |
507 | 0 | for (sfb = 0; sfb < sfbActive; sfb++) { |
508 | | /* |
509 | | MS post processing |
510 | | */ |
511 | 0 | if (msMask[sfb]) { |
512 | 0 | if ((pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb])) { |
513 | | /* AAC only: Standard */ |
514 | | /* do this to avoid ms flags in layers that should not have it */ |
515 | 0 | if (pnsDataLeft->noiseEnergyCorrelation[sfb] <= |
516 | 0 | pnsConf->noiseCorrelationThresh) { |
517 | 0 | msMask[sfb] = 0; |
518 | 0 | *msDigest = MS_SOME; |
519 | 0 | } |
520 | 0 | } else { |
521 | | /* |
522 | | No PNS coding |
523 | | */ |
524 | 0 | pnsDataLeft->pnsFlag[sfb] = 0; |
525 | 0 | pnsDataRight->pnsFlag[sfb] = 0; |
526 | 0 | } |
527 | 0 | } |
528 | | |
529 | | /* |
530 | | Use MS flag to signal noise correlation if |
531 | | pns is active in both channels |
532 | | */ |
533 | 0 | if ((pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb])) { |
534 | 0 | if (pnsDataLeft->noiseEnergyCorrelation[sfb] > |
535 | 0 | pnsConf->noiseCorrelationThresh) { |
536 | 0 | msMask[sfb] = 1; |
537 | 0 | *msDigest = MS_SOME; |
538 | 0 | } |
539 | 0 | } |
540 | 0 | } |
541 | 0 | } |