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

语音压缩

开发平台:

C/C++

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