/*
 ** 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:		tns.c

	Content:	Definition TNS tools functions

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

#include "basic_op.h"
#include "oper_32b.h"
#include "assert.h"
#include "aac_rom.h"
#include "psy_const.h"
#include "tns.h"
#include "tns_param.h"
#include "psy_configuration.h"
#include "tns_func.h"

#define UNUSED(x) (void)(x)

#define TNS_MODIFY_BEGIN         2600  /* Hz */
#define RATIO_PATCH_LOWER_BORDER 380   /* Hz */
#define TNS_GAIN_THRESH			 141   /* 1.41*100 */
#define NORM_COEF				 0x028f5c28

static const Word32 TNS_PARCOR_THRESH = 0x0ccccccd; /* 0.1*(1 << 31) */
/* Limit bands to > 2.0 kHz */
static unsigned short tnsMinBandNumberLong[12] =
{ 11, 12, 15, 16, 17, 20, 25, 26, 24, 28, 30, 31 };
static unsigned short tnsMinBandNumberShort[12] =
{ 2, 2, 2, 3, 3, 4, 6, 6, 8, 10, 10, 12 };

/**************************************/
/* Main/Low Profile TNS Parameters    */
/**************************************/
static unsigned short tnsMaxBandsLongMainLow[12] =
{ 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39 };

static unsigned short tnsMaxBandsShortMainLow[12] =
{ 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14 };


static void CalcWeightedSpectrum(const Word32 spectrum[],
                                 Word16 weightedSpectrum[],
                                 Word32* sfbEnergy,
                                 const Word16* sfbOffset, Word16 lpcStartLine,
                                 Word16 lpcStopLine, Word16 lpcStartBand,Word16 lpcStopBand,
                                 Word32 *pWork32);



void AutoCorrelation(const Word16 input[], Word32 corr[],
                            Word16 samples, Word16 corrCoeff);
static Word16 AutoToParcor(Word32 workBuffer[], Word32 reflCoeff[], Word16 numOfCoeff);

static Word16 CalcTnsFilter(const Word16* signal, const Word32 window[], Word16 numOfLines,
                                              Word16 tnsOrder, Word32 parcor[]);


static void Parcor2Index(const Word32 parcor[], Word16 index[], Word16 order,
                         Word16 bitsPerCoeff);

static void Index2Parcor(const Word16 index[], Word32 parcor[], Word16 order,
                         Word16 bitsPerCoeff);



static void AnalysisFilterLattice(const Word32 signal[], Word16 numOfLines,
                                  const Word32 parCoeff[], Word16 order,
                                  Word32 output[]);


/**
*
* function name: FreqToBandWithRounding
* description:  Retrieve index of nearest band border
* returnt:		index
*
*/
static Word16 FreqToBandWithRounding(Word32 freq,                   /*!< frequency in Hertz */
                                     Word32 fs,                     /*!< Sampling frequency in Hertz */
                                     Word16 numOfBands,             /*!< total number of bands */
                                     const Word16 *bandStartOffset) /*!< table of band borders */
{
  Word32 lineNumber, band;
  Word32 temp, shift;

  /*  assert(freq >= 0);  */
  shift = norm_l(fs);
  lineNumber = (extract_l(fixmul((bandStartOffset[numOfBands] << 2),Div_32(freq << shift,fs << shift))) + 1) >> 1;

  /* freq > fs/2 */
  temp = lineNumber - bandStartOffset[numOfBands] ;
  if (temp >= 0)
    return numOfBands;

  /* find band the line number lies in */
  for (band=0; band<numOfBands; band++) {
    temp = bandStartOffset[band + 1] - lineNumber;
    if (temp > 0) break;
  }

  temp = (lineNumber - bandStartOffset[band]);
  temp = (temp - (bandStartOffset[band + 1] - lineNumber));
  if ( temp > 0 )
  {
    band = band + 1;
  }

  return extract_l(band);
}


