/*
 ** 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:		psy_configuration.c

	Content:	Psychoaccoustic configuration functions

*******************************************************************************/

#include "basic_op.h"
#include "oper_32b.h"
#include "psy_configuration.h"
#include "adj_thr.h"
#include "aac_rom.h"



#define BARC_SCALE	100 /* integer barc values are scaled with 100 */
#define LOG2_1000	301 /* log2*1000 */
#define PI2_1000	1571 /* pi/2*1000*/
#define ATAN_COEF1	3560 /* 1000/0.280872f*/
#define ATAN_COEF2	281 /* 1000*0.280872f*/


typedef struct{
  Word32 sampleRate;
  const UWord8 *paramLong;
  const UWord8 *paramShort;
}SFB_INFO_TAB;

static const Word16 ABS_LEV = 20;
static const Word16 BARC_THR_QUIET[] = {15, 10,  7,  2,  0,  0,  0,  0,  0,  0,
                                         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                                         3,  5, 10, 20, 30};



static const Word16 max_bark = 24; /* maximum bark-value */
static const Word16 maskLow  = 30; /* in 1dB/bark */
static const Word16 maskHigh = 15; /* in 1*dB/bark */
static const Word16 c_ratio  = 0x0029; /* pow(10.0f, -(29.0f/10.0f)) */

static const Word16 maskLowSprEnLong = 30;       /* in 1dB/bark */
static const Word16 maskHighSprEnLong = 20;      /* in 1dB/bark */
static const Word16 maskHighSprEnLongLowBr = 15; /* in 1dB/bark */
static const Word16 maskLowSprEnShort = 20;      /* in 1dB/bark */
static const Word16 maskHighSprEnShort = 15;     /* in 1dB/bark */
static const Word16 c_minRemainingThresholdFactor = 0x0148;    /* 0.01 *(1 << 15)*/
static const Word32 c_maxsnr = 0x66666666;		 /* upper limit is -1 dB */
static const Word32 c_minsnr = 0x00624dd3;		 /* lower limit is -25 dB */

static const Word32 c_maxClipEnergyLong = 0x77359400;  /* 2.0e9f*/
static const Word32 c_maxClipEnergyShort = 0x01dcd650; /* 2.0e9f/(AACENC_TRANS_FAC*AACENC_TRANS_FAC)*/


Word32 GetSRIndex(Word32 sampleRate)
{
    if (92017 <= sampleRate) return 0;
    if (75132 <= sampleRate) return 1;
    if (55426 <= sampleRate) return 2;
    if (46009 <= sampleRate) return 3;
    if (37566 <= sampleRate) return 4;
    if (27713 <= sampleRate) return 5;
    if (23004 <= sampleRate) return 6;
    if (18783 <= sampleRate) return 7;
    if (13856 <= sampleRate) return 8;
    if (11502 <= sampleRate) return 9;
    if (9391 <= sampleRate) return 10;

    return 11;
}


/*********************************************************************************
*
* function name: atan_1000
* description:  calculates 1000*atan(x/1000)
*               based on atan approx for x > 0				
*				atan(x) = x/((float)1.0f+(float)0.280872f*x*x)  if x < 1
*						= pi/2 - x/((float)0.280872f +x*x)	    if x >= 1
* return:       1000*atan(x/1000)
*
**********************************************************************************/
static Word16 atan_1000(Word32 val) 
{
  Word32 y;

   
  if(L_sub(val, 1000) < 0) {
    y = extract_l(((1000 * val) / (1000 + ((val * val) / ATAN_COEF1))));
  }
  else {
    y = PI2_1000 - ((1000 * val) / (ATAN_COEF2 + ((val * val) / 1000)));
  }

  return extract_l(y);
}


