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

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

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

/*----------------------------------------------------------------*
 *  quantizer for the gain in the gain-shape coding of residual
 *---------------------------------------------------------------*/

WebRtc_Word16 WebRtcIlbcfix_GainQuant( /* (o) quantized gain value */
    WebRtc_Word16 gain, /* (i) gain value Q14 */
    WebRtc_Word16 maxIn, /* (i) maximum of gain value Q14 */
    WebRtc_Word16 stage, /* (i) The stage of the search */
    WebRtc_Word16 *index /* (o) quantization index */
                                        ) {

  WebRtc_Word16 scale, returnVal, cblen;
  WebRtc_Word32 gainW32, measure1, measure2;
  const WebRtc_Word16 *cbPtr, *cb;
  int loc, noMoves, noChecks, i;

  /* ensure a lower bound (0.1) on the scaling factor */

  scale = WEBRTC_SPL_MAX(1638, maxIn);

  /* select the quantization table and calculate
     the length of the table and the number of
     steps in the binary search that are needed */
  cb = WebRtcIlbcfix_kGain[stage];
  cblen = 32>>stage;
  noChecks = 4-stage;

  /* Multiply the gain with 2^14 to make the comparison
     easier and with higher precision */
  gainW32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)gain, 14);

  /* Do a binary search, starting in the middle of the CB
     loc - defines the current position in the table
     noMoves - defines the number of steps to move in the CB in order
     to get next CB location
  */

  loc = cblen>>1;
  noMoves = loc;
  cbPtr = cb + loc; /* Centre of CB */

  for (i=noChecks;i>0;i--) {
    noMoves>>=1;
    measure1=WEBRTC_SPL_MUL_16_16(scale, (*cbPtr));

    /* Move up if gain is larger, otherwise move down in table */
    measure1 = measure1 - gainW32;

    if (0>measure1) {
      cbPtr+=noMoves;
      loc+=noMoves;
    } else {
      cbPtr-=noMoves;
      loc-=noMoves;
    }
  }

  /* Check which value is the closest one: loc-1, loc or loc+1 */

  measure1=WEBRTC_SPL_MUL_16_16(scale, (*cbPtr));
  if (gainW32>measure1) {
    /* Check against value above loc */
    measure2=WEBRTC_SPL_MUL_16_16(scale, (*(cbPtr+1)));
    if ((measure2-gainW32)<(gainW32-measure1)) {
      loc+=1;
    }
  } else {
    /* Check against value below loc */
    measure2=WEBRTC_SPL_MUL_16_16(scale, (*(cbPtr-1)));
    if ((gainW32-measure2)<=(measure1-gainW32)) {
      loc-=1;
    }
  }

  /* Guard against getting outside the table. The calculation above can give a location
     which is one above the maximum value (in very rare cases) */
  loc=WEBRTC_SPL_MIN(loc, (cblen-1));
  *index=loc;

  /* Calculate the quantized gain value (in Q14) */
  returnVal=(WebRtc_Word16)((WEBRTC_SPL_MUL_16_16(scale, cb[loc])+8192)>>14);

  /* return the quantized value */
  return(returnVal);
}
