/*
 ** 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:		line_pe.c

	Content:	Perceptual entropie module functions

*******************************************************************************/

#include "basic_op.h"
#include "oper_32b.h"
#include "typedef.h"
#include "line_pe.h"


static const Word16  C1_I = 12;    /* log(8.0)/log(2) *4         */
static const Word32  C2_I = 10830; /* log(2.5)/log(2) * 1024 * 4 * 2 */
static const Word16  C3_I = 573;   /* (1-C2/C1) *1024            */


/*****************************************************************************
*
* function name: prepareSfbPe
* description:  constants that do not change during successive pe calculations
*
**********************************************************************************/
void prepareSfbPe(PE_DATA *peData,
                  PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
                  Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
                  Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
                  const Word16 nChannels,
                  const Word16 peOffset)
{
  Word32 sfbGrp, sfb;
  Word32 ch;     

  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++) {
	    peChanData->sfbNLines4[sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb];          
        sfbNRelevantLines[ch][sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb] >> 2;    
	    peChanData->sfbLdEnergy[sfbGrp+sfb] = logSfbEnergy[ch][sfbGrp+sfb];              
      }
    }
  }
  peData->offset = peOffset;                                                             
}


/*****************************************************************************
*
* function name: calcSfbPe
* description:  constPart is sfbPe without the threshold part n*ld(thr) or n*C3*ld(thr)
*
**********************************************************************************/
void calcSfbPe(PE_DATA *peData,
               PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
               const Word16 nChannels)
{
  Word32 ch;
  Word32 sfbGrp, sfb;
  Word32 nLines4;
  Word32 ldThr, ldRatio;
  Word32 pe, constPart, nActiveLines;

  peData->pe = peData->offset;                                           
  peData->constPart = 0;                                                 
  peData->nActiveLines = 0;                                              
  for(ch=0; ch<nChannels; ch++) {
    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
    PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
    const Word32 *sfbEnergy = psyOutChan->sfbEnergy;
    const Word32 *sfbThreshold = psyOutChan->sfbThreshold;

    pe = 0;                                                  
    constPart = 0;                                           
    nActiveLines = 0;                                        

    for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {
      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
        Word32 nrg = sfbEnergy[sfbGrp+sfb];                             
        Word32 thres = sfbThreshold[sfbGrp+sfb];                           
        Word32 sfbLDEn = peChanData->sfbLdEnergy[sfbGrp+sfb];

        if (nrg > thres) {
          ldThr = iLog4(thres);

          ldRatio = sfbLDEn - ldThr;

          nLines4 = peChanData->sfbNLines4[sfbGrp+sfb];                    
           
          /* sfbPe = nl*log2(en/thr)*/
		  if (ldRatio >= C1_I) {
            peChanData->sfbPe[sfbGrp+sfb] = (nLines4*ldRatio + 8) >> 4;
            peChanData->sfbConstPart[sfbGrp+sfb] = ((nLines4*sfbLDEn)) >> 4;
          }
          else {
		  /* sfbPe = nl*(c2 + c3*log2(en/thr))*/
            peChanData->sfbPe[sfbGrp+sfb] = extract_l((L_mpy_wx(
                    (C2_I + C3_I * ldRatio * 2) << 4, nLines4) + 4) >> 3);
            peChanData->sfbConstPart[sfbGrp+sfb] = extract_l(( L_mpy_wx(
                    (C2_I + C3_I * sfbLDEn * 2) << 4, nLines4) + 4) >> 3);
            nLines4 = (nLines4 * C3_I + (1024<<1)) >> 10;
          }
          peChanData->sfbNActiveLines[sfbGrp+sfb] = nLines4 >> 2;
        }
        else {
          peChanData->sfbPe[sfbGrp+sfb] = 0;                             
          peChanData->sfbConstPart[sfbGrp+sfb] = 0;                      
          peChanData->sfbNActiveLines[sfbGrp+sfb] = 0;                   
        }
        pe = pe + peChanData->sfbPe[sfbGrp+sfb];
        constPart = constPart + peChanData->sfbConstPart[sfbGrp+sfb];
        nActiveLines = nActiveLines + peChanData->sfbNActiveLines[sfbGrp+sfb];
      }
    }
	
	peChanData->pe = saturate(pe);                                                  
    peChanData->constPart = saturate(constPart);                                           
    peChanData->nActiveLines = saturate(nActiveLines);                                        

    
	pe += peData->pe;
	peData->pe = saturate(pe); 
    constPart += peData->constPart;
	peData->constPart = saturate(constPart); 
    nActiveLines += peData->nActiveLines;
	peData->nActiveLines = saturate(nActiveLines);
  } 
}
