/*
 ** Copyright 2003-2010, VisualOn, Inc.
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
/*******************************************************************************
	File:		adj_thr.c

	Content:	Threshold compensation functions

*******************************************************************************/

/* Include system headers before local headers - the local headers
 * redefine __inline, which can mess up definitions in libc headers if
 * they happen to use __inline. */
#include <string.h>
#include "basic_op.h"
#include "oper_32b.h"
#include "adj_thr_data.h"
#include "adj_thr.h"
#include "qc_data.h"
#include "line_pe.h"


#define  minSnrLimit    0x6666 /* 1 dB */
#define  PEBITS_COEF	0x170a /* 0.18*(1 << 15)*/

#define  HOLE_THR_LONG	0x2873	/* 0.316*(1 << 15) */
#define  HOLE_THR_SHORT 0x4000  /* 0.5  *(1 << 15) */

#define  MS_THRSPREAD_COEF 0x7333  /* 0.9 * (1 << 15) */

#define	 MIN_SNR_COEF	   0x651f  /* 3.16* (1 << (15 - 2)) */

/* values for avoid hole flag */
enum _avoid_hole_state {
  NO_AH              =0,
  AH_INACTIVE        =1,
  AH_ACTIVE          =2
};

/********************************************************************************
*
* function name:bits2pe
* description: convert from bits to pe
*			   pe = 1.18*desiredBits
*
**********************************************************************************/
Word16 bits2pe(const Word16 bits) {
  return (bits + ((PEBITS_COEF * bits) >> 15));
}

/********************************************************************************
*
* function name:calcThreshExp
* description: loudness calculation (threshold to the power of redExp)
*			   thr(n)^0.25
*
**********************************************************************************/
static void calcThreshExp(Word32 thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],
                          PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
                          const Word16 nChannels)
{
  Word16 ch, sfb, sfbGrp;
  Word32 *pthrExp = NULL, *psfbThre;
  for (ch=0; ch<nChannels; ch++) {
    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
	 for(sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; sfbGrp+= psyOutChan->sfbPerGroup)
	  pthrExp = &(thrExp[ch][sfbGrp]);
	  psfbThre = psyOutChan->sfbThreshold + sfbGrp;
	  for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
		*pthrExp = rsqrt(rsqrt(*psfbThre,INT_BITS),INT_BITS);
		pthrExp++; psfbThre++;
      }
  }
}

/********************************************************************************
*
* function name:adaptMinSnr
* description: reduce minSnr requirements for bands with relative low energies
*
**********************************************************************************/
static void adaptMinSnr(PSY_OUT_CHANNEL     psyOutChannel[MAX_CHANNELS],
                        Word16              logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
                        MINSNR_ADAPT_PARAM *msaParam,
                        const Word16        nChannels)
{
  Word16 ch, sfb, sfbOffs;
  Word32 nSfb, avgEn;
  Word16 log_avgEn = 0;
  Word32 startRatio_x_avgEn = 0;


  for (ch=0; ch<nChannels; ch++) {
    PSY_OUT_CHANNEL* psyOutChan = &psyOutChannel[ch];

    /* calc average energy per scalefactor band */
    avgEn = 0;
    nSfb = 0;
    for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup) {
      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
        avgEn = L_add(avgEn, psyOutChan->sfbEnergy[sfbOffs+sfb]);
        nSfb = nSfb + 1;
      }
    }

    if (nSfb > 0) {
	  avgEn = avgEn / nSfb;

      log_avgEn = iLog4(avgEn);
      startRatio_x_avgEn = fixmul(msaParam->startRatio, avgEn);
    }


    /* reduce minSnr requirement by minSnr^minSnrRed dependent on avgEn/sfbEn */
    for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup) {
      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
        if (psyOutChan->sfbEnergy[sfbOffs+sfb] < startRatio_x_avgEn) {
          Word16 dbRatio, minSnrRed;
          Word32 snrRed;
          Word16 newMinSnr;

          dbRatio = log_avgEn - logSfbEnergy[ch][sfbOffs+sfb];
          dbRatio = dbRatio + (dbRatio << 1);

          minSnrRed = 110 - ((dbRatio + (dbRatio << 1)) >> 2);
          minSnrRed = max(minSnrRed, 20); /* 110: (0.375(redOffs)+1)*80,
                                               3: 0.00375(redRatioFac)*80
                                               20: 0.25(maxRed) * 80 */

          snrRed = minSnrRed * iLog4((psyOutChan->sfbMinSnr[sfbOffs+sfb] << 16));
          /*
             snrRedI si now scaled by 80 (minSnrRed) and 4 (ffr_iLog4)
          */

          newMinSnr = round16(pow2_xy(snrRed,80*4));

          psyOutChan->sfbMinSnr[sfbOffs+sfb] = min(newMinSnr, minSnrLimit);
        }
      }
    }
  }

}


