/*
 ** 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:		block_switch.c

	Content:	Block switching functions

*******************************************************************************/

#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#include "psy_const.h"
#include "block_switch.h"


#define ENERGY_SHIFT (8 - 1)

/**************** internal function prototypes ***********/
static Word16
IIRFilter(const Word16 in, const Word32 coeff[], Word32 states[]);

static Word32
SrchMaxWithIndex(const Word32 *in, Word16 *index, Word16 n);


Word32
CalcWindowEnergy(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
                 Word16 *timeSignal,
                 Word16 chIncrement,
                 Word16 windowLen);



/****************** Constants *****************************/


/*
  IIR high pass coeffs
*/
Word32 hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = {
  0xbec8b439, 0x609d4952  /* -0.5095f, 0.7548f */ 
};

static const Word32 accWindowNrgFac = 0x26666666;                   /* factor for accumulating filtered window energies 0.3 */
static const Word32 oneMinusAccWindowNrgFac = 0x5999999a;			/* 0.7 */
static const Word32 invAttackRatioHighBr = 0x0ccccccd;              /* inverted lower ratio limit for attacks 0.1*/
static const Word32 invAttackRatioLowBr =  0x072b020c;              /* 0.056 */
static const Word32 minAttackNrg = 0x00001e84;                      /* minimum energy for attacks 1e+6 */


/****************** Routines ****************************/


/*****************************************************************************
*
* function name: InitBlockSwitching
* description:  init Block Switching parameter.
* returns:      TRUE if success
*
**********************************************************************************/
Word16 InitBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
                          const Word32 bitRate, const Word16 nChannels)
{
  /* select attackRatio */
           
  if ((sub(nChannels,1)==0 && L_sub(bitRate, 24000) > 0) || 
      (sub(nChannels,1)>0 && bitRate > (nChannels * 16000))) {
    blockSwitchingControl->invAttackRatio = invAttackRatioHighBr;
  }
  else  {
    blockSwitchingControl->invAttackRatio = invAttackRatioLowBr;
  }

  return(TRUE);
}

static Word16 suggestedGroupingTable[TRANS_FAC][MAX_NO_OF_GROUPS] = {
  /* Attack in Window 0 */ {1,  3,  3,  1},
  /* Attack in Window 1 */ {1,  1,  3,  3},
  /* Attack in Window 2 */ {2,  1,  3,  2},
  /* Attack in Window 3 */ {3,  1,  3,  1},
  /* Attack in Window 4 */ {3,  1,  1,  3},
  /* Attack in Window 5 */ {3,  2,  1,  2},
  /* Attack in Window 6 */ {3,  3,  1,  1},
  /* Attack in Window 7 */ {3,  3,  1,  1}
};

