/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

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

 iLBC Speech Coder ANSI-C Source Code

 WebRtcIlbcfix_FrameClassify.c

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

#include "defines.h"
#include "constants.h"

/*----------------------------------------------------------------*
 *  Classification of subframes to localize start state
 *---------------------------------------------------------------*/

WebRtc_Word16 WebRtcIlbcfix_FrameClassify(
    /* (o) Index to the max-energy sub frame */
    iLBC_Enc_Inst_t *iLBCenc_inst,
    /* (i/o) the encoder state structure */
    WebRtc_Word16 *residualFIX /* (i) lpc residual signal */
                                                ){
  WebRtc_Word16 max, scale;
  WebRtc_Word32 ssqEn[NSUB_MAX-1];
  WebRtc_Word16 *ssqPtr;
  WebRtc_Word32 *seqEnPtr;
  WebRtc_Word32 maxW32;
  WebRtc_Word16 scale1;
  WebRtc_Word16 pos;
  int n;

  /*
    Calculate the energy of each of the 80 sample blocks
    in the draft the 4 first and last samples are windowed with 1/5...4/5
    and 4/5...1/5 respectively. To simplify for the fixpoint we have changed
    this to 0 0 1 1 and 1 1 0 0
  */

  max = WebRtcSpl_MaxAbsValueW16(residualFIX, iLBCenc_inst->blockl);
  scale=WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(max,max));

  /* Scale to maximum 24 bits so that it won't overflow for 76 samples */
  scale = scale-24;
  scale1 = WEBRTC_SPL_MAX(0, scale);

  /* Calculate energies */
  ssqPtr=residualFIX + 2;
  seqEnPtr=ssqEn;
  for (n=(iLBCenc_inst->nsub-1); n>0; n--) {
    (*seqEnPtr) = WebRtcSpl_DotProductWithScale(ssqPtr, ssqPtr, 76, scale1);
    ssqPtr += 40;
    seqEnPtr++;
  }

  /* Scale to maximum 20 bits in order to allow for the 11 bit window */
  maxW32 = WebRtcSpl_MaxValueW32(ssqEn, (WebRtc_Word16)(iLBCenc_inst->nsub-1));
  scale = WebRtcSpl_GetSizeInBits(maxW32) - 20;
  scale1 = WEBRTC_SPL_MAX(0, scale);

  /* Window each 80 block with the ssqEn_winTbl window to give higher probability for
     the blocks in the middle
  */
  seqEnPtr=ssqEn;
  if (iLBCenc_inst->mode==20) {
    ssqPtr=(WebRtc_Word16*)WebRtcIlbcfix_kStartSequenceEnrgWin+1;
  } else {
    ssqPtr=(WebRtc_Word16*)WebRtcIlbcfix_kStartSequenceEnrgWin;
  }
  for (n=(iLBCenc_inst->nsub-1); n>0; n--) {
    (*seqEnPtr)=WEBRTC_SPL_MUL(((*seqEnPtr)>>scale1), (*ssqPtr));
    seqEnPtr++;
    ssqPtr++;
  }

  /* Extract the best choise of start state */
  pos = WebRtcSpl_MaxIndexW32(ssqEn, (WebRtc_Word16)(iLBCenc_inst->nsub-1)) + 1;

  return(pos);
}
