codebook.c
上传用户:touchwatch
上传日期:2007-01-06
资源大小:168k
文件大小:5k
源码类别:

语音压缩

开发平台:

Unix_Linux

  1. /*************************************************************************/
  2. /*                                                                       */
  3. /*                            LD-CELP  G.728                             */
  4. /*                                                                       */
  5. /*    Low-Delay Code Excitation Linear Prediction speech compression.    */
  6. /*                                                                       */
  7. /*    Code edited by Michael Concannon.                                  */
  8. /*    Based on code written by Alex Zatsman, Analog Devices 1993         */
  9. /*                                                                       */
  10. /*************************************************************************/
  11. #include "common.h"
  12. #include "prototyp.h"
  13. #include "fast.h"
  14. #include "data.h"
  15. /* Impulse Response Vector Calculator */
  16. void iresp_vcalc(real COEFF_MEM sf_co[], 
  17.   real COEFF_MEM pwf_z_co[], real COEFF_MEM pwf_p_co[], 
  18.   real h[])
  19. {
  20.     static real temp[IDIM];
  21.     static real rc[IDIM];
  22.     real a0,a1,a2;
  23.     int i,k;
  24.     temp[0] = rc[0] = 1.0;
  25.     for (k=1; k<IDIM; k++) {
  26.     a0=a1=a2=0.0;
  27.     for (i=k; i>=1; i--) {
  28.     temp[i] = temp[i-1];
  29.     rc[i] = rc[i-1];
  30.     a0 -= sf_co[i]   * temp[i];
  31.     a1 += pwf_z_co[i] * temp[i];
  32.     a2 -= pwf_p_co[i] * rc[i];
  33.    }
  34.     temp[0] = a0;
  35.     rc[0] = a0+a1+a2;
  36.     }
  37.     for (k=0; k<IDIM; k++)
  38. h[k] = rc[IDIM-1-k];
  39. }
  40. /* Cb_shape Codevector Convolution Module and Energy Table Calculator */
  41. /* The output is energy table */
  42. #ifdef PIPELINE
  43. void
  44. shape_conv(real h[], real shen[])
  45. {
  46.     int j;
  47.     real *shep = shen;
  48.     real CBMEM *cp = (real CBMEM *) cb_shape;
  49.     real *hp = h;
  50.     real
  51. lmul1, lmul2, rmul1, rmul2, ladd1, ladd2, ladd3, radd1, radd2;
  52. #define e0  ladd1
  53. #define x0  ladd2
  54. #define x2  ladd2
  55. #define x4  ladd2
  56. #define x1  ladd3
  57. #define x3  ladd3
  58. #define e1  radd1
  59. #define e2  radd1
  60. #define e3  radd1
  61. #define e4  radd1
  62. #define t01 radd1
  63. #define t11 radd1
  64. #define t12 radd1
  65. #define t22 radd1
  66. #define t40 radd1
  67. #define t20 radd2
  68. #define t21 radd2
  69. #define t03 radd2
  70. #define t13 radd2
  71. #define t31 radd2
  72. #define c0 lmul1
  73. #define c2 lmul1
  74. #define c4 lmul1
  75. #define c1 lmul2
  76. #define c3 lmul2
  77. #define h0 rmul1
  78. #define h2 rmul1
  79. #define h4 rmul1
  80. #define h1 rmul2
  81. #define h3 rmul2
  82.     for (j=0; j<NCWD; j++) {
  83. c0=*cp++; h0=*hp++;
  84. x0 =c0*h0;
  85. e0 =x0*x0; c1=*cp--;
  86. x1 =c1*h0; c0=*cp++; h1=*hp++;
  87. t01=c0*h1;   h2=*hp--;
  88. x1+=t01; x2 =c0*h2;
  89. e1 =x1*x1; c1=*cp++; h1=*hp--;
  90. e0+=e1; t11=c1*h1; c2=*cp++; h0=*hp++;
  91. x2+=t11; t20=c2*h0; c3=*cp--;
  92. x2+=t20; x3 =c3*h0;
  93. e2 =x2*x2; c2=*cp--; h1=*hp++;
  94. e0+=e2; t21=c2*h1; c1=*cp--; h2=*hp++;
  95. x3+=t21; t12=c1*h2; c0=*cp++; h3=*hp++;
  96. x3+=t12; t03=c0*h3;   h4=*hp--;
  97. x3+=t03; x4 =c0*h4;
  98. e3 =x3*x3; c1=*cp++; h3=*hp--;
  99. e0+=e3; t13=c1*h3; c2=*cp++; h2=*hp--;
  100. x4+=t13; t22=c2*h2; c3=*cp++; h1=*hp--;
  101. x4+=t22; t31=c3*h1; c4=*cp++; h0=*hp;
  102. x4+=t31; t40=c4*h0;
  103. x4+=t40;
  104. e4=x4*x4;
  105. e0+=e4;
  106. *shep++=e0;
  107.     }
  108. }
  109. #else
  110. /** Unoptimized version -- kept for reference */
  111. void
  112. shape_conv(real h[], real shen[])
  113. {
  114.     int j;
  115.     real h0 = h[0], h1 = h[1], h2 = h[2], h3 = h[3], h4 = h[4], tmp;
  116.     for (j=0; j<NCWD; j++) {
  117. real energy=0;
  118. tmp = h0*cb_shape[j][0];
  119. energy += tmp*tmp;
  120. tmp = h0*cb_shape[j][1] + h1*cb_shape[j][0];
  121. energy += tmp*tmp;
  122. tmp = h0*cb_shape[j][2] + h1*cb_shape[j][1] + h2*cb_shape[j][0];
  123. energy += tmp*tmp;
  124. tmp = h0*cb_shape[j][3] + h1*cb_shape[j][2] + h2*cb_shape[j][1] +
  125.       h3*cb_shape[j][0];
  126. energy += tmp*tmp;
  127. tmp = h0*cb_shape[j][4] + h1*cb_shape[j][3] + h2*cb_shape[j][2] +
  128.       h3*cb_shape[j][1] + h4*cb_shape[j][0];
  129. energy += tmp*tmp;
  130. shen[j] = energy;
  131.     }
  132. }
  133. #endif
  134. /* Time Reversed Convolution Module -- Block 13 */
  135. void
  136. trev_conv(real h[], real target[],
  137.   real pn[])
  138. {
  139.     int j, k;
  140.     for (k=0; k<IDIM; k++) {
  141. real tmp=0.0;
  142.     for (j=k; j<IDIM; j++)
  143.     tmp += target[j]*h[j-k];
  144. pn[k] = tmp;
  145.     }
  146. }
  147. /* Error Calculator and Best Codebook Index Selector */
  148. /* Blocks 17 and 18 */
  149. void
  150. cb_excitation (int ix, real v[])
  151. {
  152.     int
  153. i,
  154. sx = ix >>3,
  155. gx = ix & 7;
  156.     real gain = cb_gain[gx];
  157.     for(i=0; i<IDIM; i++)
  158. v[i] = cb_shape[sx][i] * gain;
  159. }
  160. #define GTINC(A,B,X) if(A>B)X++
  161. int
  162. cb_index (real pn[])
  163. {
  164.     real  d, distm = BIG;
  165.     int
  166. j,
  167. is=0, /* best shape index */
  168. ig=0, /* best gain index */
  169. idxg, /* current gain index */
  170. ichan; /* resulting combined index */
  171.     real CBMEM *shape_ptr = (real CBMEM *) cb_shape;
  172.     real *sher_ptr  = shape_energy;
  173.     real pcor, b0, b1, b2;
  174.     real *pb=pn;
  175.     real g2, gsq;
  176.     register real
  177. cgm0 REG(r0) = cb_gain_mid_0,
  178. cgm1 REG(r1) = cb_gain_mid_1,
  179. x REG(r2),
  180. cgm2  = cb_gain_mid_2,
  181. energy REG(r4), y REG(r5),
  182. cor REG(r8) = 0,
  183. t REG(r12);
  184.     register int minus5 REG(m0) = -5;
  185.     
  186.     for (j=0; j<NCWD; j++) {
  187. cor=cor-cor;
  188. energy = *sher_ptr++;
  189. b0 = cgm0 * energy; x=*shape_ptr++; y=*pb++;
  190.             t=x*y;  x=*shape_ptr++; y=*pb++;
  191. cor+=t;     t=x*y;  x=*shape_ptr++; y=*pb++;
  192. cor+=t;     t=x*y;  x=*shape_ptr++; y=*pb++;
  193. cor+=t;     t=x*y;  x=*shape_ptr++; y=*pb++;
  194. cor+=t;     t=x*y;
  195. cor+=t;     b1 = cgm1 * energy;
  196. pb += minus5;
  197. b2 = cgm2 * energy;
  198. idxg=idxg-idxg;
  199. pcor = cor;
  200. if (cor < 0.0) {
  201.     pcor = -cor;
  202.     idxg += 4;
  203. }
  204. GTINC(pcor, b0, idxg);
  205. GTINC(pcor, b1, idxg);
  206. GTINC(pcor, b2, idxg);
  207. g2 = cb_gain2[idxg];
  208. gsq = cb_gain_sq[idxg];
  209. d = gsq * energy - g2 * cor;
  210. if (d < distm) {
  211.     ig = idxg;
  212.     is = j;
  213.     distm = d;
  214. }
  215.     }
  216.     ichan = (is  << 3) + ig;
  217.     return ichan;
  218. }