/*****************************************************************************
*
* function name: BarcLineValue
* description:  Calculates barc value for one frequency line
* returns:      barc value of line * BARC_SCALE
* input:        number of lines in transform, index of line to check, Fs
* output:
*
*****************************************************************************/
static Word16 BarcLineValue(Word16 noOfLines, Word16 fftLine, Word32 samplingFreq)
{
  Word32 center_freq, temp, bvalFFTLine;

  /* center frequency of fft line */
  center_freq = (fftLine * samplingFreq) / (noOfLines << 1);
  temp =  atan_1000((center_freq << 2) / (3*10));
  bvalFFTLine = 
    (26600 * atan_1000((center_freq*76) / 100) + 7*temp*temp) / (2*1000*1000 / BARC_SCALE);
  
  return saturate(bvalFFTLine);
}

/*****************************************************************************
*
* function name: initThrQuiet
* description:  init thredhold in quiet
*
*****************************************************************************/
static void initThrQuiet(Word16  numPb,
                         Word16 *pbOffset,
                         Word16 *pbBarcVal,
                         Word32 *pbThresholdQuiet) {
  Word16 i;
  Word16 barcThrQuiet;

  for(i=0; i<numPb; i++) {
    Word16 bv1, bv2;

     
    if (i>0)
      bv1 = (pbBarcVal[i] + pbBarcVal[i-1]) >> 1;
    else
      bv1 = pbBarcVal[i] >> 1;

     
    if (i < (numPb - 1))
      bv2 = (pbBarcVal[i] + pbBarcVal[i+1]) >> 1;
    else {
      bv2 = pbBarcVal[i];                                        
    }

    bv1 = min((bv1 / BARC_SCALE), max_bark);
    bv2 = min((bv2 / BARC_SCALE), max_bark);

    barcThrQuiet = min(BARC_THR_QUIET[bv1], BARC_THR_QUIET[bv2]);

    
    /*
      we calculate 
      pow(10.0f,(float)(barcThrQuiet - ABS_LEV)*0.1)*(float)ABS_LOW*(pbOffset[i+1] - pbOffset[i]);
    */

    pbThresholdQuiet[i] = pow2_xy((((barcThrQuiet - ABS_LEV) * 100) +
                          LOG2_1000*(14+2*LOG_NORM_PCM)), LOG2_1000) * (pbOffset[i+1] - pbOffset[i]);
  }
}


/*****************************************************************************
*
* function name: initSpreading
* description:  init energy spreading parameter
*
*****************************************************************************/
static void initSpreading(Word16  numPb,
                          Word16 *pbBarcValue,
                          Word16 *pbMaskLoFactor,
                          Word16 *pbMaskHiFactor,
                          Word16 *pbMaskLoFactorSprEn,
                          Word16 *pbMaskHiFactorSprEn,
                          const Word32 bitrate,
                          const Word16 blockType)
{
  Word16 i;
  Word16 maskLowSprEn, maskHighSprEn;

   
  if (sub(blockType, SHORT_WINDOW) != 0) {
    maskLowSprEn = maskLowSprEnLong;                                     
       
    if (bitrate > 22000)
      maskHighSprEn = maskHighSprEnLong;
    else
      maskHighSprEn = maskHighSprEnLongLowBr;
  }
  else {
    maskLowSprEn = maskLowSprEnShort;            
    maskHighSprEn = maskHighSprEnShort;          
  }

  for(i=0; i<numPb; i++) {
     
    if (i > 0) {
      Word32 dbVal;
      Word16 dbark = pbBarcValue[i] - pbBarcValue[i-1];

      /*
        we calulate pow(10.0f, -0.1*dbVal/BARC_SCALE) 
      */
      dbVal = (maskHigh * dbark);
      pbMaskHiFactor[i] = round16(pow2_xy(L_negate(dbVal), (Word32)LOG2_1000));             /* 0.301 log10(2) */
       
      dbVal = (maskLow * dbark);
      pbMaskLoFactor[i-1] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000)); 
       
      
      dbVal = (maskHighSprEn * dbark);
      pbMaskHiFactorSprEn[i] =  round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000)); 
      dbVal = (maskLowSprEn * dbark);
      pbMaskLoFactorSprEn[i-1] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
    }
    else {
      pbMaskHiFactor[i] = 0;                     
      pbMaskLoFactor[numPb-1] = 0;               

      pbMaskHiFactorSprEn[i] = 0;                
      pbMaskLoFactorSprEn[numPb-1] = 0;          
    }
  }

}