/********************************************************************************
*
* function name:initAvoidHoleFlag
* description: determine bands where avoid hole is not necessary resp. possible
*
**********************************************************************************/
static void initAvoidHoleFlag(Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
                              PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
                              PSY_OUT_ELEMENT* psyOutElement,
                              const Word16 nChannels,
                              AH_PARAM *ahParam)
{
  Word16 ch, sfb, sfbGrp, shift;
  Word32 threshold;
  Word32* psfbSpreadEn;

  for (ch=0; ch<nChannels; ch++) {
    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];

    if (psyOutChan->windowSequence != SHORT_WINDOW) {
      for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
         psfbSpreadEn = psyOutChan->sfbSpreadedEnergy + sfbGrp;
		 for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
			*psfbSpreadEn = *psfbSpreadEn >> 1;  /* 0.5 */
			++psfbSpreadEn;
        }
      }
    }
    else {
      for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
		psfbSpreadEn = psyOutChan->sfbSpreadedEnergy + sfbGrp;
        for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
          *psfbSpreadEn = (*psfbSpreadEn >> 1) + (*psfbSpreadEn >> 3);  /* 0.63 */
		  ++psfbSpreadEn;
        }
      }
    }
  }

  /* increase minSnr for local peaks, decrease it for valleys */
  if (ahParam->modifyMinSnr) {
    for(ch=0; ch<nChannels; ch++) {
      PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];

      if (psyOutChan->windowSequence != SHORT_WINDOW)
        threshold = HOLE_THR_LONG;
      else
        threshold = HOLE_THR_SHORT;

      for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
        Word16 *psfbMinSnr = psyOutChan->sfbMinSnr + sfbGrp;
		for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
          Word32 sfbEn, sfbEnm1, sfbEnp1, avgEn;

          if (sfb > 0)
            sfbEnm1 = psyOutChan->sfbEnergy[sfbGrp+sfb-1];
          else
            sfbEnm1 = psyOutChan->sfbEnergy[sfbGrp];

          if (sfb < (psyOutChan->maxSfbPerGroup-1))
            sfbEnp1 = psyOutChan->sfbEnergy[sfbGrp+sfb+1];
          else
            sfbEnp1 = psyOutChan->sfbEnergy[sfbGrp+sfb];
          avgEn = (sfbEnm1 + sfbEnp1) >> 1;
          sfbEn = psyOutChan->sfbEnergy[sfbGrp+sfb];

          if (sfbEn > avgEn && avgEn > 0) {
            Word32 tmpMinSnr;
            shift = norm_l(sfbEn);
			tmpMinSnr = Div_32(L_mpy_ls(avgEn, minSnrLimit) << shift, sfbEn << shift );
            tmpMinSnr = max(tmpMinSnr, HOLE_THR_LONG);
            tmpMinSnr = max(tmpMinSnr, threshold);
            *psfbMinSnr = min(*psfbMinSnr, tmpMinSnr);
          }
          /* valley ? */

          if ((sfbEn < (avgEn >> 1)) && (sfbEn > 0)) {
            Word32 tmpMinSnr;
            Word32 minSnrEn = L_mpy_wx(avgEn, *psfbMinSnr);

            if(minSnrEn < sfbEn) {
			  shift = norm_l(sfbEn);
              tmpMinSnr = Div_32( minSnrEn << shift, sfbEn<<shift);
            }
            else {
              tmpMinSnr = MAX_16;
            }
            tmpMinSnr = min(minSnrLimit, tmpMinSnr);

            *psfbMinSnr =
              (min((tmpMinSnr >>  2), mult(*psfbMinSnr, MIN_SNR_COEF)) << 2);
          }
		  psfbMinSnr++;
        }
      }
    }
  }

  /* stereo: adapt the minimum requirements sfbMinSnr of mid and
     side channels */

  if (nChannels == 2) {
    PSY_OUT_CHANNEL *psyOutChanM = &psyOutChannel[0];
    PSY_OUT_CHANNEL *psyOutChanS = &psyOutChannel[1];
    for (sfb=0; sfb<psyOutChanM->sfbCnt; sfb++) {
      if (psyOutElement->toolsInfo.msMask[sfb]) {
        Word32 sfbEnM = psyOutChanM->sfbEnergy[sfb];
        Word32 sfbEnS = psyOutChanS->sfbEnergy[sfb];
        Word32 maxSfbEn = max(sfbEnM, sfbEnS);
        Word32 maxThr = L_mpy_wx(maxSfbEn, psyOutChanM->sfbMinSnr[sfb]) >> 1;

        if(maxThr >= sfbEnM) {
          psyOutChanM->sfbMinSnr[sfb] = MAX_16;
        }
        else {
          shift = norm_l(sfbEnM);
		  psyOutChanM->sfbMinSnr[sfb] = min(max(psyOutChanM->sfbMinSnr[sfb],
			  round16(Div_32(maxThr<<shift, sfbEnM << shift))), minSnrLimit);
        }

        if(maxThr >= sfbEnS) {
          psyOutChanS->sfbMinSnr[sfb] = MAX_16;
        }
        else {
		  shift = norm_l(sfbEnS);
          psyOutChanS->sfbMinSnr[sfb] = min(max(psyOutChanS->sfbMinSnr[sfb],
			  round16(Div_32(maxThr << shift, sfbEnS << shift))), minSnrLimit);
        }


        if (sfbEnM > psyOutChanM->sfbSpreadedEnergy[sfb])
          psyOutChanS->sfbSpreadedEnergy[sfb] = L_mpy_ls(sfbEnS, MS_THRSPREAD_COEF);

        if (sfbEnS > psyOutChanS->sfbSpreadedEnergy[sfb])
          psyOutChanM->sfbSpreadedEnergy[sfb] = L_mpy_ls(sfbEnM, MS_THRSPREAD_COEF);
      }
    }
  }


  /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */
  for(ch=0; ch<nChannels; ch++) {
    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
    for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
      Word16 *pahFlag = ahFlag[ch] + sfbGrp;
	  for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {

        if ((psyOutChan->sfbSpreadedEnergy[sfbGrp+sfb] > psyOutChan->sfbEnergy[sfbGrp+sfb]) ||
            (psyOutChan->sfbEnergy[sfbGrp+sfb] <= psyOutChan->sfbThreshold[sfbGrp+sfb]) ||
            (psyOutChan->sfbMinSnr[sfbGrp+sfb] == MAX_16)) {
          *pahFlag++ = NO_AH;
        }
        else {
          *pahFlag++ = AH_INACTIVE;
        }
      }
      for (sfb=psyOutChan->maxSfbPerGroup; sfb<psyOutChan->sfbPerGroup; sfb++) {
        *pahFlag++ = NO_AH;
      }
    }
  }
}

