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