/*****************************************************************************
*
* function name: BlockSwitching
* description:  detect this frame whether there is an attack
* returns:      TRUE if success
*
**********************************************************************************/
Word16 BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
                      Word16 *timeSignal,
					  Word32 sampleRate,
                      Word16 chIncrement)
{
  Word32 i, w;
  Word32 enM1, enMax;

  /* Reset grouping info */
  for (i=0; i<TRANS_FAC; i++) {
    blockSwitchingControl->groupLen[i] = 0;                                      
  }


  /* Search for position and amplitude of attack in last frame (1 windows delay) */
  blockSwitchingControl->maxWindowNrg = SrchMaxWithIndex( &blockSwitchingControl->windowNrg[0][BLOCK_SWITCH_WINDOWS-1],
                                                          &blockSwitchingControl->attackIndex,
                                                          BLOCK_SWITCH_WINDOWS);

  blockSwitchingControl->attackIndex = blockSwitchingControl->lastAttackIndex;   

  /* Set grouping info */
  blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS;                          

  for (i=0; i<MAX_NO_OF_GROUPS; i++) {
    blockSwitchingControl->groupLen[i] = suggestedGroupingTable[blockSwitchingControl->attackIndex][i];  
  }
	
  /* if the samplerate is less than 16000, it should be all the short block, avoid pre&post echo */
  if(sampleRate >= 16000) {
	  /* Save current window energy as last window energy */
	  for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) {
		  blockSwitchingControl->windowNrg[0][w] = blockSwitchingControl->windowNrg[1][w];             
		  blockSwitchingControl->windowNrgF[0][w] = blockSwitchingControl->windowNrgF[1][w];           
	  }


	  /* Calculate unfiltered and filtered energies in subwindows and combine to segments */
	  CalcWindowEnergy(blockSwitchingControl, timeSignal, chIncrement, BLOCK_SWITCH_WINDOW_LEN);

	  /* reset attack */
	  blockSwitchingControl->attack = FALSE;                                         

	  enMax = 0;                                                                     
	  enM1 = blockSwitchingControl->windowNrgF[0][BLOCK_SWITCH_WINDOWS-1];           

	  for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) {
		  Word32 enM1_Tmp, accWindowNrg_Tmp, windowNrgF_Tmp;
		  Word16 enM1_Shf, accWindowNrg_Shf, windowNrgF_Shf;

		  accWindowNrg_Shf = norm_l(blockSwitchingControl->accWindowNrg);
		  enM1_Shf = norm_l(enM1);
		  windowNrgF_Shf = norm_l(blockSwitchingControl->windowNrgF[1][w]);

		  accWindowNrg_Tmp = blockSwitchingControl->accWindowNrg << accWindowNrg_Shf;
		  enM1_Tmp = enM1 << enM1_Shf;
		  windowNrgF_Tmp = blockSwitchingControl->windowNrgF[1][w] << windowNrgF_Shf;

		  /* a sliding average of the previous energies */
		  blockSwitchingControl->accWindowNrg = (fixmul(oneMinusAccWindowNrgFac, accWindowNrg_Tmp) >> accWindowNrg_Shf) +
			  (fixmul(accWindowNrgFac, enM1_Tmp) >> enM1_Shf);


		  /* if the energy with the ratio is bigger than the average, and the attack and short block  */
		  if ((fixmul(windowNrgF_Tmp, blockSwitchingControl->invAttackRatio) >> windowNrgF_Shf) >
			  blockSwitchingControl->accWindowNrg ) {
				  blockSwitchingControl->attack = TRUE;                                      
				  blockSwitchingControl->lastAttackIndex = w;                                
		  }
		  enM1 = blockSwitchingControl->windowNrgF[1][w];                              
		  enMax = max(enMax, enM1);
	  }

	  if (enMax < minAttackNrg) {
		  blockSwitchingControl->attack = FALSE;                                       
	  }
  }
  else
  {
	  blockSwitchingControl->attack = TRUE;
  }

  /* Check if attack spreads over frame border */     
  if ((!blockSwitchingControl->attack) && (blockSwitchingControl->lastattack)) {
     
    if (blockSwitchingControl->attackIndex == TRANS_FAC-1) {
      blockSwitchingControl->attack = TRUE;                                      
    }

    blockSwitchingControl->lastattack = FALSE;                                   
  }
  else {
    blockSwitchingControl->lastattack = blockSwitchingControl->attack;           
  }

  blockSwitchingControl->windowSequence =  blockSwitchingControl->nextwindowSequence;    

     
  if (blockSwitchingControl->attack) {
    blockSwitchingControl->nextwindowSequence = SHORT_WINDOW;
  }
  else {
    blockSwitchingControl->nextwindowSequence = LONG_WINDOW;
  }

  /* update short block group */ 
  if (blockSwitchingControl->nextwindowSequence == SHORT_WINDOW) {
     
    if (blockSwitchingControl->windowSequence== LONG_WINDOW) {
      blockSwitchingControl->windowSequence = START_WINDOW;                      
    }
     
    if (blockSwitchingControl->windowSequence == STOP_WINDOW) {
      blockSwitchingControl->windowSequence = SHORT_WINDOW;                      
      blockSwitchingControl->noOfGroups = 3;                                     
      blockSwitchingControl->groupLen[0] = 3;                                    
      blockSwitchingControl->groupLen[1] = 3;                                    
      blockSwitchingControl->groupLen[2] = 2;                                    
    }
  }

  /* update block type */  
  if (blockSwitchingControl->nextwindowSequence == LONG_WINDOW) {
     
    if (blockSwitchingControl->windowSequence == SHORT_WINDOW) {
      blockSwitchingControl->nextwindowSequence = STOP_WINDOW;                   
    }
  }

  return(TRUE);
}


/*****************************************************************************
*
* function name: SrchMaxWithIndex
* description:  search for the biggest value in an array
* returns:      the max value
*
**********************************************************************************/
static Word32 SrchMaxWithIndex(const Word32 in[], Word16 *index, Word16 n)
{
  Word32 max;
  Word32 i, idx;

  /* Search maximum value in array and return index and value */
  max = 0;                                                       
  idx = 0;                                                       

  for (i = 0; i < n; i++) {
     
    if (in[i+1]  > max) {
      max = in[i+1];                                             
      idx = i;                                                   
    }
  }
  *index = idx;                                                  

  return(max);
}