/********************************************************************************
*
* function name:calcPeNoAH
* description: sum the pe data only for bands where avoid hole is inactive
*
**********************************************************************************/
static void calcPeNoAH(Word16          *pe,
                       Word16          *constPart,
                       Word16          *nActiveLines,
                       PE_DATA         *peData,
                       Word16           ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
                       PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
                       const Word16     nChannels)
{
  Word16 ch, sfb, sfbGrp;
  int ipe, iconstPart, inActiveLines;

  ipe = 0;
  iconstPart = 0;
  inActiveLines = 0;
  for(ch=0; ch<nChannels; ch++) {
    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
    PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
    for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {

        if (ahFlag[ch][sfbGrp+sfb] < AH_ACTIVE) {
          ipe = ipe + peChanData->sfbPe[sfbGrp+sfb];
          iconstPart = iconstPart + peChanData->sfbConstPart[sfbGrp+sfb];
          inActiveLines = inActiveLines + peChanData->sfbNActiveLines[sfbGrp+sfb];
        }
      }
    }
  }

  *pe = saturate(ipe);
  *constPart = saturate(iconstPart);
  *nActiveLines = saturate(inActiveLines);
}

/********************************************************************************
*
* function name:reduceThresholds
* description: apply reduction formula
*
**********************************************************************************/
static void reduceThresholds(PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
                             Word16           ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
                             Word32           thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],
                             const Word16     nChannels,
                             const Word32     redVal)
{
  Word32 sfbThrReduced;
  Word32 *psfbEn, *psfbThr;
  Word16 ch, sfb, sfbGrp;

  for(ch=0; ch<nChannels; ch++) {
    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
    for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {
 	  psfbEn  = psyOutChan->sfbEnergy + sfbGrp;
      psfbThr = psyOutChan->sfbThreshold + sfbGrp;
	  for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {

        if (*psfbEn > *psfbThr) {
          /* threshold reduction formula */
          Word32 tmp = thrExp[ch][sfbGrp+sfb] + redVal;
          tmp = fixmul(tmp, tmp);
          sfbThrReduced = fixmul(tmp, tmp);
          /* avoid holes */
          tmp = L_mpy_ls(*psfbEn, psyOutChan->sfbMinSnr[sfbGrp+sfb]);

          if ((sfbThrReduced > tmp) &&
              (ahFlag[ch][sfbGrp+sfb] != NO_AH)){
            sfbThrReduced = max(tmp, *psfbThr);
            ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE;
          }
		  *psfbThr = sfbThrReduced;
        }

		psfbEn++;  psfbThr++;
      }
    }
  }
}


/********************************************************************************
*
* function name:correctThresh
* description: if pe difference deltaPe between desired pe and real pe is small enough,
*             the difference can be distributed among the scale factor bands.
*
**********************************************************************************/
static void correctThresh(PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
                          Word16           ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
                          PE_DATA          *peData,
                          Word32           thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],
                          const Word32     redVal,
                          const Word16     nChannels,
                          const Word32     deltaPe)
{
  Word16 ch, sfb, sfbGrp,shift;
  PSY_OUT_CHANNEL *psyOutChan;
  PE_CHANNEL_DATA *peChanData;
  Word32 deltaSfbPe;
  Word32 normFactor;
  Word32 *psfbPeFactors;
  Word16 *psfbNActiveLines, *pahFlag;
  Word32 sfbEn, sfbThr;
  Word32 sfbThrReduced;

  /* for each sfb calc relative factors for pe changes */
  normFactor = 1;
  for(ch=0; ch<nChannels; ch++) {
    psyOutChan = &psyOutChannel[ch];
    peChanData = &peData->peChannelData[ch];
    for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
      psfbPeFactors = peData->sfbPeFactors[ch] + sfbGrp;
	  psfbNActiveLines = peChanData->sfbNActiveLines + sfbGrp;
	  pahFlag = ahFlag[ch] + sfbGrp;
	  for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
        Word32 redThrExp = thrExp[ch][sfbGrp+sfb] + redVal;

        if (((*pahFlag < AH_ACTIVE) || (deltaPe > 0)) && (redThrExp > 0) && (redThrExp >= *psfbNActiveLines)) {

          *psfbPeFactors = (*psfbNActiveLines) * (0x7fffffff / redThrExp);
          normFactor = L_add(normFactor, *psfbPeFactors);
        }
        else {
          *psfbPeFactors = 0;
        }
		psfbPeFactors++;
		pahFlag++; psfbNActiveLines++;
      }
    }
  }


  /* calculate new thresholds */
  for(ch=0; ch<nChannels; ch++) {
    psyOutChan = &psyOutChannel[ch];
    peChanData = &peData->peChannelData[ch];
    for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){
      psfbPeFactors = peData->sfbPeFactors[ch] + sfbGrp;
	  psfbNActiveLines = peChanData->sfbNActiveLines + sfbGrp;
	  pahFlag = ahFlag[ch] + sfbGrp;
	  for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
        /* pe difference for this sfb */
        deltaSfbPe = *psfbPeFactors * deltaPe;

		/* thr3(n) = thr2(n)*2^deltaSfbPe/b(n) */
        if (*psfbNActiveLines > 0 && (normFactor* (*psfbNActiveLines)) != 0) {
          /* new threshold */
          Word32 thrFactor;
          sfbEn  = psyOutChan->sfbEnergy[sfbGrp+sfb];
          sfbThr = psyOutChan->sfbThreshold[sfbGrp+sfb];

           if(deltaSfbPe >= 0){
            /*
              reduce threshold
            */
            thrFactor = pow2_xy(L_negate(deltaSfbPe), (normFactor* (*psfbNActiveLines)));

            sfbThrReduced = L_mpy_ls(sfbThr, round16(thrFactor));
          }
          else {
            /*
              increase threshold
            */
            thrFactor = pow2_xy(deltaSfbPe, (normFactor * (*psfbNActiveLines)));


            if(thrFactor > sfbThr) {
              shift = norm_l(thrFactor);
			  sfbThrReduced = Div_32( sfbThr << shift, thrFactor<<shift );
            }
            else {
              sfbThrReduced = MAX_32;
            }

          }

          /* avoid hole */
          sfbEn = L_mpy_ls(sfbEn, psyOutChan->sfbMinSnr[sfbGrp+sfb]);

          if ((sfbThrReduced > sfbEn) &&
              (*pahFlag == AH_INACTIVE)) {
            sfbThrReduced = max(sfbEn, sfbThr);
            *pahFlag = AH_ACTIVE;
          }

          psyOutChan->sfbThreshold[sfbGrp+sfb] = sfbThrReduced;
        }

		pahFlag++; psfbNActiveLines++; psfbPeFactors++;
      }
    }
  }
}