/**
*
* function name: InitTnsConfigurationLong
* description:  Fill TNS_CONFIG structure with sensible content for long blocks
* returns:		0 if success
*
*/
Word16 InitTnsConfigurationLong(Word32 bitRate,          /*!< bitrate */
                                Word32 sampleRate,          /*!< Sampling frequency */
                                Word16 channels,            /*!< number of channels */
                                TNS_CONFIG *tC,             /*!< TNS Config struct (modified) */
                                PSY_CONFIGURATION_LONG *pC, /*!< psy config struct */
                                Word16 active)              /*!< tns active flag */
{

  Word32 bitratePerChannel;
  tC->maxOrder     = TNS_MAX_ORDER;
  tC->tnsStartFreq = 1275;
  tC->coefRes      = 4;

  /* to avoid integer division */
  if ( sub(channels,2) == 0 ) {
    bitratePerChannel = bitRate >> 1;
  }
  else {
    bitratePerChannel = bitRate;
  }

  tC->tnsMaxSfb = tnsMaxBandsLongMainLow[pC->sampRateIdx];

  tC->tnsActive = active;

  /* now calc band and line borders */
  tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb);
  tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand];

  tC->tnsStartBand = FreqToBandWithRounding(tC->tnsStartFreq, sampleRate,
                                            pC->sfbCnt, (const Word16*)pC->sfbOffset);

  tC->tnsModifyBeginCb = FreqToBandWithRounding(TNS_MODIFY_BEGIN,
                                                sampleRate,
                                                pC->sfbCnt,
                                                (const Word16*)pC->sfbOffset);

  tC->tnsRatioPatchLowestCb = FreqToBandWithRounding(RATIO_PATCH_LOWER_BORDER,
                                                     sampleRate,
                                                     pC->sfbCnt,
                                                     (const Word16*)pC->sfbOffset);


  tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand];

  tC->lpcStopBand = tnsMaxBandsLongMainLow[pC->sampRateIdx];
  tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive);

  tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];

  tC->lpcStartBand = tnsMinBandNumberLong[pC->sampRateIdx];

  tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand];

  tC->threshold = TNS_GAIN_THRESH;


  return(0);
}

/**
*
* function name: InitTnsConfigurationShort
* description:  Fill TNS_CONFIG structure with sensible content for short blocks
* returns:		0 if success
*
*/
Word16 InitTnsConfigurationShort(Word32 bitRate,              /*!< bitrate */
                                 Word32 sampleRate,           /*!< Sampling frequency */
                                 Word16 channels,             /*!< number of channels */
                                 TNS_CONFIG *tC,              /*!< TNS Config struct (modified) */
                                 PSY_CONFIGURATION_SHORT *pC, /*!< psy config struct */
                                 Word16 active)               /*!< tns active flag */
{
  Word32 bitratePerChannel;
  tC->maxOrder     = TNS_MAX_ORDER_SHORT;
  tC->tnsStartFreq = 2750;
  tC->coefRes      = 3;

  /* to avoid integer division */
  if ( sub(channels,2) == 0 ) {
    bitratePerChannel = L_shr(bitRate,1);
  }
  else {
    bitratePerChannel = bitRate;
  }

  tC->tnsMaxSfb = tnsMaxBandsShortMainLow[pC->sampRateIdx];

  tC->tnsActive = active;

  /* now calc band and line borders */
  tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb);
  tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand];

  tC->tnsStartBand=FreqToBandWithRounding(tC->tnsStartFreq, sampleRate,
                                          pC->sfbCnt, (const Word16*)pC->sfbOffset);

  tC->tnsModifyBeginCb = FreqToBandWithRounding(TNS_MODIFY_BEGIN,
                                                sampleRate,
                                                pC->sfbCnt,
                                                (const Word16*)pC->sfbOffset);

  tC->tnsRatioPatchLowestCb = FreqToBandWithRounding(RATIO_PATCH_LOWER_BORDER,
                                                     sampleRate,
                                                     pC->sfbCnt,
                                                     (const Word16*)pC->sfbOffset);


  tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand];

  tC->lpcStopBand = tnsMaxBandsShortMainLow[pC->sampRateIdx];

  tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive);

  tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];

  tC->lpcStartBand = tnsMinBandNumberShort[pC->sampRateIdx];

  tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand];

  tC->threshold = TNS_GAIN_THRESH;

  return(0);
}

