Home | History | Annotate | Download | only in src
      1 /* -----------------------------------------------------------------------------
      2 Software License for The Fraunhofer FDK AAC Codec Library for Android
      3 
      4  Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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     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 *****************************************************************************/
    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 *****************************************************************************/
    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 
    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 
    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 
    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 
    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