/********************************************************************************
*
* function name:reduceMinSnr
* description: if the desired pe can not be reached, reduce pe by reducing minSnr
*
**********************************************************************************/
static void reduceMinSnr(PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
                         PE_DATA         *peData,
                         Word16           ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
                         const Word16     nChannels,
                         const Word16     desiredPe)
{
  Word16 ch, sfb, sfbSubWin;
  Word16 deltaPe;

  /* start at highest freq down to 0 */
  sfbSubWin = psyOutChannel[0].maxSfbPerGroup;
  while (peData->pe > desiredPe && sfbSubWin > 0) {

    sfbSubWin = sfbSubWin - 1;
    /* loop over all subwindows */
    for (sfb=sfbSubWin; sfb<psyOutChannel[0].sfbCnt;
        sfb+=psyOutChannel[0].sfbPerGroup) {
      /* loop over all channels */
		PE_CHANNEL_DATA* peChan = peData->peChannelData;
		PSY_OUT_CHANNEL* psyOutCh = psyOutChannel;
		for (ch=0; ch<nChannels; ch++) {
        if (ahFlag[ch][sfb] != NO_AH &&
            psyOutCh->sfbMinSnr[sfb] < minSnrLimit) {
          psyOutCh->sfbMinSnr[sfb] = minSnrLimit;
          psyOutCh->sfbThreshold[sfb] =
            L_mpy_ls(psyOutCh->sfbEnergy[sfb], psyOutCh->sfbMinSnr[sfb]);

          /* calc new pe */
          deltaPe = ((peChan->sfbNLines4[sfb] + (peChan->sfbNLines4[sfb] >> 1)) >> 2) -
              peChan->sfbPe[sfb];
          peData->pe = peData->pe + deltaPe;
          peChan->pe = peChan->pe + deltaPe;
        }
		peChan += 1; psyOutCh += 1;
      }
      /* stop if enough has been saved */

      if (peData->pe <= desiredPe)
        break;
    }
  }
}