/*****************************************************************************
*
* function name: initBarcValues
* description:  init bark value
*
*****************************************************************************/
static void initBarcValues(Word16  numPb,
                           Word16 *pbOffset,
                           Word16  numLines,
                           Word32  samplingFrequency,
                           Word16 *pbBval)
{
  Word16 i;
  Word16 pbBval0, pbBval1;

  pbBval0 = 0;                                       

  for(i=0; i<numPb; i++){
    pbBval1 = BarcLineValue(numLines, pbOffset[i+1], samplingFrequency);
    pbBval[i] = (pbBval0 + pbBval1) >> 1;
    pbBval0 = pbBval1;                              
  }
}


/*****************************************************************************
*
* function name: initMinSnr
* description:  calculate min snr parameter
*				minSnr(n) = 1/(2^sfbPemin(n)/w(n) - 1.5)
*
*****************************************************************************/
static void initMinSnr(const Word32  bitrate,
                       const Word32  samplerate,
                       const Word16  numLines,
                       const Word16 *sfbOffset,
                       const Word16 *pbBarcVal,
                       const Word16  sfbActive,
                       Word16       *sfbMinSnr)
{
  Word16 sfb;
  Word16 barcWidth;
  Word16 pePerWindow;
  Word32 pePart;
  Word32 snr;
  Word16 pbVal0, pbVal1, shift;

  /* relative number of active barks */


  pePerWindow = bits2pe(extract_l((bitrate * numLines) / samplerate));

  pbVal0 = 0;                                                    

  for (sfb=0; sfb<sfbActive; sfb++) {

    pbVal1 = (pbBarcVal[sfb] << 1) - pbVal0;
    barcWidth = pbVal1 - pbVal0;
    pbVal0 = pbVal1;                                             

    /* allow at least 2.4% of pe for each active barc */
	pePart = ((pePerWindow * 24) * (max_bark * barcWidth)) /
        (pbBarcVal[sfbActive-1] * (sfbOffset[sfb+1] - sfbOffset[sfb]));
   
      
    pePart = min(pePart, 8400); 
    pePart = max(pePart, 1400);

    /* minSnr(n) = 1/(2^sfbPemin(n)/w(n) - 1.5)*/
	/* we add an offset of 2^16 to the pow functions */
	/* 0xc000 = 1.5*(1 << 15)*/
      
    snr = pow2_xy((pePart - 16*1000),1000) - 0x0000c000;
      
    if(snr > 0x00008000)
	{
		shift = norm_l(snr);
		snr = Div_32(0x00008000 << shift, snr << shift);  
	}
	else
	{
		snr = 0x7fffffff;
	}
      
    /* upper limit is -1 dB */
    snr = min(snr, c_maxsnr);
    /* lower limit is -25 dB */
    snr = max(snr, c_minsnr);
    sfbMinSnr[sfb] = round16(snr);
  }

}

