cgain.c
上传用户:tsjrly
上传日期:2021-02-19
资源大小:107k
文件大小:10k
源码类别:

语音压缩

开发平台:

C/C++

  1. /*************************************************************************
  2. *
  3. * ROUTINE
  4. * cgain
  5. *
  6. * FUNCTION
  7. * Find codeword gain and error (TERNARY CODE BOOK ASSUMED!)
  8. *
  9. * SYNOPSIS
  10. *               function cgain(ex, l, first, len, match)
  11. *
  12. *   formal
  13. *
  14. *                       data    I/O
  15. *       name            type    type    function
  16. *       -------------------------------------------------------------------
  17. *       ex[l] float i excitation vector (ternary codeword)
  18. *       l int i size of ex (dimension of codeword)
  19. *       first int i first call flag
  20. * len int i length to truncate impulse response
  21. *       match float o negative partial squared error
  22. *       cgain float fun optimal gain for ex
  23. *
  24. *   external
  25. *                       data    I/O
  26. *       name            type    type    function
  27. *       -------------------------------------------------------------------
  28. * e0[] float i
  29. * h[]; float i
  30. *
  31. **************************************************************************
  32. *
  33. * DESCRIPTION
  34. *
  35. * Find the gain and error for each code word:
  36. *    a.  Filter code words through impulse response
  37. *        of perceptual weighting filter (LPC filter with
  38. *        bandwidth broadening).
  39. *    b.  Correlate filtered result with actual second error
  40. *        signal (e0).
  41. *    c.  Compute MSPE gain and error for code book vector.
  42. *
  43. * Notes:  Code words may contain many zeros (i.e., ex(1)=0).  The
  44. *         code book could be accessed by a pointer to nonzero samples.
  45. * Because the code book is static, it`s silly to test its
  46. * samples as in the code below.
  47. *
  48. * Proper selection of the convolution length (len) depends on
  49. * the perceptual weighting filter's expansion factor (gamma)
  50. * which controls the damping of the inpulse response.
  51. *
  52. *         This is one of CELP's most computationally intensive
  53. *         routines.  Neglecting overhead, the approximate number of 
  54. * DSP instructions (add, multiply, multiply accumulate, or
  55. *         compare) per second (IPS) is:
  56. *
  57. *                Code book size   MIPS
  58. *                      --------------   ----
  59. *                  64              1.1
  60. *                 128              2.1
  61. *                 256              4.2
  62. *                 512              8.3
  63. *
  64. *          C:  convolution (recursive truncated end-point correction)
  65. *          R:  correlation
  66. *          E:  energy (recursive end-point correction)
  67. *  G:  gain quantization
  68. *
  69. *
  70. * celp code book search complexity (doesn't fully exploit ternary values!):
  71. *
  72. *#define j  10
  73. *
  74. * DSP chip instructions/operations:
  75. * int MUL=1; !multiply
  76. * int ADD=1; !add
  77. * int SUB=1; !subtract
  78. * int MAC=1; !multiply & accumulate
  79. * int MAD=2; !multiply & add
  80. * int CMP=1; !compare
  81. *
  82. * CELP algorithm parameters:
  83. * int L=60; !subframe length
  84. * int len=30; !length to truncate calculations (<= L)
  85. * int K=4; !number of subframes/frame
  86. * int shift=2; !shift between code words
  87. * int g_bits=5; !cbgain bit allocation
  88. * float p=0.77; !code book sparsity
  89. * float F=30.e-3; !time (seconds)/frame
  90. *
  91. * int N[j] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512};
  92. *
  93. * main()
  94. * {
  95. *   int i;
  96. *   float C, R, E, G, IPS;
  97. *   printf("n    N       C          R          E          G       MIPSn");
  98. *   for (i = 0; i < j; i++)
  99. *   {
  100. *     C = (335)*MAD + (N[i]-1)*shift*(1.0-p)*len*ADD;
  101. *     R = N[i]*L*MAC;
  102. *     E = L*MAC + (N[i]-1)*((1.0-p*p)*L*MAC + (p*p)*2*MAD);
  103. *     G = N[i]*(g_bits*(CMP+MUL+ADD) + 3*MUL+1*SUB);
  104. *     IPS = (C+R+E+G)*K/F;
  105. *     printf("  %4d  %f   %f   %f   %f  %fn", N[i], C*K/1.e6/F,
  106. *                     R*K/1.e6/F,E*K/1.e6/F,G*K/1.e6/F,IPS/1.e6);
  107. *   }
  108. * }
  109. *
  110. *     N       C          R          E          G       MIPS
  111. *     1  0.089333   0.008000   0.008000   0.002533  0.107867
  112. *     2  0.091173   0.016000   0.011573   0.005067  0.123813
  113. *     4  0.094853   0.032000   0.018719   0.010133  0.155706
  114. *     8  0.102213   0.064000   0.033011   0.020267  0.219491
  115. *    16  0.116933   0.128000   0.061595   0.040533  0.347062
  116. *    32  0.146373   0.256000   0.118763   0.081067  0.602203
  117. *    64  0.205253   0.512000   0.233100   0.162133  1.112486
  118. *   128  0.323013   1.024000   0.461773   0.324267  2.133053
  119. *   256  0.558533   2.048000   0.919118   0.648533  4.174185
  120. *   512  1.029573   4.096000   1.833810   1.297067  8.256450
  121. *
  122. **************************************************************************
  123. *
  124. * CALLED BY
  125. *
  126. * cbsearch
  127. *
  128. * CALLS
  129. *
  130. * gainencode2
  131. *
  132. ***************************************************************************
  133. *
  134. * REFERENCES
  135. *
  136. * Tremain, Thomas E., Joseph P. Campbell, Jr and Vanoy C. Welch,
  137. * "A 4.8 kbps Code Excited Linear Predictive Coder," Proceedings
  138. * of the Mobile Satellite Conference, 3-5 May 1988, pp. 491-496.
  139. *
  140. * Campbell, Joseph P. Jr., Vanoy C. Welch and Thomas E. Tremain,
  141. * "The New 4800 bps Voice Coding Standard," Military and 
  142. * Government Speech Tech, 1989, p. 64-70.
  143. *
  144. * Lin, Daniel, "New Approaches to Stochastic Coding of Speech
  145. * Sources at Very Low Bit Rates," Signal Processing III:  Theories
  146. * and Applications (Proceedings of EUSIPCO-86), 1986, p.445.
  147. *
  148. * Xydeas, C.S., M.A. Ireton and D.K. Baghbadrani, "Theory and
  149. * Real Time Implementation of a CELP Coder at 4.8 and 6.0 kbits/s
  150. * Using Ternary Code Excitation," Fifth International Conference on
  151. * Digital Processing of Signals in Communications, 1988, p. 167.
  152. *
  153. * Ess, Mike, "Simple Convolution on the Cray X-MP,"
  154. * Supercomputer, March 1988, p. 35
  155. *
  156. * Supercomputer, July 1988, p. 24
  157. *
  158. **************************************************************************/
  159. #include <math.h>
  160. #include "ccsub.h"
  161. extern float e0[MAXLP], h[MAXLP];
  162. float
  163. cgain(ex, l, first, len, match)
  164. int l, first, len;
  165. float ex[], *match;
  166. {
  167.   register float cor;
  168.   float cgain, gainencode2();
  169.   static float y[MAXL], y59save, y60save, eng;
  170.   int i, j;
  171.   if (first)
  172.   {
  173.     /**    For first code word, calculate and save convolution
  174.    of code word with truncated (to len) impulse response:
  175.    NOTES: A standard convolution of two L point sequences
  176.           produces 2L-1 points, however, this convolution
  177.           generates only the first L points.
  178.           A "scalar times vector accumulation" method is used
  179.           to exploit (skip) zero samples of the code words:
  180.           min(L-i, len-1)
  181.    y       =  SUM  ex * h   , where i = 0, ..., L-1 points
  182.     i+j, t    j=0    i   j
  183.                 ex |0 1 .  .  . L-1|
  184.    h |x x len-1...1 0|               = y[0]
  185.      h |x x len-1...1 0|             = y[1]
  186.                       :                 :
  187.                  h |x x len-1...1 0| = y[L-1]
  188.       ----------------------------------------------------- */
  189.     for (i = 0; i < l; i++) 
  190.       y[i] = 0.0;
  191.     for (i = 0; i < l; i++)
  192.     {
  193.       if (nint(ex[i]) != 0.0)
  194.         for(j = 0; j < l-i && j < len; j++)
  195.           y[i+j] += ex[i]*h[j];
  196.     }
  197.   }
  198.   else
  199.   {
  200.     /**     End correct the convolution sum on subsequent code words:
  201.             (Do two end corrections for a shift by 2 code book)
  202.           y     =  0
  203.             0, 0
  204.            y     =  y        + ex * h   where i = 0, ..., L-1 points
  205.             i, m     i-1, m-1   -m   i  and   m = 0, ..., cbsize-1 code words
  206.    NOTE:  The data movements in the 2 loops with "y[i] = y[i - 1]"
  207.           are performed many times and can be quite time consuming.
  208.           Therefore, special precautions should be taken when
  209.           implementing this.  Some implementation suggestions:
  210.           1.  Circular buffers with pointers to eliminate data moves.
  211.           2.  Fast "block move" operation as offered on some DSPs.
  212.               -----------------------------------------------------      */
  213.     /* *First shift  */
  214.     if (nint(ex[1]) != 0)
  215.     {
  216.     /* *ternary stochastic code book (-1, 0, +1)  */
  217.       if (nint(ex[1]) == 1)
  218.         for (i = len - 1; i > 0; i--)
  219.   y[i - 1] += h[i];
  220.       else
  221.         for (i = len - 1; i > 0; i--)
  222.   y[i - 1] -= h[i];
  223.     }
  224.     for (i = l - 1; i > 0; i--)
  225.       y[i] =  y[i - 1];
  226.     y[0] = ex[1] * h[0];
  227.     /* *Second shift  */
  228.     if (nint(ex[0]) != 0)
  229.     {
  230.     /* *ternary stochastic code book (-1, 0, +1)  */
  231.       if (nint(ex[0]) == 1)
  232.         for (i = len - 1; i > 0; i--)
  233.   y[i - 1] += h[i];
  234.       else
  235.         for (i = len - 1; i > 0; i--) 
  236.           y[i - 1] -= h[i];
  237.     }
  238.               
  239.     for (i = l - 1; i > 0; i--)
  240.       y[i] = y[i - 1];
  241.     y[0] = ex[0] * h[0];
  242.   }
  243.   /** Calculate correlation and energy:
  244. e0 = spectrum & pitch prediction residual
  245. y  = error weighting filtered code words
  246. ///  CELP's computations are focused in this correlation ///
  247. - For a 512 code book this correlation takes 4 MIPS!
  248. - Decimation?, Down-sample & decimate?, FEC codes? */
  249.   cor = 0.0;
  250.   for (i = 0; i < l; i++)
  251.   {
  252.     cor += y[i] * e0[i];
  253.   }
  254.   /* *End correct energy on subsequent code words:  */
  255.   if (nint(ex[0]) == 0 && nint(ex[1]) == 0 && !first)
  256.     eng = eng - y59save * y59save - y60save * y60save;
  257.   else
  258.   {
  259.     eng = 0.0;
  260.     for (i = 0; i < l; i++)
  261.       eng += y[i] * y[i];
  262.   }
  263.   y59save = y[l - 2];
  264.   y60save = y[l - 1];
  265.   /* Compute gain and error:
  266.   NOTE: Actual MSPE = e0.e0 - cgain(2*cor-cgain*eng)
  267. since e0.e0 is independent of the code word,
  268. minimizing MSPE is equivalent to maximizing:
  269.      *match = cgain(2*cor-cgain*eng)
  270. If unquantized cgain is used, this simplifies:
  271.      *match = cor*cgain  */
  272.   /* Independent (open-loop) quantization of gain and match (index):  */
  273.   if (eng <= 0.0) eng = 1.0;
  274.   cgain = cor / eng;
  275.   *match = cor * cgain;
  276.   /* *Joint (closed-loop) quantization of gain and match (index):  */
  277.   /* *(Beware that the match score can be negative!)  */
  278.   /*  cgain = gainencode2(cor, eng, &i);  */
  279.   /*  *match = cgain * (2.0 * cor - cgain * eng);  */
  280.   return (cgain);
  281. }