/********************************************************************************
*
* function name:allowMoreHoles
* description: if the desired pe can not be reached, some more scalefactor bands
*              have to be quantized to zero
*
**********************************************************************************/
static void allowMoreHoles(PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
                           PSY_OUT_ELEMENT *psyOutElement,
                           PE_DATA         *peData,
                           Word16           ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],
                           const AH_PARAM  *ahParam,
                           const Word16     nChannels,
                           const Word16     desiredPe)
{
  Word16 ch, sfb;
  Word16 actPe, shift;

  actPe = peData->pe;

  /* for MS allow hole in the channel with less energy */

  if (nChannels==2 &&
      psyOutChannel[0].windowSequence==psyOutChannel[1].windowSequence) {
    PSY_OUT_CHANNEL *psyOutChanL = &psyOutChannel[0];
    PSY_OUT_CHANNEL *psyOutChanR = &psyOutChannel[1];
    for (sfb=0; sfb<psyOutChanL->sfbCnt; sfb++) {
      Word32 minEn;

      if (psyOutElement->toolsInfo.msMask[sfb]) {
        /* allow hole in side channel ? */
        minEn = L_mpy_ls(psyOutChanL->sfbEnergy[sfb], (minSnrLimit * psyOutChanL->sfbMinSnr[sfb]) >> 16);

        if (ahFlag[1][sfb] != NO_AH &&
            minEn > psyOutChanR->sfbEnergy[sfb]) {
          ahFlag[1][sfb] = NO_AH;
          psyOutChanR->sfbThreshold[sfb] = L_add(psyOutChanR->sfbEnergy[sfb], psyOutChanR->sfbEnergy[sfb]);
          actPe = actPe - peData->peChannelData[1].sfbPe[sfb];
        }
        /* allow hole in mid channel ? */
        else {
        minEn = L_mpy_ls(psyOutChanR->sfbEnergy[sfb], (minSnrLimit * psyOutChanR->sfbMinSnr[sfb]) >> 16);

          if (ahFlag[0][sfb]!= NO_AH &&
              minEn > psyOutChanL->sfbEnergy[sfb]) {
            ahFlag[0][sfb] = NO_AH;
            psyOutChanL->sfbThreshold[sfb] = L_add(psyOutChanL->sfbEnergy[sfb], psyOutChanL->sfbEnergy[sfb]);
            actPe = actPe - peData->peChannelData[0].sfbPe[sfb];
          }
        }

        if (actPe < desiredPe)
          break;
      }
    }
  }

  /* subsequently erase bands */
  if (actPe > desiredPe) {
    Word16 startSfb[2];
    Word32 avgEn, minEn;
    Word16 ahCnt;
    Word16 enIdx;
    Word16 enDiff;
    Word32 en[4];
    Word16 minSfb, maxSfb;
    Flag   done;

    /* do not go below startSfb */
    for (ch=0; ch<nChannels; ch++) {

      if (psyOutChannel[ch].windowSequence != SHORT_WINDOW)
        startSfb[ch] = ahParam->startSfbL;
      else
        startSfb[ch] = ahParam->startSfbS;
    }

    avgEn = 0;
    minEn = MAX_32;
    ahCnt = 0;
    for (ch=0; ch<nChannels; ch++) {
      PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
      for (sfb=startSfb[ch]; sfb<psyOutChan->sfbCnt; sfb++) {

        if ((ahFlag[ch][sfb] != NO_AH) &&
            (psyOutChan->sfbEnergy[sfb] > psyOutChan->sfbThreshold[sfb])) {
          minEn = min(minEn, psyOutChan->sfbEnergy[sfb]);
          avgEn = L_add(avgEn, psyOutChan->sfbEnergy[sfb]);
          ahCnt++;
        }
      }
    }

    if(ahCnt) {
      Word32 iahCnt;
      shift = norm_l(ahCnt);
	  iahCnt = Div_32( 1 << shift, ahCnt << shift );
      avgEn = fixmul(avgEn, iahCnt);
    }

    enDiff = iLog4(avgEn) - iLog4(minEn);
    /* calc some energy borders between minEn and avgEn */
    for (enIdx=0; enIdx<4; enIdx++) {
      Word32 enFac;
      enFac = ((6-(enIdx << 1)) * enDiff);
      en[enIdx] = fixmul(avgEn, pow2_xy(L_negate(enFac),7*4));
    }

    /* start with lowest energy border at highest sfb */
    maxSfb = psyOutChannel[0].sfbCnt - 1;
    minSfb = startSfb[0];

    if (nChannels == 2) {
      maxSfb = max(maxSfb, (psyOutChannel[1].sfbCnt - 1));
      minSfb = min(minSfb, startSfb[1]);
    }

    sfb = maxSfb;
    enIdx = 0;
    done = 0;
    while (!done) {

      for (ch=0; ch<nChannels; ch++) {
        PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];

        if (sfb>=startSfb[ch] && sfb<psyOutChan->sfbCnt) {
          /* sfb energy below border ? */

          if (ahFlag[ch][sfb] != NO_AH && psyOutChan->sfbEnergy[sfb] < en[enIdx]){
            /* allow hole */
            ahFlag[ch][sfb] = NO_AH;
            psyOutChan->sfbThreshold[sfb] = L_add(psyOutChan->sfbEnergy[sfb], psyOutChan->sfbEnergy[sfb]);
            actPe = actPe - peData->peChannelData[ch].sfbPe[sfb];
          }

          if (actPe < desiredPe) {
            done = 1;
            break;
          }
        }
      }
      sfb = sfb - 1;

      if (sfb < minSfb) {
        /* restart with next energy border */
        sfb = maxSfb;
        enIdx = enIdx + 1;

        if (enIdx - 4 >= 0)
          done = 1;
      }
    }
  }
}

