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

语音压缩

开发平台:

C/C++

  1. /**************************************************************************
  2. *
  3. * ROUTINE
  4. * pgain
  5. *
  6. * FUNCTION
  7. * Find pitch gain and error
  8. *
  9. * SYNOPSIS
  10. *               function pgain(ex, l, first, m, len, match)
  11. *
  12. *   formal
  13. *
  14. *                       data    I/O
  15. *       name            type    type    function
  16. *       -------------------------------------------------------------------
  17. *       ex[l] float i excitation vector
  18. *       l int i size of ex
  19. *       first int i first call flag
  20. * m int i pitch lag
  21. * len int i length to truncate impulse response
  22. *       match float o negative partial squared error
  23. *       pgain float fun optimal gain for ex
  24. *
  25. *   external
  26. *                       data    I/O
  27. *       name            type    type    function
  28. *       -------------------------------------------------------------------
  29. * e0[] float i
  30. * h[] float i
  31. *
  32. ***************************************************************************
  33. *
  34. * DESCRIPTION
  35. *
  36. * For each lag:
  37. *    a.  Filter first error signal (v0) through truncated
  38. *        impulse response of perceptual weighting filter
  39. *        (LPC filter with bandwidth broadening).
  40. *    b.  Correlate filtered result with actual first error
  41. *        signal (e0).
  42. *    c.  Compute first order pitch filter coefficient (pgain)
  43. *        and error (er) for each lag.
  44. *
  45. * Note:  Proper selection of the convolution length (len) depends on
  46. *        the perceptual weighting filter's expansion factor (gamma)
  47. *        which controls the damping of the impulse response.
  48. *
  49. *         This is one of CELP's most computationally intensive
  50. *         routines.  Neglecting overhead, the approximate number of
  51. * DSP instructions (add, multiply, multiply accumulate, or
  52. * compare) per second (IPS) is:
  53. *
  54. *
  55. *         C      : convolution (recursive truncated end-point correction)
  56. *               C'     : convolution (recursive truncated end-point correction)
  57. *               R  = E : full correlation & energy
  58. *               R' = E': delta correlation & energy
  59. *               G      : gain quantization
  60. *               G'     : delat gain quantization
  61. *
  62. *         IPS = 2.34 M (for integer delays)
  63. *
  64. *         i.e.,  L = 60, N = 128 pitch lags, N'= 32 delta delays
  65. *                K = K'= 2 pitch updates/frame, and F=30 ms frame rate:
  66. *
  67. *                C = 9450, C'= 3690, R = E = 7680, R'= E'= 1920
  68. *
  69. *                IPS = 2.2 M
  70. *
  71. * pitch search complexity for integer delays:
  72. *
  73. *#define j  10
  74. *
  75. * DSP chip instructions/operations:
  76. * int MUL=1; !multiply
  77. * int ADD=1; !add
  78. * int SUB=1; !subtract
  79. * int MAC=1; !multiply & accumulate
  80. * int MAD=2; !multiply & add
  81. * int CMP=1; !compare
  82. *
  83. * CELP algorithm parameters:
  84. * int L=60; !subframe length
  85. * int len=30; !length to truncate calculations (<= L)
  86. * int K=4; !number of subframes/frame
  87. * int shift=2; !shift between code words
  88. * int g_bits=5; !cbgain bit allocation
  89. * float p=0.77; !code book sparsity
  90. * float F=30.e-3; !time (seconds)/frame
  91. *
  92. * int N[j] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512};
  93. *
  94. * main()
  95. * {
  96. *   int i;
  97. *   float C, R, E, G, IPS;
  98. *   printf("n    N       C          R          E          G       MIPSn");
  99. *   for (i = 0; i < j; i++)
  100. *   {
  101. *     C = (335)*MAD + (N[i]-1)*shift*(1.0-p)*len*ADD;
  102. *     R = N[i]*L*MAC;
  103. *     E = L*MAC + (N[i]-1)*((1.0-p*p)*L*MAC + (p*p)*2*MAD);
  104. *     G = N[i]*(g_bits*(CMP+MUL+ADD) + 3*MUL+1*SUB);
  105. *     IPS = (C+R+E+G)*K/F;
  106. *     printf("  %4d  %f   %f   %f   %f  %fn", N[i], C*K/1.e6/F,
  107. *                     R*K/1.e6/F,E*K/1.e6/F,G*K/1.e6/F,IPS/1.e6);
  108. *   }
  109. * }
  110. *
  111. *     N       C          R          E          G       MIPS
  112. *     1  0.089333   0.008000   0.008000   0.002533  0.107867
  113. *     2  0.091173   0.016000   0.011573   0.005067  0.123813
  114. *     4  0.094853   0.032000   0.018719   0.010133  0.155706
  115. *     8  0.102213   0.064000   0.033011   0.020267  0.219491
  116. *    16  0.116933   0.128000   0.061595   0.040533  0.347062
  117. *    32  0.146373   0.256000   0.118763   0.081067  0.602203
  118. *    64  0.205253   0.512000   0.233100   0.162133  1.112486
  119. *   128  0.323013   1.024000   0.461773   0.324267  2.133053
  120. *   256  0.558533   2.048000   0.919118   0.648533  4.174185
  121. *   512  1.029573   4.096000   1.833810   1.297067  8.256450
  122. *
  123. *
  124. ***************************************************************************
  125. *
  126. * CALLED BY
  127. *
  128. * psearch
  129. *
  130. * CALLS
  131. *
  132. *
  133. *
  134. ***************************************************************************
  135. *
  136. * REFERENCES
  137. *
  138. * Tremain, Thomas E., Joseph P. Campbell, Jr and Vanoy C. Welch,
  139. * "A 4.8 kbps Code Excited Linear Predictive Coder," Proceedings
  140. * of the Mobile Satellite Conference, 3-5 May 1988, pp. 491-496.
  141. *
  142. * Campbell, Joseph P. Jr., Vanoy C. Welch and Thomas E. Tremain,
  143. * "An Expandable Error-Protected 4800 bps CELP Coder (U.S. Federal
  144. * Standard 4800 bps Voice Coder)," Proceedings of ICASSP, 1989.
  145. * (and Proceedings of Speech Tech, 1989.)
  146. *
  147. **************************************************************************/
  148. #include "ccsub.h"
  149. extern float e0[MAXLP], h[MAXLP];
  150. float 
  151. pgain(ex, l, first, m, len, match)
  152. int l, first, m, len;
  153. float ex[], *match;
  154. {
  155.   register float cor, eng;
  156.   float y2[MAXLP], pgain;
  157.   static float y[MAXLP];
  158.   int i, j;
  159.   if (first)
  160.   {
  161.   /* *Calculate and save convolution of truncated (to len)
  162.      *impulse response for first lag of t (=mmin) samples:
  163.   
  164.         min(i, len-1)
  165.    y     =  SUM  h * ex       , where i = 0, ..., L-1 points
  166.     i, t    j=0   j    i-j
  167.                   h |0 1...len-1 x x|
  168.    ex |L-1  . . .  1 0|               = y[0]
  169.      ex |L-1  . . .  1 0|             = y[1]
  170.                        :                :
  171.                  ex |L-1  . . .  1 0| = y[L-1]
  172.         */
  173.     for (i = 0; i < l; i++)
  174.     {
  175.       y[i] = 0.0;
  176.       for (j = 0; j <= i && j < len; j++)
  177. y[i] += h[j] * ex[i - j];
  178.     }
  179.   }
  180.   else
  181.   {
  182.   /* *End correct the convolution sum on subsequent pitch lags:
  183.       y     =  0
  184.        0, t
  185.       y     =  y        + ex  * h   where i = 1, ..., L points
  186.        i, m     i-1, m-1   -m    i  and   m = t+1, ..., tmax lags
  187.         */
  188.     for (i = len - 1; i > 0; i--)
  189.       y[i - 1] += ex[0] * h[i]; 
  190.     for (i = l - 1; i > 0; i--)
  191.       y[i] = y[i - 1];
  192.     y[0] = ex[0] * h[0];
  193.   }
  194.   /* *For lags (m) shorter than frame size (l), replicate the short
  195.      *adaptive codeword to the full codeword length by
  196.      *overlapping and adding the convolutions:    */
  197.   for (i = 0; i < l; i++)
  198.     y2[i] = y[i];
  199.   if (m < l)
  200.   {
  201.   /* add in 2nd convolution    */
  202.     for (i = m; i < l; i++)
  203.       y2[i] = y[i] + y[i - m];
  204.     if (m < l / 2)
  205.     {
  206.     /* add in 3rd convolution    */
  207.       for (i = 2 * m; i < l; i++)
  208. y2[i] = y2[i] + y[i - 2 * m];
  209.     }
  210.   }
  211.   /* *Calculate correlation and energy:
  212.       e0 = r[n]   = spectrum prediction residual
  213.       y2 = r[n-m] = error weighting filtered reconstructed
  214.                pitch prediction signal (m = correlation lag)  */
  215.   cor = 0.0;
  216.   eng = 0.0;
  217.   for (i = 0; i < l; i++)
  218.   {
  219.     cor += y2[i] * e0[i];
  220.     eng += y2[i] * y2[i];
  221.   }
  222.   /* *Compute gain and error:
  223.       NOTE: Actual MSPE = e0.e0 - pgain(2*cor-pgain*eng)
  224.             since e0.e0 is independent of the code word,
  225.     minimizing MSPE is equivalent to maximizing:
  226.          match = pgain(2*cor-pgain*eng)   (1)
  227.     If unquantized pgain is used, this simplifies:
  228.          match = cor*pgain
  229.       NOTE: Inferior results were obtained when quantized
  230.     pgain was used in equation (1)???
  231.       NOTE: When the delay is less than the frame length, "match"
  232.     is only an approximation to the actual error.
  233.       Independent (open-loop) quantization of gain and match (index):  */
  234.   if (eng <= 0.0) 
  235.     eng = 1.0;
  236.   pgain = cor / eng;
  237.   *match = cor * pgain;
  238.   return (pgain);
  239. }