/**
*
* function name: TnsDetect
* description:  Calculate TNS filter and decide on TNS usage
* returns:		0 if success
*
*/
Word32 TnsDetect(TNS_DATA* tnsData,        /*!< tns data structure (modified) */
                 TNS_CONFIG tC,            /*!< tns config structure */
                 Word32* pScratchTns,      /*!< pointer to scratch space */
                 const Word16 sfbOffset[], /*!< scalefactor size and table */
                 Word32* spectrum,         /*!< spectral data */
                 Word16 subBlockNumber,    /*!< subblock num */
                 Word16 blockType,         /*!< blocktype (long or short) */
                 Word32 * sfbEnergy)       /*!< sfb-wise energy */
{

  Word32  predictionGain;
  Word32  temp;
  Word32* pWork32 = &pScratchTns[subBlockNumber >> 8];
  Word16* pWeightedSpectrum = (Word16 *)&pScratchTns[subBlockNumber >> 8];


  if (tC.tnsActive) {
    CalcWeightedSpectrum(spectrum,
                         pWeightedSpectrum,
                         sfbEnergy,
                         sfbOffset,
                         tC.lpcStartLine,
                         tC.lpcStopLine,
                         tC.lpcStartBand,
                         tC.lpcStopBand,
                         pWork32);

    temp = blockType - SHORT_WINDOW;
    if ( temp != 0 ) {
        predictionGain = CalcTnsFilter( &pWeightedSpectrum[tC.lpcStartLine],
                                        tC.acfWindow,
                                        tC.lpcStopLine - tC.lpcStartLine,
                                        tC.maxOrder,
                                        tnsData->dataRaw.tnsLong.subBlockInfo.parcor);


        temp = predictionGain - tC.threshold;
        if ( temp > 0 ) {
          tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 1;
        }
        else {
          tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0;
        }

        tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = predictionGain;
    }
    else{

        predictionGain = CalcTnsFilter( &pWeightedSpectrum[tC.lpcStartLine],
                                        tC.acfWindow,
                                        tC.lpcStopLine - tC.lpcStartLine,
                                        tC.maxOrder,
                                        tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].parcor);

        temp = predictionGain - tC.threshold;
        if ( temp > 0 ) {
          tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 1;
        }
        else {
          tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0;
        }

        tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = predictionGain;
    }

  }
  else{

    temp = blockType - SHORT_WINDOW;
    if ( temp != 0 ) {
        tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0;
        tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = 0;
    }
    else {
        tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0;
        tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = 0;
    }
  }

  return(0);
}


/*****************************************************************************
*
* function name: TnsSync
* description: update tns parameter
*
*****************************************************************************/
void TnsSync(TNS_DATA *tnsDataDest,
             const TNS_DATA *tnsDataSrc,
             const TNS_CONFIG tC,
             const Word16 subBlockNumber,
             const Word16 blockType)
{
   TNS_SUBBLOCK_INFO *sbInfoDest;
   const TNS_SUBBLOCK_INFO *sbInfoSrc;
   Word32 i, temp;

   temp =  blockType - SHORT_WINDOW;
   if ( temp != 0 ) {
      sbInfoDest = &tnsDataDest->dataRaw.tnsLong.subBlockInfo;
      sbInfoSrc  = &tnsDataSrc->dataRaw.tnsLong.subBlockInfo;
   }
   else {
      sbInfoDest = &tnsDataDest->dataRaw.tnsShort.subBlockInfo[subBlockNumber];
      sbInfoSrc  = &tnsDataSrc->dataRaw.tnsShort.subBlockInfo[subBlockNumber];
   }

   if (100*abs_s(sbInfoDest->predictionGain - sbInfoSrc->predictionGain) <
       (3 * sbInfoDest->predictionGain)) {
      sbInfoDest->tnsActive = sbInfoSrc->tnsActive;
      for ( i=0; i< tC.maxOrder; i++) {
        sbInfoDest->parcor[i] = sbInfoSrc->parcor[i];
      }
   }
}

