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
FDKaacEnc_InitPnsConfiguration(PNS_CONFIG * pnsConf,INT bitRate,INT sampleRate,INT usePns,INT sfbCnt,const INT * sfbOffset,const INT numChan,const INT isLC)137 AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(
138 PNS_CONFIG *pnsConf, INT bitRate, INT sampleRate, INT usePns, INT sfbCnt,
139 const INT *sfbOffset, const INT numChan, const INT isLC) {
140 AAC_ENCODER_ERROR ErrorStatus;
141
142 /* init noise detection */
143 ErrorStatus = FDKaacEnc_GetPnsParam(&pnsConf->np, bitRate, sampleRate, sfbCnt,
144 sfbOffset, &usePns, numChan, isLC);
145 if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
146
147 pnsConf->minCorrelationEnergy = minCorrelationEnergy;
148 pnsConf->noiseCorrelationThresh = noiseCorrelationThresh;
149
150 pnsConf->usePns = usePns;
151
152 return AAC_ENC_OK;
153 }
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 *****************************************************************************/
FDKaacEnc_PnsDetect(PNS_CONFIG * pnsConf,PNS_DATA * pnsData,const INT lastWindowSequence,const INT sfbActive,const INT maxSfbPerGroup,FIXP_DBL * sfbThresholdLdData,const INT * sfbOffset,FIXP_DBL * mdctSpectrum,INT * sfbMaxScaleSpec,FIXP_SGL * sfbtonality,INT tnsOrder,INT tnsPredictionGain,INT tnsActive,FIXP_DBL * sfbEnergyLdData,INT * noiseNrg)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 {
182 int sfb;
183 int startNoiseSfb;
184
185 /* Reset pns info. */
186 FDKmemclear(pnsData->pnsFlag, sizeof(pnsData->pnsFlag));
187 for (sfb = 0; sfb < MAX_GROUPED_SFB; sfb++) {
188 noiseNrg[sfb] = NO_NOISE_PNS;
189 }
190
191 /* Disable PNS and skip detection in certain cases. */
192 if (pnsConf->usePns == 0) {
193 return;
194 } else {
195 /* AAC - LC core encoder */
196 if ((pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) &&
197 (lastWindowSequence == SHORT_WINDOW)) {
198 return;
199 }
200 /* AAC - (E)LD core encoder */
201 if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) &&
202 (pnsConf->np.detectionAlgorithmFlags & JUST_LONG_WINDOW) &&
203 (lastWindowSequence != LONG_WINDOW)) {
204 return;
205 }
206 }
207
208 /*
209 call noise detection
210 */
211 FDKaacEnc_FDKaacEnc_noiseDetection(
212 pnsConf, pnsData, sfbActive, sfbOffset, tnsOrder, tnsPredictionGain,
213 tnsActive, mdctSpectrum, sfbMaxScaleSpec, sfbtonality);
214
215 /* set startNoiseSfb (long) */
216 startNoiseSfb = pnsConf->np.startSfb;
217
218 /* Set noise substitution status */
219 for (sfb = 0; sfb < sfbActive; sfb++) {
220 /* No PNS below startNoiseSfb */
221 if (sfb < startNoiseSfb) {
222 pnsData->pnsFlag[sfb] = 0;
223 continue;
224 }
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 if ((pnsData->noiseFuzzyMeasure[sfb] > FL2FXCONST_SGL(0.5)) &&
234 ((sfbThresholdLdData[sfb] +
235 FL2FXCONST_DBL(0.5849625f /
236 64.0f)) /* thr * 1.5 = thrLd +ld(1.5)/64 */
237 < sfbEnergyLdData[sfb])) {
238 /*
239 mark in psyout flag array that we will code
240 this band with PNS
241 */
242 pnsData->pnsFlag[sfb] = 1; /* PNS_ON */
243 } else {
244 pnsData->pnsFlag[sfb] = 0; /* PNS_OFF */
245 }
246
247 /* no PNS if LTP is active */
248 }
249
250 /* avoid PNS holes */
251 if ((pnsData->noiseFuzzyMeasure[0] > FL2FXCONST_SGL(0.5f)) &&
252 (pnsData->pnsFlag[1])) {
253 pnsData->pnsFlag[0] = 1;
254 }
255
256 for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) {
257 if ((pnsData->noiseFuzzyMeasure[sfb] > pnsConf->np.gapFillThr) &&
258 (pnsData->pnsFlag[sfb - 1]) && (pnsData->pnsFlag[sfb + 1])) {
259 pnsData->pnsFlag[sfb] = 1;
260 }
261 }
262
263 if (maxSfbPerGroup > 0) {
264 /* avoid PNS hole */
265 if ((pnsData->noiseFuzzyMeasure[maxSfbPerGroup - 1] >
266 pnsConf->np.gapFillThr) &&
267 (pnsData->pnsFlag[maxSfbPerGroup - 2])) {
268 pnsData->pnsFlag[maxSfbPerGroup - 1] = 1;
269 }
270 /* avoid single PNS band */
271 if (pnsData->pnsFlag[maxSfbPerGroup - 2] == 0) {
272 pnsData->pnsFlag[maxSfbPerGroup - 1] = 0;
273 }
274 }
275
276 /* avoid single PNS bands */
277 if (pnsData->pnsFlag[1] == 0) {
278 pnsData->pnsFlag[0] = 0;
279 }
280
281 for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) {
282 if ((pnsData->pnsFlag[sfb - 1] == 0) && (pnsData->pnsFlag[sfb + 1] == 0)) {
283 pnsData->pnsFlag[sfb] = 0;
284 }
285 }
286
287 /*
288 calculate noiseNrg's
289 */
290 FDKaacEnc_CalcNoiseNrgs(sfbActive, pnsData->pnsFlag, sfbEnergyLdData,
291 noiseNrg);
292 }
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 *****************************************************************************/
FDKaacEnc_FDKaacEnc_noiseDetection(PNS_CONFIG * pnsConf,PNS_DATA * pnsData,const INT sfbActive,const INT * sfbOffset,int tnsOrder,INT tnsPredictionGain,INT tnsActive,FIXP_DBL * mdctSpectrum,INT * sfbMaxScaleSpec,FIXP_SGL * sfbtonality)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 FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality) {
313 INT condition = TRUE;
314 if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY)) {
315 condition = (tnsOrder > 3);
316 }
317 /*
318 no PNS if heavy TNS activity
319 clear pnsData->noiseFuzzyMeasure
320 */
321 if ((pnsConf->np.detectionAlgorithmFlags & USE_TNS_GAIN_THR) &&
322 (tnsPredictionGain >= pnsConf->np.tnsGainThreshold) && condition &&
323 !((pnsConf->np.detectionAlgorithmFlags & USE_TNS_PNS) &&
324 (tnsPredictionGain >= pnsConf->np.tnsPNSGainThreshold) &&
325 (tnsActive))) {
326 /* clear all noiseFuzzyMeasure */
327 FDKmemclear(pnsData->noiseFuzzyMeasure, sfbActive * sizeof(FIXP_SGL));
328 } else {
329 /*
330 call noise detection, output in pnsData->noiseFuzzyMeasure,
331 use real mdct spectral data
332 */
333 FDKaacEnc_noiseDetect(mdctSpectrum, sfbMaxScaleSpec, sfbActive, sfbOffset,
334 pnsData->noiseFuzzyMeasure, &pnsConf->np,
335 sfbtonality);
336 }
337 }
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
FDKaacEnc_CalcNoiseNrgs(const INT sfbActive,INT * RESTRICT pnsFlag,FIXP_DBL * RESTRICT sfbEnergyLdData,INT * RESTRICT noiseNrg)352 static void FDKaacEnc_CalcNoiseNrgs(const INT sfbActive, INT *RESTRICT pnsFlag,
353 FIXP_DBL *RESTRICT sfbEnergyLdData,
354 INT *RESTRICT noiseNrg) {
355 int sfb;
356 INT tmp = (-LOG_NORM_PCM) << 2;
357
358 for (sfb = 0; sfb < sfbActive; sfb++) {
359 if (pnsFlag[sfb]) {
360 INT nrg = (-sfbEnergyLdData[sfb] + FL2FXCONST_DBL(0.5f / 64.0f)) >>
361 (DFRACT_BITS - 1 - 7);
362 noiseNrg[sfb] = tmp - nrg;
363 }
364 }
365 }
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
FDKaacEnc_CodePnsChannel(const INT sfbActive,PNS_CONFIG * pnsConf,INT * RESTRICT pnsFlag,FIXP_DBL * RESTRICT sfbEnergyLdData,INT * RESTRICT noiseNrg,FIXP_DBL * RESTRICT sfbThresholdLdData)381 void FDKaacEnc_CodePnsChannel(const INT sfbActive, PNS_CONFIG *pnsConf,
382 INT *RESTRICT pnsFlag,
383 FIXP_DBL *RESTRICT sfbEnergyLdData,
384 INT *RESTRICT noiseNrg,
385 FIXP_DBL *RESTRICT sfbThresholdLdData) {
386 INT sfb;
387 INT lastiNoiseEnergy = 0;
388 INT firstPNSband = 1; /* TRUE for first PNS-coded band */
389
390 /* no PNS */
391 if (!pnsConf->usePns) {
392 for (sfb = 0; sfb < sfbActive; sfb++) {
393 /* no PNS coding */
394 noiseNrg[sfb] = NO_NOISE_PNS;
395 }
396 return;
397 }
398
399 /* code PNS */
400 for (sfb = 0; sfb < sfbActive; sfb++) {
401 if (pnsFlag[sfb]) {
402 /* high sfbThreshold causes pe = 0 */
403 if (noiseNrg[sfb] != NO_NOISE_PNS)
404 sfbThresholdLdData[sfb] =
405 sfbEnergyLdData[sfb] + FL2FXCONST_DBL(1.0f / LD_DATA_SCALING);
406
407 /* set noiseNrg in valid region */
408 if (!firstPNSband) {
409 INT deltaiNoiseEnergy = noiseNrg[sfb] - lastiNoiseEnergy;
410
411 if (deltaiNoiseEnergy > CODE_BOOK_PNS_LAV)
412 noiseNrg[sfb] -= deltaiNoiseEnergy - CODE_BOOK_PNS_LAV;
413 else if (deltaiNoiseEnergy < -CODE_BOOK_PNS_LAV)
414 noiseNrg[sfb] -= deltaiNoiseEnergy + CODE_BOOK_PNS_LAV;
415 } else {
416 firstPNSband = 0;
417 }
418 lastiNoiseEnergy = noiseNrg[sfb];
419 } else {
420 /* no PNS coding */
421 noiseNrg[sfb] = NO_NOISE_PNS;
422 }
423 }
424 }
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
FDKaacEnc_PreProcessPnsChannelPair(const INT sfbActive,FIXP_DBL * RESTRICT sfbEnergyLeft,FIXP_DBL * RESTRICT sfbEnergyRight,FIXP_DBL * RESTRICT sfbEnergyLeftLD,FIXP_DBL * RESTRICT sfbEnergyRightLD,FIXP_DBL * RESTRICT sfbEnergyMid,PNS_CONFIG * RESTRICT pnsConf,PNS_DATA * pnsDataLeft,PNS_DATA * pnsDataRight)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 PNS_DATA *pnsDataRight) {
447 INT sfb;
448 FIXP_DBL ccf;
449
450 if (!pnsConf->usePns) return;
451
452 FIXP_DBL *RESTRICT pNoiseEnergyCorrelationL =
453 pnsDataLeft->noiseEnergyCorrelation;
454 FIXP_DBL *RESTRICT pNoiseEnergyCorrelationR =
455 pnsDataRight->noiseEnergyCorrelation;
456
457 for (sfb = 0; sfb < sfbActive; sfb++) {
458 FIXP_DBL quot = (sfbEnergyLeftLD[sfb] >> 1) + (sfbEnergyRightLD[sfb] >> 1);
459
460 if (quot < FL2FXCONST_DBL(-32.0f / (float)LD_DATA_SCALING))
461 ccf = FL2FXCONST_DBL(0.0f);
462 else {
463 FIXP_DBL accu =
464 sfbEnergyMid[sfb] -
465 (((sfbEnergyLeft[sfb] >> 1) + (sfbEnergyRight[sfb] >> 1)) >> 1);
466 INT sign = (accu < FL2FXCONST_DBL(0.0f)) ? 1 : 0;
467 accu = fixp_abs(accu);
468
469 ccf = CalcLdData(accu) +
470 FL2FXCONST_DBL((float)1.0f / (float)LD_DATA_SCALING) -
471 quot; /* ld(accu*2) = ld(accu) + 1 */
472 ccf = (ccf >= FL2FXCONST_DBL(0.0))
473 ? ((FIXP_DBL)MAXVAL_DBL)
474 : (sign) ? -CalcInvLdData(ccf) : CalcInvLdData(ccf);
475 }
476
477 pNoiseEnergyCorrelationL[sfb] = ccf;
478 pNoiseEnergyCorrelationR[sfb] = ccf;
479 }
480 }
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
FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive,PNS_CONFIG * pnsConf,PNS_DATA * pnsDataLeft,PNS_DATA * pnsDataRight,INT * RESTRICT msMask,INT * msDigest)498 void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive,
499 PNS_CONFIG *pnsConf,
500 PNS_DATA *pnsDataLeft,
501 PNS_DATA *pnsDataRight,
502 INT *RESTRICT msMask, INT *msDigest) {
503 INT sfb;
504
505 if (!pnsConf->usePns) return;
506
507 for (sfb = 0; sfb < sfbActive; sfb++) {
508 /*
509 MS post processing
510 */
511 if (msMask[sfb]) {
512 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 if (pnsDataLeft->noiseEnergyCorrelation[sfb] <=
516 pnsConf->noiseCorrelationThresh) {
517 msMask[sfb] = 0;
518 *msDigest = MS_SOME;
519 }
520 } else {
521 /*
522 No PNS coding
523 */
524 pnsDataLeft->pnsFlag[sfb] = 0;
525 pnsDataRight->pnsFlag[sfb] = 0;
526 }
527 }
528
529 /*
530 Use MS flag to signal noise correlation if
531 pns is active in both channels
532 */
533 if ((pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb])) {
534 if (pnsDataLeft->noiseEnergyCorrelation[sfb] >
535 pnsConf->noiseCorrelationThresh) {
536 msMask[sfb] = 1;
537 *msDigest = MS_SOME;
538 }
539 }
540 }
541 }
542