/*****************************************************************************
*
* function name: InitPsyConfigurationLong
* description:  init long block psychoacoustic configuration
*
*****************************************************************************/
Word16 InitPsyConfigurationLong(Word32 bitrate,
                                Word32 samplerate,
                                Word16 bandwidth,
                                PSY_CONFIGURATION_LONG *psyConf)
{
  Word32 samplerateindex;
  Word16 sfbBarcVal[MAX_SFB_LONG];
  Word16 sfb;

  /*
    init sfb table
  */
  samplerateindex = GetSRIndex(samplerate);  
  psyConf->sfbCnt = sfBandTotalLong[samplerateindex];
  psyConf->sfbOffset = sfBandTabLong + sfBandTabLongOffset[samplerateindex];
  psyConf->sampRateIdx = samplerateindex;

  /*
    calculate barc values for each pb
  */
  initBarcValues(psyConf->sfbCnt,
                 psyConf->sfbOffset,
                 psyConf->sfbOffset[psyConf->sfbCnt],
                 samplerate,
                 sfbBarcVal);

  /*
    init thresholds in quiet
  */
  initThrQuiet(psyConf->sfbCnt,
               psyConf->sfbOffset,
               sfbBarcVal,
               psyConf->sfbThresholdQuiet);

  /*
    calculate spreading function
  */
  initSpreading(psyConf->sfbCnt,
                sfbBarcVal,
                psyConf->sfbMaskLowFactor,
                psyConf->sfbMaskHighFactor,
                psyConf->sfbMaskLowFactorSprEn,
                psyConf->sfbMaskHighFactorSprEn,
                bitrate,
                LONG_WINDOW);

  /*
    init ratio
  */
  psyConf->ratio = c_ratio;      

  psyConf->maxAllowedIncreaseFactor = 2;              
  psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor;    /* 0.01 *(1 << 15)*/  

  psyConf->clipEnergy = c_maxClipEnergyLong;                   
  psyConf->lowpassLine = extract_l((bandwidth<<1) * FRAME_LEN_LONG / samplerate);

  for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
    if (sub(psyConf->sfbOffset[sfb], psyConf->lowpassLine) >= 0)
      break;
  }
  psyConf->sfbActive = sfb;                 

  /*
    calculate minSnr
  */
  initMinSnr(bitrate,
             samplerate,
             psyConf->sfbOffset[psyConf->sfbCnt],
             psyConf->sfbOffset,
             sfbBarcVal,
             psyConf->sfbActive,
             psyConf->sfbMinSnr);


  return(0);
}

/*****************************************************************************
*
* function name: InitPsyConfigurationShort
* description:  init short block psychoacoustic configuration
*
*****************************************************************************/
Word16 InitPsyConfigurationShort(Word32 bitrate,
                                 Word32 samplerate,
                                 Word16 bandwidth,
                                 PSY_CONFIGURATION_SHORT *psyConf) 
{
  Word32 samplerateindex;
  Word16 sfbBarcVal[MAX_SFB_SHORT];
  Word16 sfb;
  /*
    init sfb table
  */
  samplerateindex = GetSRIndex(samplerate);  
  psyConf->sfbCnt = sfBandTotalShort[samplerateindex];
  psyConf->sfbOffset = sfBandTabShort + sfBandTabShortOffset[samplerateindex];
  psyConf->sampRateIdx = samplerateindex;
  /*
    calculate barc values for each pb
  */
  initBarcValues(psyConf->sfbCnt,
                 psyConf->sfbOffset,
                 psyConf->sfbOffset[psyConf->sfbCnt],
                 samplerate,
                 sfbBarcVal);

  /*
    init thresholds in quiet
  */
  initThrQuiet(psyConf->sfbCnt,
               psyConf->sfbOffset,
               sfbBarcVal,
               psyConf->sfbThresholdQuiet);

  /*
    calculate spreading function
  */
  initSpreading(psyConf->sfbCnt,
                sfbBarcVal,
                psyConf->sfbMaskLowFactor,
                psyConf->sfbMaskHighFactor,
                psyConf->sfbMaskLowFactorSprEn,
                psyConf->sfbMaskHighFactorSprEn,
                bitrate,
                SHORT_WINDOW);

  /*
    init ratio
  */
  psyConf->ratio = c_ratio;                                                      

  psyConf->maxAllowedIncreaseFactor = 2;                                         
  psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor;                            	 

  psyConf->clipEnergy = c_maxClipEnergyShort;                                    

  psyConf->lowpassLine = extract_l(((bandwidth << 1) * FRAME_LEN_SHORT) / samplerate);
 
  for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
     
    if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine)
      break;
  }
  psyConf->sfbActive = sfb;                                                      

  /*
    calculate minSnr
  */
  initMinSnr(bitrate,
             samplerate,
             psyConf->sfbOffset[psyConf->sfbCnt],
             psyConf->sfbOffset,
             sfbBarcVal,
             psyConf->sfbActive,
             psyConf->sfbMinSnr);

  return(0);
}

