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.
LcdInitialize(IN EFI_PHYSICAL_ADDRESS VramBaseAddress)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 
LcdShutdown(VOID)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 }
833