/********************************************************************************
*
* function name:adaptThresholdsToPe
* description: two guesses for the reduction value and one final correction of the
*              thresholds
*
**********************************************************************************/
static void adaptThresholdsToPe(PSY_OUT_CHANNEL     psyOutChannel[MAX_CHANNELS],
                                PSY_OUT_ELEMENT    *psyOutElement,
                                Word16              logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
                                PE_DATA            *peData,
                                const Word16        nChannels,
                                const Word16        desiredPe,
                                AH_PARAM           *ahParam,
                                MINSNR_ADAPT_PARAM *msaParam)
{
  Word16 noRedPe, redPe, redPeNoAH;
  Word16 constPart, constPartNoAH;
  Word16 nActiveLines, nActiveLinesNoAH;
  Word16 desiredPeNoAH;
  Word32 redVal, avgThrExp;
  Word32 iter;

  calcThreshExp(peData->thrExp, psyOutChannel, nChannels);

  adaptMinSnr(psyOutChannel, logSfbEnergy, msaParam, nChannels);

  initAvoidHoleFlag(peData->ahFlag, psyOutChannel, psyOutElement, nChannels, ahParam);

  noRedPe = peData->pe;
  constPart = peData->constPart;
  nActiveLines = peData->nActiveLines;

  /* first guess of reduction value t^0.25 = 2^((a-pen)/4*b) */
  avgThrExp = pow2_xy((constPart - noRedPe), (nActiveLines << 2));

  /* r1 = 2^((a-per)/4*b) - t^0.25 */
  redVal = pow2_xy((constPart - desiredPe), (nActiveLines << 2)) - avgThrExp;

  /* reduce thresholds */
  reduceThresholds(psyOutChannel, peData->ahFlag, peData->thrExp, nChannels, redVal);

  /* pe after first guess */
  calcSfbPe(peData, psyOutChannel, nChannels);
  redPe = peData->pe;

  iter = 0;
  do {
    /* pe for bands where avoid hole is inactive */
    calcPeNoAH(&redPeNoAH, &constPartNoAH, &nActiveLinesNoAH,
               peData, peData->ahFlag, psyOutChannel, nChannels);

    desiredPeNoAH = desiredPe -(redPe - redPeNoAH);

    if (desiredPeNoAH < 0) {
      desiredPeNoAH = 0;
    }

    /* second guess */

    if (nActiveLinesNoAH > 0) {

		avgThrExp = pow2_xy((constPartNoAH - redPeNoAH), (nActiveLinesNoAH << 2));

		redVal = (redVal + pow2_xy((constPartNoAH - desiredPeNoAH), (nActiveLinesNoAH << 2))) - avgThrExp;

		/* reduce thresholds */
		reduceThresholds(psyOutChannel, peData->ahFlag, peData->thrExp, nChannels, redVal);
    }

    calcSfbPe(peData, psyOutChannel, nChannels);
    redPe = peData->pe;

    iter = iter+1;

  } while ((20 * abs_s(redPe - desiredPe) > desiredPe) && (iter < 2));


  if ((100 * redPe < 115 * desiredPe)) {
    correctThresh(psyOutChannel, peData->ahFlag, peData, peData->thrExp, redVal,
                  nChannels, desiredPe - redPe);
  }
  else {
    Word16 desiredPe105 = (105 * desiredPe) / 100;
    reduceMinSnr(psyOutChannel, peData, peData->ahFlag,
                 nChannels, desiredPe105);
    allowMoreHoles(psyOutChannel, psyOutElement, peData, peData->ahFlag,
                   ahParam, nChannels, desiredPe105);
  }
}


/*****************************************************************************
*
* function name: calcBitSave
* description:  Calculates percentage of bit save, see figure below
* returns:
* input:        parameters and bitres-fullness
* output:       percentage of bit save
*
*****************************************************************************/
static Word16 calcBitSave(Word16 fillLevel,
                          const Word16 clipLow,
                          const Word16 clipHigh,
                          const Word16 minBitSave,
                          const Word16 maxBitSave)
{
  Word16 bitsave = 0;

  fillLevel = max(fillLevel, clipLow);
  fillLevel = min(fillLevel, clipHigh);

  if(clipHigh-clipLow)
  bitsave = (maxBitSave - (((maxBitSave-minBitSave)*(fillLevel-clipLow))/
                              (clipHigh-clipLow)));

  return (bitsave);
}



/*****************************************************************************
*
* function name: calcBitSpend
* description:  Calculates percentage of bit spend, see figure below
* returns:
* input:        parameters and bitres-fullness
* output:       percentage of bit spend
*
*****************************************************************************/
static Word16 calcBitSpend(Word16 fillLevel,
                           const Word16 clipLow,
                           const Word16 clipHigh,
                           const Word16 minBitSpend,
                           const Word16 maxBitSpend)
{
  Word16 bitspend = 1;

  fillLevel = max(fillLevel, clipLow);
  fillLevel = min(fillLevel, clipHigh);

  if(clipHigh-clipLow)
  bitspend = (minBitSpend + ((maxBitSpend - minBitSpend)*(fillLevel - clipLow) /
                                (clipHigh-clipLow)));

  return (bitspend);
}


/*****************************************************************************
*
* function name: adjustPeMinMax()
* description:  adjusts peMin and peMax parameters over time
* returns:
* input:        current pe, peMin, peMax
* output:       adjusted peMin/peMax
*
*****************************************************************************/
static void adjustPeMinMax(const Word16 currPe,
                           Word16      *peMin,
                           Word16      *peMax)
{
  Word16 minFacHi, maxFacHi, minFacLo, maxFacLo;
  Word16 diff;
  Word16 minDiff = extract_l(currPe / 6);
  minFacHi = 30;
  maxFacHi = 100;
  minFacLo = 14;
  maxFacLo = 7;

  diff = currPe - *peMax ;

  if (diff > 0) {
    *peMin = *peMin + ((diff * minFacHi) / 100);
    *peMax = *peMax + ((diff * maxFacHi) / 100);
  } else {
    diff = *peMin - currPe;

    if (diff > 0) {
      *peMin = *peMin - ((diff * minFacLo) / 100);
      *peMax = *peMax - ((diff * maxFacLo) / 100);
    } else {
      *peMin = *peMin + ((currPe - *peMin) * minFacHi / 100);
      *peMax = *peMax - ((*peMax - currPe) * maxFacLo / 100);
    }
  }


  if ((*peMax - *peMin) < minDiff) {
    Word16 partLo, partHi;

    partLo = max(0, (currPe - *peMin));
    partHi = max(0, (*peMax - currPe));

    *peMax = currPe + ((partHi * minDiff) / (partLo + partHi));
    *peMin = currPe - ((partLo * minDiff) / (partLo + partHi));
    *peMin = max(0, *peMin);
  }
}


