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/qua_gain.c
35 Functions:
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: Changed include files to lowercase.
46
47 Description: Replaced OSCL mem type functions and eliminated include
48 files that now are chosen by OSCL definitions
49
50 Description: Replaced "int" and/or "char" with OSCL defined types.
51
52 Description: Added #ifdef __cplusplus around extern'ed table.
53
54 Description:
55
56 ------------------------------------------------------------------------------
57 MODULE DESCRIPTION
58
59 Quantization of pitch and codebook gains.
60 ------------------------------------------------------------------------------
61 */
62
63 /*----------------------------------------------------------------------------
64 ; INCLUDES
65 ----------------------------------------------------------------------------*/
66 #include "qua_gain.h"
67 #include "typedef.h"
68 #include "basic_op.h"
69
70 #include "mode.h"
71 #include "cnst.h"
72 #include "pow2.h"
73 #include "gc_pred.h"
74
75 /*--------------------------------------------------------------------------*/
76 #ifdef __cplusplus
77 extern "C"
78 {
79 #endif
80
81 /*----------------------------------------------------------------------------
82 ; MACROS
83 ; Define module specific macros here
84 ----------------------------------------------------------------------------*/
85
86 /*----------------------------------------------------------------------------
87 ; DEFINES
88 ; Include all pre-processor statements here. Include conditional
89 ; compile variables also.
90 ----------------------------------------------------------------------------*/
91
92 /*----------------------------------------------------------------------------
93 ; LOCAL FUNCTION DEFINITIONS
94 ; Function Prototype declaration
95 ----------------------------------------------------------------------------*/
96
97 /*----------------------------------------------------------------------------
98 ; LOCAL VARIABLE DEFINITIONS
99 ; Variable declaration - defined here and used outside this module
100 ----------------------------------------------------------------------------*/
101
102 /*----------------------------------------------------------------------------
103 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
104 ; Declare variables used in this module but defined elsewhere
105 ----------------------------------------------------------------------------*/
106 extern const Word16 table_gain_lowrates[];
107 extern const Word16 table_gain_highrates[];
108
109 /*--------------------------------------------------------------------------*/
110 #ifdef __cplusplus
111 }
112 #endif
113
114 /*
115 ------------------------------------------------------------------------------
116 FUNCTION NAME:
117 ------------------------------------------------------------------------------
118 INPUT AND OUTPUT DEFINITIONS
119
120
121 Inputs:
122 mode -- enum Mode -- AMR mode
123 Word16 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0
124 Word16 frac_gcode0 -- Word16 -- predicted CB gain (fraction), Q15
125 Word16 frac_coeff -- Word16 Array -- energy coeff. (5), fraction part, Q15
126 Word16 exp_coeff -- Word16 Array -- energy coeff. (5), exponent part, Q0
127 (frac_coeff and exp_coeff computed in
128 calc_filt_energies())
129
130 Word16 gp_limit -- Word16 -- pitch gain limit
131
132 Outputs:
133 Word16 *gain_pit -- Pointer to Word16 -- Pitch gain, Q14
134 Word16 *gain_cod -- Pointer to Word16 -- Code gain, Q1
135 Word16 *qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10
136 (for MR122 MA predictor update)
137 Word16 *qua_ener -- Pointer to Word16 -- quantized energy error, Q10
138 (for other MA predictor update)
139 Flag *pOverflow -- Pointer to Flag -- overflow indicator
140
141 Returns:
142 Word16 -- index of quantization.
143
144 Global Variables Used:
145
146
147 Local Variables Needed:
148 None
149
150 ------------------------------------------------------------------------------
151 FUNCTION DESCRIPTION
152
153 Quantization of pitch and codebook gains.
154 ------------------------------------------------------------------------------
155 REQUIREMENTS
156
157 None
158
159 ------------------------------------------------------------------------------
160 REFERENCES
161
162 qua_gain.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
191
192 Word16
Qua_gain(enum Mode mode,Word16 exp_gcode0,Word16 frac_gcode0,Word16 frac_coeff[],Word16 exp_coeff[],Word16 gp_limit,Word16 * gain_pit,Word16 * gain_cod,Word16 * qua_ener_MR122,Word16 * qua_ener,Flag * pOverflow)193 Qua_gain( /* o : index of quantization. */
194 enum Mode mode, /* i : AMR mode */
195 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
196 Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */
197 Word16 frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */
198 Word16 exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */
199 /* (frac_coeff and exp_coeff computed in */
200 /* calc_filt_energies()) */
201 Word16 gp_limit, /* i : pitch gain limit */
202 Word16 *gain_pit, /* o : Pitch gain, Q14 */
203 Word16 *gain_cod, /* o : Code gain, Q1 */
204 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
205 /* (for MR122 MA predictor update) */
206 Word16 *qua_ener, /* o : quantized energy error, Q10 */
207 /* (for other MA predictor update) */
208 Flag *pOverflow /* o : overflow indicator */
209 )
210 {
211 const Word16 *p;
212 Word16 i;
213 Word16 j;
214 Word16 index = 0;
215 Word16 gcode0;
216 Word16 e_max;
217 Word16 temp;
218 Word16 exp_code;
219 Word16 g_pitch;
220 Word16 g2_pitch;
221 Word16 g_code;
222 Word16 g2_code;
223 Word16 g_pit_cod;
224 Word16 coeff[5];
225 Word16 coeff_lo[5];
226 Word16 exp_max[5];
227 Word32 L_tmp;
228 Word32 L_tmp2;
229 Word32 dist_min;
230 const Word16 *table_gain;
231 Word16 table_len;
232
233 if (mode == MR102 || mode == MR74 || mode == MR67)
234 {
235 table_len = VQ_SIZE_HIGHRATES;
236 table_gain = table_gain_highrates;
237 }
238 else
239 {
240 table_len = VQ_SIZE_LOWRATES;
241 table_gain = table_gain_lowrates;
242 }
243
244 /*-------------------------------------------------------------------*
245 * predicted codebook gain *
246 * ~~~~~~~~~~~~~~~~~~~~~~~ *
247 * gc0 = 2^exp_gcode0 + 2^frac_gcode0 *
248 * *
249 * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) *
250 *-------------------------------------------------------------------*/
251
252 gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow));
253
254 /*-------------------------------------------------------------------*
255 * Scaling considerations: *
256 * ~~~~~~~~~~~~~~~~~~~~~~~ *
257 *-------------------------------------------------------------------*/
258
259 /*
260 * The error energy (sum) to be minimized consists of five terms, t[0..4].
261 *
262 * t[0] = gp^2 * <y1 y1>
263 * t[1] = -2*gp * <xn y1>
264 * t[2] = gc^2 * <y2 y2>
265 * t[3] = -2*gc * <xn y2>
266 * t[4] = 2*gp*gc * <y1 y2>
267 *
268 */
269
270 /* determine the scaling exponent for g_code: ec = ec0 - 11 */
271 exp_code = sub(exp_gcode0, 11, pOverflow);
272
273 /* calculate exp_max[i] = s[i]-1 */
274 exp_max[0] = sub(exp_coeff[0], 13, pOverflow);
275 exp_max[1] = sub(exp_coeff[1], 14, pOverflow);
276
277 temp = shl(exp_code, 1, pOverflow);
278 temp = add(15, temp, pOverflow);
279 exp_max[2] = add(exp_coeff[2], temp, pOverflow);
280
281 exp_max[3] = add(exp_coeff[3], exp_code, pOverflow);
282
283 temp = add(1, exp_code, pOverflow);
284 exp_max[4] = add(exp_coeff[4], temp, pOverflow);
285
286
287 /*-------------------------------------------------------------------*
288 * Find maximum exponent: *
289 * ~~~~~~~~~~~~~~~~~~~~~~ *
290 * *
291 * For the sum operation, all terms must have the same scaling; *
292 * that scaling should be low enough to prevent overflow. There- *
293 * fore, the maximum scale is determined and all coefficients are *
294 * re-scaled: *
295 * *
296 * e_max = max(exp_max[i]) + 1; *
297 * e = exp_max[i]-e_max; e <= 0! *
298 * c[i] = c[i]*2^e *
299 *-------------------------------------------------------------------*/
300
301 e_max = exp_max[0];
302 for (i = 1; i < 5; i++)
303 {
304 if (exp_max[i] > e_max)
305 {
306 e_max = exp_max[i];
307 }
308 }
309
310 e_max = add(e_max, 1, pOverflow); /* To avoid overflow */
311
312 for (i = 0; i < 5; i++)
313 {
314 j = sub(e_max, exp_max[i], pOverflow);
315 L_tmp = L_deposit_h(frac_coeff[i]);
316 L_tmp = L_shr(L_tmp, j, pOverflow);
317 L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow);
318 }
319
320
321 /*-------------------------------------------------------------------*
322 * Codebook search: *
323 * ~~~~~~~~~~~~~~~~ *
324 * *
325 * For each pair (g_pitch, g_fac) in the table calculate the *
326 * terms t[0..4] and sum them up; the result is the mean squared *
327 * error for the quantized gains from the table. The index for the *
328 * minimum MSE is stored and finally used to retrieve the quantized *
329 * gains *
330 *-------------------------------------------------------------------*/
331
332 /* start with "infinite" MSE */
333 dist_min = MAX_32;
334
335 p = &table_gain[0];
336
337 for (i = 0; i < table_len; i++)
338 {
339 g_pitch = *p++;
340 g_code = *p++; /* this is g_fac */
341 p++; /* skip log2(g_fac) */
342 p++; /* skip 20*log10(g_fac) */
343
344 if (g_pitch <= gp_limit)
345 {
346 g_code = mult(g_code, gcode0, pOverflow);
347 g2_pitch = mult(g_pitch, g_pitch, pOverflow);
348 g2_code = mult(g_code, g_code, pOverflow);
349 g_pit_cod = mult(g_code, g_pitch, pOverflow);
350
351 L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow);
352 L_tmp2 = Mpy_32_16(coeff[1], coeff_lo[1], g_pitch, pOverflow);
353 L_tmp = L_add(L_tmp, L_tmp2, pOverflow);
354
355 L_tmp2 = Mpy_32_16(coeff[2], coeff_lo[2], g2_code, pOverflow);
356 L_tmp = L_add(L_tmp, L_tmp2, pOverflow);
357
358 L_tmp2 = Mpy_32_16(coeff[3], coeff_lo[3], g_code, pOverflow);
359 L_tmp = L_add(L_tmp, L_tmp2, pOverflow);
360
361 L_tmp2 = Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod, pOverflow);
362 L_tmp = L_add(L_tmp, L_tmp2, pOverflow);
363
364 /* store table index if MSE for this index is lower
365 than the minimum MSE seen so far */
366 if (L_tmp < dist_min)
367 {
368 dist_min = L_tmp;
369 index = i;
370 }
371 }
372 }
373
374 /*------------------------------------------------------------------*
375 * read quantized gains and new values for MA predictor memories *
376 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
377 *------------------------------------------------------------------*/
378
379 /* Read the quantized gains */
380 p = &table_gain[shl(index, 2, pOverflow)];
381 *gain_pit = *p++;
382 g_code = *p++;
383 *qua_ener_MR122 = *p++;
384 *qua_ener = *p;
385
386 /*------------------------------------------------------------------*
387 * calculate final fixed codebook gain: *
388 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
389 * *
390 * gc = gc0 * g *
391 *------------------------------------------------------------------*/
392
393 L_tmp = L_mult(g_code, gcode0, pOverflow);
394 temp = sub(10, exp_gcode0, pOverflow);
395 L_tmp = L_shr(L_tmp, temp, pOverflow);
396
397 *gain_cod = extract_h(L_tmp);
398
399 return index;
400 }
401