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