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

语音压缩

开发平台:

C/C++

  1. /*
  2. **
  3. ** File:        "util_cng.c"
  4. **
  5. ** Description:     General Comfort Noise Generation functions
  6. **
  7. **
  8. ** Functions:       Calc_Exc_Rand() Computes random excitation
  9. **                                  used both by coder & decoder
  10. **                  Qua_SidGain()   Quantization of SID gain
  11. **                                  used by coder
  12. **                  Dec_SidGain()   Decoding of SID gain
  13. **                                  used both by coder & decoder
  14. **
  15. ** Local functions :
  16. **                  distG()
  17. **                  random_number()
  18. */
  19. /*
  20.     ITU-T G.723 Speech Coder   ANSI-C Source Code     Version 5.00
  21.     copyright (c) 1995, AudioCodes, DSP Group, France Telecom,
  22.     Universite de Sherbrooke.  All rights reserved.
  23. */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include "typedef.h"
  27. #include "cst_lbc.h"
  28. #include "tab_lbc.h"
  29. #include "util_lbc.h"
  30. #include "exc_lbc.h"
  31. #include "basop.h"
  32. #include "util_cng.h"
  33. /* Declaration of local functions */
  34. static Word16 random_number(Word16 number_max_p1, Word16 *nRandom);
  35. /*
  36. **
  37. ** Function:           Calc_Exc_Rand()
  38. **
  39. ** Description:        Computation of random excitation for inactive frames:
  40. **                     Adaptive codebook entry selected randomly
  41. **                     Higher rate innovation pattern selected randomly
  42. **                     Computes innovation gain to match curGain
  43. **
  44. ** Links to text:
  45. **
  46. ** Arguments:
  47. **
  48. **  Word16 curGain     current average gain to match
  49. **  Word16 *PrevExc    previous/current excitation (updated)
  50. **  Word16 *DataEXc    current frame excitation
  51. **  Word16 *nRandom    random generator status (input/output)
  52. **
  53. ** Outputs:
  54. **
  55. **  Word16 *PrevExc
  56. **  Word16 *DataExc
  57. **  Word16 *nRandom
  58. **
  59. ** Return value:       None
  60. **
  61. */
  62. void Calc_Exc_Rand(Word16 curGain, Word16 *PrevExc, Word16 *DataExc,
  63.                                       Word16 *nRandom, LINEDEF *Line)
  64. {
  65.     int i, i_subfr, iblk;
  66.     Word16 temp, temp2;
  67.     Word16 j;
  68.     Word16 TabPos[2*NbPulsBlk], TabSign[2*NbPulsBlk];
  69.     Word16 *ptr_TabPos, *ptr_TabSign;
  70.     Word16 *ptr1, *curExc;
  71.     Word16 sh1, x1, x2, inter_exc, delta, b0;
  72.     Word32 L_acc, L_c, L_temp;
  73.     Word16 tmp[SubFrLen/Sgrid];
  74.     Word16 offset[SubFrames];
  75.     Word16 tempExc[SubFrLenD];
  76.  /*
  77.   * generate LTP codes
  78.   */
  79.     Line->Olp[0] = random_number(21, nRandom) + (Word16)123;
  80.     Line->Olp[1] = random_number(21, nRandom) + (Word16)123;
  81.     for(i_subfr=0; i_subfr<SubFrames; i_subfr++) {  /* in [1, NbFilt] */
  82.         Line->Sfs[i_subfr].AcGn = random_number(NbFilt, nRandom) + (Word16)1;
  83.     }
  84.     Line->Sfs[0].AcLg = 1;
  85.     Line->Sfs[1].AcLg = 0;
  86.     Line->Sfs[2].AcLg = 1;
  87.     Line->Sfs[3].AcLg = 3;
  88.  /*
  89.   * Random innovation :
  90.   * Selection of the grids, signs and pulse positions
  91.   */
  92.     /* Signs and Grids */
  93.     ptr_TabSign = TabSign;
  94.     ptr1 = offset;
  95.     for(iblk=0; iblk<SubFrames/2; iblk++) {
  96.         temp    = random_number((1 << (NbPulsBlk+2)), nRandom);
  97.         *ptr1++ = temp & (Word16)0x0001;
  98.         temp    = shr(temp, 1);
  99.         *ptr1++ = add( (Word16) SubFrLen, (Word16) (temp & 0x0001) );
  100.         for(i=0; i<NbPulsBlk; i++) {
  101.             *ptr_TabSign++= shl(sub((temp & (Word16)0x0002), 1), 14);
  102.             temp = shr(temp, 1);
  103.         }
  104.     }
  105.     /* Positions */
  106.     ptr_TabPos  = TabPos;
  107.     for(i_subfr=0; i_subfr<SubFrames; i_subfr++) {
  108.         for(i=0; i<(SubFrLen/Sgrid); i++) tmp[i] = (Word16)i;
  109.         temp = (SubFrLen/Sgrid);
  110.         for(i=0; i<Nb_puls[i_subfr]; i++) {
  111.             j = random_number(temp, nRandom);
  112.             *ptr_TabPos++ = add(shl(tmp[(int)j],1), offset[i_subfr]);
  113.             temp = sub(temp, 1);
  114.             tmp[(int)j] = tmp[(int)temp];
  115.         }
  116.     }
  117.  /*
  118.   * Compute fixed codebook gains
  119.   */
  120.     ptr_TabPos = TabPos;
  121.     ptr_TabSign = TabSign;
  122.     curExc = DataExc;
  123.     i_subfr = 0;
  124.     for(iblk=0; iblk<SubFrames/2; iblk++) {
  125.         /* decode LTP only */
  126.         Decod_Acbk(curExc, &PrevExc[0], Line->Olp[iblk],
  127.                     Line->Sfs[i_subfr].AcLg, Line->Sfs[i_subfr].AcGn);
  128.         Decod_Acbk(&curExc[SubFrLen], &PrevExc[SubFrLen], Line->Olp[iblk],
  129.             Line->Sfs[i_subfr+1].AcLg, Line->Sfs[i_subfr+1].AcGn);
  130.         temp2 = 0;
  131.         for(i=0; i<SubFrLenD; i++) {
  132.             temp = abs_s(curExc[i]);
  133.             if(temp > temp2) temp2 = temp;
  134.         }
  135.         if(temp2 == 0) sh1 = 0;
  136.         else {
  137.             sh1 = sub(4,norm_s(temp2)); /* 4 bits of margin  */
  138.             if(sh1 < -2) sh1 = -2;
  139.         }
  140.         L_temp = 0L;
  141.         for(i=0; i<SubFrLenD; i++) {
  142.             temp  = shr(curExc[i], sh1); /* left if sh1 < 0 */
  143.             L_temp = L_mac(L_temp, temp, temp);
  144.             tempExc[i] = temp;
  145.         }  /* ener_ltp x 2**(-2sh1+1) */
  146.         L_acc = 0L;
  147.         for(i=0; i<NbPulsBlk; i++) {
  148.             L_acc = L_mac(L_acc, tempExc[(int)ptr_TabPos[i]], ptr_TabSign[i]);
  149.         }
  150.         inter_exc = extract_h(L_shl(L_acc, 1)); /* inter_exc x 2-sh1 */
  151.         /* compute SubFrLenD x curGain**2 x 2**(-2sh1+1)    */
  152.         /* curGain input = 2**5 curGain                     */
  153.         L_acc = L_mult(curGain, SubFrLen);
  154.         L_acc = L_shr(L_acc, 6);
  155.         temp  = extract_l(L_acc);   /* SubFrLen x curGain : avoids overflows */
  156.         L_acc = L_mult(temp, curGain);
  157.         temp = shl(sh1, 1);
  158.         temp = add(temp, 4);
  159.         L_acc = L_shr(L_acc, temp); /* SubFrLenD x curGain**2 x 2**(-2sh1+1) */
  160.         /* c = (ener_ltp - SubFrLenD x curGain**2)/nb_pulses_blk */
  161.         /* compute L_c = c >> 2sh1-1                                */
  162.         L_acc = L_sub(L_temp, L_acc);
  163.         /* x 1/nb_pulses_blk */
  164.         L_c  = L_mls(L_acc, InvNbPulsBlk);
  165. /*
  166.  * Solve EQ(X) = X**2 + 2 b0 X + c
  167.  */
  168.         /* delta = b0 x b0 - c */
  169.         b0 = mult_r(inter_exc, InvNbPulsBlk);   /* b0 >> sh1 */
  170.         L_acc = L_msu(L_c, b0, b0);             /* (c - b0**2) >> 2sh1-1 */
  171.         L_acc = L_negate(L_acc);                /* delta x 2**(-2sh1+1) */
  172.         /* Case delta <= 0 */
  173.         if(L_acc <= 0) {  /* delta <= 0 */
  174.             x1 = negate(b0);        /* sh1 */
  175.         }
  176.         /* Case delta > 0 */
  177.         else {
  178.             delta = Sqrt_lbc(L_acc);  /* >> sh1 */
  179.             x1 = sub(delta, b0);      /* x1 >> sh1 */
  180.             x2 = add(b0, delta);      /* (-x2) >> sh1 */
  181.             if(abs_s(x2) < abs_s(x1)) {
  182.                 x1 = negate(x2);
  183.             }
  184.         }
  185.         /* Update DataExc */
  186.         sh1 = add(sh1, 1);
  187.         temp = shl(x1, sh1);
  188.         if(temp > (2*Gexc_Max)) temp = (2*Gexc_Max);
  189.         if(temp < -(2*Gexc_Max)) temp = -(2*Gexc_Max);
  190.         for(i=0; i<NbPulsBlk; i++) {
  191.             j = *ptr_TabPos++;
  192.             curExc[(int)j] = add(curExc[(int)j], mult(temp,
  193.                                                 (*ptr_TabSign++)) );
  194.         }
  195.         /* update PrevExc */
  196.         ptr1 = PrevExc;
  197.         for(i=SubFrLenD; i<PitchMax; i++)   *ptr1++ = PrevExc[i];
  198.         for(i=0; i<SubFrLenD; i++)  *ptr1++ = curExc[i];
  199.         curExc += SubFrLenD;
  200.         i_subfr += 2;
  201.     } /* end of loop on LTP blocks */
  202.     return;
  203. }
  204. /*
  205. **
  206. ** Function:           random_number()
  207. **
  208. ** Description:        returns a number randomly taken in [0, n]
  209. **                     with np1 = n+1 at input
  210. **
  211. ** Links to text:
  212. **
  213. ** Arguments:
  214. **
  215. **  Word16 np1
  216. **  Word16 *nRandom    random generator status (input/output)
  217. **
  218. ** Outputs:
  219. **
  220. **  Word16 *nRandom
  221. **
  222. ** Return value:       random number in [0, (np1-1)]
  223. **
  224. */
  225. Word16 random_number(Word16 np1, Word16 *nRandom)
  226. {
  227.     Word16 temp;
  228.     temp = Rand_lbc(nRandom) & (Word16)0x7FFF;
  229.     temp = mult(temp, np1);
  230.     return(temp);
  231. }
  232. /*
  233. **
  234. ** Function:           Qua_SidGain()
  235. **
  236. ** Description:        Quantization of Sid gain
  237. **                     Pseudo-log quantizer in 3 segments
  238. **                     1st segment : length = 16, resolution = 2
  239. **                     2nd segment : length = 16, resolution = 4
  240. **                     3rd segment : length = 32, resolution = 8
  241. **                     quantizes a sum of energies
  242. **
  243. ** Links to text:
  244. **
  245. ** Arguments:
  246. **
  247. **  Word16 *Ener        table of the energies
  248. **  Word16 *shEner      corresponding scaling factors
  249. **  Word16 nq           if nq >= 1 : quantization of nq energies
  250. **                      for SID gain calculation in function Cod_Cng()
  251. **                      if nq = 0 : in function Comp_Info(),
  252. **                      quantization of saved estimated excitation energy
  253. **
  254. ** Outputs:             None
  255. **
  256. **
  257. ** Return value:       index of quantized energy
  258. **
  259. */
  260. Word16 Qua_SidGain(Word16 *Ener, Word16 *shEner, Word16 nq)
  261. {
  262.     Word16 temp, iseg, iseg_p1;
  263.     Word16 j, j2, k, exp;
  264.     Word32 L_x, L_y;
  265.     Word16 sh1;
  266.     Word32 L_acc;
  267.     int i;
  268.     if(nq == 0) {
  269.          /* Quantize energy saved for frame erasure case                */
  270.          /* L_x = 2 x average_ener                                      */
  271.          temp = shl(*shEner, 1);
  272.          temp = sub(16, temp);
  273.          L_acc = L_deposit_l(*Ener);
  274.          L_acc = L_shl(L_acc, temp); /* may overflow, and >> if temp < 0 */
  275.          L_x = L_mls(L_acc, fact[0]);
  276.     }
  277.     else {
  278.  /*
  279.   * Compute weighted average of energies
  280.   * Ener[i] = enerR[i] x 2**(shEner[i]-14)
  281.   * L_x = k[nq] x SUM(i=0->nq-1) enerR[i]
  282.   * with k[nq] =  2 x fact_mul x fact_mul / nq x Frame
  283.   */
  284.          sh1 = shEner[0];
  285.          for(i=1; i<nq; i++) {
  286.              if(shEner[i] < sh1) sh1 = shEner[i];
  287.          }
  288.          for(i=0, L_x=0L; i<nq; i++) {
  289.              temp = sub(shEner[i], sh1);
  290.              temp = shr(Ener[i], temp);
  291.              temp = mult_r(fact[nq], temp);
  292.              L_x = L_add(L_x, L_deposit_l(temp));
  293.          }
  294.          temp = sub(15, sh1);
  295.          L_x = L_shl(L_x, temp);
  296.     }
  297.     /* Quantize L_x */
  298.     if(L_x >= L_bseg[2]) return(63);
  299.     /* Compute segment number iseg */
  300.     if(L_x >= L_bseg[1]) {
  301.         iseg = 2;
  302.         exp = 4;
  303.     }
  304.     else {
  305.         exp  = 3;
  306.         if(L_x >= L_bseg[0]) iseg = 1;
  307.         else iseg = 0;
  308.     }
  309.     iseg_p1 = add(iseg,1);
  310.     j = shl(1, exp);
  311.     k = shr(j,1);
  312.     /* Binary search in segment iseg */
  313.     for(i=0; i<exp; i++) {
  314.         temp = add(base[iseg], shl(j, iseg_p1));
  315.         L_y = L_mult(temp, temp);
  316.         if(L_x >= L_y) j = add(j, k);
  317.         else j = sub(j, k);
  318.         k = shr(k, 1);
  319.     }
  320.     temp = add(base[iseg], shl(j, iseg_p1));
  321.     L_y = L_mult(temp, temp);
  322.     L_y = L_sub(L_y, L_x);
  323.     if(L_y <= 0L) {
  324.         j2    = add(j, 1);
  325.         temp  = add(base[iseg], shl(j2, iseg_p1));
  326.         L_acc = L_mult(temp, temp);
  327.         L_acc = L_sub(L_x, L_acc);
  328.         if(L_y > L_acc) temp = add(shl(iseg,4), j);
  329.         else temp = add(shl(iseg,4), j2);
  330.     }
  331.     else {
  332.         j2    = sub(j, 1);
  333.         temp  = add(base[iseg], shl(j2, iseg_p1));
  334.         L_acc = L_mult(temp, temp);
  335.         L_acc = L_sub(L_x, L_acc);
  336.         if(L_y < L_acc) temp = add(shl(iseg,4), j);
  337.         else temp = add(shl(iseg,4), j2);
  338.     }
  339.     return(temp);
  340. }
  341. /*
  342. **
  343. ** Function:           Dec_SidGain()
  344. **
  345. ** Description:        Decoding of quantized Sid gain
  346. **                     (corresponding to sqrt of average energy)
  347. **
  348. ** Links to text:
  349. **
  350. ** Arguments:
  351. **
  352. **  Word16 iGain        index of quantized Sid Gain
  353. **
  354. ** Outputs:             None
  355. **
  356. ** Return value:        decoded gain value << 5
  357. **
  358. */
  359. Word16 Dec_SidGain(Word16 iGain)
  360. {
  361.     Word16 i, iseg;
  362.     Word16 temp;
  363.     iseg = shr(iGain, 4);
  364.     if(iseg == 3) iseg = 2;
  365.     i = sub(iGain, shl(iseg, 4));
  366.     temp = add(iseg, 1);
  367.     temp = shl(i, temp);
  368.     temp = add(temp, base[iseg]);  /* SidGain */
  369.     temp = shl(temp, 5); /* << 5 */
  370.     return(temp);
  371. }