/*****************************************************************************
*
* function name: TnsEncode
* description: do TNS filtering
* returns:     0 if success
*
*****************************************************************************/
Word16 TnsEncode(TNS_INFO* tnsInfo,     /*!< tns info structure (modified) */
                 TNS_DATA* tnsData,     /*!< tns data structure (modified) */
                 Word16 numOfSfb,       /*!< number of scale factor bands */
                 TNS_CONFIG tC,         /*!< tns config structure */
                 Word16 lowPassLine,    /*!< lowpass line */
                 Word32* spectrum,      /*!< spectral data (modified) */
                 Word16 subBlockNumber, /*!< subblock num */
                 Word16 blockType)      /*!< blocktype (long or short) */
{
  Word32 i;
  Word32 temp_s;
  Word32 temp;
  TNS_SUBBLOCK_INFO *psubBlockInfo;

  temp_s = blockType - SHORT_WINDOW;
  if ( temp_s != 0) {
    psubBlockInfo = &tnsData->dataRaw.tnsLong.subBlockInfo;
	if (psubBlockInfo->tnsActive == 0) {
      tnsInfo->tnsActive[subBlockNumber] = 0;
      return(0);
    }
    else {

      Parcor2Index(psubBlockInfo->parcor,
                   tnsInfo->coef,
                   tC.maxOrder,
                   tC.coefRes);

      Index2Parcor(tnsInfo->coef,
                   psubBlockInfo->parcor,
                   tC.maxOrder,
                   tC.coefRes);

      for (i=tC.maxOrder - 1; i>=0; i--)  {
        temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH;
        if ( temp > 0 )
          break;
        temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH;
        if ( temp < 0 )
          break;
      }
      tnsInfo->order[subBlockNumber] = i + 1;


      tnsInfo->tnsActive[subBlockNumber] = 1;
      for (i=subBlockNumber+1; i<TRANS_FAC; i++) {
        tnsInfo->tnsActive[i] = 0;
      }
      tnsInfo->coefRes[subBlockNumber] = tC.coefRes;
      tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand;


      AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]),
                            (min(tC.tnsStopLine,lowPassLine) - tC.tnsStartLine),
                            psubBlockInfo->parcor,
                            tnsInfo->order[subBlockNumber],
                            &(spectrum[tC.tnsStartLine]));

    }
  }     /* if (blockType!=SHORT_WINDOW) */
  else /*short block*/ {
    psubBlockInfo = &tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber];
	if (psubBlockInfo->tnsActive == 0) {
      tnsInfo->tnsActive[subBlockNumber] = 0;
      return(0);
    }
    else {

      Parcor2Index(psubBlockInfo->parcor,
                   &tnsInfo->coef[subBlockNumber*TNS_MAX_ORDER_SHORT],
                   tC.maxOrder,
                   tC.coefRes);

      Index2Parcor(&tnsInfo->coef[subBlockNumber*TNS_MAX_ORDER_SHORT],
                   psubBlockInfo->parcor,
                   tC.maxOrder,
                   tC.coefRes);
      for (i=(tC.maxOrder - 1); i>=0; i--)  {
        temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH;
         if ( temp > 0 )
          break;

        temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH;
        if ( temp < 0 )
          break;
      }
      tnsInfo->order[subBlockNumber] = i + 1;

      tnsInfo->tnsActive[subBlockNumber] = 1;
      tnsInfo->coefRes[subBlockNumber] = tC.coefRes;
      tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand;


      AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]), (tC.tnsStopLine - tC.tnsStartLine),
                 psubBlockInfo->parcor,
                 tnsInfo->order[subBlockNumber],
                 &(spectrum[tC.tnsStartLine]));

    }
  }

  return(0);
}


/*****************************************************************************
*
* function name: m_pow2_cordic
* description: Iterative power function
*
*	Calculates pow(2.0,x-1.0*(scale+1)) with INT_BITS bit precision
*	using modified cordic algorithm
* returns:     the result of pow2
*
*****************************************************************************/
static Word32 m_pow2_cordic(Word32 x, Word16 scale)
{
  Word32 k;

  Word32 accu_y = 0x40000000;
  accu_y = L_shr(accu_y,scale);

  for(k=1; k<INT_BITS; k++) {
    const Word32 z = m_log2_table[k];

    while(L_sub(x,z) >= 0) {

      x = L_sub(x, z);
      accu_y = L_add(accu_y, (accu_y >> k));
    }
  }
  return(accu_y);
}


