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

语音压缩

开发平台:

C/C++

  1. /**************************************************************************
  2. *
  3. * ROUTINE
  4. *               psearch
  5. *
  6. * FUNCTION
  7. *               find pitch VQ parameters
  8. *
  9. * SYNOPSIS
  10. *               subroutine psearch(l)
  11. *
  12. *   formal 
  13. *
  14. *                       data    I/O
  15. *       name            type    type    function
  16. *       -------------------------------------------------------------------
  17. *       l               int i       dimension of s
  18. *
  19. *   external 
  20. *                       data    I/O
  21. *       name            type    type    function
  22. *       -------------------------------------------------------------------
  23. * idb int i dimension of d1a and d1b???
  24. * no int i filter order  predictor
  25. * nseg int i segment counter
  26. * pindex int i/o pitch gain index bb[2]
  27. * bb float i/o pitch predictor coefficients
  28. * d1b[] float i/o memory 1/P(z)
  29. *  frame int  i
  30. * h[] float i/o impulse response
  31. * ptype[] char i pitch gain (bb[2]) quantizer type
  32. * pstype[] char i pitch search type
  33. * pitch_gain_vid int i
  34. * pitch_qgain_vid int i
  35. * pitch_match_vid int i
  36. * pitch_ir_vid int i
  37. * fndpp_v0_vid int i
  38. * tauptr int pitch delay pointer
  39. * pdelay float pitch delay coding table
  40. * minptr int minimum delay pointer
  41. * plevel1 int number of full search pitch delays
  42. * plevel2 int number of delta search pitch delays
  43. *
  44. ***************************************************************************
  45. *
  46. * DESCRIPTION
  47. *
  48. *  Pitch search is performed by closed-loop analysis using a modification
  49. *  of what is commonly called any one of the following: "self-excited",
  50. *  "adaptive code book" or "VQ" method.  This method was found to be
  51. *  superior to the conventional "filtering approach", especially for high
  52. *  pitched speakers.  The filtering and VQ methods are identical except when
  53. *  the delay is less than the frame length.  The pitch delay ranges from minptr
  54. *  to maxptr (i.e., 20 to 147 including noninteger) lags every odd subframe 
  55. *  while even subframes are searched and coded within 2**pbits[1] (i.e., 32)  
  56. *  lags relative to the previous subframe.  The delta search greatly reduces
  57. *  the computational complexity and data rate while causing no percievable 
  58. *  loss in speech quality.
  59. *
  60. *  The minimum squared prediction error (MSPE) search criteria is modified
  61. *  to check the error at submultiples of the delay to determine if it is
  62. *  within 1 dB of the MSPE.  The submultiple delay is selected if its error
  63. *  satisfies our modified criteria.  This results in a smooth "pitch" delay
  64. *  contour which produces higher quality speech and is crucial to the
  65. *  synthesizer's smoother in the presence of bit errors. 
  66. *  
  67. ***************************************************************************
  68. *
  69. * CALLED BY
  70. *
  71. *       csub
  72. *
  73. * CALLS
  74. *
  75. *  movefr   pitchencode   pgain   save_sg   delay
  76. *
  77. **************************************************************************
  78. *
  79. * REFRENCES
  80. *
  81. * Tremain, Thomas E., Joseph P. Campbell, Jr and Vanoy C. Welch,
  82. * "A 4.8 kbps Code Excited Linear Predictive Coder," Proceedings
  83. * of the Mobile Satellite Conference, 3-5 May 1988, pp. 491-496.
  84. *
  85. * Campbell, Joseph P. Jr., Vanoy C. Welch and Thomas E. Tremain,
  86. * "An Expandable Error-Protected 4800 bps CELP Coder (U.S. Federal
  87. * Standard 4800 bps Voice Coder)," Proceedings of ICASSP, 1989.
  88. * (and Proceedings of Speech Tech, 1989.)
  89. *
  90. * Kroon, Peter and Bishnu Atal, "On Improving the Performance of
  91. * Pitch Predictions in Speech Coding Systems," IEEE Speech Coding
  92. * Workshop, September 1989.
  93. *
  94. * Marques, J.S., et al., "Pitch Prediction with Fractional Delays
  95. * in CELP Coding," European Conference on Speech Communication and
  96. * Technology, September, 1989.
  97. *
  98. **************************************************************************/
  99. #define TRUE 1
  100. #define FALSE 0
  101. #define LEN 30  /* *length of truncated impulse response  */
  102. #define MAXBUFPTR MMAX + MAXNO + 2  * MAXLP + MAXNP - 1
  103. #define mmin(A,B)      ((A)<(B)?(A):(B))
  104. #define mmax(A,B)      ((A)>(B)?(A):(B))
  105. #include <stdio.h>
  106. #include <math.h>
  107. #include "ccsub.h"
  108. static int submult[MAXPD][4] = 
  109. {
  110. #include "submult.h"      /* *load pitch submultiple delay table     */
  111. };
  112. extern int idb, no, nseg, pindex, tauptr, minptr;
  113. extern int plevel1, plevel2, frame;
  114. extern float bb[MAXNP+1], d1b[MAXPA];
  115. extern float h[MAXLP], pdelay[MAXPD];
  116. extern char ptype[10], pstype[10];
  117. #ifdef SUNGRAPH
  118. extern int pitch_gain_vid, pitch_qgain_vid, pitch_match_vid, pitch_ir_vid, fndpp_v0_vid;
  119. #endif
  120. psearch(l)
  121. int l;
  122. {
  123. #ifdef SUNGRAPH
  124.   int saveindex;
  125. #endif
  126.   int i, m, lag, start;
  127.   int first, bigptr, subptr, topptr, maxptr, bufptr;
  128.   static int oldptr = {1};
  129.   float g[MAXPD], match[MAXPD], emax, pgain(), pitchencode();
  130.   int fraction, neigh, whole, sub, nrange = 0;
  131.   /* See warning below ----------------  / max (MAXL, MAXLP) */
  132.   float v0[MAXBUFPTR], v0shift[MAXLP], frac;
  133. /*   */
  134. /* *choose type of pitch delay search:  */
  135. /*  *two stage hierarchical search of integer and neighboring  */
  136. /* *noninteger delays  */
  137.   if (strcmp(pstype, "hier") == 0) 
  138.   {
  139.     whole = 1;
  140.     fraction = 0;
  141.     sub = 1;
  142.     neigh = 1;
  143.     nrange = 3;
  144.   }
  145.   /* *integer only search  */
  146.   else if (strcmp(pstype, "intg") == 0)
  147.   {
  148.     whole = 1;
  149.     fraction = 0;
  150.     sub = 1;
  151.     neigh = 0;
  152.   }
  153.   /* *full exhaustive search  */
  154.   else if (strcmp(pstype, "full") == 0)
  155.   {
  156.     whole = 1;
  157.     fraction = 1;
  158.     sub = 1;
  159.     neigh = 0;
  160.   }
  161.   else
  162.   {
  163.     perror("psearch: incorrect pitch search type (pstype)");
  164.     exit(0);
  165.   }
  166.   /* *initialize arrays  */
  167.   for (i = 0; i < MAXBUFPTR; i++)
  168.     v0[i] = 0.0;
  169.    for (i = 0; i < MAXLP; i++)
  170.     v0shift[i] = 0.0;
  171.   for (i = 0; i < MAXPD; i++)
  172.     g[i] = match[i] = 0.0;
  173.   if (LEN > l) 
  174.   {
  175.     fprintf(stderr,"psearch: impulse resp too longn");
  176.     exit(1);
  177.   }    
  178.   bufptr = MMAX + no + 2*l + MAXNP - 1;
  179.   if (MAXLP < MAXL)
  180.   {
  181.     fprintf(stderr,"psearch: MAXLP < MAXLn");
  182.     exit(1);
  183.   }
  184.   
  185. #ifdef SUNGRAPH
  186.   
  187.   /* *save impulse response in file 'pitch'    */
  188.   
  189.   save_sg(pitch_ir_vid, h, l, "save pitch_ir_vid");
  190. #endif
  191.   /* *update adaptive code book (pitch memory)  */
  192.   movefr(idb, d1b, &v0[bufptr - idb - l]);
  193.   /* *initial conditions  */
  194.   if (nseg == 1)
  195.   {
  196.     bb[2] = 0.0;
  197.     bb[0] = MMIN;
  198.   }
  199.   else
  200.   {
  201. #ifdef SUNGRAPH
  202.     saveindex = bufptr - idb - l;
  203.     /* *save fndpp_v0 in file 'error'  */
  204.     save_sg(fndpp_v0_vid, &v0[saveindex], l, "save fndpp_v0_vid");
  205. #endif
  206.     /* *find allowable pointer range (minptr to maxptr)  */
  207.   
  208.     if ((nseg % 2) == 0)
  209.     {
  210.     /* *delta delay coding on even subframes    */
  211.       minptr = oldptr - (plevel2/2 - 1);
  212.       maxptr = oldptr + (plevel2/2);
  213.       if (minptr < 0)
  214.       {
  215.         minptr = 0;
  216.         maxptr = plevel2 - 1;
  217.       }
  218.       if (maxptr > plevel1 - 1)
  219.       {
  220.           maxptr = plevel1 - 1;
  221.           minptr = plevel1 - plevel2;
  222.       }
  223.     }
  224.     else
  225.     {
  226.     /* *full range coding on odd subframes  */
  227.       minptr = 0;
  228.       maxptr = plevel1 - 1;
  229.     }
  230.     start = bufptr - l + 1;
  231.     /* *find gain and match score for integer pitch delays  */
  232.     /* *(using end-point correction on unity spaced delays)  */
  233.     if (whole)
  234.     {
  235.       first = TRUE;
  236.       for (i = minptr; i <= maxptr; i++)
  237.       {
  238.         m = (int) pdelay[i];
  239.         frac = pdelay[i] - m;
  240.         if (fabs(frac) < 1.e-4)
  241.         {
  242.           lag = start - m;
  243.           g[i] = pgain(&v0[lag-1], l, first, m, LEN, &match[i]);
  244.           first = FALSE;
  245.         }
  246.         else
  247.           match[i] = 0.0;
  248.       }
  249.      }
  250.   
  251.     /* *find gain and match score for fractional delays  */
  252.     /* *(beware of combining this loop with above loop!)  */
  253.     /* *(could use end-point correction on unity spaced delays)  */
  254.     if (fraction)
  255.     {
  256.       for (i = minptr; i <= maxptr; i++)
  257.       {
  258.         m = (int) pdelay[i];
  259.         frac = pdelay[i] - m;
  260.         if (fabs(frac) >= 1.e-4)
  261.         {
  262.           delay(v0, start, l, frac, m, v0shift);
  263.           g[i] = pgain(v0shift, l, TRUE, 70, LEN, &match[i]);
  264.         }
  265.       }
  266.     }
  267.     /* *find pointer to top (MSPE) match score (topptr)  */
  268.     /* *search for best match score (max -error term)  */
  269.     topptr = minptr;
  270.     emax = match[topptr];
  271.     for (i = minptr; i <= maxptr; i++)
  272.     {
  273.       if (match[i] > emax)
  274.       {
  275.         topptr = i;
  276.         emax = match[topptr];
  277.       }
  278.     }
  279.     /* *for full search (odd) subframes:  */
  280.     /* *select shortest delay of 2, 3, or 4 submultiples. if its match   */
  281.     /* *is within 1 dB of MSPE to favor smooth "pitch"  */
  282.     tauptr = topptr;
  283.     if (sub)
  284.     {
  285.       if ((nseg % 2) != 0)
  286.       {
  287.       /* *for each submultiple {2, 3 & 4}  */
  288.   
  289.         for (i = 1; i <= submult[topptr][0]; i++)
  290.         {
  291.           /* *find best neighborhood match for given submultiple  */
  292.           bigptr = submult[topptr][i];
  293.           for (subptr = mmax(submult[topptr][i] - 8, minptr); subptr <= 
  294.          mmin(submult[topptr][i] + 8, maxptr); subptr++)
  295.           {
  296.             if (match[subptr] > match[bigptr])
  297.               bigptr = subptr;
  298.           }
  299.           /* *select submultiple match if within 1 dB MSPE match  */
  300.           if (match[bigptr] >= 0.88 * match[topptr])
  301.           {
  302.             tauptr = bigptr;
  303.           }
  304.         }
  305.       }
  306.     }
  307.     /* *search tauptr's neighboring delays  */
  308.     /* *(to be used with earlier stages of searching)  */
  309.     /* *find gain and match score for neighboring delays  */
  310.     /* *and find best neighborhood match  */
  311.     /* *(could use end-point correction on unity spaced delays)  */
  312.     if (neigh)
  313.     {
  314.       bigptr = tauptr;
  315.       for (i = mmax(tauptr - nrange, minptr); i <= mmin(tauptr + nrange, maxptr); i++)
  316.       {
  317.         if (i != tauptr)
  318.         {
  319.           m = (int) pdelay[i];
  320.           frac = pdelay[i] - m;
  321.           lag = start - m;
  322.           if (fabs(frac) < 1.e-4)
  323.             g[i] = pgain(&v0[lag - 1], l, TRUE, m, LEN, &match[i]);
  324.           else
  325.           {
  326.     delay(v0, start, l, frac, m, v0shift);
  327.             g[i] = pgain(v0shift, l, TRUE, 70, LEN, &match[i]);
  328.           }
  329.           if (match[i] > match[tauptr])
  330.             bigptr = i;
  331.         }
  332.       }
  333.       tauptr = bigptr;
  334.     }
  335.     /* *OPTIONAL (may be useful for integer DSPs)  */
  336.     /* *given chosen pointer to delay (tauptr), recompute its  */
  337.     /* *gain to correct errors accumulated in recursions   */
  338.     /* *and errors due to truncation  */
  339.     m = (int) pdelay[tauptr];
  340.     frac = pdelay[tauptr] - m;
  341.     lag = start - m;
  342.     if (fabs(frac) < 1.e-4)
  343.     /* *integer delay:  */
  344.       g[tauptr] = pgain(&v0[lag - 1], l, TRUE, m, l, &match[tauptr]);
  345.     else
  346.     /* *fractional delay:  */
  347.     {
  348.       delay(v0, start, l, frac, m, v0shift);
  349.       g[tauptr] = pgain(v0shift, l, TRUE, 70, l, &match[tauptr]);
  350.     }
  351.     /* *place pitch parameters in common bb "structure"  */
  352.     bb[2] = g[tauptr];
  353.     bb[0] = pdelay[tauptr];
  354.     /* *save pitch pointer to determine delta delay  */
  355.     oldptr = tauptr;
  356. #ifdef SUNGRAPH
  357.   /* *save pitch match score function in file 'pitch'  */
  358.     save_sg(pitch_match_vid, match, plevel1, "save pitch_error_vid");
  359. #endif
  360.   }
  361. #ifdef SUNGRAPH
  362.   /* *save unquantized pitch gain in file 'pitch'  */
  363.     save_sg(pitch_gain_vid, &bb[2], 1, "save pitch_gain_vid");
  364. #endif
  365.   /* *pitch quantization bb[2]  */
  366.   if (strncmp(ptype, "none", 4) != 0)
  367.     bb[2] = pitchencode(bb[2], &pindex);
  368.   else
  369.     fprintf(stderr, "psearch: no pitch quantization!n");
  370. #ifdef SUNGRAPH
  371.   /* *save quantized pitch gain in fle 'pitch'   */
  372.     save_sg(pitch_qgain_vid, &bb[2], 1, "save pitch_qgain_vid");
  373. #endif
  374. }
  375.