pit_lib.c
上传用户:cxx_68
上传日期:2021-02-21
资源大小:161k
文件大小:25k
源码类别:

语音压缩

开发平台:

Visual C++

  1. /*
  2. 2.4 kbps MELP Proposed Federal Standard speech coder
  3. Fixed-point C code, version 1.0
  4. Copyright (c) 1998, Texas Instruments, Inc.  
  5. Texas Instruments has intellectual property rights on the MELP
  6. algorithm.  The Texas Instruments contact for licensing issues for
  7. commercial and non-government use is William Gordon, Director,
  8. Government Contracts, Texas Instruments Incorporated, Semiconductor
  9. Group (phone 972 480 7442).
  10. The fixed-point version of the voice codec Mixed Excitation Linear
  11. Prediction (MELP) is based on specifications on the C-language software
  12. simulation contained in GSM 06.06 which is protected by copyright and
  13. is the property of the European Telecommunications Standards Institute
  14. (ETSI). This standard is available from the ETSI publication office
  15. tel. +33 (0)4 92 94 42 58. ETSI has granted a license to United States
  16. Department of Defense to use the C-language software simulation contained
  17. in GSM 06.06 for the purposes of the development of a fixed-point
  18. version of the voice codec Mixed Excitation Linear Prediction (MELP).
  19. Requests for authorization to make other use of the GSM 06.06 or
  20. otherwise distribute or modify them need to be addressed to the ETSI
  21. Secretariat fax: +33 493 65 47 16.
  22. */
  23. /*
  24.   pit_lib.c: pitch analysis subroutines 
  25. */
  26. #include <stdio.h>
  27. #include <math.h>
  28. #include "spbstd.h"
  29. #include "mathhalf.h"
  30. #include "mathdp31.h"
  31. #include "wmops.h"
  32. #include "mat.h"
  33. #include "math_lib.h"
  34. #include "dsp_sub.h"
  35. #include "pit.h"
  36. #include "constant.h"
  37. extern int saturation;  /* saturation flag */
  38. /*                                                                  */
  39. /*  double_chk.c: check for pitch doubling                          */
  40. /*  and also verify pitch multiple for short pitches.               */
  41. /*                                                                  */
  42. /* Q values 
  43.    --------
  44.    sig_in - Q0
  45.    pcorr - Q14
  46.    pitch - Q7
  47.    pdouble - Q7
  48. */
  49. #define NUM_MULT 8
  50. Shortword double_chk(Shortword sig_in[],Shortword *pcorr,Shortword pitch,
  51.      Shortword pdouble,Shortword pmin,Shortword pmax,
  52.      Shortword pmin_q7,Shortword pmax_q7,
  53.      Shortword lmin)
  54. {
  55.     Shortword mult;
  56.     Shortword corr,thresh;
  57.     Shortword temp_pit;
  58.     Shortword temp1,temp2;
  59.     Longword L_temp;
  60.     pitch = frac_pch(sig_in,pcorr,pitch,0,pmin,pmax,pmin_q7,pmax_q7,lmin);
  61.     /* compute threshold Q14*Q7>>8 */
  62.     /* extra right shift to compensate left shift of L_mult */
  63.     L_temp = L_mult(*pcorr,pdouble);
  64.     L_temp = L_shr(L_temp,8);
  65.     thresh = extract_l(L_temp);      /* Q14 */
  66.     /* Check pitch submultiples from shortest to longest */
  67.     for (mult = NUM_MULT; mult >= 2; mult--) {
  68.         /* temp_pit = pitch / mult */
  69.         temp1 = 0;      data_move();
  70. temp2 = shl(mult,11);     /* Q11 */      data_move();
  71. temp_pit = pitch;     data_move();
  72. while (temp_pit > temp2) {
  73.   /* increment complexity for while statement */
  74.   compare_nonzero();
  75.   temp_pit = shr(temp_pit,1);      data_move();
  76.   temp1 = add(temp1,1);      data_move();
  77. }
  78. /* Q7*Q15/Q11 -> Q11 */
  79. temp2 = divide_s(temp_pit,temp2);     data_move();
  80. temp1 = sub(4,temp1);      data_move();
  81. /* temp_pit=pitch/mult in Q7 */
  82. temp_pit = shr(temp2,temp1);      data_move();
  83. /* increment complexity for if statement */
  84. compare_nonzero();
  85. if (temp_pit >= pmin_q7) {
  86.     temp_pit = frac_pch(sig_in,&corr,temp_pit,0,pmin,pmax,pmin_q7,
  87.     pmax_q7,lmin);
  88.     double_ver(sig_in,&corr,temp_pit,pmin,pmax,pmin_q7,
  89.    pmax_q7,lmin);
  90.     
  91.     /* stop if submultiple greater than threshold */
  92.     /* increment complexity for if statement */
  93.     compare_nonzero();
  94.     if (corr > thresh) {
  95. /* refine estimate one more time since previous window */
  96. /* may be off center slightly and temp_pit has moved */
  97. pitch = frac_pch(sig_in,pcorr,temp_pit,0,pmin,pmax,pmin_q7,
  98.      pmax_q7,lmin);
  99. break;
  100.     }
  101. }
  102.     }
  103.     /* Verify pitch multiples for short pitches */
  104.     double_ver(sig_in,pcorr,pitch,pmin,pmax,pmin_q7,pmax_q7,lmin);
  105.     /* Return full floating point pitch value and correlation*/
  106.     return(pitch);
  107. }
  108. #undef NUM_MULT
  109. /*                                                                  */
  110. /*  double_ver.c: verify pitch multiple for short pitches.          */
  111. /*                                                                  */
  112. /* Q values 
  113.    --------
  114.    pitch - Q7
  115.    pcorr - Q14
  116. */
  117. #define SHORT_PITCH 3840     /* (30*(1<<7)) */     /* Q7 */
  118. void double_ver(Shortword sig_in[],Shortword *pcorr,Shortword pitch,
  119. Shortword pmin,Shortword pmax,Shortword pmin_q7,
  120. Shortword pmax_q7,Shortword lmin)
  121. {  
  122.     Shortword multiple;
  123.     Shortword corr,temp_pit;
  124.    
  125.     /* Verify pitch multiples for short pitches */
  126.     multiple = 1;          data_move();
  127.     while (extract_l(L_shr(L_mult(pitch,multiple),1)) < SHORT_PITCH) {
  128.       /* increment complexity for while statement */
  129.       compare_nonzero();
  130.       multiple=add(multiple,1);     data_move();
  131.     }
  132.     /* increment complexity for if statement */
  133.     compare_nonzero();
  134.     if (multiple > 1) {
  135.         temp_pit = extract_l(L_shr(L_mult(pitch,multiple),1));
  136.         temp_pit = frac_pch(sig_in,&corr,temp_pit,0,pmin,pmax,
  137. pmin_q7,pmax_q7,lmin);
  138.         /* use smaller of two correlation values */
  139. /* increment complexity for if statement */
  140. compare_nonzero();
  141.         if (corr < *pcorr) {
  142.           *pcorr = corr;    data_move();
  143. }
  144.     }
  145. }
  146. #undef SHORT_PITCH
  147. /*                                                                  */
  148. /*  f_pitch_scale.c: Scale pitch signal buffer for best precision   */
  149. /*                                                                  */
  150. Shortword f_pitch_scale(Shortword sig_out[],Shortword sig_in[],
  151. Shortword length)
  152. {
  153.     int sat_save;
  154.     Shortword scale;
  155.     Shortword *temp_buf;
  156.     Longword corr;
  157.     /* allocate scratch buffer */
  158.     MEM_ALLOC(MALLOC,temp_buf,length,Shortword);
  159.     /* Compute signal buffer scale factor */
  160.     sat_save = saturation;
  161.     scale = 0;
  162.     corr = L_v_magsq(sig_in, length, 0, 1);
  163.     if (saturation > sat_save) {
  164. /* saturation: right shift input signal and try again */
  165. scale = 5;
  166. v_equ_shr(temp_buf,sig_in,scale,length);
  167. corr = L_v_magsq(temp_buf, length, 0, 1);
  168. /* could add delta to compensate possible truncation error */
  169. /* reset saturation counter */
  170. saturation = sat_save;
  171.     }
  172.     scale = sub(scale,shr(norm_l(corr),1));
  173.     /* Scale signal buffer */
  174.     v_equ_shr(sig_out,sig_in,scale,length);
  175.     /* free scratch buffer */
  176.     MEM_FREE(FREE,temp_buf);
  177.     /* return scale factor */
  178.     return(scale);
  179. }
  180. /*                                                                  */
  181. /*  find_pitch.c: Determine pitch value.                            */
  182. /*                                                                  */
  183. /*  Q values:
  184.     sig_in - Q0
  185.     ipitch - Q0
  186.     *pcorr - Q14 */
  187. /*
  188.   WARNING: this function assumes the input buffer has been normalized
  189.   by f_pitch_scale.
  190. */
  191. Shortword find_pitch(Shortword sig_in[],Shortword *pcorr,Shortword lower,
  192.      Shortword upper,Shortword length)
  193. {
  194.     Shortword i,cbegin,ipitch,even_flag;
  195.     Shortword s_corr;
  196.     Shortword shift1a,shift1b,shift2,shift;
  197.     Longword c0_0,cT_T,corr;
  198.     Longword denom,max_denom,num,max_num;
  199.     /* Find beginning of correlation window centered on signal */
  200.     ipitch = lower;    data_move();
  201.     max_num = 0;    data_move();
  202.     max_denom = 1;    data_move();
  203.     even_flag = 1;    data_move();
  204.     /* cbegin = -((length+upper)/2) */
  205.     cbegin = negate(shr(add(length,upper),1));    data_move();
  206.     c0_0 = L_v_magsq(&sig_in[cbegin],length, 0, 1);    L_data_move();
  207.     cT_T = L_v_magsq(&sig_in[cbegin+upper],length, 0, 1);    L_data_move();
  208.     for (i = upper; i >= lower; i--) {
  209. /* calculate normalized crosscorrelation */
  210. corr= L_v_inner(&sig_in[cbegin],&sig_in[cbegin+i],length,0,0,1);
  211. /* calculate normalization for numerator and denominator */
  212. shift1a = norm_s(extract_h(c0_0));
  213. shift1b = norm_s(extract_h(cT_T));
  214. shift = add(shift1a,shift1b);
  215. shift2 = shr(shift,1);  /* shift2 = half of total shift */
  216. if (shl(shift2,1) != shift)
  217.     shift1a = sub(shift1a,1);
  218. /* check if current maximum value */
  219. if (corr > 0) {
  220.     s_corr = extract_h(L_shl(corr,shift2));
  221.     num = extract_h(L_mult(s_corr,s_corr));
  222. }
  223. else
  224.     num = 0;
  225. denom = extract_h(L_mult(extract_h(L_shl(c0_0,shift1a)),
  226.  extract_h(L_shl(cT_T,shift1b))));
  227. if (denom < 1)
  228.   denom = 1;
  229. L_compare_nonzero();
  230. if (L_mult((Shortword)num,(Shortword)max_denom) > L_mult((Shortword)max_num,(Shortword)denom)) {
  231.     max_denom = denom;  data_move();
  232.     max_num = num;      data_move();
  233.     ipitch = i;     data_move();
  234. }
  235.     
  236. /* update for next iteration */
  237. /* increment complexity for if statement */
  238. compare_zero();
  239. if (even_flag) {
  240.     even_flag = 0;     data_move();
  241.     c0_0 = L_msu(c0_0,sig_in[cbegin],sig_in[cbegin]);  L_data_move();
  242.     c0_0 = L_mac(c0_0,sig_in[cbegin+length],
  243.  sig_in[cbegin+length]);     L_data_move();
  244.     cbegin = add(cbegin,1);    data_move();
  245. }
  246. else {
  247.     even_flag = 1;    data_move();
  248.     cT_T = L_msu(cT_T, sig_in[cbegin+i-1+length], 
  249.  sig_in[cbegin+i-1+length]);  L_data_move();
  250.     cT_T = L_mac(cT_T, sig_in[cbegin+i-1], sig_in[cbegin+i-1]);
  251.     L_data_move();
  252. }
  253.     
  254.     }
  255.     /* Return pitch value and correlation*/
  256.     *pcorr = shr(sqrt_fxp(divide_s((Shortword)max_num,(Shortword)max_denom),15),1);
  257.     data_move();
  258.     return(ipitch);
  259. }
  260. /*
  261.     Name: frac_pch.c
  262.     Description: Determine fractional pitch.
  263.     Inputs:
  264.       sig_in - input signal
  265.       fpitch - initial floating point pitch estimate
  266.       range - range for local integer pitch search (0=none)
  267.       pmin - minimum allowed pitch value
  268.       pmax - maximum allowed pitch value
  269.       lmin - minimum correlation length
  270.     Outputs:
  271.       pcorr - correlation at fractional pitch value
  272.     Returns: fpitch - fractional pitch value
  273.     Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
  274. */
  275. /* Q values
  276.    --------
  277.    ipitch - Q0
  278.    fpitch - Q7
  279.    sig_in - Q0
  280.    *pcorr - Q14
  281. */
  282. /*
  283.   WARNING: this function assumes the input buffer has been normalized
  284.   by f_pitch_scale.
  285. */
  286. #define MAXFRAC 16384    /* (2.0*(1<<13)) */     /* Q13 */
  287. #define MINFRAC -8192    /* (-1.0*(1<<13)) */    /* Q13 */
  288. Shortword frac_pch(Shortword sig_in[],Shortword *pcorr,Shortword fpitch,
  289.    Shortword range,Shortword pmin,Shortword pmax,
  290.    Shortword pmin_q7,Shortword pmax_q7,Shortword lmin)
  291. {
  292.     Shortword length,cbegin,lower,upper,ipitch;
  293.     Shortword c0_0,c0_T,c0_T1,cT_T,cT_T1,cT1_T1,c0_Tm1;
  294.     Shortword shift1a,shift1b,shift2,shift;
  295.     Shortword frac,frac1,corr;
  296.     Shortword temp;
  297.     Longword denom,denom1,denom2,denom3,numer;
  298.     Longword mag_sq;
  299.     Longword L_temp1;
  300.     /* Perform local integer pitch search for better fpitch estimate */
  301.     /* increment complexity for if statement */
  302.     compare_zero();
  303.     if (range > 0) {
  304.         ipitch = shift_r(fpitch, -7);    data_move();
  305.         lower = sub(ipitch,range);    data_move();
  306.         upper = add(ipitch,range);    data_move();
  307. /* increment complexity for if statement */
  308. compare_nonzero();
  309.         if (upper > pmax) {
  310.           upper = pmax;    data_move();
  311. }
  312. /* increment complexity for if statement */
  313. compare_nonzero();
  314.         if (lower < pmin) {
  315.           lower = pmin;    data_move();
  316. }
  317. /* increment complexity for if statement */
  318. compare_nonzero();
  319.         if (lower < add(shr(ipitch,1),shr(ipitch,2))) {
  320.           lower = add(shr(ipitch,1),shr(ipitch,2));    data_move();
  321. }
  322.         length = ipitch;    data_move();
  323. /* increment complexity for if statement */
  324. compare_nonzero();
  325.         if (length < lmin) {
  326.           length = lmin;    data_move();
  327. }
  328.         fpitch = shl(find_pitch(sig_in,&corr,lower,upper,length),7);
  329. data_move();
  330.     }
  331.     /* Estimate needed crosscorrelations */
  332.     ipitch = shift_r(fpitch,-7);    data_move();
  333.     /* increment complexity for if statement */
  334.     compare_nonzero();
  335.     if (ipitch >= pmax) {
  336.       ipitch = sub(pmax,1);    data_move();
  337.     }
  338.     length = ipitch;    data_move();
  339.     /* increment complexity for if statement */
  340.     compare_nonzero();
  341.     if (length < lmin) {
  342.       length = lmin;    data_move();
  343.     }
  344.     cbegin = negate(shr(add(length,ipitch),1));    data_move();
  345.     /* Calculate normalization for numerator and denominator */
  346.     mag_sq = L_v_magsq(&sig_in[cbegin],length,0,1);
  347.     shift1a = norm_s(extract_h(mag_sq));
  348.     shift1b = norm_s(extract_h(
  349. L_v_magsq(&sig_in[cbegin+ipitch-1],(Shortword)(length+2),0,1)));
  350.     shift = add(shift1a,shift1b);
  351.     shift2 = shr(shift,1);  /* shift2 = half of total shift */
  352.     if (shl(shift2,1) != shift)
  353. shift1a = sub(shift1a,1);
  354.     /* Calculate correlations with appropriate normalization */
  355.     c0_0 = extract_h(L_shl(mag_sq,shift1a));
  356.     c0_T = extract_h(L_shl(L_v_inner(&sig_in[cbegin],
  357.      &sig_in[cbegin+ipitch],length,
  358.      0,0,1),shift2));
  359.     c0_T1 = extract_h(L_shl(L_v_inner(&sig_in[cbegin],
  360.       &sig_in[cbegin+ipitch+1],
  361.       length,0,0,1),shift2));
  362.     c0_Tm1 = extract_h(L_shl(L_v_inner(&sig_in[cbegin],
  363.        &sig_in[cbegin+ipitch-1],
  364.        length,0,0,1),shift2));
  365.     /* increment complexity for if statement */
  366.     compare_nonzero();
  367.     if (c0_Tm1 > c0_T1) {
  368.         /* fractional component should be less than 1, so decrement pitch */
  369.         c0_T1 = c0_T;    data_move();
  370.         c0_T = c0_Tm1;    data_move();
  371.         ipitch = sub(ipitch,1) ;    data_move();
  372.     }
  373.     cT_T1 = extract_h(L_shl(L_v_inner(&sig_in[cbegin+ipitch],
  374.       &sig_in[cbegin+ipitch+1],length,
  375.       0,0,1),shift1b));
  376.     cT_T = extract_h(L_shl(L_v_inner(&sig_in[cbegin+ipitch],
  377.      &sig_in[cbegin+ipitch],length,
  378.      0,0,1),shift1b));
  379.     cT1_T1 = extract_h(L_shl(L_v_inner(&sig_in[cbegin+ipitch+1],
  380.        &sig_in[cbegin+ipitch+1],length,
  381.        0,0,1),shift1b));
  382.     /* Find fractional component of pitch within integer range */
  383.     /* frac = Q13 */
  384.     denom = L_add(L_mult(c0_T1,sub(shr(cT_T,1),shr(cT_T1,1))),
  385.                   L_mult(c0_T,sub(shr(cT1_T1,1),shr(cT_T1,1))));
  386.         L_data_move();
  387.     numer = L_sub(L_shr(L_mult(c0_T1,cT_T),1), L_shr(L_mult(c0_T,cT_T1),1)); 
  388.         L_data_move();
  389.     
  390.     /* increment complexity for if statement */
  391.     compare_zero();
  392.     L_temp1 = L_abs(denom);
  393.     if (L_temp1 > 0) {
  394.       if (L_abs(L_shr(numer,2)) > L_temp1) {
  395. if (((numer>0)&&(denom<0)) || ((numer<0)&&(denom>0)))
  396.   frac = (Shortword)MINFRAC;
  397. else
  398.   frac = (Shortword)MAXFRAC;
  399.       }
  400.       else
  401. frac = L_divider2(numer,denom,2,0);    data_move();
  402.     }
  403.     else {
  404.       frac = (Shortword)X05_Q13;    data_move();
  405.     }
  406.     /* increment complexity for if statement */
  407.     compare_nonzero();
  408.     if (frac > MAXFRAC) {
  409.       frac = (Shortword)MAXFRAC;    data_move();
  410.     }
  411.     /* increment complexity for if statement */
  412.     compare_nonzero();
  413.     if (frac < MINFRAC) {
  414.       frac = (Shortword)MINFRAC;    data_move();
  415.     }
  416.     
  417.     /* Make sure pitch is still within range */
  418.     fpitch = add(shl(ipitch,7), shr(frac,6));      data_move();
  419.     /* increment complexity for if statement */
  420.     compare_nonzero();
  421.     if (fpitch > pmax_q7) {
  422.       fpitch = pmax_q7;    data_move();
  423.       frac = shl(sub(fpitch, shl(ipitch,7)),6);     data_move();
  424.     }
  425.     /* increment complexity for if statement */
  426.     compare_nonzero();
  427.     if (fpitch < pmin_q7) {
  428.       fpitch = pmin_q7;    data_move();
  429.       frac = shl(sub(fpitch, shl(ipitch,7)),6);     data_move();
  430.     }
  431.     
  432.     /* Calculate interpolated correlation strength */
  433.     frac1 = sub(ONE_Q13 ,frac);    data_move();
  434.     /* Calculate denominator */
  435.     data_move();   data_move();   data_move();   data_move();
  436.     denom1 = L_shr(L_mpy_ls(L_mult(cT_T,frac1),frac1),1);  /* Q(X+11) */
  437.     denom2 = L_mpy_ls(L_mult(cT_T1,frac1),frac); 
  438.     denom3 = L_shr(L_mpy_ls(L_mult(cT1_T1,frac),frac),1);  /* Q(X+11) */
  439.     denom = L_mpy_ls(L_add(L_add(denom1,denom2),denom3),c0_0); /* Q(2X-4) */ 
  440.     temp = L_sqrt_fxp(denom,0);     /* temp in Q(X-2) */   data_move();
  441.     /* Calculate numerator */
  442.     L_temp1 = L_mult(c0_T,frac1);         /* Q(X+14) */
  443.     L_temp1 = L_mac(L_temp1,c0_T1,frac);
  444.     compare_zero();
  445.     if (L_temp1 <= 0) {
  446. corr = 0;    data_move();
  447.     }
  448.     else {
  449.         corr = extract_h(L_temp1);
  450.     }
  451.     /* Q value of *pcorr =       Q(L_temp1)                 X+14
  452.                                - extract_h                -   16
  453.        + scale in divide_s()      +   15
  454.        - Q(temp)                  -(X-2)
  455.                                   =   15   */
  456.     /* increment complexity for if statement */
  457.     compare_nonzero();
  458.     if (corr < temp) {
  459. *pcorr = shr(divide_s(corr,temp),1);    data_move();
  460.     }
  461.     else if (temp <= 0) {
  462. *pcorr = 0;          data_move();
  463.     }
  464.     else {
  465. *pcorr = ONE_Q14;    data_move();
  466.     }
  467.     
  468.     /* Return fractional pitch value */
  469.     return(fpitch);
  470. }
  471. #undef MAXFRAC
  472. #undef MINFRAC
  473. /*
  474.     Name: p_avg_update.c
  475.     Description: Update pitch average value.
  476.     Inputs:
  477.       pitch - current pitch value
  478.       pcorr - correlation strength at current pitch value
  479.       pthresh - pitch correlation threshold
  480.     Returns: pitch_avg - updated average pitch value
  481.     Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
  482. */
  483. /* Static constants */
  484. static Shortword PDECAY_Q15;
  485. static Shortword DEFAULT_PITCH_Q7;
  486. static Shortword PDECAY_PITCH_Q7;
  487. static Shortword NUM_GOOD;
  488. /* Static data */
  489. static Shortword *good_pitch;
  490. Shortword p_avg_update(Shortword pitch, Shortword pcorr, Shortword pthresh)
  491. {
  492.     Shortword i;
  493.     Shortword pitch_avg;
  494.     Shortword temp;
  495.     /* Strong correlation: update good pitch array */
  496.     if (pcorr > pthresh) {
  497. for (i = NUM_GOOD-1; i >= 1; i--)
  498.   good_pitch[i] = good_pitch[i-1];
  499. good_pitch[0] = pitch;
  500.     }
  501.     
  502.     /* Otherwise decay good pitch array to default value */
  503.     else {
  504.       for (i = 0; i < NUM_GOOD; i++) {
  505.   /* good_pitch[i] = 
  506.          (PDECAY*good_pitch[i]) +((1.0-PDECAY)*DEFAULT_PITCH); */
  507.   temp = mult(PDECAY_Q15,good_pitch[i]);
  508.   good_pitch[i] = add(temp,PDECAY_PITCH_Q7);
  509.       }
  510.     }
  511.     
  512.     /* Pitch_avg = median of pitch values */
  513.     pitch_avg = median(good_pitch,NUM_GOOD);
  514.     return(pitch_avg);
  515. }
  516. void p_avg_init(Shortword pdecay, Shortword default_pitch, 
  517. Shortword pdecay_pitch, Shortword num_good)
  518. {
  519.     /* Initialize constants */
  520.     PDECAY_Q15 = pdecay;
  521.     DEFAULT_PITCH_Q7 = default_pitch;
  522.     PDECAY_PITCH_Q7 = pdecay_pitch;
  523.     NUM_GOOD = num_good;
  524.     /* Allocate and initialize good pitch array */
  525.     MEM_ALLOC(malloc,good_pitch,NUM_GOOD,Shortword);
  526.     fill(good_pitch,DEFAULT_PITCH_Q7,NUM_GOOD);
  527. }
  528. /*
  529.     Name: pitch_ana.c
  530.     Description: Pitch analysis - outputs candidates
  531.     Inputs:
  532.       resid[] - input residual signal
  533.       pitch_est - initial (floating point) pitch estimate
  534.     Outputs: 
  535.       pitch_cand - pitch candidates for frame
  536.       pcorr - pitch correlation strengths for candidates
  537.     Returns: void
  538.     See_Also:
  539.     Includes:
  540.         spbstd.h
  541. mat.h
  542.     Organization:
  543.          Speech Research, Corporate R&D
  544.          Texas Instruments
  545.     Author: Alan McCree
  546.     Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
  547. */
  548. /* Compiler constants */
  549. /* Added 1 to variables which appear in comparison statements to make it
  550.    bit-exact as tested version */
  551. #define UVMAX       (9011+1)  /* (0.55*(1<<14)) */     /* Q14 */
  552. #define PCORR_THR   (9830+1)  /* (0.6*(1<<14)) */      /* Q14 */
  553. #define PDOUBLE1    96        /* (0.75*(1<<7)) */      /* Q7 */
  554. #define PDOUBLE2    64        /* (0.5*(1<<7)) */       /* Q7 */
  555. #define PDOUBLE3    115       /* (0.9*(1<<7)) */       /* Q7 */
  556. #define PDOUBLE4    89        /* (0.7*(1<<7)) */       /* Q7 */
  557. #define LONG_PITCH  12800     /* (100.0*(1<<7)) */     /* Q7 */
  558. #define LPF_ORD_SOS 2
  559. /* Static constants */
  560. static Shortword PITCHMAX;
  561. static Shortword PITCHMIN;
  562. static Shortword PITCHMAX_Q7;
  563. static Shortword PITCHMIN_Q7;
  564. static Shortword FRAME;
  565. static Shortword LPF_ORD;
  566. static Shortword PITCH_FR;
  567. static Shortword LMIN;
  568. /* External variables */
  569. extern Shortword lpf_num[], lpf_den[];
  570. /* Static data */
  571. static Shortword *lpres_delin;
  572. static Shortword *lpres_delout;
  573. static Shortword *sigbuf;
  574. /* Q values 
  575.    --------
  576.    speech - Q0
  577.    resid - Q0
  578.    pitch_est - Q7
  579.    pitch_avg - Q7
  580.    pcorr2 - Q14
  581. */
  582. Shortword pitch_ana(Shortword speech[],Shortword resid[],
  583.     Shortword pitch_est,Shortword pitch_avg, 
  584.     Shortword *pcorr2)
  585. {
  586.     Shortword i,section;
  587.     Shortword temp, temp2, pcorr, pitch;
  588.     Shortword *lpf_res;
  589.     Shortword *temp_delin;
  590.     Shortword *temp_delout;
  591.     
  592.     /* Allocate and initialize delay memory */
  593.     MEM_ALLOC(malloc,temp_delin,LPF_ORD,Shortword);
  594.     MEM_ALLOC(malloc,temp_delout,LPF_ORD,Shortword);
  595.     /* Lowpass filter residual signal */
  596.     v_equ(&sigbuf[LPF_ORD_SOS],&resid[-PITCHMAX],PITCH_FR);
  597.     for (section=0; section<LPF_ORD/2; section++) {
  598.       iir_2nd_s(&sigbuf[LPF_ORD_SOS],&lpf_den[section*3],
  599. &lpf_num[section*3],&sigbuf[LPF_ORD_SOS],
  600. &lpres_delin[section*2],&lpres_delout[section*2],FRAME);
  601.       /* save delay buffers for the next overlapping frame */
  602.       for (i = section*2; i < section*2+2; i++) {
  603.         temp_delin[i] = lpres_delin[i];      data_move();
  604.         temp_delout[i] = lpres_delout[i];      data_move();
  605.       }
  606.       iir_2nd_s(&sigbuf[LPF_ORD_SOS+FRAME],&lpf_den[section*3],
  607.                 &lpf_num[section*3],&sigbuf[LPF_ORD_SOS+FRAME],
  608.                 &lpres_delin[section*2],&lpres_delout[section*2],
  609. (Shortword)(PITCH_FR-FRAME));
  610.       /* restore delay buffers for the next overlapping frame */
  611.       for (i = section*2; i < section*2+2; i++) {
  612.         lpres_delin[i] = temp_delin[i];      data_move();
  613.         lpres_delout[i] = temp_delout[i];      data_move();
  614.       }
  615.     }
  616.     lpf_res = &sigbuf[LPF_ORD_SOS+(PITCH_FR/2)];  
  617.     /* Scale lowpass residual for pitch correlations */
  618.     f_pitch_scale(&sigbuf[LPF_ORD_SOS],&sigbuf[LPF_ORD_SOS],PITCH_FR);
  619.     /* Perform local search around pitch estimate */
  620.     temp = frac_pch(&sigbuf[LPF_ORD_SOS+(PITCH_FR/2)],&pcorr,
  621.     pitch_est,5,PITCHMIN,PITCHMAX,PITCHMIN_Q7,
  622.     PITCHMAX_Q7,LMIN);
  623.     if (pcorr < PCORR_THR) {
  624.       /* If correlation is too low, try speech signal instead */
  625.       v_equ(&sigbuf[LPF_ORD],&speech[-PITCHMAX],PITCH_FR);
  626.       /* Scale speech for pitch correlations */
  627.       f_pitch_scale(&sigbuf[LPF_ORD_SOS],&sigbuf[LPF_ORD_SOS],PITCH_FR);
  628.       temp = frac_pch(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr,
  629.       pitch_est,0,PITCHMIN,PITCHMAX,PITCHMIN_Q7,
  630.       PITCHMAX_Q7,LMIN);
  631.       if (pcorr < UVMAX)
  632. /* If correlation still too low, use average pitch */
  633. pitch = pitch_avg;
  634.       else {
  635. /* Else check for pitch doubling (speech thresholds) */
  636. temp2 = (Shortword)PDOUBLE3;
  637. if (temp > LONG_PITCH)
  638.   /* longer pitches are more likely to be doubles */
  639.   temp2 = (Shortword)PDOUBLE4;
  640. pitch = double_chk(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr,
  641.    temp,temp2,PITCHMIN,PITCHMAX,PITCHMIN_Q7,
  642.    PITCHMAX_Q7,LMIN);
  643.       }
  644.     }
  645.     else {
  646.       /* Else check for pitch doubling (residual thresholds) */
  647.       temp2 = (Shortword)PDOUBLE1;
  648.       if (temp > LONG_PITCH)
  649. /* longer pitches are more likely to be doubles */
  650. temp2 = (Shortword)PDOUBLE2;
  651.       pitch = double_chk(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr,
  652.  temp,temp2,PITCHMIN,PITCHMAX,PITCHMIN_Q7,
  653.  PITCHMAX_Q7,LMIN);
  654.     }
  655.     if (pcorr < UVMAX) {
  656. /* If correlation still too low, use average pitch */
  657. pitch = pitch_avg;
  658.     }
  659.     MEM_FREE(FREE,temp_delin);
  660.     MEM_FREE(FREE,temp_delout);
  661.     /* Return pitch and set correlation strength */
  662.     *pcorr2 = pcorr;
  663.     return(pitch);
  664. } /* pitch_ana */
  665. void pitch_ana_init(Shortword pmin,Shortword pmax,Shortword fr,
  666.     Shortword lpf_ord, Shortword lmin)
  667. {
  668.     /* Initialize constants */
  669.     FRAME = fr;
  670.     PITCHMIN = pmin;
  671.     PITCHMAX = pmax;
  672.     PITCHMIN_Q7 = shl(pmin,7);
  673.     PITCHMAX_Q7 = shl(pmax,7);
  674.     LPF_ORD = lpf_ord;
  675.     LMIN = lmin;
  676.     PITCH_FR = ((2*PITCHMAX)+1);
  677.     /* Allocate and initialize delay memory */
  678.     MEM_ALLOC(malloc,lpres_delin,LPF_ORD,Shortword);
  679.     MEM_ALLOC(malloc,lpres_delout,LPF_ORD,Shortword);
  680.     v_zap(lpres_delin,LPF_ORD);
  681.     v_zap(lpres_delout,LPF_ORD);
  682.     /* Allocate scratch buffer */
  683.     MEM_ALLOC(malloc,sigbuf,(LPF_ORD+PITCH_FR),Shortword);
  684. }