/*****************************************************************************
*
* function name: CalcWeightedSpectrum
* description: Calculate weighted spectrum for LPC calculation
*
*****************************************************************************/
static void CalcWeightedSpectrum(const Word32  spectrum[],         /*!< input spectrum */
                                 Word16        weightedSpectrum[],
                                 Word32       *sfbEnergy,          /*!< sfb energies */
                                 const Word16 *sfbOffset,
                                 Word16        lpcStartLine,
                                 Word16        lpcStopLine,
                                 Word16        lpcStartBand,
                                 Word16        lpcStopBand,
                                 Word32       *pWork32)
{
    #define INT_BITS_SCAL 1<<(INT_BITS/2)

    Word32 i, sfb, shift;
    Word32 maxShift;
    Word32 tmp_s, tmp2_s;
    Word32 tmp, tmp2;
    Word32 maxWS;
    Word32 tnsSfbMean[MAX_SFB];    /* length [lpcStopBand-lpcStartBand] should be sufficient here */

    maxWS = 0;

    /* calc 1.0*2^-INT_BITS/2/sqrt(en) */
    for( sfb = lpcStartBand; sfb < lpcStopBand; sfb++) {

      tmp2 = sfbEnergy[sfb] - 2;
      if( tmp2 > 0) {
        tmp = rsqrt(sfbEnergy[sfb], INT_BITS);
		if(tmp > INT_BITS_SCAL)
		{
			shift =  norm_l(tmp);
			tmp = Div_32( INT_BITS_SCAL << shift, tmp << shift );
		}
		else
		{
			tmp = 0x7fffffff;
		}
      }
      else {
        tmp = 0x7fffffff;
      }
      tnsSfbMean[sfb] = tmp;
    }

    /* spread normalized values from sfbs to lines */
    sfb = lpcStartBand;
    tmp = tnsSfbMean[sfb];
    for ( i=lpcStartLine; i<lpcStopLine; i++){
      tmp_s = sfbOffset[sfb + 1] - i;
      if ( tmp_s == 0 ) {
        sfb = sfb + 1;
        tmp2_s = sfb + 1 - lpcStopBand;
        if (tmp2_s <= 0) {
          tmp = tnsSfbMean[sfb];
        }
      }
      pWork32[i] = tmp;
    }
    /*filter down*/
    for (i=(lpcStopLine - 2); i>=lpcStartLine; i--){
        pWork32[i] = (pWork32[i] + pWork32[i + 1]) >> 1;
    }
    /* filter up */
    for (i=(lpcStartLine + 1); i<lpcStopLine; i++){
       pWork32[i] = (pWork32[i] + pWork32[i - 1]) >> 1;
    }

    /* weight and normalize */
    for (i=lpcStartLine; i<lpcStopLine; i++){
      pWork32[i] = MULHIGH(pWork32[i], spectrum[i]);
      maxWS |= L_abs(pWork32[i]);
    }
    maxShift = norm_l(maxWS);

	maxShift = 16 - maxShift;
    if(maxShift >= 0)
	{
		for (i=lpcStartLine; i<lpcStopLine; i++){
			weightedSpectrum[i] = pWork32[i] >> maxShift;
		}
    }
	else
	{
		maxShift = -maxShift;
		for (i=lpcStartLine; i<lpcStopLine; i++){
			weightedSpectrum[i] = saturate(pWork32[i] << maxShift);
		}
	}
}




/*****************************************************************************
*
* function name: CalcTnsFilter
* description:  LPC calculation for one TNS filter
* returns:      prediction gain
* input:        signal spectrum, acf window, no. of spectral lines,
*                max. TNS order, ptr. to reflection ocefficients
* output:       reflection coefficients
*(half) window size must be larger than tnsOrder !!*
******************************************************************************/

static Word16 CalcTnsFilter(const Word16 *signal,
                            const Word32 window[],
                            Word16 numOfLines,
                            Word16 tnsOrder,
                            Word32 parcor[])
{
  Word32 parcorWorkBuffer[2*TNS_MAX_ORDER+1];
  Word32 predictionGain;
  Word32 i;
  Word32 tnsOrderPlus1 = tnsOrder + 1;

  UNUSED(window);

  assert(tnsOrder <= TNS_MAX_ORDER);      /* remove asserts later? (btg) */

  for(i=0;i<tnsOrder;i++) {
    parcor[i] = 0;
  }

  AutoCorrelation(signal, parcorWorkBuffer, numOfLines, tnsOrderPlus1);

  /* early return if signal is very low: signal prediction off, with zero parcor coeffs */
  if (parcorWorkBuffer[0] == 0)
    return 0;

  predictionGain = AutoToParcor(parcorWorkBuffer, parcor, tnsOrder);

  return(predictionGain);
}