/*****************************************************************************
*
* function name: BitresCalcBitFac
* description:  calculates factor of spending bits for one frame
*                1.0 : take all frame dynpart bits
*                >1.0 : take all frame dynpart bits + bitres
*                <1.0 : put bits in bitreservoir
*  returns:      BitFac*100
*  input:        bitres-fullness, pe, blockType, parameter-settings
*  output:
*
*****************************************************************************/
static Word16 bitresCalcBitFac( const Word16   bitresBits,
                                const Word16   maxBitresBits,
                                const Word16   pe,
                                const Word16   windowSequence,
                                const Word16   avgBits,
                                const Word16   maxBitFac,
                                ADJ_THR_STATE *AdjThr,
                                ATS_ELEMENT   *adjThrChan)
{
  BRES_PARAM *bresParam;
  Word16 pex;
  Word16 fillLevel;
  Word16 bitSave, bitSpend, bitresFac;

  fillLevel = extract_l((100* bitresBits) / maxBitresBits);

  if (windowSequence != SHORT_WINDOW)
    bresParam = &(AdjThr->bresParamLong);
  else
    bresParam = &(AdjThr->bresParamShort);

  pex = max(pe, adjThrChan->peMin);
  pex = min(pex,adjThrChan->peMax);

  bitSave = calcBitSave(fillLevel,
                        bresParam->clipSaveLow, bresParam->clipSaveHigh,
                        bresParam->minBitSave, bresParam->maxBitSave);

  bitSpend = calcBitSpend(fillLevel,
                          bresParam->clipSpendLow, bresParam->clipSpendHigh,
                          bresParam->minBitSpend, bresParam->maxBitSpend);

  if(adjThrChan->peMax != adjThrChan->peMin)
	bitresFac = (100 - bitSave) + extract_l(((bitSpend + bitSave) * (pex - adjThrChan->peMin)) /
                    (adjThrChan->peMax - adjThrChan->peMin));
  else
	bitresFac = 0x7fff;

  bitresFac = min(bitresFac,
                    (100-30 + extract_l((100 * bitresBits) / avgBits)));

  bitresFac = min(bitresFac, maxBitFac);

  adjustPeMinMax(pe, &adjThrChan->peMin, &adjThrChan->peMax);

  return bitresFac;
}

/*****************************************************************************
*
* function name: AdjThrInit
* description:  init thresholds parameter
*
*****************************************************************************/
void AdjThrInit(ADJ_THR_STATE *hAdjThr,
                const Word32   meanPe,
                Word32         chBitrate)
{
  ATS_ELEMENT* atsElem = &hAdjThr->adjThrStateElem;
  MINSNR_ADAPT_PARAM *msaParam = &atsElem->minSnrAdaptParam;

  /* common for all elements: */
  /* parameters for bitres control */
  hAdjThr->bresParamLong.clipSaveLow   =  20;
  hAdjThr->bresParamLong.clipSaveHigh  =  95;
  hAdjThr->bresParamLong.minBitSave    =  -5;
  hAdjThr->bresParamLong.maxBitSave    =  30;
  hAdjThr->bresParamLong.clipSpendLow  =  20;
  hAdjThr->bresParamLong.clipSpendHigh =  95;
  hAdjThr->bresParamLong.minBitSpend   = -10;
  hAdjThr->bresParamLong.maxBitSpend   =  40;

  hAdjThr->bresParamShort.clipSaveLow   =  20;
  hAdjThr->bresParamShort.clipSaveHigh  =  75;
  hAdjThr->bresParamShort.minBitSave    =   0;
  hAdjThr->bresParamShort.maxBitSave    =  20;
  hAdjThr->bresParamShort.clipSpendLow  =  20;
  hAdjThr->bresParamShort.clipSpendHigh =  75;
  hAdjThr->bresParamShort.minBitSpend   = -5;
  hAdjThr->bresParamShort.maxBitSpend   =  50;

  /* specific for each element: */

  /* parameters for bitres control */
  atsElem->peMin = extract_l(((80*meanPe) / 100));
  atsElem->peMax = extract_l(((120*meanPe) / 100));

  /* additional pe offset to correct pe2bits for low bitrates */
  atsElem->peOffset = 0;
  if (chBitrate < 32000) {
    atsElem->peOffset = max(50, (100 - extract_l((100 * chBitrate) / 32000)));
  }

  /* avoid hole parameters */
  if (chBitrate > 20000) {
    atsElem->ahParam.modifyMinSnr = TRUE;
    atsElem->ahParam.startSfbL = 15;
    atsElem->ahParam.startSfbS = 3;
  }
  else {
    atsElem->ahParam.modifyMinSnr = FALSE;
    atsElem->ahParam.startSfbL = 0;
    atsElem->ahParam.startSfbS = 0;
  }

  /* minSnr adaptation */
  /* maximum reduction of minSnr goes down to minSnr^maxRed */
  msaParam->maxRed = 0x20000000;     /* *0.25f */
  /* start adaptation of minSnr for avgEn/sfbEn > startRatio */
  msaParam->startRatio = 0x0ccccccd; /* 10 */
  /* maximum minSnr reduction to minSnr^maxRed is reached for
     avgEn/sfbEn >= maxRatio */
  msaParam->maxRatio =  0x0020c49c; /* 1000 */
  /* helper variables to interpolate minSnr reduction for
     avgEn/sfbEn between startRatio and maxRatio */

  msaParam->redRatioFac = 0xfb333333; /* -0.75/20 */

  msaParam->redOffs = 0x30000000;  /* msaParam->redRatioFac * 10*log10(msaParam->startRatio) */


  /* pe correction */
  atsElem->peLast = 0;
  atsElem->dynBitsLast = 0;
  atsElem->peCorrectionFactor = 100; /* 1.0 */

}

