GAINPRED.C
上传用户:meifeng08
上传日期:2013-06-18
资源大小:5304k
文件大小:7k
源码类别:

语音压缩

开发平台:

C/C++

  1. /* Version 3.3    Last modified: December 26, 1995 */
  2. /*---------------------------------------------------------------------------*
  3.  *  Gain_predict()        : make gcode0(exp_gcode0)                          *
  4.  *  Gain_update()         : update table of past quantized energies.         *
  5.  *  Gain_update_erasure() : update table of past quantized energies.         *
  6.  *                                                        (frame erasure)    *
  7.  *    This function is used both Coder and Decoder.                          *
  8.  *---------------------------------------------------------------------------*/
  9. #include "typedef.h"
  10. #include "basic_op.h"
  11. #include "ld8k.h"
  12. #include "tab_ld8k.h"
  13. #include "oper_32b.h"
  14. /*---------------------------------------------------------------------------*
  15.  * Function  Gain_predict                                                    *
  16.  * ~~~~~~~~~~~~~~~~~~~~~~                                                    *
  17.  * MA prediction is performed on the innovation energy (in dB with mean      *
  18.  * removed).                                                                 *
  19.  *---------------------------------------------------------------------------*/
  20. void Gain_predict(
  21.    Word16 past_qua_en[],/* (i) Q10 :Past quantized energies        */
  22.    Word16 code[],       /* (i) Q13 :Innovative vector.             */
  23.    Word16 L_subfr,      /* (i)     :Subframe length.               */
  24.    Word16 *gcode0,      /* (o) Qxx :Predicted codebook gain        */
  25.    Word16 *exp_gcode0   /* (o)     :Q-Format(gcode0)               */
  26. )
  27. {
  28.    Word16  i, exp, frac;
  29.    Word32  L_tmp;
  30.   /*-------------------------------*
  31.    * Energy coming from code       *
  32.    *-------------------------------*/
  33.    L_tmp = 0;
  34.    for(i=0; i<L_subfr; i++)
  35.      L_tmp = L_mac(L_tmp, code[i], code[i]);
  36.   /*-----------------------------------------------------------------*
  37.    *  Compute: means_ener - 10log10(ener_code/ L_sufr)               *
  38.    *  Note: mean_ener change from 36 dB to 30 dB because input/2     *
  39.    *                                                                 *
  40.    * = 30.0 - 10 log10( ener_code / lcode)  + 10log10(2^27)          *
  41.    *                                          !!ener_code in Q27!!   *
  42.    * = 30.0 - 3.0103 * log2(ener_code) + 10log10(40) + 10log10(2^27) *
  43.    * = 30.0 - 3.0103 * log2(ener_code) + 16.02  + 81.278             *
  44.    * = 127.298 - 3.0103 * log2(ener_code)                            *
  45.    *-----------------------------------------------------------------*/
  46.    Log2(L_tmp, &exp, &frac);               /* Q27->Q0 ^Q0 ^Q15       */
  47.    L_tmp = Mpy_32_16(exp, frac, -24660);   /* Q0 Q15 Q13 -> ^Q14     */
  48.                                            /* hi:Q0+Q13+1            */
  49.                                            /* lo:Q15+Q13-15+1        */
  50.                                            /* -24660[Q13]=-3.0103    */
  51.    L_tmp = L_mac(L_tmp, 32588, 32);        /* 32588*32[Q14]=127.298  */
  52.   /*-----------------------------------------------------------------*
  53.    * Compute gcode0.                                                 *
  54.    *  = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener    *
  55.    *-----------------------------------------------------------------*/
  56.    L_tmp = L_shl(L_tmp, 10);                      /* From Q14 to Q24 */
  57.    for(i=0; i<4; i++)
  58.      L_tmp = L_mac(L_tmp, pred[i], past_qua_en[i]); /* Q13*Q10 ->Q24 */
  59.    *gcode0 = extract_h(L_tmp);                    /* From Q24 to Q8  */
  60.   /*-----------------------------------------------------------------*
  61.    * gcode0 = pow(10.0, gcode0/20)                                   *
  62.    *        = pow(2, 3.3219*gcode0/20)                               *
  63.    *        = pow(2, 0.166*gcode0)                                   *
  64.    *-----------------------------------------------------------------*/
  65.    L_tmp = L_mult(*gcode0, 5439);       /* *0.166 in Q15, result in Q24*/
  66.    L_tmp = L_shr(L_tmp, 8);             /* From Q24 to Q16             */
  67.    L_Extract(L_tmp, &exp, &frac);       /* Extract exponent of gcode0  */
  68.    *gcode0 = extract_l(Pow2(14, frac)); /* Put 14 as exponent so that  */
  69.                                         /* output of Pow2() will be:   */
  70.                                         /* 16768 < Pow2() <= 32767     */
  71.    *exp_gcode0 = sub(14,exp);
  72. }
  73. /*---------------------------------------------------------------------------*
  74.  * Function  Gain_update                                                     *
  75.  * ~~~~~~~~~~~~~~~~~~~~~~                                                    *
  76.  * update table of past quantized energies                                   *
  77.  *---------------------------------------------------------------------------*/
  78. void Gain_update(
  79.    Word16 past_qua_en[],/* (io) Q10 :Past quantized energies        */
  80.    Word32  L_gbk12   /* (i) Q13 : gbk1[indice1][1]+gbk2[indice2][1] */
  81. )
  82. {
  83.    Word16  i, tmp;
  84.    Word16  exp, frac;
  85.    Word32  L_acc;
  86.    for(i=3; i>0; i--){
  87.       past_qua_en[i] = past_qua_en[i-1];         /* Q10 */
  88.    }
  89.   /*----------------------------------------------------------------------*
  90.    * -- past_qua_en[0] = 20*log10(gbk1[index1][1]+gbk2[index2][1]); --    *
  91.    *    2 * 10 log10( gbk1[index1][1]+gbk2[index2][1] )                   *
  92.    *  = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] )                *
  93.    *  = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] )                *
  94.    *                                                 24660:Q12(6.0205)    *
  95.    *----------------------------------------------------------------------*/
  96.    Log2( L_gbk12, &exp, &frac );               /* L_gbk12:Q13       */
  97.    L_acc = L_Comp( sub(exp,13), frac);         /* L_acc:Q16           */
  98.    tmp = extract_h( L_shl( L_acc,13 ) );       /* tmp:Q13           */
  99.    past_qua_en[0] = mult( tmp, 24660 );        /* past_qua_en[]:Q10 */
  100. }
  101. /*---------------------------------------------------------------------------*
  102.  * Function  Gain_update_erasure                                             *
  103.  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                             *
  104.  * update table of past quantized energies (frame erasure)                   *
  105.  *---------------------------------------------------------------------------*
  106.  *     av_pred_en = 0.0;                                                     *
  107.  *     for (i = 0; i < 4; i++)                                               *
  108.  *        av_pred_en += past_qua_en[i];                                      *
  109.  *     av_pred_en = av_pred_en*0.25 - 4.0;                                   *
  110.  *     if (av_pred_en < -14.0) av_pred_en = -14.0;                           *
  111.  *---------------------------------------------------------------------------*/
  112. void Gain_update_erasure(
  113.    Word16 past_qua_en[]/* (i) Q10 :Past quantized energies        */
  114. )
  115. {
  116.    Word16  i, av_pred_en;
  117.    Word32  L_tmp;
  118.    L_tmp = 0;                                                    /* Q10 */
  119.    for(i=0; i<4; i++)
  120.       L_tmp = L_add( L_tmp, L_deposit_l( past_qua_en[i] ) );
  121.    av_pred_en = extract_l( L_shr( L_tmp, 2 ) );
  122.    av_pred_en = sub( av_pred_en, 4096 );                          /* Q10 */
  123.    if( sub(av_pred_en, -14336) < 0 ){
  124.       av_pred_en = -14336;                              /* 14336:14[Q10] */
  125.    }
  126.    for(i=3; i>0; i--){
  127.       past_qua_en[i] = past_qua_en[i-1];
  128.    }
  129.    past_qua_en[0] = av_pred_en;
  130. }