/*****************************************************************************
*
* function name: AutoCorrelation
* description:  calc. autocorrelation (acf)
* returns:      -
* input:        input values, no. of input values, no. of acf values
* output:       acf values
*
*****************************************************************************/
#ifndef ARMV5E
void AutoCorrelation(const Word16		 input[],
                            Word32       corr[],
                            Word16       samples,
                            Word16       corrCoeff) {
  Word32 i, j, isamples;
  Word32 accu;
  Word32 scf;

  scf = 10 - 1;

  isamples = samples;
  /* calc first corrCoef:  R[0] = sum { t[i] * t[i] } ; i = 0..N-1 */
  accu = 0;
  for(j=0; j<isamples; j++) {
    accu = L_add(accu, ((input[j] * input[j]) >> scf));
  }
  corr[0] = accu;

  /* early termination if all corr coeffs are likely going to be zero */
  if(corr[0] == 0) return ;

  /* calc all other corrCoef:  R[j] = sum { t[i] * t[i+j] } ; i = 0..(N-j-1), j=1..p */
  for(i=1; i<corrCoeff; i++) {
    isamples = isamples - 1;
    accu = 0;
    for(j=0; j<isamples; j++) {
      accu = L_add(accu, ((input[j] * input[j+i]) >> scf));
    }
    corr[i] = accu;
  }
}
#endif

/*****************************************************************************
*
* function name: AutoToParcor
* description:  conversion autocorrelation to reflection coefficients
* returns:      prediction gain
* input:        <order+1> input values, no. of output values (=order),
*               ptr. to workbuffer (required size: 2*order)
* output:       <order> reflection coefficients
*
*****************************************************************************/
static Word16 AutoToParcor(Word32 workBuffer[], Word32 reflCoeff[], Word16 numOfCoeff) {

  Word32 i, j, shift;
  Word32 *pWorkBuffer; /* temp pointer */
  Word32 predictionGain = 0;
  Word32 num, denom;
  Word32 temp, workBuffer0;


  num = workBuffer[0];
  temp = workBuffer[numOfCoeff];

  for(i=0; i<numOfCoeff-1; i++) {
    workBuffer[i + numOfCoeff] = workBuffer[i + 1];
  }
  workBuffer[i + numOfCoeff] = temp;

  for(i=0; i<numOfCoeff; i++) {
    Word32 refc;


    if (workBuffer[0] < L_abs(workBuffer[i + numOfCoeff])) {
      return 0 ;
    }
	shift = norm_l(workBuffer[0]);
	workBuffer0 = Div_32(1 << shift, workBuffer[0] << shift);
    /* calculate refc = -workBuffer[numOfCoeff+i] / workBuffer[0]; -1 <= refc < 1 */
	refc = L_negate(fixmul(workBuffer[numOfCoeff + i], workBuffer0));

    reflCoeff[i] = refc;

    pWorkBuffer = &(workBuffer[numOfCoeff]);

    for(j=i; j<numOfCoeff; j++) {
      Word32 accu1, accu2;
      accu1 = L_add(pWorkBuffer[j], fixmul(refc, workBuffer[j - i]));
      accu2 = L_add(workBuffer[j - i], fixmul(refc, pWorkBuffer[j]));
      pWorkBuffer[j] = accu1;
      workBuffer[j - i] = accu2;
    }
  }

  denom = MULHIGH(workBuffer[0], NORM_COEF);

  if (denom != 0) {
    Word32 temp;
	shift = norm_l(denom);
	temp = Div_32(1 << shift, denom << shift);
    predictionGain = fixmul(num, temp);
  }

  return extract_l(predictionGain);
}



static Word16 Search3(Word32 parcor)
{
  Word32 index = 0;
  Word32 i;
  Word32 temp;

  for (i=0;i<8;i++) {
    temp = L_sub( parcor, tnsCoeff3Borders[i]);
    if (temp > 0)
      index=i;
  }
  return extract_l(index - 4);
}

