gc_pred.cpp revision 2d0ac425564ff9882ebaac5267d1a04d4af67d00
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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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) */
86static const Word16 pred[NPRED] = {5571, 4751, 2785, 1556};
87
88/* MA prediction coefficients (Q6)  */
89static 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
133int 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
173Word16 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
256The original etsi reference code uses a global flag Overflow. However, in the
257actual implementation a pointer to a the overflow flag is passed in.
258
259void
260gc_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
466void 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
791void 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
836void 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
912The original etsi reference code uses a global flag Overflow. However, in the
913actual implementation a pointer to a the overflow flag is passed in.
914
915void 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
986void 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