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

语音压缩

开发平台:

C/C++

  1. /*
  2. **
  3. ** File:            "cod_cng.c"
  4. **
  5. ** Description:     Comfort noise generation
  6. **                  performed at the encoder part
  7. **
  8. ** Functions:       Init_Cod_Cng()
  9. **                  Cod_Cng()
  10. **                  Update_Cng()
  11. **
  12. ** Local functions:
  13. **                  ComputePastAvFilter()
  14. **                  CalcRC()
  15. **                  LpcDiff()
  16. **
  17. **
  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 "basop.h"
  31. #include "lsp.h"
  32. #include "lpc.h"
  33. #include "util_cng.h"
  34. #include "cod_cng.h"
  35. #include "vad.h"
  36. #include "coder.h"
  37. /* Declaration of local functions */
  38. static void ComputePastAvFilter(Word16 *Coeff);
  39. static void CalcRC(Word16 *Coeff, Word16 *RC, Word16 *shRC);
  40. static Flag LpcDiff(Word16 *RC, Word16 shRC, Word16 *Acf, Word16 alpha);
  41. /* Global Variables */
  42. CODCNGDEF CodCng;
  43. /*
  44. **
  45. ** Function:        Init_Cod_Cng()
  46. **
  47. ** Description:     Initialize Cod_Cng static variables
  48. **
  49. ** Links to text:
  50. **
  51. ** Arguments:       None
  52. **
  53. ** Outputs:         None
  54. **
  55. ** Return value:    None
  56. **
  57. */
  58. void Init_Cod_Cng(void)
  59. {
  60.     int i;
  61.     CodCng.CurGain = 0;
  62.     for(i=0; i< SizAcf; i++) CodCng.Acf[i] = 0;
  63.     for(i=0; i <= NbAvAcf; i++) CodCng.ShAcf[i] = 40;
  64.     for(i=0; i < LpcOrder; i++) CodCng.SidLpc[i] = 0;
  65.     CodCng.PastFtyp = 1;
  66.     CodCng.RandSeed = 12345;
  67.     return;
  68. }
  69. /*
  70. **
  71. ** Function:           Cod_Cng()
  72. **
  73. ** Description:        Computes Ftyp for inactive frames
  74. **                              0  :  for untransmitted frames
  75. **                              2  :  for SID frames
  76. **                     Computes current frame excitation
  77. **                     Computes current frame LSPs
  78. **                     Computes the coded parameters of SID frames
  79. **
  80. ** Links to text:
  81. **
  82. ** Arguments:
  83. **
  84. **  Word16 *DataExc    Current frame synthetic excitation
  85. **  Word16 *Ftyp     Characterizes the frame type for CNG
  86. **  LINEDEF *Line      Quantized parameters (used for SID frames)
  87. **  Word16 *QntLpc     Interpolated frame LPC coefficients
  88. **
  89. ** Outputs:
  90. **
  91. **  Word16 *DataExc
  92. **  Word16 *Ftyp
  93. **  LINEDEF *Line
  94. **  Word16 *QntLpc
  95. **
  96. ** Return value:       None
  97. **
  98. */
  99. void Cod_Cng(Word16 *DataExc, Word16 *Ftyp, LINEDEF *Line, Word16 *QntLpc)
  100. {
  101.     Word16 curCoeff[LpcOrder];
  102.     Word16 curQGain;
  103.     Word16 temp;
  104.     int i;
  105.  /*
  106.   * Update Ener
  107.   */
  108.     for(i=NbAvGain-1; i>=1; i--) {
  109.         CodCng.Ener[i] = CodCng.Ener[i-1];
  110.     }
  111.  /*
  112.   * Compute LPC filter of present frame
  113.   */
  114.     CodCng.Ener[0] = Durbin(curCoeff, &CodCng.Acf[1], CodCng.Acf[0], &temp);
  115.  /*
  116.   * if first frame of silence => SID frame
  117.   */
  118.     if(CodCng.PastFtyp == 1) {
  119.         *Ftyp = 2;
  120.         CodCng.NbEner = 1;
  121.         curQGain = Qua_SidGain(CodCng.Ener, CodCng.ShAcf, CodCng.NbEner);
  122.     }
  123.     else {
  124.         CodCng.NbEner++;
  125.         if(CodCng.NbEner > NbAvGain) CodCng.NbEner = NbAvGain;
  126.         curQGain = Qua_SidGain(CodCng.Ener, CodCng.ShAcf, CodCng.NbEner);
  127.  /*
  128.   * Compute stationarity of current filter
  129.   * versus reference filter
  130.   */
  131.         if(LpcDiff(CodCng.RC, CodCng.ShRC, CodCng.Acf, *CodCng.Ener) == 0) {
  132.             /* transmit SID frame */
  133.             *Ftyp = 2;
  134.         }
  135.         else {
  136.             temp = abs_s(sub(curQGain, CodCng.IRef));
  137.             if(temp > ThreshGain) {
  138.                 *Ftyp = 2;
  139.             }
  140.             else {
  141.                 /* no transmission */
  142.                 *Ftyp = 0;
  143.             }
  144.         }
  145.     }
  146.  /*
  147.   * If SID frame : Compute SID filter
  148.   */
  149.     if(*Ftyp == 2) {
  150.  /*
  151.   * Evaluates local stationnarity :
  152.   * Computes difference between current filter and past average filter
  153.   * if signal not locally stationary SID filter = current filter
  154.   * else SID filter = past average filter
  155.   */
  156.         /* Compute past average filter */
  157.         ComputePastAvFilter(CodCng.SidLpc) ;
  158.         /* If adaptation enabled, fill noise filter */
  159.         if ( !VadStat.Aen ) {
  160.             for(i=0; i<LpcOrder; i++) VadStat.NLpc[i] = CodCng.SidLpc[i];
  161.         }
  162.         /* Compute autocorr. of past average filter coefficients */
  163.         CalcRC(CodCng.SidLpc , CodCng.RC, &CodCng.ShRC);
  164.         if(LpcDiff(CodCng.RC, CodCng.ShRC, CodCng.Acf, *CodCng.Ener) == 0){
  165.             for(i=0; i<LpcOrder; i++) {
  166.                 CodCng.SidLpc[i] = curCoeff[i];
  167.             }
  168.             CalcRC(curCoeff, CodCng.RC, &CodCng.ShRC);
  169.         }
  170.  /*
  171.   * Compute SID frame codes
  172.   */
  173.         /* Compute LspSid */
  174.         AtoLsp(CodCng.LspSid, CodCng.SidLpc, CodStat.PrevLsp);
  175.         Line->LspId = Lsp_Qnt(CodCng.LspSid, CodStat.PrevLsp);
  176.         Lsp_Inq(CodCng.LspSid, CodStat.PrevLsp, Line->LspId, 0);
  177.         Line->Sfs[0].Mamp = curQGain;
  178.         CodCng.IRef = curQGain;
  179.         CodCng.SidGain = Dec_SidGain(CodCng.IRef);
  180.     } /* end of Ftyp=2 case (SID frame) */
  181.  /*
  182.   * Compute new excitation
  183.   */
  184.     if(CodCng.PastFtyp == 1) {
  185.         CodCng.CurGain = CodCng.SidGain;
  186.     }
  187.     else {
  188.           CodCng.CurGain = extract_h(L_add( L_mult(CodCng.CurGain,0x7000),
  189.                     L_mult(CodCng.SidGain,0x1000) ) ) ;
  190.     }
  191.     Calc_Exc_Rand(CodCng.CurGain, CodStat.PrevExc, DataExc,
  192.                                                 &CodCng.RandSeed, Line);
  193.  /*
  194.   * Interpolate LSPs and update PrevLsp
  195.   */
  196.     Lsp_Int(QntLpc, CodCng.LspSid, CodStat.PrevLsp);
  197.     for (i=0; i < LpcOrder ; i++) {
  198.         CodStat.PrevLsp[i] = CodCng.LspSid[i];
  199.     }
  200.  /*
  201.   * Output & save frame type info
  202.   */
  203.     CodCng.PastFtyp = *Ftyp;
  204.     return;
  205. }
  206. /*
  207. **
  208. ** Function:           Update_Acf()
  209. **
  210. ** Description:        Computes & Stores sums of subframe-acfs
  211. **
  212. ** Links to text:
  213. **
  214. ** Arguments:
  215. **
  216. **  Word16 *Acf_sf     sets of subframes Acfs of current frame
  217. **  Word16 *ShAcf_sf   corresponding scaling factors
  218. **
  219. ** Output :            None
  220. **
  221. ** Return value:       None
  222. **
  223. */
  224. void Update_Acf(Word16 *Acf_sf, Word16 *ShAcf_sf)
  225. {
  226.     int i, i_subfr;
  227.     Word16 *ptr1, *ptr2;
  228.     Word32 L_temp[LpcOrderP1];
  229.     Word16 sh1, temp;
  230.     Word32 L_acc0;
  231.     /* Update Acf and ShAcf */
  232.     ptr2 = CodCng.Acf + SizAcf;
  233.     ptr1 = ptr2 - LpcOrderP1;
  234.     for(i=LpcOrderP1; i<SizAcf; i++) *(--ptr2) = *(--ptr1);
  235.     for(i=NbAvAcf; i>=1; i--) CodCng.ShAcf[i] = CodCng.ShAcf[i-1];
  236.     /* Search ShAcf_sf min for current frame */
  237.     sh1 = ShAcf_sf[0];
  238.     for(i_subfr=1; i_subfr<SubFrames; i_subfr++) {
  239.         if(ShAcf_sf[i_subfr] < sh1) sh1 = ShAcf_sf[i_subfr];
  240.     }
  241.     sh1 = add(sh1, 14);  /* 2 bits of margin */
  242.     /* Compute current sum of acfs */
  243.     for(i=0; i<= LpcOrder; i++) L_temp[i] = 0;
  244.     ptr2 = Acf_sf;
  245.     for(i_subfr=0; i_subfr<SubFrames; i_subfr++) {
  246.         temp = sub(sh1, ShAcf_sf[i_subfr]);
  247.         for(i=0; i <= LpcOrder; i++) {
  248.             L_acc0 = L_deposit_l(*ptr2++);
  249.             L_acc0 = L_shl(L_acc0, temp);  /* shift right if temp<0 */
  250.             L_temp[i] = L_add(L_temp[i], L_acc0);
  251.         }
  252.     }
  253.     /* Normalize */
  254.     temp = norm_l(L_temp[0]);
  255.     temp = sub(16, temp);
  256.     if(temp < 0) temp = 0;
  257.     for(i=0; i <= LpcOrder; i++) {
  258.         CodCng.Acf[i] = extract_l(L_shr(L_temp[i],temp));
  259.     }
  260.     CodCng.ShAcf[0] = sub(sh1, temp);
  261.     return;
  262. }
  263. /*
  264. **
  265. ** Function:           ComputePastAvFilter()
  266. **
  267. ** Description:        Computes past average filter
  268. **
  269. ** Links to text:
  270. **
  271. ** Argument:
  272. **
  273. **  Word16 *Coeff      set of LPC coefficients
  274. **
  275. ** Output:
  276. **
  277. **  Word16 *Coeff
  278. **
  279. ** Return value:       None
  280. **
  281. */
  282. void ComputePastAvFilter(Word16 *Coeff)
  283. {
  284.     int i, j;
  285.     Word16 *ptr_Acf;
  286.     Word32 L_sumAcf[LpcOrderP1];
  287.     Word16 Corr[LpcOrder], Err;
  288.     Word16 sh1, temp;
  289.     Word32 L_acc0;
  290.     /* Search ShAcf min */
  291.     sh1 = CodCng.ShAcf[1];
  292.     for(i=2; i <= NbAvAcf; i ++) {
  293.         temp = CodCng.ShAcf[i];
  294.         if(temp < sh1) sh1 = temp;
  295.     }
  296.     sh1 = add(sh1, 14);     /* 2 bits of margin : NbAvAcf <= 4 */
  297.     /* Compute sum of NbAvAcf frame-Acfs  */
  298.     for(j=0; j <= LpcOrder; j++) L_sumAcf[j] = 0;
  299.     ptr_Acf = CodCng.Acf + LpcOrderP1;
  300.     for(i=1; i <= NbAvAcf; i ++) {
  301.         temp = sub(sh1, CodCng.ShAcf[i]);
  302.         for(j=0; j <= LpcOrder; j++) {
  303.             L_acc0 = L_deposit_l(*ptr_Acf++);
  304.             L_acc0 = L_shl(L_acc0, temp); /* shift right if temp<0 */
  305.             L_sumAcf[j] = L_add(L_sumAcf[j], L_acc0);
  306.         }
  307.     }
  308.     /* Normalize */
  309.     temp = norm_l(L_sumAcf[0]);
  310.     temp = sub(16, temp);
  311.     if(temp < 0) temp = 0;
  312.     Err = extract_l(L_shr(L_sumAcf[0],temp));
  313.     for(i=1; i<LpcOrderP1; i++) {
  314.         Corr[i-1] = extract_l(L_shr(L_sumAcf[i],temp));
  315.     }
  316.     Durbin(Coeff, Corr, Err, &temp);
  317.     return;
  318. }
  319. /*
  320. **
  321. ** Function:           CalcRC()
  322. **
  323. ** Description:        Computes function derived from
  324. **                     the autocorrelation of LPC coefficients
  325. **                     used for Itakura distance
  326. **
  327. ** Links to text:
  328. **
  329. ** Arguments :
  330. **
  331. **  Word16 *Coeff      set of LPC coefficients
  332. **  Word16 *RC         derived from LPC coefficients autocorrelation
  333. **  Word16 *ShRC       corresponding scaling factor
  334. **
  335. ** Outputs :
  336. **
  337. **  Word16 *RC
  338. **  Word16 *ShRC
  339. **
  340. ** Return value:       None
  341. **
  342. */
  343. void CalcRC(Word16 *Coeff, Word16 *RC, Word16 *ShRC)
  344. {
  345.     int i, j;
  346.     Word16 sh1;
  347.     Word32 L_acc;
  348.     L_acc = 0L;
  349.     for(j=0; j<LpcOrder; j++) {
  350.         L_acc = L_mac(L_acc, Coeff[j], Coeff[j]);
  351.     }
  352.     L_acc = L_shr(L_acc, 1);
  353.     L_acc = L_add(L_acc, 0x04000000L);  /* 1 << 2 * Lpc_justif. */
  354.     sh1 = norm_l(L_acc) - (Word16)2;    /* 1 bit because of x2 in RC[i], i> 0*/
  355.                                 /* & 1 bit margin for Itakura distance */
  356.     L_acc = L_shl(L_acc, sh1); /* shift right if < 0 */
  357.     RC[0] = round(L_acc);
  358.     for(i=1; i<=LpcOrder; i++) {
  359.         L_acc = L_mult( (Word16) 0xE000, Coeff[i-1]);   /* - (1 << Lpc_justif.) */
  360.         for(j=0; j<LpcOrder-i; j++) {
  361.             L_acc = L_mac(L_acc, Coeff[j], Coeff[j+i]);
  362.         }
  363.         L_acc = L_shl(L_acc, sh1);
  364.         RC[i] = round(L_acc);
  365.     }
  366.     *ShRC = sh1;
  367.     return;
  368. }
  369. /*
  370. **
  371. ** Function:           LpcDiff()
  372. **
  373. ** Description:        Comparison of two filters
  374. **                     using Itakura distance
  375. **                     1st filter : defined by *ptrAcf
  376. **                     2nd filter : defined by *RC
  377. **                     the autocorrelation of LPC coefficients
  378. **                     used for Itakura distance
  379. **
  380. ** Links to text:
  381. **
  382. ** Arguments :
  383. **
  384. **  Word16 *RC         derived from LPC coefficients autocorrelation
  385. **  Word16 ShRC        corresponding scaling factor
  386. **  Word16 *ptrAcf     pointer on signal autocorrelation function
  387. **  Word16 alpha       residual energy in LPC analysis using *ptrAcf
  388. **
  389. ** Output:             None
  390. **
  391. ** Return value:       flag = 1 if similar filters
  392. **                     flag = 0 if different filters
  393. **
  394. */
  395. Flag LpcDiff(Word16 *RC, Word16 ShRC, Word16 *ptrAcf, Word16 alpha)
  396. {
  397.     Word32 L_temp0, L_temp1;
  398.     Word16 temp;
  399.     int i;
  400.     Flag diff;
  401.     L_temp0 = 0L;
  402.     for(i=0; i<=LpcOrder; i++) {
  403.         temp = shr(ptrAcf[i], 2);  /* + 2 margin bits */
  404.         L_temp0 = L_mac(L_temp0, RC[i], temp);
  405.     }
  406.     temp = mult_r(alpha, FracThresh);
  407.     L_temp1 = L_add((Word32)temp, (Word32)alpha);
  408.     temp = add(ShRC, 9);  /* 9 = Lpc_justif. * 2 - 15 - 2 */
  409.     L_temp1 = L_shl(L_temp1, temp);
  410.     if(L_temp0 < L_temp1) diff = 1;
  411.     else diff = 0;
  412.     return(diff);
  413. }