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  Pathname: ./audio/gsm-amr/c/src/gc_pred.c
32  Functions:
33             gc_pred_reset
34             gc_pred
35             gc_pred_update
36             gc_pred_average_limited
37 
38 ------------------------------------------------------------------------------
39  MODULE DESCRIPTION
40 
41  This file contains the functions that perform codebook gain MA prediction.
42 
43 ------------------------------------------------------------------------------
44 */
45 
46 /*----------------------------------------------------------------------------
47 ; INCLUDES
48 ----------------------------------------------------------------------------*/
49 #include "gc_pred.h"
50 #include "basicop_malloc.h"
51 #include "basic_op.h"
52 #include "cnst.h"
53 #include "log2.h"
54 
55 /*----------------------------------------------------------------------------
56 ; MACROS
57 ; Define module specific macros here
58 ----------------------------------------------------------------------------*/
59 
60 /*----------------------------------------------------------------------------
61 ; DEFINES
62 ; Include all pre-processor statements here. Include conditional
63 ; compile variables also.
64 ----------------------------------------------------------------------------*/
65 #define NPRED 4  /* number of prediction taps */
66 
67 /* average innovation energy.                               */
68 /* MEAN_ENER  = 36.0/constant, constant = 20*Log10(2)       */
69 #define MEAN_ENER_MR122  783741L  /* 36/(20*log10(2)) (Q17) */
70 
71 /* minimum quantized energy: -14 dB */
72 #define MIN_ENERGY       -14336       /* 14                 Q10 */
73 #define MIN_ENERGY_MR122  -2381       /* 14 / (20*log10(2)) Q10 */
74 
75 /*----------------------------------------------------------------------------
76 ; LOCAL FUNCTION DEFINITIONS
77 ; Function Prototype declaration
78 ----------------------------------------------------------------------------*/
79 
80 /*----------------------------------------------------------------------------
81 ; LOCAL VARIABLE DEFINITIONS
82 ; Variable declaration - defined here and used outside this module
83 ----------------------------------------------------------------------------*/
84 
85 /* MA prediction coefficients (Q13) */
86 static const Word16 pred[NPRED] = {5571, 4751, 2785, 1556};
87 
88 /* MA prediction coefficients (Q6)  */
89 static const Word16 pred_MR122[NPRED] = {44, 37, 22, 12};
90 
91 /*
92 ------------------------------------------------------------------------------
93  FUNCTION NAME: gc_pred_reset
94 ------------------------------------------------------------------------------
95  INPUT AND OUTPUT DEFINITIONS
96 
97  Inputs:
98     state = pointer to a structure of type gc_predState
99 
100  Outputs:
101     past_qua_en field in the structure pointed to by state is initialized
102       to MIN_ENERGY
103     past_qua_en_MR122 field in the structure pointed to by state is
104       initialized to MIN_ENERGY_MR122
105 
106  Returns:
107     return_value = 0, if reset was successful; -1, otherwise (int)
108 
109  Global Variables Used:
110     None
111 
112  Local Variables Needed:
113     None
114 
115 ------------------------------------------------------------------------------
116  FUNCTION DESCRIPTION
117 
118  This function initializes the state memory used by gc_pred to zero.
119 
120 ------------------------------------------------------------------------------
121  REQUIREMENTS
122 
123  None
124 
125 ------------------------------------------------------------------------------
126  REFERENCES
127 
128  gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
129 
130 ------------------------------------------------------------------------------
131  PSEUDO-CODE
132 
133 int gc_pred_reset (gc_predState *state)
134 {
135    Word16 i;
136 
137    if (state == (gc_predState *) NULL){
138       fprintf(stderr, "gc_pred_reset: invalid parameter\n");
139       return -1;
140    }
141 
142    for(i = 0; i < NPRED; i++)
143    {
144       state->past_qua_en[i] = MIN_ENERGY;
145       state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
146    }
147   return 0;
148 }
149 
150 ------------------------------------------------------------------------------
151  RESOURCES USED [optional]
152 
153  When the code is written for a specific target processor the
154  the resources used should be documented below.
155 
156  HEAP MEMORY USED: x bytes
157 
158  STACK MEMORY USED: x bytes
159 
160  CLOCK CYCLES: (cycle count equation for this function) + (variable
161                 used to represent cycle count for each subroutine
162                 called)
163      where: (cycle count variable) = cycle count for [subroutine
164                                      name]
165 
166 ------------------------------------------------------------------------------
167  CAUTION [optional]
168  [State any special notes, constraints or cautions for users of this function]
169 
170 ------------------------------------------------------------------------------
171 */
172 
gc_pred_reset(gc_predState * state)173 Word16 gc_pred_reset(gc_predState *state)
174 {
175     Word16 i;
176 
177     if (state == (gc_predState *) NULL)
178     {
179         /* fprintf(stderr, "gc_pred_reset: invalid parameter\n"); */
180         return -1;
181     }
182 
183     for (i = 0; i < NPRED; i++)
184     {
185         state->past_qua_en[i] = MIN_ENERGY;
186         state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
187     }
188 
189     return(0);
190 }
191 
192 /****************************************************************************/
193 
194 /*
195 ------------------------------------------------------------------------------
196  FUNCTION NAME: gc_pred
197 ------------------------------------------------------------------------------
198  INPUT AND OUTPUT DEFINITIONS
199 
200  Inputs:
201     st = pointer to a structure of type gc_predState
202     mode = AMR mode (enum Mode)
203     code = pointer to the innovative codebook vector; Q12 in MR122 mode,
204            otherwise, Q13 (Word16)
205     exp_gcode0 = pointer to the exponent part of predicted gain factor
206              (Q0) (Word16)
207     frac_gcode0 = pointer to the fractional part of predicted gain factor
208               (Q15) (Word16)
209     exp_en = pointer to the exponent part of the innovation energy; this
210          is calculated for MR795 mode, Q0 (Word16)
211     frac_en = pointer to the fractional part of the innovation energy;
212           this is calculated for MR795 mode, Q15 (Word16)
213     pOverflow = pointer to overflow (Flag)
214 
215  Outputs:
216     store pointed to by exp_gcode0 contains the exponent part of the
217       recently calculated predicted gain factor
218     store pointed to by frac_gcode0 contains the fractional part of the
219       recently calculated predicted gain factor
220     store pointed to by exp_en contains the exponent part of the
221       recently calculated innovation energy
222     store pointed to by frac_en contains the fractional part of the
223       recently calculated innovation energy
224     pOverflow = 1 if the math functions called by gc_pred
225                 results in overflow else zero.
226 
227  Returns:
228     None
229 
230  Global Variables Used:
231     None
232 
233  Local Variables Needed:
234     pred = table of MA prediction coefficients (Q13) (Word16)
235     pred_MR122 = table of MA prediction coefficients (Q6) (Word16)
236 
237 ------------------------------------------------------------------------------
238  FUNCTION DESCRIPTION
239 
240  This function performs the MA prediction of the innovation energy (in
241  dB/(20*log10(2))), with the mean removed.
242 
243 ------------------------------------------------------------------------------
244  REQUIREMENTS
245 
246  None
247 
248 ------------------------------------------------------------------------------
249  REFERENCES
250 
251  gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
252 
253 ------------------------------------------------------------------------------
254  PSEUDO-CODE
255 
256 The original etsi reference code uses a global flag Overflow. However, in the
257 actual implementation a pointer to a the overflow flag is passed in.
258 
259 void
260 gc_pred(
261     gc_predState *st,   // i/o: State struct
262     enum Mode mode,     // i  : AMR mode
263     Word16 *code,       // i  : innovative codebook vector (L_SUBFR)
264                         //      MR122: Q12, other modes: Q13
265     Word16 *exp_gcode0, // o  : exponent of predicted gain factor, Q0
266     Word16 *frac_gcode0,// o  : fraction of predicted gain factor  Q15
267     Word16 *exp_en,     // o  : exponent of innovation energy,     Q0
268                         //      (only calculated for MR795)
269     Word16 *frac_en     // o  : fraction of innovation energy,     Q15
270                         //      (only calculated for MR795)
271 )
272 {
273     Word16 i;
274     Word32 ener_code;
275     Word16 exp, frac;
276 
277      *-------------------------------------------------------------------*
278      *  energy of code:                                                  *
279      *  ~~~~~~~~~~~~~~~                                                  *
280      *  ener_code = sum(code[i]^2)                                       *
281      *-------------------------------------------------------------------*
282     ener_code = L_mac((Word32) 0, code[0], code[0]);
283                                                  // MR122:  Q12*Q12 -> Q25
284                                                  // others: Q13*Q13 -> Q27
285     for (i = 1; i < L_SUBFR; i++)
286         ener_code = L_mac(ener_code, code[i], code[i]);
287 
288     if (sub (mode, MR122) == 0)
289     {
290         Word32 ener;
291 
292         // ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20
293         ener_code = L_mult (pv_round (ener_code), 26214);   // Q9  * Q20 -> Q30
294 
295          *-------------------------------------------------------------------*
296          *  energy of code:                                                  *
297          *  ~~~~~~~~~~~~~~~                                                  *
298          *  ener_code(Q17) = 10 * Log10(energy) / constant                   *
299          *                 = 1/2 * Log2(energy)                              *
300          *                                           constant = 20*Log10(2)  *
301          *-------------------------------------------------------------------*
302         // ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30
303         Log2(ener_code, &exp, &frac);
304         ener_code = L_Comp (sub (exp, 30), frac);     // Q16 for log()
305                                                     // ->Q17 for 1/2 log()
306 
307          *-------------------------------------------------------------------*
308          *  predicted energy:                                                *
309          *  ~~~~~~~~~~~~~~~~~                                                *
310          *  ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant           *
311          *            = MEAN_ENER + sum(pred[i]*past_qua_en[i])              *
312          *                                           constant = 20*Log10(2)  *
313          *-------------------------------------------------------------------*
314 
315         ener = MEAN_ENER_MR122;                      // Q24 (Q17)
316         for (i = 0; i < NPRED; i++)
317         {
318             ener = L_mac (ener, st->past_qua_en_MR122[i], pred_MR122[i]);
319                                                      // Q10 * Q13 -> Q24
320                                                      // Q10 * Q6  -> Q17
321         }
322 
323          *-------------------------------------------------------------------*
324          *  predicted codebook gain                                          *
325          *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *
326          *  gc0     = Pow10( (ener*constant - ener_code*constant) / 20 )     *
327          *          = Pow2(ener-ener_code)                                   *
328          *          = Pow2(int(d)+frac(d))                                   *
329          *                                                                   *
330          *  (store exp and frac for pow2())                                  *
331          *-------------------------------------------------------------------*
332 
333         ener = L_shr (L_sub (ener, ener_code), 1);                // Q16
334         L_Extract(ener, exp_gcode0, frac_gcode0);
335     }
336     else // all modes except 12.2
337     {
338         Word32 L_tmp;
339         Word16 exp_code, gcode0;
340 
341          *-----------------------------------------------------------------*
342          *  Compute: means_ener - 10log10(ener_code/ L_sufr)               *
343          *-----------------------------------------------------------------*
344 
345         exp_code = norm_l (ener_code);
346         ener_code = L_shl (ener_code, exp_code);
347 
348         // Log2 = log2 + 27
349         Log2_norm (ener_code, exp_code, &exp, &frac);
350 
351         // fact = 10/log2(10) = 3.01 = 24660 Q13
352         L_tmp = Mpy_32_16(exp, frac, -24660); // Q0.Q15 * Q13 -> Q14
353 
354          *   L_tmp = means_ener - 10log10(ener_code/L_SUBFR)
355          *         = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)
356          *         = K - fact * Log2(ener_code)
357          *         = K - fact * log2(ener_code) - fact*27
358          *
359          *   ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
360          *
361          *   means_ener =       33    =  540672    Q14  (MR475, MR515, MR59)
362          *   means_ener =       28.75 =  471040    Q14  (MR67)
363          *   means_ener =       30    =  491520    Q14  (MR74)
364          *   means_ener =       36    =  589824    Q14  (MR795)
365          *   means_ener =       33    =  540672    Q14  (MR102)
366          *   10log10(L_SUBFR) = 16.02 =  262481.51 Q14
367          *   fact * 27                = 1331640    Q14
368          *   -----------------------------------------
369          *   (MR475, MR515, MR59)   K = 2134793.51 Q14 ~= 16678 * 64 * 2
370          *   (MR67)                 K = 2065161.51 Q14 ~= 32268 * 32 * 2
371          *   (MR74)                 K = 2085641.51 Q14 ~= 32588 * 32 * 2
372          *   (MR795)                K = 2183945.51 Q14 ~= 17062 * 64 * 2
373          *   (MR102)                K = 2134793.51 Q14 ~= 16678 * 64 * 2
374 
375 
376         if (sub (mode, MR102) == 0)
377         {
378             // mean = 33 dB
379             L_tmp = L_mac(L_tmp, 16678, 64);     // Q14
380         }
381         else if (sub (mode, MR795) == 0)
382         {
383             // ener_code  = <xn xn> * 2^27*2^exp_code
384             // frac_en    = ener_code / 2^16
385             //            = <xn xn> * 2^11*2^exp_code
386             // <xn xn>    = <xn xn>*2^11*2^exp * 2^exp_en
387             //           := frac_en            * 2^exp_en
388 
389             // ==> exp_en = -11-exp_code;
390 
391             *frac_en = extract_h (ener_code);
392             *exp_en = sub (-11, exp_code);
393 
394             // mean = 36 dB
395             L_tmp = L_mac(L_tmp, 17062, 64);     // Q14
396         }
397         else if (sub (mode, MR74) == 0)
398         {
399             // mean = 30 dB
400             L_tmp = L_mac(L_tmp, 32588, 32);     // Q14
401         }
402         else if (sub (mode, MR67) == 0)
403         {
404             // mean = 28.75 dB
405             L_tmp = L_mac(L_tmp, 32268, 32);     // Q14
406         }
407         else // MR59, MR515, MR475
408         {
409             // mean = 33 dB
410             L_tmp = L_mac(L_tmp, 16678, 64);     // Q14
411         }
412 
413          *-----------------------------------------------------------------*
414          * Compute gcode0.                                                 *
415          *  = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener    *
416          *-----------------------------------------------------------------*
417 
418         L_tmp = L_shl(L_tmp, 10);                // Q24
419         for (i = 0; i < 4; i++)
420             L_tmp = L_mac(L_tmp, pred[i], st->past_qua_en[i]);
421                                                  // Q13 * Q10 -> Q24
422 
423         gcode0 = extract_h(L_tmp);               // Q8
424 
425          *-----------------------------------------------------------------*
426          * gcode0 = pow(10.0, gcode0/20)                                   *
427          *        = pow(2, 3.3219*gcode0/20)                               *
428          *        = pow(2, 0.166*gcode0)                                   *
429          *-----------------------------------------------------------------*
430 
431         // 5439 Q15 = 0.165985
432         // (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15)
433         if (sub (mode, MR74) == 0) // For IS641 bitexactness
434             L_tmp = L_mult(gcode0, 5439);  // Q8 * Q15 -> Q24
435         else
436             L_tmp = L_mult(gcode0, 5443);  // Q8 * Q15 -> Q24
437 
438         L_tmp = L_shr(L_tmp, 8);                   //          -> Q16
439         L_Extract(L_tmp, exp_gcode0, frac_gcode0); //       -> Q0.Q15
440     }
441 }
442 
443 ------------------------------------------------------------------------------
444  RESOURCES USED [optional]
445 
446  When the code is written for a specific target processor the
447  the resources used should be documented below.
448 
449  HEAP MEMORY USED: x bytes
450 
451  STACK MEMORY USED: x bytes
452 
453  CLOCK CYCLES: (cycle count equation for this function) + (variable
454                 used to represent cycle count for each subroutine
455                 called)
456      where: (cycle count variable) = cycle count for [subroutine
457                                      name]
458 
459 ------------------------------------------------------------------------------
460  CAUTION [optional]
461  [State any special notes, constraints or cautions for users of this function]
462 
463 ------------------------------------------------------------------------------
464 */
465 
gc_pred(gc_predState * st,enum Mode mode,Word16 * code,Word16 * exp_gcode0,Word16 * frac_gcode0,Word16 * exp_en,Word16 * frac_en,Flag * pOverflow)466 void gc_pred(
467     gc_predState *st,   /* i/o: State struct                           */
468     enum Mode mode,     /* i  : AMR mode                               */
469     Word16 *code,       /* i  : innovative codebook vector (L_SUBFR)   */
470     /*      MR122: Q12, other modes: Q13           */
471     Word16 *exp_gcode0, /* o  : exponent of predicted gain factor, Q0  */
472     Word16 *frac_gcode0,/* o  : fraction of predicted gain factor  Q15 */
473     Word16 *exp_en,     /* o  : exponent of innovation energy,     Q0  */
474     /*      (only calculated for MR795)            */
475     Word16 *frac_en,    /* o  : fraction of innovation energy,     Q15 */
476     /*      (only calculated for MR795)            */
477     Flag   *pOverflow
478 )
479 {
480     Word16 i;
481     Word32 L_temp1, L_temp2;
482     Word32 L_tmp;
483     Word32 ener_code;
484     Word32 ener;
485     Word16 exp, frac;
486     Word16 exp_code, gcode0;
487     Word16 tmp;
488     Word16 *p_code = &code[0];
489 
490     /*-------------------------------------------------------------------*
491      *  energy of code:                                                  *
492      *  ~~~~~~~~~~~~~~~                                                  *
493      *  ener_code = sum(code[i]^2)                                       *
494      *-------------------------------------------------------------------*/
495     ener_code = 0;
496 
497     /* MR122:  Q12*Q12 -> Q25 */
498     /* others: Q13*Q13 -> Q27 */
499 
500     for (i = L_SUBFR >> 2; i != 0; i--)
501     {
502         tmp = *(p_code++);
503         ener_code += ((Word32) tmp * tmp) >> 3;
504         tmp = *(p_code++);
505         ener_code += ((Word32) tmp * tmp) >> 3;
506         tmp = *(p_code++);
507         ener_code += ((Word32) tmp * tmp) >> 3;
508         tmp = *(p_code++);
509         ener_code += ((Word32) tmp * tmp) >> 3;
510     }
511 
512     ener_code <<= 4;
513 
514     if (ener_code < 0)      /*  Check for saturation */
515     {
516         ener_code = MAX_32;
517     }
518 
519     if (mode == MR122)
520     {
521         /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */
522         /* Q9  * Q20 -> Q30 */
523 
524         ener_code = ((Word32)(pv_round(ener_code, pOverflow) * 26214)) << 1;
525 
526         /*-------------------------------------------------------------*
527          *  energy of code:                                            *
528          *  ~~~~~~~~~~~~~~~                                            *
529          *  ener_code(Q17) = 10 * Log10(energy) / constant             *
530          *                 = 1/2 * Log2(energy)                        *
531          *  constant = 20*Log10(2)                                     *
532          *-------------------------------------------------------------*/
533         /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */
534         Log2(ener_code, &exp, &frac, pOverflow);
535 
536         /* Q16 for log()    */
537         /* ->Q17 for 1/2 log()*/
538 
539         L_temp1 = (Word32)(exp - 30) << 16;
540         ener_code = L_temp1 + ((Word32)frac << 1);
541 
542         /*-------------------------------------------------------------*
543          *  predicted energy:                                          *
544          *  ~~~~~~~~~~~~~~~~~                                          *
545          *  ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant     *
546          *            = MEAN_ENER + sum(pred[i]*past_qua_en[i])        *
547          *  constant = 20*Log10(2)                                     *
548          *-------------------------------------------------------------*/
549 
550         ener = MEAN_ENER_MR122;                   /* Q24 (Q17) */
551         for (i = 0; i < NPRED; i++)
552         {
553             L_temp1 = (((Word32) st->past_qua_en_MR122[i]) *
554                        pred_MR122[i]) << 1;
555             ener = L_add(ener, L_temp1, pOverflow);
556 
557             /* Q10 * Q13 -> Q24 */
558             /* Q10 * Q6  -> Q17 */
559         }
560 
561         /*---------------------------------------------------------------*
562          *  predicted codebook gain                                      *
563          *  ~~~~~~~~~~~~~~~~~~~~~~~                                      *
564          *  gc0     = Pow10( (ener*constant - ener_code*constant) / 20 ) *
565          *          = Pow2(ener-ener_code)                               *
566          *          = Pow2(int(d)+frac(d))                               *
567          *                                                               *
568          *  (store exp and frac for pow2())                              *
569          *---------------------------------------------------------------*/
570         /* Q16 */
571 
572         L_temp1 = L_sub(ener, ener_code, pOverflow);
573 
574 
575         *exp_gcode0 = (Word16)(L_temp1 >> 17);
576 
577         L_temp2 = (Word32) * exp_gcode0 << 15;
578         L_temp1 >>= 2;
579 
580         *frac_gcode0 = (Word16)(L_temp1 - L_temp2);
581 
582     }
583     else /* all modes except 12.2 */
584     {
585         /*-----------------------------------------------------------------*
586          *  Compute: means_ener - 10log10(ener_code/ L_sufr)               *
587          *-----------------------------------------------------------------*/
588 
589         exp_code = norm_l(ener_code);
590         ener_code = L_shl(ener_code, exp_code, pOverflow);
591 
592         /* Log2 = log2 + 27 */
593         Log2_norm(ener_code, exp_code, &exp, &frac);
594 
595         /* fact = 10/log2(10) = 3.01 = 24660 Q13 */
596         /* Q0.Q15 * Q13 -> Q14 */
597 
598         L_temp2 = (((Word32) exp) * -24660) << 1;
599         L_tmp = (((Word32) frac) * -24660) >> 15;
600 
601         /* Sign-extend resulting product */
602         if (L_tmp & (Word32) 0x00010000L)
603         {
604             L_tmp = L_tmp | (Word32) 0xffff0000L;
605         }
606 
607         L_tmp = L_tmp << 1;
608         L_tmp = L_add(L_tmp, L_temp2, pOverflow);
609 
610 
611         /*   L_tmp = means_ener - 10log10(ener_code/L_SUBFR)
612          *         = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)
613          *         = K - fact * Log2(ener_code)
614          *         = K - fact * log2(ener_code) - fact*27
615          *
616          *   ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
617          *
618          *   means_ener =       33    =  540672    Q14  (MR475, MR515, MR59)
619          *   means_ener =       28.75 =  471040    Q14  (MR67)
620          *   means_ener =       30    =  491520    Q14  (MR74)
621          *   means_ener =       36    =  589824    Q14  (MR795)
622          *   means_ener =       33    =  540672    Q14  (MR102)
623          *   10log10(L_SUBFR) = 16.02 =  262481.51 Q14
624          *   fact * 27                = 1331640    Q14
625          *   -----------------------------------------
626          *   (MR475, MR515, MR59)   K = 2134793.51 Q14 ~= 16678 * 64 * 2
627          *   (MR67)                 K = 2065161.51 Q14 ~= 32268 * 32 * 2
628          *   (MR74)                 K = 2085641.51 Q14 ~= 32588 * 32 * 2
629          *   (MR795)                K = 2183945.51 Q14 ~= 17062 * 64 * 2
630          *   (MR102)                K = 2134793.51 Q14 ~= 16678 * 64 * 2
631          */
632 
633         if (mode == MR102)
634         {
635             /* mean = 33 dB */
636             L_temp2 = (Word32) 16678 << 7;
637             L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */
638         }
639         else if (mode == MR795)
640         {
641             /* ener_code  = <xn xn> * 2^27*2^exp_code
642                frac_en    = ener_code / 2^16
643                           = <xn xn> * 2^11*2^exp_code
644                <xn xn>    = <xn xn>*2^11*2^exp * 2^exp_en
645             :                 = frac_en            * 2^exp_en
646                           ==> exp_en = -11-exp_code;      */
647             *frac_en = (Word16)(ener_code >> 16);
648             *exp_en = sub(-11, exp_code, pOverflow);
649 
650             /* mean = 36 dB */
651             L_temp2 = (Word32) 17062 << 7;
652             L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */
653         }
654         else if (mode == MR74)
655         {
656             /* mean = 30 dB */
657             L_temp2 = (Word32) 32588 << 6;
658             L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */
659         }
660         else if (mode == MR67)
661         {
662             /* mean = 28.75 dB */
663             L_temp2 = (Word32) 32268 << 6;
664             L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */
665         }
666         else /* MR59, MR515, MR475 */
667         {
668             /* mean = 33 dB */
669             L_temp2 = (Word32) 16678 << 7;
670             L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */
671         }
672 
673         /*-------------------------------------------------------------*
674          * Compute gcode0.                                              *
675          *  = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener *
676          *--------------------------------------------------------------*/
677         /* Q24 */
678         if (L_tmp > (Word32) 0X001fffffL)
679         {
680             *pOverflow = 1;
681             L_tmp = MAX_32;
682         }
683         else if (L_tmp < (Word32) 0xffe00000L)
684         {
685             *pOverflow = 1;
686             L_tmp = MIN_32;
687         }
688         else
689         {
690             L_tmp = L_tmp << 10;
691         }
692 
693         for (i = 0; i < 4; i++)
694         {
695             L_temp2 = ((((Word32) pred[i]) * st->past_qua_en[i]) << 1);
696             L_tmp = L_add(L_tmp, L_temp2, pOverflow);  /* Q13 * Q10 -> Q24 */
697         }
698 
699         gcode0 = (Word16)(L_tmp >> 16);               /* Q8  */
700 
701         /*-----------------------------------------------------------*
702          * gcode0 = pow(10.0, gcode0/20)                             *
703          *        = pow(2, 3.3219*gcode0/20)                         *
704          *        = pow(2, 0.166*gcode0)                             *
705          *-----------------------------------------------------------*/
706 
707         /* 5439 Q15 = 0.165985                                       */
708         /* (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15)            */
709 
710         if (mode == MR74) /* For IS641 bitexactness */
711         {
712             L_tmp = (((Word32) gcode0) * 5439) << 1;  /* Q8 * Q15 -> Q24 */
713         }
714         else
715         {
716             L_tmp = (((Word32) gcode0) * 5443) << 1;  /* Q8 * Q15 -> Q24 */
717         }
718 
719         if (L_tmp < 0)
720         {
721             L_tmp = ~((~L_tmp) >> 8);
722         }
723         else
724         {
725             L_tmp = L_tmp >> 8;     /* -> Q16 */
726         }
727 
728         *exp_gcode0 = (Word16)(L_tmp >> 16);
729         if (L_tmp < 0)
730         {
731             L_temp1 = ~((~L_tmp) >> 1);
732         }
733         else
734         {
735             L_temp1 = L_tmp >> 1;
736         }
737         L_temp2 = (Word32) * exp_gcode0 << 15;
738         *frac_gcode0 = (Word16)(L_sub(L_temp1, L_temp2, pOverflow));
739         /* -> Q0.Q15 */
740     }
741 
742     return;
743 }
744 
745 /****************************************************************************/
746 
747 /*
748 ------------------------------------------------------------------------------
749  FUNCTION NAME: gc_pred_update
750 ------------------------------------------------------------------------------
751  INPUT AND OUTPUT DEFINITIONS
752 
753  Inputs:
754     st = pointer to a structure of type gc_predState
755     qua_ener_MR122 = quantized energy for update (Q10); calculated as
756              (log2(qua_err)) (Word16)
757     qua_ener = quantized energy for update (Q10); calculated as
758            (20*log10(qua_err)) (Word16)
759 
760  Outputs:
761     structure pointed to by st contains the calculated quantized energy
762       for update
763 
764  Returns:
765     None
766 
767  Global Variables Used:
768     None
769 
770  Local Variables Needed:
771     None
772 
773 ------------------------------------------------------------------------------
774  FUNCTION DESCRIPTION
775 
776  This function updates the MA predictor with the last quantized energy.
777 
778 ------------------------------------------------------------------------------
779  REQUIREMENTS
780 
781  None
782 
783 ------------------------------------------------------------------------------
784  REFERENCES
785 
786  gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
787 
788 ------------------------------------------------------------------------------
789  PSEUDO-CODE
790 
791 void gc_pred_update(
792     gc_predState *st,      // i/o: State struct
793     Word16 qua_ener_MR122, // i  : quantized energy for update, Q10
794                            //      (log2(qua_err))
795     Word16 qua_ener        // i  : quantized energy for update, Q10
796                            //      (20*log10(qua_err))
797 )
798 {
799     Word16 i;
800 
801     for (i = 3; i > 0; i--)
802     {
803         st->past_qua_en[i] = st->past_qua_en[i - 1];
804         st->past_qua_en_MR122[i] = st->past_qua_en_MR122[i - 1];
805     }
806 
807     st->past_qua_en_MR122[0] = qua_ener_MR122;  //    log2 (qua_err), Q10
808 
809     st->past_qua_en[0] = qua_ener;              // 20*log10(qua_err), Q10
810 
811 }
812 
813 ------------------------------------------------------------------------------
814  RESOURCES USED [optional]
815 
816  When the code is written for a specific target processor the
817  the resources used should be documented below.
818 
819  HEAP MEMORY USED: x bytes
820 
821  STACK MEMORY USED: x bytes
822 
823  CLOCK CYCLES: (cycle count equation for this function) + (variable
824                 used to represent cycle count for each subroutine
825                 called)
826      where: (cycle count variable) = cycle count for [subroutine
827                                      name]
828 
829 ------------------------------------------------------------------------------
830  CAUTION [optional]
831  [State any special notes, constraints or cautions for users of this function]
832 
833 ------------------------------------------------------------------------------
834 */
835 
gc_pred_update(gc_predState * st,Word16 qua_ener_MR122,Word16 qua_ener)836 void gc_pred_update(
837     gc_predState *st,      /* i/o: State struct                     */
838     Word16 qua_ener_MR122, /* i  : quantized energy for update, Q10 */
839     /*      (log2(qua_err))                  */
840     Word16 qua_ener        /* i  : quantized energy for update, Q10 */
841     /*      (20*log10(qua_err))              */
842 )
843 {
844     st->past_qua_en[3] = st->past_qua_en[2];
845     st->past_qua_en_MR122[3] = st->past_qua_en_MR122[2];
846 
847     st->past_qua_en[2] = st->past_qua_en[1];
848     st->past_qua_en_MR122[2] = st->past_qua_en_MR122[1];
849 
850     st->past_qua_en[1] = st->past_qua_en[0];
851     st->past_qua_en_MR122[1] = st->past_qua_en_MR122[0];
852 
853     st->past_qua_en_MR122[0] = qua_ener_MR122; /*    log2 (qua_err), Q10 */
854 
855     st->past_qua_en[0] = qua_ener;            /* 20*log10(qua_err), Q10 */
856 
857     return;
858 }
859 
860 /****************************************************************************/
861 
862 /*
863 ------------------------------------------------------------------------------
864  FUNCTION NAME: gc_pred_average_limited
865 ------------------------------------------------------------------------------
866  INPUT AND OUTPUT DEFINITIONS
867 
868  Inputs:
869     st = pointer to a structure of type gc_predState
870     ener_avg_MR122 = pointer to the averaged quantized energy (Q10);
871              calculated as (log2(qua_err)) (Word16)
872     ener_avg = pointer to the averaged quantized energy (Q10); calculated
873            as (20*log10(qua_err)) (Word16)
874     pOverflow = pointer to overflow (Flag)
875 
876  Outputs:
877     store pointed to by ener_avg_MR122 contains the new averaged quantized
878       energy
879     store pointed to by ener_avg contains the new averaged quantized
880       energy
881     pOverflow = 1 if the math functions called by gc_pred_average_limited
882             results in overflow else zero.
883 
884  Returns:
885     None
886 
887  Global Variables Used:
888     None
889 
890  Local Variables Needed:
891     None
892 
893 ------------------------------------------------------------------------------
894  FUNCTION DESCRIPTION
895 
896  This function calculates the average of MA predictor state values (with a
897  lower limit) used in error concealment.
898 
899 ------------------------------------------------------------------------------
900  REQUIREMENTS
901 
902  None
903 
904 ------------------------------------------------------------------------------
905  REFERENCES
906 
907  gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
908 
909 ------------------------------------------------------------------------------
910  PSEUDO-CODE
911 
912 The original etsi reference code uses a global flag Overflow. However, in the
913 actual implementation a pointer to a the overflow flag is passed in.
914 
915 void gc_pred_average_limited(
916     gc_predState *st,       // i: State struct
917     Word16 *ener_avg_MR122, // o: everaged quantized energy,  Q10
918                             //    (log2(qua_err))
919     Word16 *ener_avg        // o: averaged quantized energy,  Q10
920                             //    (20*log10(qua_err))
921 )
922 {
923     Word16 av_pred_en;
924     Word16 i;
925 
926     // do average in MR122 mode (log2() domain)
927     av_pred_en = 0;
928     for (i = 0; i < NPRED; i++)
929     {
930         av_pred_en = add (av_pred_en, st->past_qua_en_MR122[i]);
931     }
932 
933     // av_pred_en = 0.25*av_pred_en
934     av_pred_en = mult (av_pred_en, 8192);
935 
936     // if (av_pred_en < -14/(20Log10(2))) av_pred_en = ..
937 
938     if (sub (av_pred_en, MIN_ENERGY_MR122) < 0)
939     {
940         av_pred_en = MIN_ENERGY_MR122;
941     }
942     *ener_avg_MR122 = av_pred_en;
943 
944     // do average for other modes (20*log10() domain)
945     av_pred_en = 0;
946     for (i = 0; i < NPRED; i++)
947     {
948         av_pred_en = add (av_pred_en, st->past_qua_en[i]);
949     }
950 
951     // av_pred_en = 0.25*av_pred_en
952     av_pred_en = mult (av_pred_en, 8192);
953 
954     // if (av_pred_en < -14) av_pred_en = ..
955 
956     if (sub (av_pred_en, MIN_ENERGY) < 0)
957     {
958         av_pred_en = MIN_ENERGY;
959     }
960     *ener_avg = av_pred_en;
961 }
962 
963 ------------------------------------------------------------------------------
964  RESOURCES USED [optional]
965 
966  When the code is written for a specific target processor the
967  the resources used should be documented below.
968 
969  HEAP MEMORY USED: x bytes
970 
971  STACK MEMORY USED: x bytes
972 
973  CLOCK CYCLES: (cycle count equation for this function) + (variable
974                 used to represent cycle count for each subroutine
975                 called)
976      where: (cycle count variable) = cycle count for [subroutine
977                                      name]
978 
979 ------------------------------------------------------------------------------
980  CAUTION [optional]
981  [State any special notes, constraints or cautions for users of this function]
982 
983 ------------------------------------------------------------------------------
984 */
985 
gc_pred_average_limited(gc_predState * st,Word16 * ener_avg_MR122,Word16 * ener_avg,Flag * pOverflow)986 void gc_pred_average_limited(
987     gc_predState *st,       /* i: State struct                    */
988     Word16 *ener_avg_MR122, /* o: everaged quantized energy,  Q10 */
989     /*    (log2(qua_err))                 */
990     Word16 *ener_avg,       /* o: averaged quantized energy,  Q10 */
991     /*    (20*log10(qua_err))             */
992     Flag *pOverflow
993 )
994 {
995     Word16 av_pred_en;
996     Word16 i;
997 
998     /* do average in MR122 mode (log2() domain) */
999     av_pred_en = 0;
1000     for (i = 0; i < NPRED; i++)
1001     {
1002         av_pred_en =
1003             add(av_pred_en, st->past_qua_en_MR122[i], pOverflow);
1004     }
1005 
1006     /* av_pred_en = 0.25*av_pred_en  (with sign-extension)*/
1007     if (av_pred_en < 0)
1008     {
1009         av_pred_en = (av_pred_en >> 2) | 0xc000;
1010     }
1011     else
1012     {
1013         av_pred_en >>= 2;
1014     }
1015 
1016     /* if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. */
1017     if (av_pred_en < MIN_ENERGY_MR122)
1018     {
1019         av_pred_en = MIN_ENERGY_MR122;
1020     }
1021     *ener_avg_MR122 = av_pred_en;
1022 
1023     /* do average for other modes (20*log10() domain) */
1024     av_pred_en = 0;
1025     for (i = 0; i < NPRED; i++)
1026     {
1027         av_pred_en = add(av_pred_en, st->past_qua_en[i], pOverflow);
1028     }
1029 
1030     /* av_pred_en = 0.25*av_pred_en  (with sign-extension)*/
1031     if (av_pred_en < 0)
1032     {
1033         av_pred_en = (av_pred_en >> 2) | 0xc000;
1034     }
1035     else
1036     {
1037         av_pred_en >>= 2;
1038     }
1039 
1040     /* if (av_pred_en < -14) av_pred_en = .. */
1041     if (av_pred_en < MIN_ENERGY)
1042     {
1043         av_pred_en = MIN_ENERGY;
1044     }
1045     *ener_avg = av_pred_en;
1046 }
1047