static Word16 Search4(Word32 parcor)
{
  Word32 index = 0;
  Word32 i;
  Word32 temp;


  for (i=0;i<16;i++) {
    temp = L_sub(parcor, tnsCoeff4Borders[i]);
    if (temp > 0)
      index=i;
  }
  return extract_l(index - 8);
}



/*****************************************************************************
*
* functionname: Parcor2Index
* description:  quantization index for reflection coefficients
*
*****************************************************************************/
static void Parcor2Index(const Word32 parcor[],   /*!< parcor coefficients */
                         Word16 index[],          /*!< quantized coeff indices */
                         Word16 order,            /*!< filter order */
                         Word16 bitsPerCoeff) {   /*!< quantizer resolution */
  Word32 i;
  Word32 temp;

  for(i=0; i<order; i++) {
    temp = bitsPerCoeff - 3;
    if (temp == 0) {
      index[i] = Search3(parcor[i]);
    }
    else {
      index[i] = Search4(parcor[i]);
    }
  }
}

/*****************************************************************************
*
* functionname: Index2Parcor
* description:  Inverse quantization for reflection coefficients
*
*****************************************************************************/
static void Index2Parcor(const Word16 index[],  /*!< quantized values */
                         Word32 parcor[],       /*!< ptr. to reflection coefficients (output) */
                         Word16 order,          /*!< no. of coefficients */
                         Word16 bitsPerCoeff)   /*!< quantizer resolution */
{
  Word32 i;
  Word32 temp;

  for (i=0; i<order; i++) {
    temp = bitsPerCoeff - 4;
    if ( temp == 0 ) {
        parcor[i] = tnsCoeff4[index[i] + 8];
    }
    else {
        parcor[i] = tnsCoeff3[index[i] + 4];
    }
  }
}

/*****************************************************************************
*
* functionname: FIRLattice
* description:  in place lattice filtering of spectral data
* returns:		pointer to modified data
*
*****************************************************************************/
static Word32 FIRLattice(Word16 order,           /*!< filter order */
                         Word32 x,               /*!< spectral data */
                         Word32 *state_par,      /*!< filter states */
                         const Word32 *coef_par) /*!< filter coefficients */
{
   Word32 i;
   Word32 accu,tmp,tmpSave;

   x = x >> 1;
   tmpSave = x;

   for (i=0; i<(order - 1); i++) {

     tmp = L_add(fixmul(coef_par[i], x), state_par[i]);
     x   = L_add(fixmul(coef_par[i], state_par[i]), x);

     state_par[i] = tmpSave;
     tmpSave = tmp;
  }

  /* last stage: only need half operations */
  accu = fixmul(state_par[order - 1], coef_par[(order - 1)]);
  state_par[(order - 1)] = tmpSave;

  x = L_add(accu, x);
  x = L_add(x, x);

  return x;
}

/*****************************************************************************
*
* functionname: AnalysisFilterLattice
* description:  filters spectral lines with TNS filter
*
*****************************************************************************/
static void AnalysisFilterLattice(const  Word32 signal[],  /*!< input spectrum */
                                  Word16 numOfLines,       /*!< no. of lines */
                                  const  Word32 parCoeff[],/*!< PARC coefficients */
                                  Word16 order,            /*!< filter order */
                                  Word32 output[])         /*!< filtered signal values */
{

  Word32 state_par[TNS_MAX_ORDER];
  Word32 j;

  for ( j=0; j<TNS_MAX_ORDER; j++ ) {
    state_par[j] = 0;
  }

  for(j=0; j<numOfLines; j++) {
    output[j] = FIRLattice(order,signal[j],state_par,parCoeff);
  }
}

/*****************************************************************************
*
* functionname: ApplyTnsMultTableToRatios
* description:  Change thresholds according to tns
*
*****************************************************************************/
void ApplyTnsMultTableToRatios(Word16 startCb,
                               Word16 stopCb,
                               TNS_SUBBLOCK_INFO subInfo, /*!< TNS subblock info */
                               Word32 *thresholds)        /*!< thresholds (modified) */
{
  Word32 i;
  if (subInfo.tnsActive) {
    for(i=startCb; i<stopCb; i++) {
      /* thresholds[i] * 0.25 */
      thresholds[i] = (thresholds[i] >> 2);
    }
  }
}
