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 Pathname: ./audio/gsm-amr/c/src/q_gain_c.c
35 Functions: q_gain_code
36
37 Date: 02/05/2002
38
39 ------------------------------------------------------------------------------
40 REVISION HISTORY
41
42 Description: Updated template used to PV coding template.
43 Changed to accept the pOverflow flag for EPOC compatibility.
44
45 Description:
46 (1) Removed optimization -- mult(i, 3, pOverflow) is NOT the same as adding
47 i to itself 3 times. The reason is because the mult function does a
48 right shift by 15, which will obliterate smaller numbers.
49
50 Description:
51 1. Eliminated unused include files.
52 2. Eliminated math operations that unnecessary checked for
53 saturation by evaluating the operands
54
55 Description: Replaced "int" and/or "char" with OSCL defined types.
56
57 Description: Added #ifdef __cplusplus around extern'ed table.
58
59 Description:
60
61 ------------------------------------------------------------------------------
62 MODULE DESCRIPTION
63
64 Scalar quantization of the innovative codebook gain.
65
66 ------------------------------------------------------------------------------
67 */
68
69 /*----------------------------------------------------------------------------
70 ; INCLUDES
71 ----------------------------------------------------------------------------*/
72 #include "q_gain_c.h"
73 #include "mode.h"
74 #include "oper_32b.h"
75 #include "basic_op.h"
76 #include "log2.h"
77 #include "pow2.h"
78
79 /*--------------------------------------------------------------------------*/
80 #ifdef __cplusplus
81 extern "C"
82 {
83 #endif
84
85 /*----------------------------------------------------------------------------
86 ; MACROS
87 ; Define module specific macros here
88 ----------------------------------------------------------------------------*/
89
90 /*----------------------------------------------------------------------------
91 ; DEFINES
92 ; Include all pre-processor statements here. Include conditional
93 ; compile variables also.
94 ----------------------------------------------------------------------------*/
95 #define NB_QUA_CODE 32
96
97 /*----------------------------------------------------------------------------
98 ; LOCAL FUNCTION DEFINITIONS
99 ; Function Prototype declaration
100 ----------------------------------------------------------------------------*/
101
102 /*----------------------------------------------------------------------------
103 ; LOCAL VARIABLE DEFINITIONS
104 ; Variable declaration - defined here and used outside this module
105 ----------------------------------------------------------------------------*/
106
107 /*----------------------------------------------------------------------------
108 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
109 ; Declare variables used in this module but defined elsewhere
110 ----------------------------------------------------------------------------*/
111 extern const Word16 qua_gain_code[NB_QUA_CODE*3];
112
113 /*--------------------------------------------------------------------------*/
114 #ifdef __cplusplus
115 }
116 #endif
117
118 /*
119 ------------------------------------------------------------------------------
120 FUNCTION NAME: q_gain_code
121 ------------------------------------------------------------------------------
122 INPUT AND OUTPUT DEFINITIONS
123
124 Inputs:
125 mode -- enum Mode -- AMR mode
126 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0
127 frac_gcode0 -- Word16 -- predicted CB gain (fraction), Q15
128 gain -- Pointer to Word16 -- quantized fixed codebook gain, Q1
129
130 Outputs:
131 gain -- Pointer to Word16 -- quantized fixed codebook gain, Q1
132
133 qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10
134 (for MR122 MA predictor update)
135
136 qua_ener -- Pointer to Word16 -- quantized energy error, Q10
137 (for other MA predictor update)
138
139 pOverflow -- Pointer to Flag -- overflow indicator
140 Returns:
141 quantization index -- Word16 -- Q0
142
143 Global Variables Used:
144 qua_gain_code[]
145
146 Local Variables Needed:
147 None
148
149 ------------------------------------------------------------------------------
150 FUNCTION DESCRIPTION
151
152 Scalar quantization of the innovative codebook gain.
153
154 ------------------------------------------------------------------------------
155 REQUIREMENTS
156
157 None
158
159 ------------------------------------------------------------------------------
160 REFERENCES
161
162 q_gain_c.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
163
164 ------------------------------------------------------------------------------
165 PSEUDO-CODE
166
167
168 ------------------------------------------------------------------------------
169 RESOURCES USED [optional]
170
171 When the code is written for a specific target processor the
172 the resources used should be documented below.
173
174 HEAP MEMORY USED: x bytes
175
176 STACK MEMORY USED: x bytes
177
178 CLOCK CYCLES: (cycle count equation for this function) + (variable
179 used to represent cycle count for each subroutine
180 called)
181 where: (cycle count variable) = cycle count for [subroutine
182 name]
183
184 ------------------------------------------------------------------------------
185 CAUTION [optional]
186 [State any special notes, constraints or cautions for users of this function]
187
188 ------------------------------------------------------------------------------
189 */
190
q_gain_code(enum Mode mode,Word16 exp_gcode0,Word16 frac_gcode0,Word16 * gain,Word16 * qua_ener_MR122,Word16 * qua_ener,Flag * pOverflow)191 Word16 q_gain_code( /* o : quantization index, Q0 */
192 enum Mode mode, /* i : AMR mode */
193 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
194 Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */
195 Word16 *gain, /* i/o: quantized fixed codebook gain, Q1 */
196 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
197 /* (for MR122 MA predictor update) */
198 Word16 *qua_ener, /* o : quantized energy error, Q10 */
199 /* (for other MA predictor update) */
200 Flag *pOverflow
201 )
202 {
203 const Word16 *p;
204 Word16 i;
205 Word16 index;
206 Word16 gcode0;
207 Word16 err;
208 Word16 err_min;
209 Word16 g_q0;
210 Word16 temp;
211
212 if (mode == MR122)
213 {
214 g_q0 = *gain >> 1; /* Q1 -> Q0 */
215 }
216 else
217 {
218 g_q0 = *gain;
219 }
220
221 /*-------------------------------------------------------------------*
222 * predicted codebook gain *
223 * ~~~~~~~~~~~~~~~~~~~~~~~ *
224 * gc0 = Pow2(int(d)+frac(d)) *
225 * = 2^exp + 2^frac *
226 * *
227 *-------------------------------------------------------------------*/
228
229 gcode0 = (Word16) Pow2(exp_gcode0, frac_gcode0, pOverflow); /* predicted gain */
230
231 if (mode == MR122)
232 {
233 gcode0 = shl(gcode0, 4, pOverflow);
234 }
235 else
236 {
237 gcode0 = shl(gcode0, 5, pOverflow);
238 }
239
240 /*-------------------------------------------------------------------*
241 * Search for best quantizer *
242 *-------------------------------------------------------------------*/
243
244 p = &qua_gain_code[0];
245 err_min = ((Word32)gcode0 * *(p++)) >> 15;
246 err_min = g_q0 - err_min;
247 if (err_min < 0)
248 {
249 err_min = -err_min;
250 }
251
252 p += 2; /* skip quantized energy errors */
253 index = 0;
254
255 for (i = 1; i < NB_QUA_CODE; i++)
256 {
257 err = ((Word32)gcode0 * *(p++)) >> 15;
258 err = g_q0 - err;
259
260 if (err < 0)
261 {
262 err = -err;
263 }
264
265 p += 2; /* skip quantized energy error */
266
267 if (err < err_min)
268 {
269 err_min = err;
270 index = i;
271 }
272 }
273
274 temp = index + (index << 1);
275
276 p = &qua_gain_code[temp];
277
278 temp = (gcode0 * *(p++)) >> 15;
279 if (mode == MR122)
280 {
281 *gain = temp << 1;
282 }
283 else
284 {
285 *gain = temp;
286 }
287
288 /* quantized error energies (for MA predictor update) */
289 *qua_ener_MR122 = *p++;
290 *qua_ener = *p;
291
292 return index;
293 }
294