Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / q_gain_c.cpp
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21     3GPP TS 26.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34  Filename: q_gain_c.cpp
35  Functions: q_gain_code
36
37 ------------------------------------------------------------------------------
38  MODULE DESCRIPTION
39
40     Scalar quantization of the innovative codebook gain.
41
42 ------------------------------------------------------------------------------
43 */
44
45 /*----------------------------------------------------------------------------
46 ; INCLUDES
47 ----------------------------------------------------------------------------*/
48 #include "q_gain_c.h"
49 #include "mode.h"
50 #include "oper_32b.h"
51 #include "basic_op.h"
52 #include "log2.h"
53 #include "pow2.h"
54
55 /*--------------------------------------------------------------------------*/
56 #ifdef __cplusplus
57 extern "C"
58 {
59 #endif
60
61     /*----------------------------------------------------------------------------
62     ; MACROS
63     ; Define module specific macros here
64     ----------------------------------------------------------------------------*/
65
66     /*----------------------------------------------------------------------------
67     ; DEFINES
68     ; Include all pre-processor statements here. Include conditional
69     ; compile variables also.
70     ----------------------------------------------------------------------------*/
71 #define NB_QUA_CODE 32
72
73     /*----------------------------------------------------------------------------
74     ; LOCAL FUNCTION DEFINITIONS
75     ; Function Prototype declaration
76     ----------------------------------------------------------------------------*/
77
78     /*----------------------------------------------------------------------------
79     ; LOCAL VARIABLE DEFINITIONS
80     ; Variable declaration - defined here and used outside this module
81     ----------------------------------------------------------------------------*/
82
83     /*----------------------------------------------------------------------------
84     ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
85     ; Declare variables used in this module but defined elsewhere
86     ----------------------------------------------------------------------------*/
87
88     /*--------------------------------------------------------------------------*/
89 #ifdef __cplusplus
90 }
91 #endif
92
93 /*
94 ------------------------------------------------------------------------------
95  FUNCTION NAME: q_gain_code
96 ------------------------------------------------------------------------------
97  INPUT AND OUTPUT DEFINITIONS
98
99  Inputs:
100     mode -- enum Mode -- AMR mode
101     exp_gcode0 -- Word16 -- predicted CB gain (exponent),  Q0
102     frac_gcode0 -- Word16 -- predicted CB gain (fraction),  Q15
103     gain -- Pointer to Word16 -- quantized fixed codebook gain, Q1
104
105  Outputs:
106     gain -- Pointer to Word16 -- quantized fixed codebook gain, Q1
107
108     qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10
109                                            (for MR122 MA predictor update)
110
111     qua_ener -- Pointer to Word16 -- quantized energy error,        Q10
112                                      (for other MA predictor update)
113
114     pOverflow -- Pointer to Flag -- overflow indicator
115  Returns:
116     quantization index -- Word16 -- Q0
117
118  Global Variables Used:
119     qua_gain_code[]
120
121  Local Variables Needed:
122     None
123
124 ------------------------------------------------------------------------------
125  FUNCTION DESCRIPTION
126
127     Scalar quantization of the innovative codebook gain.
128
129 ------------------------------------------------------------------------------
130  REQUIREMENTS
131
132  None
133
134 ------------------------------------------------------------------------------
135  REFERENCES
136
137  q_gain_c.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
138
139 ------------------------------------------------------------------------------
140  PSEUDO-CODE
141
142
143 ------------------------------------------------------------------------------
144  CAUTION [optional]
145  [State any special notes, constraints or cautions for users of this function]
146
147 ------------------------------------------------------------------------------
148 */
149
150 Word16 q_gain_code(         /* o  : quantization index,            Q0  */
151     enum Mode mode,         /* i  : AMR mode                           */
152     Word16 exp_gcode0,      /* i  : predicted CB gain (exponent),  Q0  */
153     Word16 frac_gcode0,     /* i  : predicted CB gain (fraction),  Q15 */
154     Word16 *gain,           /* i/o: quantized fixed codebook gain, Q1  */
155     Word16 *qua_ener_MR122, /* o  : quantized energy error,        Q10 */
156     /*      (for MR122 MA predictor update)    */
157     Word16 *qua_ener,       /* o  : quantized energy error,        Q10 */
158     /*      (for other MA predictor update)    */
159     const Word16* qua_gain_code_ptr, /* i : ptr to read-only table           */
160     Flag   *pOverflow
161 )
162 {
163     const Word16 *p;
164     Word16 i;
165     Word16 index;
166     Word16 gcode0;
167     Word16 err;
168     Word16 err_min;
169     Word16 g_q0;
170     Word16 temp;
171
172     if (mode == MR122)
173     {
174         g_q0 = *gain >> 1; /* Q1 -> Q0 */
175     }
176     else
177     {
178         g_q0 = *gain;
179     }
180
181     /*-------------------------------------------------------------------*
182      *  predicted codebook gain                                          *
183      *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *
184      *  gc0     = Pow2(int(d)+frac(d))                                   *
185      *          = 2^exp + 2^frac                                         *
186      *                                                                   *
187      *-------------------------------------------------------------------*/
188
189     gcode0 = (Word16) Pow2(exp_gcode0, frac_gcode0, pOverflow);  /* predicted gain */
190
191     if (mode == MR122)
192     {
193         gcode0 = shl(gcode0, 4, pOverflow);
194     }
195     else
196     {
197         gcode0 = shl(gcode0, 5, pOverflow);
198     }
199
200     /*-------------------------------------------------------------------*
201      *                   Search for best quantizer                        *
202      *-------------------------------------------------------------------*/
203
204     p = &qua_gain_code_ptr[0];
205     err_min = ((Word32)gcode0 * *(p++)) >> 15;
206     err_min =  g_q0 - err_min;
207     if (err_min < 0)
208     {
209         err_min = -err_min;
210     }
211
212     p += 2;                                  /* skip quantized energy errors */
213     index = 0;
214
215     for (i = 1; i < NB_QUA_CODE; i++)
216     {
217         err = ((Word32)gcode0 * *(p++)) >> 15;
218         err =  g_q0 - err;
219
220         if (err < 0)
221         {
222             err = -err;
223         }
224
225         p += 2;                              /* skip quantized energy error */
226
227         if (err < err_min)
228         {
229             err_min = err;
230             index = i;
231         }
232     }
233
234     temp = index + (index << 1);
235
236     p = &qua_gain_code_ptr[temp];
237
238     temp  = (gcode0 * *(p++)) >> 15;
239     if (mode == MR122)
240     {
241         *gain =  temp << 1;
242     }
243     else
244     {
245         *gain = temp;
246     }
247
248     /* quantized error energies (for MA predictor update) */
249     *qua_ener_MR122 = *p++;
250     *qua_ener = *p;
251
252     return index;
253 }