1 /*
2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 /******************************************************************
12 
13  iLBC Speech Coder ANSI-C Source Code
14 
15  WebRtcIlbcfix_GainQuant.c
16 
17 ******************************************************************/
18 
19 #include "defines.h"
20 #include "constants.h"
21 
22 /*----------------------------------------------------------------*
23  *  quantizer for the gain in the gain-shape coding of residual
24  *---------------------------------------------------------------*/
25 
WebRtcIlbcfix_GainQuant(int16_t gain,int16_t maxIn,int16_t stage,int16_t * index)26 int16_t WebRtcIlbcfix_GainQuant( /* (o) quantized gain value */
27     int16_t gain, /* (i) gain value Q14 */
28     int16_t maxIn, /* (i) maximum of gain value Q14 */
29     int16_t stage, /* (i) The stage of the search */
30     int16_t *index /* (o) quantization index */
31                                         ) {
32 
33   int16_t scale, cblen;
34   int32_t gainW32, measure1, measure2;
35   const int16_t *cbPtr, *cb;
36   int loc, noMoves, noChecks, i;
37 
38   /* ensure a lower bound (0.1) on the scaling factor */
39 
40   scale = WEBRTC_SPL_MAX(1638, maxIn);
41 
42   /* select the quantization table and calculate
43      the length of the table and the number of
44      steps in the binary search that are needed */
45   cb = WebRtcIlbcfix_kGain[stage];
46   cblen = 32>>stage;
47   noChecks = 4-stage;
48 
49   /* Multiply the gain with 2^14 to make the comparison
50      easier and with higher precision */
51   gainW32 = gain << 14;
52 
53   /* Do a binary search, starting in the middle of the CB
54      loc - defines the current position in the table
55      noMoves - defines the number of steps to move in the CB in order
56      to get next CB location
57   */
58 
59   loc = cblen>>1;
60   noMoves = loc;
61   cbPtr = cb + loc; /* Centre of CB */
62 
63   for (i=noChecks;i>0;i--) {
64     noMoves>>=1;
65     measure1 = scale * *cbPtr;
66 
67     /* Move up if gain is larger, otherwise move down in table */
68     measure1 = measure1 - gainW32;
69 
70     if (0>measure1) {
71       cbPtr+=noMoves;
72       loc+=noMoves;
73     } else {
74       cbPtr-=noMoves;
75       loc-=noMoves;
76     }
77   }
78 
79   /* Check which value is the closest one: loc-1, loc or loc+1 */
80 
81   measure1 = scale * *cbPtr;
82   if (gainW32>measure1) {
83     /* Check against value above loc */
84     measure2 = scale * cbPtr[1];
85     if ((measure2-gainW32)<(gainW32-measure1)) {
86       loc+=1;
87     }
88   } else {
89     /* Check against value below loc */
90     measure2 = scale * cbPtr[-1];
91     if ((gainW32-measure2)<=(measure1-gainW32)) {
92       loc-=1;
93     }
94   }
95 
96   /* Guard against getting outside the table. The calculation above can give a location
97      which is one above the maximum value (in very rare cases) */
98   loc=WEBRTC_SPL_MIN(loc, (cblen-1));
99   *index=loc;
100 
101   /* Calculate and return the quantized gain value (in Q14) */
102   return (int16_t)((scale * cb[loc] + 8192) >> 14);
103 }
104