Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / qgain795.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: qgain795.cpp
35  Functions: MR795_gain_code_quant3
36             MR795_gain_code_quant_mod
37             MR795_gain_quant
38
39 ------------------------------------------------------------------------------
40  MODULE DESCRIPTION
41
42
43 ------------------------------------------------------------------------------
44 */
45
46 /*----------------------------------------------------------------------------
47 ; INCLUDES
48 ----------------------------------------------------------------------------*/
49 #include "qgain795.h"
50 #include "typedef.h"
51 #include "basic_op.h"
52 #include "cnst.h"
53 #include "log2.h"
54 #include "pow2.h"
55 #include "sqrt_l.h"
56 #include "g_adapt.h"
57 #include "calc_en.h"
58 #include "q_gain_p.h"
59
60
61 /*--------------------------------------------------------------------------*/
62 #ifdef __cplusplus
63 extern "C"
64 {
65 #endif
66
67     /*----------------------------------------------------------------------------
68     ; MACROS
69     ; Define module specific macros here
70     ----------------------------------------------------------------------------*/
71
72     /*----------------------------------------------------------------------------
73     ; DEFINES
74     ; Include all pre-processor statements here. Include conditional
75     ; compile variables also.
76     ----------------------------------------------------------------------------*/
77 #define NB_QUA_CODE 32
78
79     /*----------------------------------------------------------------------------
80     ; LOCAL FUNCTION DEFINITIONS
81     ; Function Prototype declaration
82     ----------------------------------------------------------------------------*/
83
84     /*----------------------------------------------------------------------------
85     ; LOCAL VARIABLE DEFINITIONS
86     ; Variable declaration - defined here and used outside this module
87     ----------------------------------------------------------------------------*/
88
89     /*----------------------------------------------------------------------------
90     ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
91     ; Declare variables used in this module but defined elsewhere
92     ----------------------------------------------------------------------------*/
93
94     /*--------------------------------------------------------------------------*/
95 #ifdef __cplusplus
96 }
97 #endif
98
99 /*
100 ------------------------------------------------------------------------------
101  FUNCTION NAME: MR795_gain_code_quant3
102 ------------------------------------------------------------------------------
103  INPUT AND OUTPUT DEFINITIONS
104
105  Inputs:
106     exp_gcode0     -- Word16       -- predicted CB gain (exponent), Q0
107     gcode0         -- Word16       -- predicted CB gain (norm.)
108     g_pitch_cand[] -- Word16 array -- Pitch gain candidates (3),    Q14
109     g_pitch_cind[] -- Word16 array -- Pitch gain cand. indices (3), Q0
110     frac_coeff[]   -- Word16 array -- coefficients (5),             Q15
111     exp_coeff[]    -- Word16 array -- energy coefficients (5),      Q0
112                                       coefficients from calc_filt_ener()
113
114  Outputs:
115     gain_pit       -- Pointer to Word16 -- Pitch gain,                     Q14
116     gain_pit_ind   -- Pointer to Word16 -- Pitch gain index,               Q0
117     gain_cod       -- Pointer to Word16 -- Code gain,                      Q1
118     gain_cod_ind   -- Pointer to Word16 -- Code gain index,                Q0
119     qua_ener_MR122 -- Pointer to Word16 -- quantized energy error,         Q10
120                                           (for MR122 MA predictor update)
121
122     qua_ener -- Pointer to Word16 -- quantized energy error,       Q10
123                                      (for other MA predictor update)
124
125     pOverflow -- Pointer to Flag --  overflow indicator
126
127  Returns:
128     None
129
130  Global Variables Used:
131     None
132
133  Local Variables Needed:
134     None
135
136 ------------------------------------------------------------------------------
137  FUNCTION DESCRIPTION
138
139  PURPOSE: Pre-quantization of codebook gains, given three possible
140           LTP gains (using predicted codebook gain)
141 ------------------------------------------------------------------------------
142  REQUIREMENTS
143
144  None
145
146 ------------------------------------------------------------------------------
147  REFERENCES
148
149  qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
150
151 ------------------------------------------------------------------------------
152  PSEUDO-CODE
153
154
155 ------------------------------------------------------------------------------
156  CAUTION [optional]
157  [State any special notes, constraints or cautions for users of this function]
158
159 ------------------------------------------------------------------------------
160 */
161
162 static void
163 MR795_gain_code_quant3(
164     Word16 exp_gcode0,        /* i  : predicted CB gain (exponent), Q0  */
165     Word16 gcode0,            /* i  : predicted CB gain (norm.),    Q14 */
166     Word16 g_pitch_cand[],    /* i  : Pitch gain candidates (3),    Q14 */
167     Word16 g_pitch_cind[],    /* i  : Pitch gain cand. indices (3), Q0  */
168     Word16 frac_coeff[],      /* i  : coefficients (5),             Q15 */
169     Word16 exp_coeff[],       /* i  : energy coefficients (5),      Q0  */
170     /*      coefficients from calc_filt_ener()*/
171     Word16 *gain_pit,         /* o  : Pitch gain,                   Q14 */
172     Word16 *gain_pit_ind,     /* o  : Pitch gain index,             Q0  */
173     Word16 *gain_cod,         /* o  : Code gain,                    Q1  */
174     Word16 *gain_cod_ind,     /* o  : Code gain index,              Q0  */
175     Word16 *qua_ener_MR122,   /* o  : quantized energy error,       Q10 */
176     /*      (for MR122 MA predictor update)   */
177     Word16 *qua_ener,         /* o  : quantized energy error,       Q10 */
178     /*      (for other MA predictor update)   */
179     const Word16* qua_gain_code_ptr, /* i : ptr to read-only table      */
180     Flag   *pOverflow         /* o  : overflow indicator                */
181 )
182 {
183     const Word16 *p;
184     Word16 i;
185     Word16 j;
186     Word16 cod_ind;
187     Word16 pit_ind;
188     Word16 e_max;
189     Word16 exp_code;
190     Word16 g_pitch;
191     Word16 g2_pitch;
192     Word16 g_code;
193     Word16 g2_code_h;
194     Word16 g2_code_l;
195     Word16 g_pit_cod_h;
196     Word16 g_pit_cod_l;
197     Word16 coeff[5];
198     Word16 coeff_lo[5];
199     Word16 exp_max[5];
200     Word32 L_tmp;
201     Word32 L_tmp0;
202     Word32 dist_min;
203
204     /*
205      * The error energy (sum) to be minimized consists of five terms, t[0..4].
206      *
207      *                      t[0] =    gp^2  * <y1 y1>
208      *                      t[1] = -2*gp    * <xn y1>
209      *                      t[2] =    gc^2  * <y2 y2>
210      *                      t[3] = -2*gc    * <xn y2>
211      *                      t[4] =  2*gp*gc * <y1 y2>
212      *
213      */
214
215     /* determine the scaling exponent for g_code: ec = ec0 - 10 */
216     exp_code = exp_gcode0 - 10;
217
218     /* calculate exp_max[i] = s[i]-1 */
219     exp_max[0] = exp_coeff[0] - 13;
220     exp_max[1] = exp_coeff[1] - 14;
221     exp_max[2] = exp_coeff[2] + shl(exp_code, 1, pOverflow) + 15;
222     exp_max[3] = exp_coeff[3] + exp_code;
223     exp_max[4] = exp_coeff[4] + (exp_code + 1);
224
225
226     /*-------------------------------------------------------------------*
227      *  Find maximum exponent:                                           *
228      *  ~~~~~~~~~~~~~~~~~~~~~~                                           *
229      *                                                                   *
230      *  For the sum operation, all terms must have the same scaling;     *
231      *  that scaling should be low enough to prevent overflow. There-    *
232      *  fore, the maximum scale is determined and all coefficients are   *
233      *  re-scaled:                                                       *
234      *                                                                   *
235      *    e_max = max(exp_max[i]) + 1;                                   *
236      *    e = exp_max[i]-e_max;         e <= 0!                          *
237      *    c[i] = c[i]*2^e                                                *
238      *-------------------------------------------------------------------*/
239
240     e_max = exp_max[0];
241     for (i = 1; i < 5; i++)     /* implemented flattened */
242     {
243         if (exp_max[i] > e_max)
244         {
245             e_max = exp_max[i];
246         }
247     }
248
249     e_max = add_16(e_max, 1, pOverflow);      /* To avoid overflow */
250
251     for (i = 0; i < 5; i++)
252     {
253         j = e_max - exp_max[i];
254         L_tmp = ((Word32)frac_coeff[i] << 16);
255         L_tmp = L_shr(L_tmp, j, pOverflow);
256         L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow);
257     }
258
259
260     /*-------------------------------------------------------------------*
261      *  Codebook search:                                                 *
262      *  ~~~~~~~~~~~~~~~~                                                 *
263      *                                                                   *
264      *  For each of the candiates LTP gains in g_pitch_cand[], the terms *
265      *  t[0..4] are calculated from the values in the table (and the     *
266      *  pitch gain candidate) and summed up; the result is the mean      *
267      *  squared error for the LPT/CB gain pair. The index for the mini-  *
268      *  mum MSE is stored and finally used to retrieve the quantized CB  *
269      *  gain                                                             *
270      *-------------------------------------------------------------------*/
271
272     /* start with "infinite" MSE */
273     dist_min = MAX_32;
274     cod_ind = 0;
275     pit_ind = 0;
276
277     /* loop through LTP gain candidates */
278     for (j = 0; j < 3; j++)
279     {
280         /* pre-calculate terms only dependent on pitch gain */
281         g_pitch = g_pitch_cand[j];
282         g2_pitch = mult(g_pitch, g_pitch, pOverflow);
283         L_tmp0 = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow);
284         L_tmp0 = Mac_32_16(L_tmp0, coeff[1], coeff_lo[1], g_pitch, pOverflow);
285
286         p = &qua_gain_code_ptr[0];
287         for (i = 0; i < NB_QUA_CODE; i++)
288         {
289             g_code = *p++;                   /* this is g_fac        Q11 */
290             p++;                             /* skip log2(g_fac)         */
291             p++;                             /* skip 20*log10(g_fac)     */
292
293             g_code = mult(g_code, gcode0, pOverflow);
294
295             L_tmp = L_mult(g_code, g_code, pOverflow);
296             L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow);
297
298             L_tmp = L_mult(g_code, g_pitch, pOverflow);
299             L_Extract(L_tmp, &g_pit_cod_h, &g_pit_cod_l, pOverflow);
300
301             L_tmp = Mac_32(L_tmp0, coeff[2], coeff_lo[2],
302                            g2_code_h, g2_code_l, pOverflow);
303             L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3],
304                               g_code, pOverflow);
305             L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4],
306                            g_pit_cod_h, g_pit_cod_l, pOverflow);
307
308             /* store table index if MSE for this index is lower
309                than the minimum MSE seen so far; also store the
310                pitch gain for this (so far) lowest MSE          */
311             if (L_tmp < dist_min)
312             {
313                 dist_min = L_tmp;
314                 cod_ind = i;
315                 pit_ind = j;
316             }
317         }
318     }
319
320     /*------------------------------------------------------------------*
321      *  read quantized gains and new values for MA predictor memories   *
322      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
323      *------------------------------------------------------------------*/
324
325     /* Read the quantized gains */
326     p = &qua_gain_code_ptr[(cod_ind<<2) - cod_ind];
327
328     g_code = *p++;
329     *qua_ener_MR122 = *p++;
330     *qua_ener = *p;
331
332     /*------------------------------------------------------------------*
333      *  calculate final fixed codebook gain:                            *
334      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                            *
335      *                                                                  *
336      *   gc = gc0 * g                                                   *
337      *------------------------------------------------------------------*/
338
339     L_tmp = L_mult(g_code, gcode0, pOverflow);
340     L_tmp = L_shr(L_tmp, 9 - exp_gcode0, pOverflow);
341     *gain_cod = (Word16)(L_tmp >> 16);
342     *gain_cod_ind = cod_ind;
343     *gain_pit = g_pitch_cand[pit_ind];
344     *gain_pit_ind = g_pitch_cind[pit_ind];
345 }
346
347
348 /*
349 ------------------------------------------------------------------------------
350  FUNCTION NAME: MR795_gain_code_quant_mod
351 ------------------------------------------------------------------------------
352  INPUT AND OUTPUT DEFINITIONS
353
354  Inputs:
355     gain_pit     -- Word16 -- pitch gain,                                   Q14
356     exp_gcode0   -- Word16 -- predicted CB gain (exponent),                 Q0
357     gcode0       -- Word16 -- predicted CB gain (norm.),                    Q14
358     frac_en[]    -- Word16 array -- energy coefficients (4), fraction part, Q15
359     exp_en[]     -- Word16 array -- energy coefficients (4), exponent part, Q0
360     alpha        -- Word16 -- gain adaptor factor (>0),                     Q15
361
362     gain_cod_unq -- Word16 -- Code gain (unquantized)
363                               (scaling: Q10 - exp_gcode0)
364
365     gain_cod     -- Pointer to Word16 -- Code gain (pre-/quantized),        Q1
366
367  Outputs:
368     qua_ener_MR122 -- Pointer to Word16 -- quantized energy error,       Q10
369                                            (for MR122 MA predictor update)
370     qua_ener       -- Pointer to Word16 -- quantized energy error,       Q10
371                                            (for other MA predictor update)
372     pOverflow      -- Pointer to Flag -- overflow indicator
373
374  Returns:
375     index of quantization (Word16)
376
377  Global Variables Used:
378     None
379
380  Local Variables Needed:
381     None
382
383 ------------------------------------------------------------------------------
384  FUNCTION DESCRIPTION
385
386  PURPOSE: Modified quantization of the MR795 codebook gain
387
388  Uses pre-computed energy coefficients in frac_en[]/exp_en[]
389
390        frac_en[0]*2^exp_en[0] = <res res>   // LP residual energy
391        frac_en[1]*2^exp_en[1] = <exc exc>   // LTP residual energy
392        frac_en[2]*2^exp_en[2] = <exc code>  // LTP/CB innovation dot product
393        frac_en[3]*2^exp_en[3] = <code code> // CB innovation energy
394 ------------------------------------------------------------------------------
395  REQUIREMENTS
396
397  None
398
399 ------------------------------------------------------------------------------
400  REFERENCES
401
402  qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
403
404 ------------------------------------------------------------------------------
405  PSEUDO-CODE
406
407
408 ------------------------------------------------------------------------------
409  CAUTION [optional]
410  [State any special notes, constraints or cautions for users of this function]
411
412 ------------------------------------------------------------------------------
413 */
414
415 static Word16
416 MR795_gain_code_quant_mod(  /* o  : index of quantization.            */
417     Word16 gain_pit,        /* i  : pitch gain,                   Q14 */
418     Word16 exp_gcode0,      /* i  : predicted CB gain (exponent), Q0  */
419     Word16 gcode0,          /* i  : predicted CB gain (norm.),    Q14 */
420     Word16 frac_en[],       /* i  : energy coefficients (4),
421                                     fraction part,                Q15 */
422     Word16 exp_en[],        /* i  : energy coefficients (4),
423                                     eponent part,                 Q0  */
424     Word16 alpha,           /* i  : gain adaptor factor (>0),     Q15 */
425     Word16 gain_cod_unq,    /* i  : Code gain (unquantized)           */
426     /*      (scaling: Q10 - exp_gcode0)       */
427     Word16 *gain_cod,       /* i/o: Code gain (pre-/quantized),   Q1  */
428     Word16 *qua_ener_MR122, /* o  : quantized energy error,       Q10 */
429     /*      (for MR122 MA predictor update)   */
430     Word16 *qua_ener,       /* o  : quantized energy error,       Q10 */
431     /*      (for other MA predictor update)   */
432     const Word16* qua_gain_code_ptr, /* i : ptr to read-only ptr      */
433     Flag   *pOverflow       /* o  : overflow indicator                */
434 )
435 {
436     const Word16 *p;
437     Word16 i;
438     Word16 index;
439     Word16 tmp;
440     Word16 one_alpha;
441     Word16 exp;
442     Word16 e_max;
443
444     Word16 g2_pitch;
445     Word16 g_code;
446     Word16 g2_code_h;
447     Word16 g2_code_l;
448     Word16 d2_code_h;
449     Word16 d2_code_l;
450     Word16 coeff[5];
451     Word16 coeff_lo[5];
452     Word16 exp_coeff[5];
453     Word32 L_tmp;
454     Word32 L_t0;
455     Word32 L_t1;
456     Word32 dist_min;
457     Word16 gain_code;
458
459     /*
460       Steps in calculation of the error criterion (dist):
461       ---------------------------------------------------
462
463       underlined = constant; alp = FLP value of alpha, alpha = FIP
464       ----------
465
466
467         ExEn = gp^2 * LtpEn + 2.0*gp*gc[i] * XC + gc[i]^2 * InnEn;
468                ------------   ------         --             -----
469
470         aExEn= alp * ExEn
471              = alp*gp^2*LtpEn + 2.0*alp*gp*XC* gc[i] + alp*InnEn* gc[i]^2
472                --------------   -------------          ---------
473
474              =         t[1]   +              t[2]    +          t[3]
475
476         dist = d1 + d2;
477
478           d1 = (1.0 - alp) * InnEn * (gcu - gc[i])^2 = t[4]
479                -------------------    ---
480
481           d2 =        alp  * (ResEn - 2.0 * sqrt(ResEn*ExEn) + ExEn);
482                       ---     -----   ---        -----
483
484              =        alp  * (sqrt(ExEn) - sqrt(ResEn))^2
485                       ---                  -----------
486
487              =               (sqrt(aExEn) - sqrt(alp*ResEn))^2
488                                             ---------------
489
490              =               (sqrt(aExEn) -       t[0]     )^2
491                                                   ----
492
493      */
494
495     /*
496      * calculate scalings of the constant terms
497      */
498     gain_code = shl(*gain_cod, (10 - exp_gcode0), pOverflow);   /* Q1  -> Q11 (-ec0) */
499     g2_pitch = mult(gain_pit, gain_pit, pOverflow);               /* Q14 -> Q13        */
500     /* 0 < alpha <= 0.5 => 0.5 <= 1-alpha < 1, i.e one_alpha is normalized  */
501     one_alpha = add_16((32767 - alpha), 1, pOverflow);   /* 32768 - alpha */
502
503
504     /*  alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */
505     L_t1 = L_mult(alpha, frac_en[1], pOverflow);
506     L_t1 = L_shl(L_t1, 1, pOverflow);
507     tmp = (Word16)(L_t1 >> 16);
508
509     /* directly store in 32 bit variable because no further mult. required */
510     L_t1 = L_mult(tmp, g2_pitch, pOverflow);
511     exp_coeff[1] = exp_en[1] - 15;
512
513
514     tmp = (Word16)(L_shl(L_mult(alpha, frac_en[2], pOverflow), 1, pOverflow) >> 16);
515     coeff[2] = mult(tmp, gain_pit, pOverflow);
516     exp = exp_gcode0 - 10;
517     exp_coeff[2] = add_16(exp_en[2], exp, pOverflow);
518
519
520     /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */
521     coeff[3] = (Word16)(L_shl(L_mult(alpha, frac_en[3], pOverflow), 1, pOverflow) >> 16);
522     exp = shl(exp_gcode0, 1, pOverflow) - 7;
523     exp_coeff[3] = add_16(exp_en[3], exp, pOverflow);
524
525
526     coeff[4] = mult(one_alpha, frac_en[3], pOverflow);
527     exp_coeff[4] = add_16(exp_coeff[3], 1, pOverflow);
528
529
530     L_tmp = L_mult(alpha, frac_en[0], pOverflow);
531     /* sqrt_l returns normalized value and 2*exponent
532        -> result = val >> (exp/2)
533        exp_coeff holds 2*exponent for c[0]            */
534     /* directly store in 32 bit variable because no further mult. required */
535     L_t0 = sqrt_l_exp(L_tmp, &exp, pOverflow);  /* normalization included in sqrt_l_exp */
536     exp += 47;
537     exp_coeff[0] = exp_en[0] - exp;
538
539     /*
540      * Determine the maximum exponent occuring in the distance calculation
541      * and adjust all fractions accordingly (including a safety margin)
542      *
543      */
544
545     /* find max(e[1..4],e[0]+31) */
546     e_max = exp_coeff[0] + 31;
547     for (i = 1; i <= 4; i++)
548     {
549         if (exp_coeff[i] > e_max)
550         {
551             e_max = exp_coeff[i];
552         }
553     }
554
555     /* scale c[1]         (requires no further multiplication) */
556     tmp = e_max - exp_coeff[1];
557     L_t1 = L_shr(L_t1, tmp, pOverflow);
558
559     /* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */
560     for (i = 2; i <= 4; i++)
561     {
562         tmp = e_max - exp_coeff[i];
563         L_tmp = ((Word32)coeff[i] << 16);
564         L_tmp = L_shr(L_tmp, tmp, pOverflow);
565         L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow);
566     }
567
568     /* scale c[0]         (requires no further multiplication) */
569     exp = e_max - 31;              /* new exponent */
570     tmp = exp - exp_coeff[0];
571     L_t0 = L_shr(L_t0, shr(tmp, 1, pOverflow), pOverflow);
572     /* perform correction by 1/sqrt(2) if exponent difference is odd */
573     if ((tmp & 0x1) != 0)
574     {
575         L_Extract(L_t0, &coeff[0], &coeff_lo[0], pOverflow);
576         L_t0 = Mpy_32_16(coeff[0], coeff_lo[0],
577                          23170, pOverflow);                    /* 23170 Q15 = 1/sqrt(2)*/
578     }
579
580     /* search the quantizer table for the lowest value
581        of the search criterion                           */
582     dist_min = MAX_32;
583     index = 0;
584     p = &qua_gain_code_ptr[0];
585
586     for (i = 0; i < NB_QUA_CODE; i++)
587     {
588         g_code = *p++;                   /* this is g_fac (Q11)  */
589         p++;                             /* skip log2(g_fac)     */
590         p++;                             /* skip 20*log10(g_fac) */
591         g_code = mult(g_code, gcode0, pOverflow);
592
593         /* only continue if    gc[i]            < 2.0*gc
594            which is equiv. to  g_code (Q10-ec0) < gain_code (Q11-ec0) */
595
596         if (g_code >= gain_code)
597         {
598             break;
599         }
600
601         L_tmp = L_mult(g_code, g_code, pOverflow);
602         L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow);
603
604         tmp = sub(g_code, gain_cod_unq, pOverflow);
605         L_tmp = L_mult(tmp, tmp, pOverflow);
606         L_Extract(L_tmp, &d2_code_h, &d2_code_l, pOverflow);
607
608         /* t2, t3, t4 */
609         L_tmp = Mac_32_16(L_t1, coeff[2], coeff_lo[2], g_code, pOverflow);
610         L_tmp = Mac_32(L_tmp,    coeff[3], coeff_lo[3], g2_code_h, g2_code_l, pOverflow);
611
612         L_tmp = sqrt_l_exp(L_tmp, &exp, pOverflow);
613         L_tmp = L_shr(L_tmp, shr(exp, 1, pOverflow), pOverflow);
614
615         /* d2 */
616         tmp = pv_round(L_sub(L_tmp, L_t0, pOverflow), pOverflow);
617         L_tmp = L_mult(tmp, tmp, pOverflow);
618
619         /* dist */
620         L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], d2_code_h, d2_code_l, pOverflow);
621
622         /* store table index if distance measure for this
623             index is lower than the minimum seen so far   */
624         if (L_tmp < dist_min)
625         {
626             dist_min = L_tmp;
627             index = i;
628         }
629     }
630
631     /*------------------------------------------------------------------*
632      *  read quantized gains and new values for MA predictor memories   *
633      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
634      *------------------------------------------------------------------*/
635
636     /* Read the quantized gains */
637     p = &qua_gain_code_ptr[(index<<2) - index];
638     g_code = *p++;
639     *qua_ener_MR122 = *p++;
640     *qua_ener = *p;
641
642     /*------------------------------------------------------------------*
643      *  calculate final fixed codebook gain:                            *
644      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                            *
645      *                                                                  *
646      *   gc = gc0 * g                                                   *
647      *------------------------------------------------------------------*/
648
649     L_tmp = L_mult(g_code, gcode0, pOverflow);
650     L_tmp = L_shr(L_tmp, 9 - exp_gcode0, pOverflow);
651     *gain_cod = (Word16)(L_tmp >> 16);
652
653     return index;
654 }
655
656 /*
657 ------------------------------------------------------------------------------
658  FUNCTION NAME: MR795_gain_quant
659 ------------------------------------------------------------------------------
660  INPUT AND OUTPUT DEFINITIONS
661 MR795_gain_quant(
662
663
664  Inputs:
665     adapt_st      -- Pointer to GainAdaptState -- gain adapter state structure
666     res           -- Word16 array -- LP residual,                  Q0
667     exc           -- Word16 array -- LTP excitation (unfiltered),  Q0
668     code          -- Word16 array -- CB innovation (unfiltered),   Q13
669     frac_coeff    -- Word16 array -- coefficients (5),             Q15
670     exp_coeff     -- Word16 array -- energy coefficients (5),      Q0
671                                     coefficients from calc_filt_ener()
672     exp_code_en   -- Word16 -- innovation energy (exponent), Q0
673     frac_code_en  -- Word16 -- innovation energy (fraction), Q15
674     exp_gcode0    -- Word16 -- predicted CB gain (exponent), Q0
675     frac_gcode0   -- Word16 -- predicted CB gain (fraction), Q15
676     L_subfr       -- Word16 -- Subframe length
677     cod_gain_frac -- Word16 -- opt. codebook gain (fraction),Q15
678     cod_gain_exp  -- Word16 -- opt. codebook gain (exponent), Q0
679     gp_limit      -- Word16 -- pitch gain limit
680     gain_pit      -- Pointer to Word16 -- Pitch gain,              Q14
681
682  Output
683     adapt_st       -- Pointer to GainAdaptState -- gain adapter state structure
684     gain_pit       -- Pointer to Word16 -- Pitch gain,              Q14
685
686     gain_pit       -- Pointer to Word16 -- Pitch gain,                   Q14
687     gain_cod       -- Pointer to Word16 -- Code gain,                    Q1
688     qua_ener_MR122 -- Pointer to Word16 -- quantized energy error,       Q10
689                                            (for MR122 MA predictor update)
690
691     qua_ener       -- Pointer to Word16 -- quantized energy error,       Q10
692                                            (for other MA predictor update)
693
694     anap           -- Double Pointer to Word16 -- Index of quantization
695                                            (first gain pitch, then code pitch)
696
697     pOverflow      -- Pointer to Flag -- overflow indicator
698
699  Returns:
700     None
701
702  Global Variables Used:
703     None
704
705  Local Variables Needed:
706     None
707
708 ------------------------------------------------------------------------------
709  FUNCTION DESCRIPTION
710
711  pitch and codebook quantization for MR795
712 ------------------------------------------------------------------------------
713  REQUIREMENTS
714
715  None
716
717 ------------------------------------------------------------------------------
718  REFERENCES
719
720  qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
721
722 ------------------------------------------------------------------------------
723  PSEUDO-CODE
724
725
726 ------------------------------------------------------------------------------
727  CAUTION [optional]
728  [State any special notes, constraints or cautions for users of this function]
729
730 ------------------------------------------------------------------------------
731 */
732
733 void
734 MR795_gain_quant(
735     GainAdaptState *adapt_st, /* i/o: gain adapter state structure       */
736     Word16 res[],             /* i  : LP residual,                  Q0   */
737     Word16 exc[],             /* i  : LTP excitation (unfiltered),  Q0   */
738     Word16 code[],            /* i  : CB innovation (unfiltered),   Q13  */
739     Word16 frac_coeff[],      /* i  : coefficients (5),             Q15  */
740     Word16 exp_coeff[],       /* i  : energy coefficients (5),      Q0   */
741     /*      coefficients from calc_filt_ener() */
742     Word16 exp_code_en,       /* i  : innovation energy (exponent), Q0   */
743     Word16 frac_code_en,      /* i  : innovation energy (fraction), Q15  */
744     Word16 exp_gcode0,        /* i  : predicted CB gain (exponent), Q0   */
745     Word16 frac_gcode0,       /* i  : predicted CB gain (fraction), Q15  */
746     Word16 L_subfr,           /* i  : Subframe length                    */
747     Word16 cod_gain_frac,     /* i  : opt. codebook gain (fraction),Q15  */
748     Word16 cod_gain_exp,      /* i  : opt. codebook gain (exponent), Q0  */
749     Word16 gp_limit,          /* i  : pitch gain limit                   */
750     Word16 *gain_pit,         /* i/o: Pitch gain,                   Q14  */
751     Word16 *gain_cod,         /* o  : Code gain,                    Q1   */
752     Word16 *qua_ener_MR122,   /* o  : quantized energy error,       Q10  */
753     /*      (for MR122 MA predictor update)    */
754     Word16 *qua_ener,         /* o  : quantized energy error,       Q10  */
755     /*      (for other MA predictor update)    */
756     Word16 **anap,            /* o  : Index of quantization              */
757     /*      (first gain pitch, then code pitch)*/
758     CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of table ptrs   */
759     Flag   *pOverflow         /* o  : overflow indicator                */
760 )
761 {
762     Word16 frac_en[4];
763     Word16 exp_en[4];
764     Word16 ltpg, alpha, gcode0;
765     Word16 g_pitch_cand[3];      /* pitch gain candidates   Q14 */
766     Word16 g_pitch_cind[3];      /* pitch gain indices      Q0  */
767     Word16 gain_pit_index;
768     Word16 gain_cod_index;
769     Word16 exp;
770     Word16 gain_cod_unq;         /* code gain (unq.) Q(10-exp_gcode0)  */
771
772
773     /* get list of candidate quantized pitch gain values
774      * and corresponding quantization indices
775      */
776     gain_pit_index = q_gain_pitch(MR795, gp_limit, gain_pit,
777                                   g_pitch_cand, g_pitch_cind, common_amr_tbls->qua_gain_pitch_ptr, pOverflow);
778
779     /*-------------------------------------------------------------------*
780      *  predicted codebook gain                                          *
781      *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *
782      *  gc0     = 2^exp_gcode0 + 2^frac_gcode0                           *
783      *                                                                   *
784      *  gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0)      *
785      *-------------------------------------------------------------------*/
786     gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow));           /* Q14 */
787
788     /* pre-quantization of codebook gain
789      * (using three pitch gain candidates);
790      * result: best guess of pitch gain and code gain
791      */
792     MR795_gain_code_quant3(
793         exp_gcode0, gcode0, g_pitch_cand, g_pitch_cind,
794         frac_coeff, exp_coeff,
795         gain_pit, &gain_pit_index, gain_cod, &gain_cod_index,
796         qua_ener_MR122, qua_ener, common_amr_tbls->qua_gain_code_ptr, pOverflow);
797
798     /* calculation of energy coefficients and LTP coding gain */
799     calc_unfilt_energies(res, exc, code, *gain_pit, L_subfr,
800                          frac_en, exp_en, &ltpg, pOverflow);
801
802     /* run gain adaptor, calculate alpha factor to balance LTP/CB gain
803      * (this includes the gain adaptor update)
804      * Note: ltpg = 0 if frac_en[0] == 0, so the update is OK in that case
805      */
806     gain_adapt(adapt_st, ltpg, *gain_cod, &alpha, pOverflow);
807
808     /* if this is a very low energy signal (threshold: see
809      * calc_unfilt_energies) or alpha <= 0 then don't run the modified quantizer
810      */
811     if (frac_en[0] != 0 && alpha > 0)
812     {
813         /* innovation energy <cod cod> was already computed in gc_pred() */
814         /* (this overwrites the LtpResEn which is no longer needed)      */
815         frac_en[3] = frac_code_en;
816         exp_en[3] = exp_code_en;
817
818         /* store optimum codebook gain in Q(10-exp_gcode0) */
819         exp = sub(cod_gain_exp, exp_gcode0, pOverflow) + 10;
820         gain_cod_unq = shl(cod_gain_frac, exp, pOverflow);
821
822         /* run quantization with modified criterion */
823         gain_cod_index = MR795_gain_code_quant_mod(
824                              *gain_pit, exp_gcode0, gcode0,
825                              frac_en, exp_en, alpha, gain_cod_unq,
826                              gain_cod, qua_ener_MR122, qua_ener, common_amr_tbls->qua_gain_code_ptr,
827                              pOverflow); /* function result */
828     }
829
830     *(*anap)++ = gain_pit_index;
831     *(*anap)++ = gain_cod_index;
832 }