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 "modules/audio_coding/codecs/ilbc/gain_quant.h"
20
21 #include "modules/audio_coding/codecs/ilbc/constants.h"
22 #include "modules/audio_coding/codecs/ilbc/defines.h"
23
24 /*----------------------------------------------------------------*
25 * quantizer for the gain in the gain-shape coding of residual
26 *---------------------------------------------------------------*/
27
WebRtcIlbcfix_GainQuant(int16_t gain,int16_t maxIn,int16_t stage,int16_t * index)28 int16_t WebRtcIlbcfix_GainQuant( /* (o) quantized gain value */
29 int16_t gain, /* (i) gain value Q14 */
30 int16_t maxIn, /* (i) maximum of gain value Q14 */
31 int16_t stage, /* (i) The stage of the search */
32 int16_t *index /* (o) quantization index */
33 ) {
34
35 int16_t scale, cblen;
36 int32_t gainW32, measure1, measure2;
37 const int16_t *cbPtr, *cb;
38 int loc, noMoves, noChecks, i;
39
40 /* ensure a lower bound (0.1) on the scaling factor */
41
42 scale = WEBRTC_SPL_MAX(1638, maxIn);
43
44 /* select the quantization table and calculate
45 the length of the table and the number of
46 steps in the binary search that are needed */
47 cb = WebRtcIlbcfix_kGain[stage];
48 cblen = 32>>stage;
49 noChecks = 4-stage;
50
51 /* Multiply the gain with 2^14 to make the comparison
52 easier and with higher precision */
53 gainW32 = gain << 14;
54
55 /* Do a binary search, starting in the middle of the CB
56 loc - defines the current position in the table
57 noMoves - defines the number of steps to move in the CB in order
58 to get next CB location
59 */
60
61 loc = cblen>>1;
62 noMoves = loc;
63 cbPtr = cb + loc; /* Centre of CB */
64
65 for (i=noChecks;i>0;i--) {
66 noMoves>>=1;
67 measure1 = scale * *cbPtr;
68
69 /* Move up if gain is larger, otherwise move down in table */
70 measure1 = measure1 - gainW32;
71
72 if (0>measure1) {
73 cbPtr+=noMoves;
74 loc+=noMoves;
75 } else {
76 cbPtr-=noMoves;
77 loc-=noMoves;
78 }
79 }
80
81 /* Check which value is the closest one: loc-1, loc or loc+1 */
82
83 measure1 = scale * *cbPtr;
84 if (gainW32>measure1) {
85 /* Check against value above loc */
86 measure2 = scale * cbPtr[1];
87 if ((measure2-gainW32)<(gainW32-measure1)) {
88 loc+=1;
89 }
90 } else {
91 /* Check against value below loc */
92 measure2 = scale * cbPtr[-1];
93 if ((gainW32-measure2)<=(measure1-gainW32)) {
94 loc-=1;
95 }
96 }
97
98 /* Guard against getting outside the table. The calculation above can give a location
99 which is one above the maximum value (in very rare cases) */
100 loc=WEBRTC_SPL_MIN(loc, (cblen-1));
101 *index=loc;
102
103 /* Calculate and return the quantized gain value (in Q14) */
104 return (int16_t)((scale * cb[loc] + 8192) >> 14);
105 }
106