Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / qua_gain.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: qua_gain.cpp
35
36 ------------------------------------------------------------------------------
37  MODULE DESCRIPTION
38
39     Quantization of pitch and codebook gains.
40 ------------------------------------------------------------------------------
41 */
42
43 /*----------------------------------------------------------------------------
44 ; INCLUDES
45 ----------------------------------------------------------------------------*/
46 #include "qua_gain.h"
47 #include "typedef.h"
48 #include "basic_op.h"
49
50 #include "mode.h"
51 #include "cnst.h"
52 #include "pow2.h"
53 #include "gc_pred.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
72     /*----------------------------------------------------------------------------
73     ; LOCAL FUNCTION DEFINITIONS
74     ; Function Prototype declaration
75     ----------------------------------------------------------------------------*/
76
77     /*----------------------------------------------------------------------------
78     ; LOCAL VARIABLE DEFINITIONS
79     ; Variable declaration - defined here and used outside this module
80     ----------------------------------------------------------------------------*/
81
82     /*----------------------------------------------------------------------------
83     ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
84     ; Declare variables used in this module but defined elsewhere
85     ----------------------------------------------------------------------------*/
86
87     /*--------------------------------------------------------------------------*/
88 #ifdef __cplusplus
89 }
90 #endif
91
92 /*
93 ------------------------------------------------------------------------------
94  FUNCTION NAME:
95 ------------------------------------------------------------------------------
96  INPUT AND OUTPUT DEFINITIONS
97
98
99  Inputs:
100     mode -- enum Mode -- AMR mode
101     Word16 exp_gcode0  -- Word16 -- predicted CB gain (exponent),       Q0
102     Word16 frac_gcode0 -- Word16 -- predicted CB gain (fraction),      Q15
103     Word16 frac_coeff -- Word16 Array -- energy coeff. (5), fraction part, Q15
104     Word16 exp_coeff  -- Word16 Array -- energy coeff. (5), exponent part,  Q0
105                                     (frac_coeff and exp_coeff computed in
106                                     calc_filt_energies())
107
108     Word16 gp_limit -- Word16 --  pitch gain limit
109
110  Outputs:
111     Word16 *gain_pit -- Pointer to Word16 -- Pitch gain,               Q14
112     Word16 *gain_cod -- Pointer to Word16 -- Code gain,                Q1
113     Word16 *qua_ener_MR122 -- Pointer to Word16 -- quantized energy error,  Q10
114                                                 (for MR122 MA predictor update)
115     Word16 *qua_ener -- Pointer to Word16 -- quantized energy error,        Q10
116                                                 (for other MA predictor update)
117     Flag   *pOverflow -- Pointer to Flag -- overflow indicator
118
119  Returns:
120     Word16 -- index of quantization.
121
122  Global Variables Used:
123
124
125  Local Variables Needed:
126     None
127
128 ------------------------------------------------------------------------------
129  FUNCTION DESCRIPTION
130
131     Quantization of pitch and codebook gains.
132 ------------------------------------------------------------------------------
133  REQUIREMENTS
134
135  None
136
137 ------------------------------------------------------------------------------
138  REFERENCES
139
140  qua_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
141
142 ------------------------------------------------------------------------------
143  PSEUDO-CODE
144
145
146 ------------------------------------------------------------------------------
147  CAUTION [optional]
148  [State any special notes, constraints or cautions for users of this function]
149
150 ------------------------------------------------------------------------------
151 */
152
153
154 Word16
155 Qua_gain(                   /* o  : index of quantization.                 */
156     enum Mode mode,         /* i  : AMR mode                               */
157     Word16 exp_gcode0,      /* i  : predicted CB gain (exponent),      Q0  */
158     Word16 frac_gcode0,     /* i  : predicted CB gain (fraction),      Q15 */
159     Word16 frac_coeff[],    /* i  : energy coeff. (5), fraction part,  Q15 */
160     Word16 exp_coeff[],     /* i  : energy coeff. (5), exponent part,  Q0  */
161     /*      (frac_coeff and exp_coeff computed in  */
162     /*       calc_filt_energies())                 */
163     Word16 gp_limit,        /* i  : pitch gain limit                       */
164     Word16 *gain_pit,       /* o  : Pitch gain,                        Q14 */
165     Word16 *gain_cod,       /* o  : Code gain,                         Q1  */
166     Word16 *qua_ener_MR122, /* o  : quantized energy error,            Q10 */
167     /*      (for MR122 MA predictor update)        */
168     Word16 *qua_ener,       /* o  : quantized energy error,            Q10 */
169     /*      (for other MA predictor update)        */
170     CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of tables ptrs    */
171     Flag   *pOverflow       /* o  : overflow indicator                     */
172 )
173 {
174     const Word16 *p;
175     Word16 i;
176     Word16 j;
177     Word16 index = 0;
178     Word16 gcode0;
179     Word16 e_max;
180     Word16 temp;
181     Word16 exp_code;
182     Word16 g_pitch;
183     Word16 g2_pitch;
184     Word16 g_code;
185     Word16 g2_code;
186     Word16 g_pit_cod;
187     Word16 coeff[5];
188     Word16 coeff_lo[5];
189     Word16 exp_max[5];
190     Word32 L_tmp;
191     Word32 L_tmp2;
192     Word32 dist_min;
193     const Word16 *table_gain;
194     Word16 table_len;
195
196     if (mode == MR102 || mode == MR74 || mode == MR67)
197     {
198         table_len = VQ_SIZE_HIGHRATES;
199         table_gain = common_amr_tbls->table_gain_highrates_ptr;
200     }
201     else
202     {
203         table_len = VQ_SIZE_LOWRATES;
204         table_gain = common_amr_tbls->table_gain_lowrates_ptr;
205     }
206
207     /*-------------------------------------------------------------------*
208      *  predicted codebook gain                                          *
209      *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *
210      *  gc0     = 2^exp_gcode0 + 2^frac_gcode0                           *
211      *                                                                   *
212      *  gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0)      *
213      *-------------------------------------------------------------------*/
214
215     gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow));
216
217     /*-------------------------------------------------------------------*
218      *  Scaling considerations:                                          *
219      *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *
220      *-------------------------------------------------------------------*/
221
222     /*
223      * The error energy (sum) to be minimized consists of five terms, t[0..4].
224      *
225      *                      t[0] =    gp^2  * <y1 y1>
226      *                      t[1] = -2*gp    * <xn y1>
227      *                      t[2] =    gc^2  * <y2 y2>
228      *                      t[3] = -2*gc    * <xn y2>
229      *                      t[4] =  2*gp*gc * <y1 y2>
230      *
231      */
232
233     /* determine the scaling exponent for g_code: ec = ec0 - 11 */
234     exp_code = exp_gcode0 - 11;
235
236     /* calculate exp_max[i] = s[i]-1 */
237     exp_max[0] = exp_coeff[0] - 13;
238     exp_max[1] = exp_coeff[1] - 14;
239
240     temp = shl(exp_code, 1, pOverflow);
241     temp += 15;
242     exp_max[2] = add_16(exp_coeff[2], temp, pOverflow);
243
244     exp_max[3] = add_16(exp_coeff[3], exp_code, pOverflow);
245
246     temp = exp_code + 1;
247     exp_max[4] = add_16(exp_coeff[4], temp, pOverflow);
248
249
250     /*-------------------------------------------------------------------*
251      *  Find maximum exponent:                                           *
252      *  ~~~~~~~~~~~~~~~~~~~~~~                                           *
253      *                                                                   *
254      *  For the sum operation, all terms must have the same scaling;     *
255      *  that scaling should be low enough to prevent overflow. There-    *
256      *  fore, the maximum scale is determined and all coefficients are   *
257      *  re-scaled:                                                       *
258      *                                                                   *
259      *    e_max = max(exp_max[i]) + 1;                                   *
260      *    e = exp_max[i]-e_max;         e <= 0!                          *
261      *    c[i] = c[i]*2^e                                                *
262      *-------------------------------------------------------------------*/
263
264     e_max = exp_max[0];
265     for (i = 1; i < 5; i++)
266     {
267         if (exp_max[i] > e_max)
268         {
269             e_max = exp_max[i];
270         }
271     }
272
273     e_max++;
274
275     for (i = 0; i < 5; i++)
276     {
277         j = e_max - exp_max[i];
278         L_tmp = ((Word32)frac_coeff[i] << 16);
279         L_tmp = L_shr(L_tmp, j, pOverflow);
280         L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow);
281     }
282
283
284     /*-------------------------------------------------------------------*
285      *  Codebook search:                                                 *
286      *  ~~~~~~~~~~~~~~~~                                                 *
287      *                                                                   *
288      *  For each pair (g_pitch, g_fac) in the table calculate the        *
289      *  terms t[0..4] and sum them up; the result is the mean squared    *
290      *  error for the quantized gains from the table. The index for the  *
291      *  minimum MSE is stored and finally used to retrieve the quantized *
292      *  gains                                                            *
293      *-------------------------------------------------------------------*/
294
295     /* start with "infinite" MSE */
296     dist_min = MAX_32;
297
298     p = &table_gain[0];
299
300     for (i = 0; i < table_len; i++)
301     {
302         g_pitch = *p++;
303         g_code = *p++;                   /* this is g_fac        */
304         p++;                             /* skip log2(g_fac)     */
305         p++;                             /* skip 20*log10(g_fac) */
306
307         if (g_pitch <= gp_limit)
308         {
309             g_code = mult(g_code, gcode0, pOverflow);
310             g2_pitch = mult(g_pitch, g_pitch, pOverflow);
311             g2_code = mult(g_code, g_code, pOverflow);
312             g_pit_cod = mult(g_code, g_pitch, pOverflow);
313
314             L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow);
315             L_tmp2 = Mpy_32_16(coeff[1], coeff_lo[1], g_pitch, pOverflow);
316             L_tmp = L_add(L_tmp, L_tmp2, pOverflow);
317
318             L_tmp2 = Mpy_32_16(coeff[2], coeff_lo[2], g2_code, pOverflow);
319             L_tmp = L_add(L_tmp, L_tmp2, pOverflow);
320
321             L_tmp2 =  Mpy_32_16(coeff[3], coeff_lo[3], g_code, pOverflow);
322             L_tmp = L_add(L_tmp, L_tmp2, pOverflow);
323
324             L_tmp2 = Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod, pOverflow);
325             L_tmp = L_add(L_tmp, L_tmp2, pOverflow);
326
327             /* store table index if MSE for this index is lower
328                than the minimum MSE seen so far */
329             if (L_tmp < dist_min)
330             {
331                 dist_min = L_tmp;
332                 index = i;
333             }
334         }
335     }
336
337     /*------------------------------------------------------------------*
338      *  read quantized gains and new values for MA predictor memories   *
339      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
340      *------------------------------------------------------------------*/
341
342     /* Read the quantized gains */
343     p = &table_gain[shl(index, 2, pOverflow)];
344     *gain_pit = *p++;
345     g_code = *p++;
346     *qua_ener_MR122 = *p++;
347     *qua_ener = *p;
348
349     /*------------------------------------------------------------------*
350      *  calculate final fixed codebook gain:                            *
351      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                            *
352      *                                                                  *
353      *   gc = gc0 * g                                                   *
354      *------------------------------------------------------------------*/
355
356     L_tmp = L_mult(g_code, gcode0, pOverflow);
357     temp  = 10 - exp_gcode0;
358     L_tmp = L_shr(L_tmp, temp, pOverflow);
359
360     *gain_cod = (Word16)(L_tmp >> 16);
361
362     return index;
363 }