123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- /*
- *****************************************************************************
- *
- * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
- * R99 Version 3.3.0
- * REL-4 Version 4.1.0
- *
- *****************************************************************************
- *
- * File : gc_pred.c
- * Purpose : codebook gain MA prediction
- *
- *****************************************************************************
- */
- /*
- *****************************************************************************
- * MODULE INCLUDE FILE AND VERSION ID
- *****************************************************************************
- */
- #include "gc_pred.h"
- const char gc_pred_id[] = "@(#)$Id $" gc_pred_h;
- /*
- *****************************************************************************
- * INCLUDE FILES
- *****************************************************************************
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include "typedef.h"
- #include "basic_op.h"
- #include "oper_32b.h"
- #include "cnst.h"
- #include "count.h"
- #include "log2.h"
- #include "copy.h"
- /*
- *****************************************************************************
- * LOCAL VARIABLES AND TABLES
- *****************************************************************************
- */
- #define NPRED 4 /* number of prediction taps */
- /* MA prediction coefficients (Q13) */
- static const Word16 pred[NPRED] = {5571, 4751, 2785, 1556};
- /* average innovation energy. */
- /* MEAN_ENER = 36.0/constant, constant = 20*Log10(2) */
- #define MEAN_ENER_MR122 783741L /* 36/(20*log10(2)) (Q17) */
- /* MA prediction coefficients (Q6) */
- static const Word16 pred_MR122[NPRED] = {44, 37, 22, 12};
- /* minimum quantized energy: -14 dB */
- #define MIN_ENERGY -14336 /* 14 Q10 */
- #define MIN_ENERGY_MR122 -2381 /* 14 / (20*log10(2)) Q10 */
- /*
- *****************************************************************************
- * PUBLIC PROGRAM CODE
- *****************************************************************************
- */
- /*************************************************************************
- *
- * Function: qua_gain_init
- * Purpose: Allocates state memory and initializes state memory
- *
- **************************************************************************
- */
- int gc_pred_init (gc_predState **state)
- {
- gc_predState* s;
- if (state == (gc_predState **) NULL){
- wfprintf(stderr, "gc_pred_init: invalid parameter\n");
- return -1;
- }
- *state = NULL;
- /* allocate memory */
- if ((s= (gc_predState *) wmalloc(sizeof(gc_predState))) == NULL){
- wfprintf(stderr, "gc_pred_init: can not malloc state structure\n");
- return -1;
- }
- gc_pred_reset(s);
- *state = s;
- return 0;
- }
- /*************************************************************************
- *
- * Function: gc_pred_reset
- * Purpose: Initializes state memory to zero
- *
- **************************************************************************
- */
- int gc_pred_reset (gc_predState *state)
- {
- Word16 i;
- if (state == (gc_predState *) NULL){
- wfprintf(stderr, "gc_pred_reset: invalid parameter\n");
- return -1;
- }
- for(i = 0; i < NPRED; i++)
- {
- state->past_qua_en[i] = MIN_ENERGY;
- state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
- }
- return 0;
- }
- /*************************************************************************
- *
- * Function: gc_pred_exit
- * Purpose: The memory used for state memory is freed
- *
- **************************************************************************
- */
- void gc_pred_exit (gc_predState **state)
- {
- if (state == NULL || *state == NULL)
- return;
- /* deallocate memory */
- wfree(*state);
- *state = NULL;
- return;
- }
- /*************************************************************************
- *
- * FUNCTION: gc_pred_copy()
- *
- * PURPOSE: Copy MA predictor state variable
- *
- *************************************************************************/
- void
- gc_pred_copy(
- gc_predState *st_src, /* i : State struct */
- gc_predState *st_dest /* o : State struct */
- )
- {
- Copy (st_src->past_qua_en, st_dest->past_qua_en, NPRED);
- Copy (st_src->past_qua_en_MR122, st_dest->past_qua_en_MR122, NPRED);
- }
- /*************************************************************************
- *
- * FUNCTION: gc_pred()
- *
- * PURPOSE: MA prediction of the innovation energy
- * (in dB/(20*log10(2))) with mean removed).
- *
- *************************************************************************/
- void
- gc_pred(
- gc_predState *st, /* i/o: State struct */
- enum Mode mode, /* i : AMR mode */
- Word16 *code, /* i : innovative codebook vector (L_SUBFR) */
- /* MR122: Q12, other modes: Q13 */
- Word16 *exp_gcode0, /* o : exponent of predicted gain factor, Q0 */
- Word16 *frac_gcode0,/* o : fraction of predicted gain factor Q15 */
- Word16 *exp_en, /* o : exponent of innovation energy, Q0 */
- /* (only calculated for MR795) */
- Word16 *frac_en /* o : fraction of innovation energy, Q15 */
- /* (only calculated for MR795) */
- )
- {
- Word16 i;
- Word32 ener_code;
- Word16 exp, frac;
- /*-------------------------------------------------------------------*
- * energy of code: *
- * ~~~~~~~~~~~~~~~ *
- * ener_code = sum(code[i]^2) *
- *-------------------------------------------------------------------*/
- ener_code = L_mac_ex((Word32) 0, code[0], code[0]);
- /* MR122: Q12*Q12 -> Q25 */
- /* others: Q13*Q13 -> Q27 */
- for (i = 1; i < L_SUBFR; i++)
- ener_code = L_mac_ex(ener_code, code[i], code[i]);
-
- test ();
- if (sub_ex (mode, MR122) == 0)
- {
- Word32 ener;
- /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */
- ener_code = L_mult_ex (round_ex (ener_code), 26214); /* Q9 * Q20 -> Q30 */
- /*-------------------------------------------------------------------*
- * energy of code: *
- * ~~~~~~~~~~~~~~~ *
- * ener_code(Q17) = 10 * Log10(energy) / constant *
- * = 1/2 * Log2(energy) *
- * constant = 20*Log10(2) *
- *-------------------------------------------------------------------*/
- /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */
- Log2(ener_code, &exp, &frac);
- ener_code = L_Comp (sub_ex (exp, 30), frac); /* Q16 for log() */
- /* ->Q17 for 1/2 log()*/
- /*-------------------------------------------------------------------*
- * predicted energy: *
- * ~~~~~~~~~~~~~~~~~ *
- * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant *
- * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) *
- * constant = 20*Log10(2) *
- *-------------------------------------------------------------------*/
- ener = MEAN_ENER_MR122; move32 (); /* Q24 (Q17) */
- for (i = 0; i < NPRED; i++)
- {
- ener = L_mac_ex (ener, st->past_qua_en_MR122[i], pred_MR122[i]);
- /* Q10 * Q13 -> Q24 */
- /* Q10 * Q6 -> Q17 */
- }
- /*-------------------------------------------------------------------*
- * predicted codebook gain *
- * ~~~~~~~~~~~~~~~~~~~~~~~ *
- * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) *
- * = Pow2(ener-ener_code) *
- * = Pow2(int(d)+frac(d)) *
- * *
- * (store exp and frac for pow2()) *
- *-------------------------------------------------------------------*/
- ener = L_shr_ex (L_sub_ex (ener, ener_code), 1); /* Q16 */
- L_Extract(ener, exp_gcode0, frac_gcode0);
- }
- else /* all modes except 12.2 */
- {
- Word32 L_tmp;
- Word16 exp_code, gcode0;
-
- /*-----------------------------------------------------------------*
- * Compute: means_ener - 10log10(ener_code/ L_sufr) *
- *-----------------------------------------------------------------*/
- exp_code = norm_l_ex (ener_code);
- ener_code = L_shl_ex (ener_code, exp_code);
-
- /* Log2 = log2 + 27 */
- Log2_norm (ener_code, exp_code, &exp, &frac);
-
- /* fact = 10/log2(10) = 3.01 = 24660 Q13 */
- L_tmp = Mpy_32_16(exp, frac, -24660); /* Q0.Q15 * Q13 -> Q14 */
- /* L_tmp = means_ener - 10log10(ener_code/L_SUBFR)
- * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)
- * = K - fact * Log2(ener_code)
- * = K - fact * log2(ener_code) - fact*27
- *
- * ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
- *
- * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59)
- * means_ener = 28.75 = 471040 Q14 (MR67)
- * means_ener = 30 = 491520 Q14 (MR74)
- * means_ener = 36 = 589824 Q14 (MR795)
- * means_ener = 33 = 540672 Q14 (MR102)
- * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14
- * fact * 27 = 1331640 Q14
- * -----------------------------------------
- * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2
- * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2
- * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2
- * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2
- * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2
- */
- if (test (), sub_ex (mode, MR102) == 0)
- {
- /* mean = 33 dB */
- L_tmp = L_mac_ex(L_tmp, 16678, 64); /* Q14 */
- }
- else if (test (), sub_ex (mode, MR795) == 0)
- {
- /* ener_code = <xn xn> * 2^27*2^exp_code
- frac_en = ener_code / 2^16
- = <xn xn> * 2^11*2^exp_code
- <xn xn> = <xn xn>*2^11*2^exp * 2^exp_en
- := frac_en * 2^exp_en
- ==> exp_en = -11-exp_code;
- */
- *frac_en = extract_h_ex (ener_code); move16 ();
- *exp_en = sub_ex (-11, exp_code); move16 ();
- /* mean = 36 dB */
- L_tmp = L_mac_ex(L_tmp, 17062, 64); /* Q14 */
- }
- else if (test (), sub_ex (mode, MR74) == 0)
- {
- /* mean = 30 dB */
- L_tmp = L_mac_ex(L_tmp, 32588, 32); /* Q14 */
- }
- else if (test (), sub_ex (mode, MR67) == 0)
- {
- /* mean = 28.75 dB */
- L_tmp = L_mac_ex(L_tmp, 32268, 32); /* Q14 */
- }
- else /* MR59, MR515, MR475 */
- {
- /* mean = 33 dB */
- L_tmp = L_mac_ex(L_tmp, 16678, 64); /* Q14 */
- }
-
- /*-----------------------------------------------------------------*
- * Compute gcode0. *
- * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener *
- *-----------------------------------------------------------------*/
- L_tmp = L_shl_ex(L_tmp, 10); /* Q24 */
- for (i = 0; i < 4; i++)
- L_tmp = L_mac_ex(L_tmp, pred[i], st->past_qua_en[i]);
- /* Q13 * Q10 -> Q24 */
- gcode0 = extract_h_ex(L_tmp); /* Q8 */
- /*-----------------------------------------------------------------*
- * gcode0 = pow(10.0, gcode0/20) *
- * = pow(2, 3.3219*gcode0/20) *
- * = pow(2, 0.166*gcode0) *
- *-----------------------------------------------------------------*/
- /* 5439 Q15 = 0.165985 */
- /* (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15) */
- test ();
- if (sub_ex (mode, MR74) == 0) /* For IS641 bitexactness */
- L_tmp = L_mult_ex(gcode0, 5439); /* Q8 * Q15 -> Q24 */
- else
- L_tmp = L_mult_ex(gcode0, 5443); /* Q8 * Q15 -> Q24 */
- L_tmp = L_shr_ex(L_tmp, 8); /* -> Q16 */
- L_Extract(L_tmp, exp_gcode0, frac_gcode0); /* -> Q0.Q15 */
- }
- }
- /*************************************************************************
- *
- * FUNCTION: gc_pred_update()
- *
- * PURPOSE: update MA predictor with last quantized energy
- *
- *************************************************************************/
- void gc_pred_update(
- gc_predState *st, /* i/o: State struct */
- Word16 qua_ener_MR122, /* i : quantized energy for update, Q10 */
- /* (log2(qua_err)) */
- Word16 qua_ener /* i : quantized energy for update, Q10 */
- /* (20*log10(qua_err)) */
- )
- {
- Word16 i;
- for (i = 3; i > 0; i--)
- {
- st->past_qua_en[i] = st->past_qua_en[i - 1]; move16 ();
- st->past_qua_en_MR122[i] = st->past_qua_en_MR122[i - 1]; move16 ();
- }
- st->past_qua_en_MR122[0] = qua_ener_MR122; /* log2 (qua_err), Q10 */
- move16 ();
- st->past_qua_en[0] = qua_ener; /* 20*log10(qua_err), Q10 */
- move16 ();
- }
- /*************************************************************************
- *
- * FUNCTION: gc_pred_average_limited()
- *
- * PURPOSE: get average of MA predictor state values (with a lower limit)
- * [used in error concealment]
- *
- *************************************************************************/
- void gc_pred_average_limited(
- gc_predState *st, /* i: State struct */
- Word16 *ener_avg_MR122, /* o: everaged quantized energy, Q10 */
- /* (log2(qua_err)) */
- Word16 *ener_avg /* o: averaged quantized energy, Q10 */
- /* (20*log10(qua_err)) */
- )
- {
- Word16 av_pred_en;
- Word16 i;
- /* do average in MR122 mode (log2() domain) */
- av_pred_en = 0; move16 ();
- for (i = 0; i < NPRED; i++)
- {
- av_pred_en = add_ex (av_pred_en, st->past_qua_en_MR122[i]);
- }
- /* av_pred_en = 0.25*av_pred_en */
- av_pred_en = mult_ex (av_pred_en, 8192);
- /* if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. */
- test ();
- if (sub_ex (av_pred_en, MIN_ENERGY_MR122) < 0)
- {
- av_pred_en = MIN_ENERGY_MR122; move16 ();
- }
- *ener_avg_MR122 = av_pred_en; move16 ();
- /* do average for other modes (20*log10() domain) */
- av_pred_en = 0; move16 ();
- for (i = 0; i < NPRED; i++)
- {
- av_pred_en = add_ex (av_pred_en, st->past_qua_en[i]);
- }
- /* av_pred_en = 0.25*av_pred_en */
- av_pred_en = mult_ex (av_pred_en, 8192);
- /* if (av_pred_en < -14) av_pred_en = .. */
- test ();
- if (sub_ex (av_pred_en, MIN_ENERGY) < 0)
- {
- av_pred_en = MIN_ENERGY; move16 ();
- }
- *ener_avg = av_pred_en; move16 ();
- }
|