xref: /aosp_15_r20/external/webrtc/modules/audio_coding/codecs/ilbc/gain_quant.c (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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