1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
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 ****************************************************************************************/
36 gc_pred_average_limited
38 ------------------------------------------------------------------------------
41 This file contains the functions that perform codebook gain MA prediction.
43 ------------------------------------------------------------------------------
46 /*----------------------------------------------------------------------------
48 ----------------------------------------------------------------------------*/
50 #include "basicop_malloc.h"
55 /*----------------------------------------------------------------------------
57 ; Define module specific macros here
58 ----------------------------------------------------------------------------*/
60 /*----------------------------------------------------------------------------
62 ; Include all pre-processor statements here. Include conditional
63 ; compile variables also.
64 ----------------------------------------------------------------------------*/
65 #define NPRED 4 /* number of prediction taps */
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) */
71 /* minimum quantized energy: -14 dB */
72 #define MIN_ENERGY -14336 /* 14 Q10 */
73 #define MIN_ENERGY_MR122 -2381 /* 14 / (20*log10(2)) Q10 */
75 /*----------------------------------------------------------------------------
76 ; LOCAL FUNCTION DEFINITIONS
77 ; Function Prototype declaration
78 ----------------------------------------------------------------------------*/
80 /*----------------------------------------------------------------------------
81 ; LOCAL VARIABLE DEFINITIONS
82 ; Variable declaration - defined here and used outside this module
83 ----------------------------------------------------------------------------*/
85 /* MA prediction coefficients (Q13) */
86 static const Word16 pred[NPRED] = {5571, 4751, 2785, 1556};
88 /* MA prediction coefficients (Q6) */
89 static const Word16 pred_MR122[NPRED] = {44, 37, 22, 12};
92 ------------------------------------------------------------------------------
93 FUNCTION NAME: gc_pred_reset
94 ------------------------------------------------------------------------------
95 INPUT AND OUTPUT DEFINITIONS
98 state = pointer to a structure of type gc_predState
101 past_qua_en field in the structure pointed to by state is initialized
103 past_qua_en_MR122 field in the structure pointed to by state is
104 initialized to MIN_ENERGY_MR122
107 return_value = 0, if reset was successful; -1, otherwise (int)
109 Global Variables Used:
112 Local Variables Needed:
115 ------------------------------------------------------------------------------
118 This function initializes the state memory used by gc_pred to zero.
120 ------------------------------------------------------------------------------
125 ------------------------------------------------------------------------------
128 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
130 ------------------------------------------------------------------------------
133 int gc_pred_reset (gc_predState *state)
137 if (state == (gc_predState *) NULL){
138 fprintf(stderr, "gc_pred_reset: invalid parameter\n");
142 for(i = 0; i < NPRED; i++)
144 state->past_qua_en[i] = MIN_ENERGY;
145 state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
150 ------------------------------------------------------------------------------
152 [State any special notes, constraints or cautions for users of this function]
154 ------------------------------------------------------------------------------
157 OSCL_EXPORT_REF Word16 gc_pred_reset(gc_predState *state)
161 if (state == (gc_predState *) NULL)
163 /* fprintf(stderr, "gc_pred_reset: invalid parameter\n"); */
167 for (i = 0; i < NPRED; i++)
169 state->past_qua_en[i] = MIN_ENERGY;
170 state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
176 /****************************************************************************/
179 ------------------------------------------------------------------------------
180 FUNCTION NAME: gc_pred
181 ------------------------------------------------------------------------------
182 INPUT AND OUTPUT DEFINITIONS
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
191 frac_gcode0 = pointer to the fractional part of predicted gain factor
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)
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.
214 Global Variables Used:
217 Local Variables Needed:
218 pred = table of MA prediction coefficients (Q13) (Word16)
219 pred_MR122 = table of MA prediction coefficients (Q6) (Word16)
221 ------------------------------------------------------------------------------
224 This function performs the MA prediction of the innovation energy (in
225 dB/(20*log10(2))), with the mean removed.
227 ------------------------------------------------------------------------------
232 ------------------------------------------------------------------------------
235 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
237 ------------------------------------------------------------------------------
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.
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)
261 *-------------------------------------------------------------------*
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]);
272 if (sub (mode, MR122) == 0)
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
279 *-------------------------------------------------------------------*
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()
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 *-------------------------------------------------------------------*
299 ener = MEAN_ENER_MR122; // Q24 (Q17)
300 for (i = 0; i < NPRED; i++)
302 ener = L_mac (ener, st->past_qua_en_MR122[i], pred_MR122[i]);
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)) *
314 * (store exp and frac for pow2()) *
315 *-------------------------------------------------------------------*
317 ener = L_shr (L_sub (ener, ener_code), 1); // Q16
318 L_Extract(ener, exp_gcode0, frac_gcode0);
320 else // all modes except 12.2
323 Word16 exp_code, gcode0;
325 *-----------------------------------------------------------------*
326 * Compute: means_ener - 10log10(ener_code/ L_sufr) *
327 *-----------------------------------------------------------------*
329 exp_code = norm_l (ener_code);
330 ener_code = L_shl (ener_code, exp_code);
333 Log2_norm (ener_code, exp_code, &exp, &frac);
335 // fact = 10/log2(10) = 3.01 = 24660 Q13
336 L_tmp = Mpy_32_16(exp, frac, -24660); // Q0.Q15 * Q13 -> Q14
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
343 * ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
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
360 if (sub (mode, MR102) == 0)
363 L_tmp = L_mac(L_tmp, 16678, 64); // Q14
365 else if (sub (mode, MR795) == 0)
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
373 // ==> exp_en = -11-exp_code;
375 *frac_en = extract_h (ener_code);
376 *exp_en = sub (-11, exp_code);
379 L_tmp = L_mac(L_tmp, 17062, 64); // Q14
381 else if (sub (mode, MR74) == 0)
384 L_tmp = L_mac(L_tmp, 32588, 32); // Q14
386 else if (sub (mode, MR67) == 0)
389 L_tmp = L_mac(L_tmp, 32268, 32); // Q14
391 else // MR59, MR515, MR475
394 L_tmp = L_mac(L_tmp, 16678, 64); // Q14
397 *-----------------------------------------------------------------*
399 * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener *
400 *-----------------------------------------------------------------*
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]);
407 gcode0 = extract_h(L_tmp); // Q8
409 *-----------------------------------------------------------------*
410 * gcode0 = pow(10.0, gcode0/20) *
411 * = pow(2, 3.3219*gcode0/20) *
412 * = pow(2, 0.166*gcode0) *
413 *-----------------------------------------------------------------*
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
420 L_tmp = L_mult(gcode0, 5443); // Q8 * Q15 -> Q24
422 L_tmp = L_shr(L_tmp, 8); // -> Q16
423 L_Extract(L_tmp, exp_gcode0, frac_gcode0); // -> Q0.Q15
427 ------------------------------------------------------------------------------
429 [State any special notes, constraints or cautions for users of this function]
431 ------------------------------------------------------------------------------
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) */
449 register Word32 L_temp1, L_temp2;
450 register Word32 L_tmp;
454 Word16 exp_code, gcode0;
456 Word16 *p_code = &code[0];
458 /*-------------------------------------------------------------------*
461 * ener_code = sum(code[i]^2) *
462 *-------------------------------------------------------------------*/
465 /* MR122: Q12*Q12 -> Q25 */
466 /* others: Q13*Q13 -> Q27 */
468 for (i = L_SUBFR >> 2; i != 0; i--)
471 ener_code += ((Word32) tmp * tmp) >> 3;
473 ener_code += ((Word32) tmp * tmp) >> 3;
475 ener_code += ((Word32) tmp * tmp) >> 3;
477 ener_code += ((Word32) tmp * tmp) >> 3;
482 if (ener_code < 0) /* Check for saturation */
489 /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */
490 /* Q9 * Q20 -> Q30 */
492 ener_code = ((Word32)(pv_round(ener_code, pOverflow) * 26214)) << 1;
494 /*-------------------------------------------------------------*
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);
505 /* ->Q17 for 1/2 log()*/
507 L_temp1 = (Word32)(exp - 30) << 16;
508 ener_code = L_temp1 + ((Word32)frac << 1);
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 *-------------------------------------------------------------*/
518 ener = MEAN_ENER_MR122; /* Q24 (Q17) */
519 for (i = 0; i < NPRED; i++)
521 L_temp1 = (((Word32) st->past_qua_en_MR122[i]) *
523 ener = L_add(ener, L_temp1, pOverflow);
525 /* Q10 * Q13 -> Q24 */
526 /* Q10 * Q6 -> Q17 */
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)) *
536 * (store exp and frac for pow2()) *
537 *---------------------------------------------------------------*/
540 L_temp1 = L_sub(ener, ener_code, pOverflow);
543 *exp_gcode0 = (Word16)(L_temp1 >> 17);
545 L_temp2 = (Word32) * exp_gcode0 << 15;
548 *frac_gcode0 = (Word16)(L_temp1 - L_temp2);
551 else /* all modes except 12.2 */
553 /*-----------------------------------------------------------------*
554 * Compute: means_ener - 10log10(ener_code/ L_sufr) *
555 *-----------------------------------------------------------------*/
557 exp_code = norm_l(ener_code);
558 ener_code = L_shl(ener_code, exp_code, pOverflow);
560 /* Log2 = log2 + 27 */
561 Log2_norm(ener_code, exp_code, &exp, &frac);
563 /* fact = 10/log2(10) = 3.01 = 24660 Q13 */
564 /* Q0.Q15 * Q13 -> Q14 */
566 L_temp2 = (((Word32) exp) * -24660) << 1;
567 L_tmp = (((Word32) frac) * -24660) >> 15;
569 /* Sign-extend resulting product */
570 if (L_tmp & (Word32) 0x00010000L)
572 L_tmp = L_tmp | (Word32) 0xffff0000L;
576 L_tmp = L_add(L_tmp, L_temp2, pOverflow);
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
584 * ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
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
604 L_temp2 = (Word32) 16678 << 7;
605 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
607 else if (mode == MR795)
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;
619 L_temp2 = (Word32) 17062 << 7;
620 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
622 else if (mode == MR74)
625 L_temp2 = (Word32) 32588 << 6;
626 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
628 else if (mode == MR67)
630 /* mean = 28.75 dB */
631 L_temp2 = (Word32) 32268 << 6;
632 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
634 else /* MR59, MR515, MR475 */
637 L_temp2 = (Word32) 16678 << 7;
638 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
641 /*-------------------------------------------------------------*
643 * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener *
644 *--------------------------------------------------------------*/
646 if (L_tmp > (Word32) 0X001fffffL)
651 else if (L_tmp < (Word32) 0xffe00000L)
661 for (i = 0; i < 4; i++)
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 */
667 gcode0 = (Word16)(L_tmp >> 16); /* Q8 */
669 /*-----------------------------------------------------------*
670 * gcode0 = pow(10.0, gcode0/20) *
671 * = pow(2, 3.3219*gcode0/20) *
672 * = pow(2, 0.166*gcode0) *
673 *-----------------------------------------------------------*/
675 /* 5439 Q15 = 0.165985 */
676 /* (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15) */
678 if (mode == MR74) /* For IS641 bitexactness */
680 L_tmp = (((Word32) gcode0) * 5439) << 1; /* Q8 * Q15 -> Q24 */
684 L_tmp = (((Word32) gcode0) * 5443) << 1; /* Q8 * Q15 -> Q24 */
689 L_tmp = ~((~L_tmp) >> 8);
693 L_tmp = L_tmp >> 8; /* -> Q16 */
696 *exp_gcode0 = (Word16)(L_tmp >> 16);
699 L_temp1 = ~((~L_tmp) >> 1);
703 L_temp1 = L_tmp >> 1;
705 L_temp2 = (Word32) * exp_gcode0 << 15;
706 *frac_gcode0 = (Word16)(L_sub(L_temp1, L_temp2, pOverflow));
713 /****************************************************************************/
716 ------------------------------------------------------------------------------
717 FUNCTION NAME: gc_pred_update
718 ------------------------------------------------------------------------------
719 INPUT AND OUTPUT DEFINITIONS
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)
729 structure pointed to by st contains the calculated quantized energy
735 Global Variables Used:
738 Local Variables Needed:
741 ------------------------------------------------------------------------------
744 This function updates the MA predictor with the last quantized energy.
746 ------------------------------------------------------------------------------
751 ------------------------------------------------------------------------------
754 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
756 ------------------------------------------------------------------------------
760 gc_predState *st, // i/o: State struct
761 Word16 qua_ener_MR122, // i : quantized energy for update, Q10
763 Word16 qua_ener // i : quantized energy for update, Q10
764 // (20*log10(qua_err))
769 for (i = 3; i > 0; i--)
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];
775 st->past_qua_en_MR122[0] = qua_ener_MR122; // log2 (qua_err), Q10
777 st->past_qua_en[0] = qua_ener; // 20*log10(qua_err), Q10
781 ------------------------------------------------------------------------------
783 [State any special notes, constraints or cautions for users of this function]
785 ------------------------------------------------------------------------------
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)) */
796 st->past_qua_en[3] = st->past_qua_en[2];
797 st->past_qua_en_MR122[3] = st->past_qua_en_MR122[2];
799 st->past_qua_en[2] = st->past_qua_en[1];
800 st->past_qua_en_MR122[2] = st->past_qua_en_MR122[1];
802 st->past_qua_en[1] = st->past_qua_en[0];
803 st->past_qua_en_MR122[1] = st->past_qua_en_MR122[0];
805 st->past_qua_en_MR122[0] = qua_ener_MR122; /* log2 (qua_err), Q10 */
807 st->past_qua_en[0] = qua_ener; /* 20*log10(qua_err), Q10 */
812 /****************************************************************************/
815 ------------------------------------------------------------------------------
816 FUNCTION NAME: gc_pred_average_limited
817 ------------------------------------------------------------------------------
818 INPUT AND OUTPUT DEFINITIONS
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)
829 store pointed to by ener_avg_MR122 contains the new averaged quantized
831 store pointed to by ener_avg contains the new averaged quantized
833 pOverflow = 1 if the math functions called by gc_pred_average_limited
834 results in overflow else zero.
839 Global Variables Used:
842 Local Variables Needed:
845 ------------------------------------------------------------------------------
848 This function calculates the average of MA predictor state values (with a
849 lower limit) used in error concealment.
851 ------------------------------------------------------------------------------
856 ------------------------------------------------------------------------------
859 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
861 ------------------------------------------------------------------------------
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.
867 void gc_pred_average_limited(
868 gc_predState *st, // i: State struct
869 Word16 *ener_avg_MR122, // o: everaged quantized energy, Q10
871 Word16 *ener_avg // o: averaged quantized energy, Q10
872 // (20*log10(qua_err))
878 // do average in MR122 mode (log2() domain)
880 for (i = 0; i < NPRED; i++)
882 av_pred_en = add (av_pred_en, st->past_qua_en_MR122[i]);
885 // av_pred_en = 0.25*av_pred_en
886 av_pred_en = mult (av_pred_en, 8192);
888 // if (av_pred_en < -14/(20Log10(2))) av_pred_en = ..
890 if (sub (av_pred_en, MIN_ENERGY_MR122) < 0)
892 av_pred_en = MIN_ENERGY_MR122;
894 *ener_avg_MR122 = av_pred_en;
896 // do average for other modes (20*log10() domain)
898 for (i = 0; i < NPRED; i++)
900 av_pred_en = add (av_pred_en, st->past_qua_en[i]);
903 // av_pred_en = 0.25*av_pred_en
904 av_pred_en = mult (av_pred_en, 8192);
906 // if (av_pred_en < -14) av_pred_en = ..
908 if (sub (av_pred_en, MIN_ENERGY) < 0)
910 av_pred_en = MIN_ENERGY;
912 *ener_avg = av_pred_en;
915 ------------------------------------------------------------------------------
917 [State any special notes, constraints or cautions for users of this function]
919 ------------------------------------------------------------------------------
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)) */
934 /* do average in MR122 mode (log2() domain) */
936 for (i = 0; i < NPRED; i++)
939 add_16(av_pred_en, st->past_qua_en_MR122[i], pOverflow);
942 /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/
945 av_pred_en = (av_pred_en >> 2) | 0xc000;
952 /* if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. */
953 if (av_pred_en < MIN_ENERGY_MR122)
955 av_pred_en = MIN_ENERGY_MR122;
957 *ener_avg_MR122 = av_pred_en;
959 /* do average for other modes (20*log10() domain) */
961 for (i = 0; i < NPRED; i++)
963 av_pred_en = add_16(av_pred_en, st->past_qua_en[i], pOverflow);
966 /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/
969 av_pred_en = (av_pred_en >> 2) | 0xc000;
976 /* if (av_pred_en < -14) av_pred_en = .. */
977 if (av_pred_en < MIN_ENERGY)
979 av_pred_en = MIN_ENERGY;
981 *ener_avg = av_pred_en;