/*****************************************************************************
*
* function name: calcPeCorrection
* description:  calculates the desired perceptual entropy factor
*				It is between 0.85 and 1.15
*
*****************************************************************************/
static void calcPeCorrection(Word16 *correctionFac,
                             const Word16 peAct,
                             const Word16 peLast,
                             const Word16 bitsLast)
{
  Word32 peAct100 = 100 * peAct;
  Word32 peLast100 = 100 * peLast;
  Word16 peBitsLast = bits2pe(bitsLast);

  if ((bitsLast > 0) &&
      (peAct100 < (150 * peLast)) &&  (peAct100 > (70 * peLast)) &&
      ((120 * peBitsLast) > peLast100 ) && (( 65 * peBitsLast) < peLast100))
    {
      Word16 newFac = (100 * peLast) / peBitsLast;
      /* dead zone */

      if (newFac < 100) {
        newFac = min(((110 * newFac) / 100), 100);
        newFac = max(newFac, 85);
      }
      else {
        newFac = max(((90 * newFac) / 100), 100);
        newFac = min(newFac, 115);
      }

      if ((newFac > 100 && *correctionFac < 100) ||
          (newFac < 100 && *correctionFac > 100)) {
        *correctionFac = 100;
      }
      /* faster adaptation towards 1.0, slower in the other direction */

      if ((*correctionFac < 100 && newFac < *correctionFac) ||
          (*correctionFac > 100 && newFac > *correctionFac))
        *correctionFac = (85 * *correctionFac + 15 * newFac) / 100;
      else
        *correctionFac = (70 * *correctionFac + 30 * newFac) / 100;
      *correctionFac = min(*correctionFac, 115);
      *correctionFac = max(*correctionFac, 85);
    }
  else {
    *correctionFac = 100;
  }
}

/********************************************************************************
*
* function name: AdjustThresholds
* description:  Adjust thresholds to the desired bitrate
*
**********************************************************************************/
void AdjustThresholds(ADJ_THR_STATE   *adjThrState,
                      ATS_ELEMENT     *AdjThrStateElement,
                      PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
                      PSY_OUT_ELEMENT *psyOutElement,
                      Word16          *chBitDistribution,
                      Word16           logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
                      Word16           sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
                      QC_OUT_ELEMENT  *qcOE,
					  ELEMENT_BITS	  *elBits,
					  const Word16     nChannels,
                      const Word16     maxBitFac)
{
  PE_DATA peData;
  Word16 noRedPe, grantedPe, grantedPeCorr;
  Word16 curWindowSequence;
  Word16 bitFactor;
  Word16 avgBits = (elBits->averageBits - (qcOE->staticBitsUsed + qcOE->ancBitsUsed));
  Word16 bitresBits = elBits->bitResLevel;
  Word16 maxBitresBits = elBits->maxBits;
  Word16 sideInfoBits = (qcOE->staticBitsUsed + qcOE->ancBitsUsed);
  Word16 ch;
  memset(&peData, 0, sizeof(peData));

  prepareSfbPe(&peData, psyOutChannel, logSfbEnergy, sfbNRelevantLines, nChannels, AdjThrStateElement->peOffset);

  /* pe without reduction */
  calcSfbPe(&peData, psyOutChannel, nChannels);
  noRedPe = peData.pe;


  curWindowSequence = LONG_WINDOW;

  if (nChannels == 2) {

    if ((psyOutChannel[0].windowSequence == SHORT_WINDOW) ||
        (psyOutChannel[1].windowSequence == SHORT_WINDOW)) {
      curWindowSequence = SHORT_WINDOW;
    }
  }
  else {
    curWindowSequence = psyOutChannel[0].windowSequence;
  }


  /* bit factor */
  bitFactor = bitresCalcBitFac(bitresBits, maxBitresBits, noRedPe+5*sideInfoBits,
                               curWindowSequence, avgBits, maxBitFac,
                               adjThrState,
                               AdjThrStateElement);

  /* desired pe */
  grantedPe = ((bitFactor * bits2pe(avgBits)) / 100);

  /* correction of pe value */
  calcPeCorrection(&(AdjThrStateElement->peCorrectionFactor),
                   min(grantedPe, noRedPe),
                   AdjThrStateElement->peLast,
                   AdjThrStateElement->dynBitsLast);
  grantedPeCorr = (grantedPe * AdjThrStateElement->peCorrectionFactor) / 100;


  if (grantedPeCorr < noRedPe && noRedPe > peData.offset) {
    /* calc threshold necessary for desired pe */
    adaptThresholdsToPe(psyOutChannel,
                        psyOutElement,
                        logSfbEnergy,
                        &peData,
                        nChannels,
                        grantedPeCorr,
                        &AdjThrStateElement->ahParam,
                        &AdjThrStateElement->minSnrAdaptParam);
  }

  /* calculate relative distribution */
  for (ch=0; ch<nChannels; ch++) {
    Word16 peOffsDiff = peData.pe - peData.offset;
    chBitDistribution[ch] = 200;

    if (peOffsDiff > 0) {
      Word32 temp = 1000 - (nChannels * 200);
      chBitDistribution[ch] = chBitDistribution[ch] +
		  (temp * peData.peChannelData[ch].pe) / peOffsDiff;
    }
  }

  /* store pe */
  qcOE->pe = noRedPe;

  /* update last pe */
  AdjThrStateElement->peLast = grantedPe;
}

/********************************************************************************
*
* function name: AdjThrUpdate
* description:  save dynBitsUsed for correction of bits2pe relation
*
**********************************************************************************/
void AdjThrUpdate(ATS_ELEMENT *AdjThrStateElement,
                  const Word16 dynBitsUsed)
{
  AdjThrStateElement->dynBitsLast = dynBitsUsed;
}


