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

语音压缩

开发平台:

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 "fast.h"
  13. #include "parm.h"
  14. #include "data.h"
  15. #include "prototyp.h"
  16. static int sf_levdur (real[], real[]);
  17. static int levdur (real[], real[], int);
  18. static void hybwin(int lpsize, int framesize, int nrsize,
  19.     real old_input[], real new_input[], real output[],
  20.     real window[], real rec[],  real decay);
  21. static void bw_expand2(real input[],
  22.        real z_out[], real p_out[],
  23.        int order, real z_vec[], real p_vec[]);
  24. static void bw_expand1(real input[], real  p_out[],
  25. int order, real p_vec[]);
  26. /********************************** Adapter for Perceptual Weighting Filter */
  27. static real 
  28.     pwf_z_vec[LPCW+1], /* Arrays for band widening: zeros and*/
  29.     pwf_p_vec[LPCW+1], /* poles */
  30.     pwf_old_input[LPCW+NFRSZ+NONRW],
  31.     pwf_rec[LPCW+1]; /* Recursive Part */
  32.     
  33. void
  34. pwf_adapter (real input[],
  35.      real  z_out[], /* zero coefficients */
  36.      real  p_out[]) /* pole coefficients */
  37. {
  38.     static real
  39. acorr[LPCW+1], /* autocorrelation coefficients */
  40. lpcoeff[LPCW+1];
  41.     static real LPC_MEM
  42. temp[LPCW+1];
  43.     hybwin(LPCW, /* lpsize */
  44.    NFRSZ, /* framesize */
  45.    NONRW, /* nrsize -- nonrecursive size */
  46.    pwf_old_input,
  47.    input,
  48.    acorr,
  49.    hw_percw,
  50.    pwf_rec,
  51.    0.5);
  52.     if (levdur(acorr, temp, LPCW))
  53.       {
  54. RCOPY(temp, lpcoeff, LPCW+1);
  55. bw_expand2 (lpcoeff, z_out, p_out, LPCW,
  56.     pwf_z_vec, pwf_p_vec);
  57.       }
  58. }
  59. void
  60. init_pwf_adapter (real  z_co[], real  p_co[])
  61. {
  62.     real zv = 1.0, pv = 1.0;
  63.     int i;
  64.     for (i=0; i<=LPCW; i++)
  65.     {
  66. pwf_z_vec[i] = zv;
  67. pwf_p_vec[i] = pv;
  68. zv *= WZCF;
  69. pv *= WPCF;
  70. z_co[i] = 0.0;
  71. p_co[i] = 0.0;
  72.     }
  73.     p_co[0] = 1.0;
  74.     z_co[0] = 1.0;
  75.     ZARR(pwf_old_input);
  76.     ZARR(pwf_rec);
  77. }
  78. /*************************************** Backward Synthesis Filter Adapter */
  79. static real facv[LPC+1];
  80. static real
  81.     bsf_old_input[LPC+NFRSZ+NONR],
  82.     bsf_rec[LPC+1]; 
  83. void
  84. bsf_adapter (real input[], real p_out[])
  85. {
  86.     static real
  87. old_input[LPC + NFRSZ + NONR],
  88. acorr[LPC+1], /* autocorrelation coefficients */
  89. lpcoeff[LPC+1];
  90.     static real temp[LPC+1];
  91.     hybwin(LPC, /* lpsize */
  92.    NFRSZ, /* framesize */
  93.    NONR, /* nrsize -- nonrecursive size */
  94.    old_input,
  95.    input,
  96.    acorr,
  97.    hw_synth,
  98.    bsf_rec,
  99.    0.75);
  100.     if (sf_levdur(acorr, temp))
  101.       {
  102. k10 = -acorr[1]/acorr[0];
  103. RCOPY(temp, lpcoeff, LPC+1);
  104. bw_expand1(lpcoeff, p_out, LPC, facv);
  105.       }
  106. }
  107. /******************************************************* Gain Adapter **/
  108. static real gain_p_vec[LPCLG+1]=  /* Array for band widening */
  109. {1.0, 0.90625, 0.8212890625, 0.74432373046875, 0.67449951171875, 
  110. 0.61126708984375, 0.553955078125, 0.50201416015625, 0.4549560546875, 
  111. 0.41229248046875, 0.3736572265625};
  112. static real g_rec[LPCLG+1]; /* Recursive part for Hybrid Window */
  113. static real g_old_input[LPCLG + NUPDATE + NONRLG];
  114. /*** recompute lpc_coeff **/
  115. void gain_adapter (real log_gain[], real  coeff[])
  116. {
  117.     static real
  118. acorr[LPCLG+1], /* autocorrelation coefficients */
  119. lpcoeff[LPCLG+1];
  120.     
  121.     static real temp[LPCLG+1];
  122.     hybwin(LPCLG, /* lpsize */
  123.    NUPDATE, /* framesize */
  124.    NONRLG, /* nrsize -- nonrecursive size */
  125.    g_old_input,
  126.    log_gain,
  127.    acorr,
  128.    hw_gain,
  129.    g_rec,
  130.    0.75);
  131.     if (levdur(acorr, temp, LPCLG)) {
  132. int i;
  133. for(i=1; i<=LPCLG; i++)
  134.     lpcoeff[i] = temp[i];
  135.     bw_expand1 (lpcoeff, coeff, LPCLG,
  136. gain_p_vec);
  137.       }
  138. }
  139. /******************************************** Initializations **/
  140. void
  141. init_bsf_adapter(real co[])
  142. {
  143.     int i;
  144.     real v = 1.0;
  145.     for(i=0; i<=LPC; i++) {
  146. facv[i] = v;
  147. v *= FAC;
  148. co[i] = 0;
  149.     }
  150.     co[0] = 1.0;
  151.     ZARR(bsf_old_input);
  152.     ZARR(bsf_rec);
  153.     
  154. }
  155. void init_gain_adapter (real coeff[])
  156. {
  157.     int i;
  158.     gain_p_vec[0] = 1.0;
  159.     coeff[0] = 1.0;
  160.     coeff[1] = -1.0;
  161.     for(i=0; i<LPCLG+NUPDATE+NONRLG; i++)
  162. g_old_input[i] = -GOFF;
  163.     ZARR(g_rec);
  164.     ZARR(g_old_input);
  165. }
  166. /******************************************** Hybrid Window Module **/
  167. /*
  168.   Hybrid Window 
  169.   LPSIZE - size of OUTPUT (autocorrelation vector)
  170.   FRAMESIZE - size of NEW_INPUT
  171.   NRSIZE - size of non-recursive part.
  172.   OLD_INPUT - buffer for holding old input (size LPSIZE+FRAMESIZE+NRSIZE)
  173.   NEW_INPUT - new input, or frame (size FRAMESIZE)
  174.   OUTPUT - autocorrelation vector (size LPSIZE)
  175.   WINDOW - window coefficients (size LPSIZE+FRAMESIZE+NRSIZE)
  176.   REC -  - recursive part (size LPSIZE)
  177.   DECAY -  - scaling for the old recursive part.
  178.  */
  179. static void
  180. hybwin(int lpsize, int framesize, int nrsize, real old_input[], 
  181.        real new_input[], real output[],real WIN_MEM window[],
  182.     real rec[], /* Recursive Part */
  183.     real decay)
  184. {
  185.     static void autocorr();
  186.     int N1 = lpsize + framesize; /* M+L */
  187.     int N2 = lpsize + nrsize; /* M+N */
  188.     int N3 = lpsize + framesize + nrsize;
  189.     int i;
  190.     real ws[N3];
  191.     real tmp1[lpsize+1], tmp2[lpsize+1];
  192.     /* shift in INPUT into OLD_INPUT and window it*/
  193.     
  194.     for(i=0; i<N2; i++)
  195. old_input[i] = old_input[i+framesize];
  196.     for(i=0; i<framesize; i++)
  197. old_input[N2+i] = new_input[i];
  198.     VPROD(old_input,window,ws,N3);
  199.     
  200.     autocorr(ws, tmp1, lpsize, lpsize, N1);
  201.     
  202.     for(i=0; i<=lpsize; i++)
  203. rec[i] = decay * rec[i] + tmp1[i];
  204.     
  205.     autocorr(ws, tmp2, lpsize,  N1, N3);
  206.     
  207.     for(i=0; i<=lpsize; i++)
  208. output[i] = rec[i] + tmp2[i];
  209.     output[0] *= WNCF;
  210. }
  211. /********************************************* Levinson-Durbin Routines */
  212. /* Levinson-Durbin algorithm */
  213. /* return 1 if ok, otherwise 0 */
  214. static int levdur(real acorr[], real  coeff[], int order)
  215. {
  216.   /* Local variables */
  217.   static int minc, minc2;
  218.   static float s;
  219.   static int ib, mh;
  220.   static float at;
  221.   static int ip;
  222.   static float rc[20];
  223.   static float alpha;
  224.   static float tmp;
  225.   /* Parameter adjustments */
  226.   --acorr;
  227.   --coeff;
  228. /* .......CHECK FOR ZERO SIGNAL OR ILLEGAL ZERO-LAG AUTOCORRELATION */
  229.   if ((acorr[1] <= (float)0.)||(acorr[order+1] == 0))
  230.     return 0;
  231. /* .......START DURBIN's RECURSION */
  232.   rc[1] = -acorr[2] / acorr[1];
  233.   coeff[1] = (float)1.;
  234.   coeff[2] = rc[1];
  235.   alpha = acorr[1] + acorr[2] * rc[1];
  236.   if (alpha <= (float)0.)
  237.     return 0;
  238.   for (minc = 2; minc <= order; ++minc) {
  239.     minc2 = minc + 2;
  240.     s = acorr[minc + 1];
  241.     for (ip = 2; ip <= minc; ++ip) {
  242.       s += acorr[minc2 - ip] * coeff[ip];
  243.     }
  244.     rc[minc] = -s / alpha;
  245.     mh = minc / 2 + 1;
  246.     for (ip = 2; ip <= mh; ++ip) {
  247.       ib = minc2 - ip;
  248.       at = rc[minc] * coeff[ib];
  249.       at += coeff[ip];
  250.       tmp = rc[minc] * coeff[ip];
  251.       coeff[ib] += tmp;
  252.       coeff[ip] = at;
  253.     }
  254.     coeff[minc + 1] = rc[minc];
  255.     alpha += rc[minc] * s;
  256. /* ...........IF RESIDUAL ENERGY LESS THAN ZERO (DUE TO ILL-CONDITIONING), */
  257. /* ...........RETURN WITHOUT UPDATING FILTER COEFFICIENTS (USE OLD ONES). */
  258.     if (alpha <= (float)0.)
  259.       return 0;
  260.   }
  261.   return 1;
  262. }
  263. /*
  264.   Levinson-Durbin algorithm  for Synthesis Filter. Its main 
  265.   difference from the above is the fact that it saves 10-th
  266.   order coefficients for Postfilter, plus some speedup since this 
  267.   is one of the longest routines in the algorithm.
  268.   */ 
  269. real a10[11];
  270. real k10;
  271. static int sf_levdur(real acorr[], real  coeff[])
  272. {
  273.     real E;
  274.     register real K REG(r9), c1 REG(r0), tmp REG(r12);
  275.     int m, j, halfm;
  276.     if (acorr[LPC] == 0)
  277.         return 0;
  278.     E = acorr[0];
  279.     if (E<=0) 
  280. return 0;
  281.     coeff[0] = 1.0;
  282.     for(m=1; m<=LPC; m++) {
  283. K =  -acorr[m];
  284. if (m>1)
  285. {
  286.     real a1 REG(r4)=acorr[m-1];
  287.     c1=coeff[1];
  288.     tmp = c1*a1;
  289.     if (m>2) {
  290. c1 = coeff[2]; a1 = acorr[m-2];
  291. for(j=3; j<=m-1; j++) {
  292.     K -= tmp;
  293.     tmp = c1 * a1;
  294.     c1 = coeff[j];
  295.     a1 = acorr[m-j];
  296. }
  297. K -= tmp;
  298. tmp = c1*a1;
  299.     }
  300.     K -= tmp;
  301. }
  302. K = K/E;
  303. coeff[m] = K;
  304. halfm = m>>1;
  305. /** this is pipilened version of parallel assignment:  **/
  306. /*  coeff[j]   =     coeff[j] + K * coeff[m-j] */
  307. /*  coeff[m-j] = K * coeff[j] +     coeff[m-j] */
  308.       {
  309.   if (halfm>=1) {
  310.       register real
  311.   x  REG(r1),   y  REG(r5), t1 REG(r10),
  312.   t2 REG(r14), t3 REG(r2), t4 REG(r6);
  313.       register real  *p  REG(i10);
  314.       register real  *pp REG(i11);
  315.       register real  *q  REG(i12);
  316.       register real  *qq REG(i13);
  317.       p = coeff+1;   pp = p;
  318.       q = coeff+m-1; qq = q;
  319.       x=*p++;
  320.       y=*q--;
  321.       t1 = K * x;
  322.       t2 = K * y;
  323.       for(j=2; j<=halfm; j++) {
  324.   t4 = t2 + x;  x=*p++;
  325.   t3 = t1 + y;   y=*q--;      
  326.   t1 = K * x; *pp++ = t4;
  327.   t2 = K * y; *qq-- = t3;
  328.       }
  329.       t3 = t1 + y;
  330.       t4 = t2 + x;
  331.       *pp = t4;
  332.       *qq = t3;
  333.   }
  334.       }
  335. if (m==10) {
  336.     int jj;
  337.     for(jj=0; jj<=10; jj++)
  338. a10[jj] = coeff[jj];
  339. }
  340. E = (1 - K * K) * E;
  341. if (E<0)
  342.     return 0;
  343.     }
  344.     return 1;
  345. }
  346. /******************************************** Band Width Expanders **/
  347. /* Don't have to worry about i=0 -- z_vec[0] and p_vec[0] should stay 1.0. */
  348. static void
  349. bw_expand2(real input[], real z_out[], real p_out[],
  350.        int order, real z_vec[], real p_vec[])
  351. {
  352. int i;
  353. for(i=1; i<=order; i++)
  354.     z_out[i] = z_vec[i] * input[i];
  355. for(i=1; i<=order; i++)
  356.     p_out[i] = p_vec[i]*input[i];
  357. }
  358. /* Poles only */
  359. static void
  360. bw_expand1(real input[],  real p_out[], int order, real p_vec[])
  361. {
  362. int i;
  363. for(i=1; i<=order; i++)
  364.     p_out[i] = p_vec[i]*input[i];
  365. }
  366. static void
  367. autocorr(real X[], real R[], int K, int M, int N)
  368. {
  369.   int  ii,jj;
  370.   float tmp;
  371.   for(ii=0; ii<=K; ii++) {
  372.     R[ii] = 0;
  373.     for(jj=M; jj<N; jj++) {
  374.       tmp = X[jj] * X[jj-ii];
  375.       R[ii] += tmp;
  376.     }
  377.   }
  378. }