/*****************************************************************************
*
* function name: CalcWindowEnergy
* description:  calculate the energy before iir-filter and after irr-filter
* returns:      TRUE if success
*
**********************************************************************************/
#ifndef ARMV5E
Word32 CalcWindowEnergy(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
                        Word16 *timeSignal,
                        Word16 chIncrement,
                        Word16 windowLen)
{
  Word32 w, i, wOffset, tidx, ch;
  Word32 accuUE, accuFE;
  Word32 tempUnfiltered;
  Word32 tempFiltered;
  Word32 states0, states1;
  Word32 Coeff0, Coeff1;


  states0 = blockSwitchingControl->iirStates[0];
  states1 = blockSwitchingControl->iirStates[1];
  Coeff0 = hiPassCoeff[0];
  Coeff1 = hiPassCoeff[1];
  tidx = 0;                                                   
  for (w=0; w < BLOCK_SWITCH_WINDOWS; w++) {

    accuUE = 0;                                                  
    accuFE = 0;                                                  

    for(i=0; i<windowLen; i++) {
	  Word32 accu1, accu2, accu3;
	  Word32 out;
	  tempUnfiltered = timeSignal[tidx];
      tidx = tidx + chIncrement;

	  accu1 = L_mpy_ls(Coeff1, tempUnfiltered);
	  accu2 = fixmul( Coeff0, states1 );
	  accu3 = accu1 - states0;
	  out = accu3 - accu2;

	  states0 = accu1;             
	  states1 = out;               

      tempFiltered = extract_h(out);	  
      accuUE += (tempUnfiltered * tempUnfiltered) >> ENERGY_SHIFT;
      accuFE += (tempFiltered * tempFiltered) >> ENERGY_SHIFT;
    }

    blockSwitchingControl->windowNrg[1][w] = accuUE;             
    blockSwitchingControl->windowNrgF[1][w] = accuFE;            

  }

  blockSwitchingControl->iirStates[0] = states0;
  blockSwitchingControl->iirStates[1] = states1;

  return(TRUE);
}
#endif

/*****************************************************************************
*
* function name: IIRFilter
* description:  calculate the iir-filter for an array
* returns:      the result after iir-filter
*
**********************************************************************************/
static Word16 IIRFilter(const Word16 in, const Word32 coeff[], Word32 states[])
{
  Word32 accu1, accu2, accu3;
  Word32 out;

  accu1 = L_mpy_ls(coeff[1], in);
  accu3 = accu1 - states[0];
  accu2 = fixmul( coeff[0], states[1] );
  out = accu3 - accu2;

  states[0] = accu1;             
  states[1] = out;               

  return round16(out);
}


static Word16 synchronizedBlockTypeTable[4][4] = {
  /*                 LONG_WINDOW   START_WINDOW  SHORT_WINDOW  STOP_WINDOW */
  /* LONG_WINDOW  */{LONG_WINDOW,  START_WINDOW, SHORT_WINDOW, STOP_WINDOW},
  /* START_WINDOW */{START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW},
  /* SHORT_WINDOW */{SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW},
  /* STOP_WINDOW  */{STOP_WINDOW,  SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW}
};


/*****************************************************************************
*
* function name: SyncBlockSwitching
* description:  update block type and group value
* returns:      TRUE if success
*
**********************************************************************************/
Word16 SyncBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft,
                          BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight,
                          const Word16 nChannels)
{
  Word16 i;
  Word16 patchType = LONG_WINDOW;                

   
  if (nChannels == 1) { /* Mono */
    if (blockSwitchingControlLeft->windowSequence != SHORT_WINDOW) {
      blockSwitchingControlLeft->noOfGroups = 1;                         
      blockSwitchingControlLeft->groupLen[0] = 1;                        

      for (i=1; i<TRANS_FAC; i++) {
        blockSwitchingControlLeft->groupLen[i] = 0;                      
      }
    }
  }
  else { /* Stereo common Window */
    patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft->windowSequence];        
    patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight->windowSequence];       

    /* Set synchronized Blocktype */
    blockSwitchingControlLeft->windowSequence = patchType;               
    blockSwitchingControlRight->windowSequence = patchType;              

    /* Synchronize grouping info */     
    if(patchType != SHORT_WINDOW) { /* Long Blocks */
      /* Set grouping info */
      blockSwitchingControlLeft->noOfGroups = 1;                         
      blockSwitchingControlRight->noOfGroups = 1;                        
      blockSwitchingControlLeft->groupLen[0] = 1;                        
      blockSwitchingControlRight->groupLen[0] = 1;                       

      for (i=1; i<TRANS_FAC; i++) {
        blockSwitchingControlLeft->groupLen[i] = 0;                      
        blockSwitchingControlRight->groupLen[i] = 0;                     
      }
    }
    else {
       
      if (blockSwitchingControlLeft->maxWindowNrg > blockSwitchingControlRight->maxWindowNrg) {
        /* Left Channel wins */
        blockSwitchingControlRight->noOfGroups = blockSwitchingControlLeft->noOfGroups;          
        for (i=0; i<TRANS_FAC; i++) {
          blockSwitchingControlRight->groupLen[i] = blockSwitchingControlLeft->groupLen[i];      
        }
      }
      else {
        /* Right Channel wins */
        blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups;          
        for (i=0; i<TRANS_FAC; i++) {
          blockSwitchingControlLeft->groupLen[i] = blockSwitchingControlRight->groupLen[i];      
        }
      }
    }
  } /*endif Mono or Stereo */

  return(TRUE);
}
