pit_lib.c
上传用户:luckfish
上传日期:2021-12-16
资源大小:77k
文件大小:11k
源码类别:

语音压缩

开发平台:

Visual C++

  1. /*
  2. 2.4 kbps MELP Proposed Federal Standard speech coder
  3. version 1.2
  4. Copyright (c) 1996, 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. */
  11. /*
  12.   pit_lib.c: pitch analysis subroutines 
  13. */
  14. #include <stdio.h>
  15. #include <math.h>
  16. #include "spbstd.h"
  17. #include "mat.h"
  18. #include "melp_sub.h"
  19. #include "dsp_sub.h"
  20. #include "pit.h"
  21. /*                                                                  */
  22. /*  double_chk.c: check for pitch doubling                          */
  23. /*  and also verify pitch multiple for short pitches.               */
  24. /*                                                                  */
  25. #define NUM_MULT 8
  26. float double_chk(float sig_in[], float *pcorr, float pitch, float pdouble, int pmin, int pmax, int lmin)
  27. {
  28.     int mult;
  29.     float corr,thresh;
  30.     float temp_pit;
  31.     pitch = frac_pch(sig_in,pcorr,pitch,0,pmin,pmax,lmin);
  32.     thresh = pdouble * (*pcorr);
  33.     /* Check pitch submultiples from shortest to longest */
  34.     for (mult = NUM_MULT; mult >= 2; mult--) {
  35. temp_pit = pitch / mult;
  36. if (temp_pit >= pmin) {
  37.     temp_pit = frac_pch(sig_in,&corr,temp_pit,0,pmin,pmax,lmin);
  38.     double_ver(sig_in,&corr,temp_pit,pmin,pmax,lmin);
  39.     
  40.     /* stop if submultiple greater than threshold */
  41.     if (corr > thresh) {
  42. /* refine estimate one more time since previous window */
  43. /* may be off center slightly and temp_pit has moved */
  44. pitch = frac_pch(sig_in,pcorr,temp_pit,0,pmin,pmax,lmin);
  45. break;
  46.     }
  47. }
  48.     }
  49.     /* Verify pitch multiples for short pitches */
  50.     double_ver(sig_in,pcorr,pitch,pmin,pmax,lmin);
  51.     /* Return full floating point pitch value and correlation*/
  52.     return(pitch);
  53. }
  54. #undef NUM_MULT
  55. /*                                                                  */
  56. /*  double_ver.c: verify pitch multiple for short pitches.          */
  57. /*                                                                  */
  58. #define SHORT_PITCH 30
  59. void double_ver(float sig_in[], float *pcorr, float pitch, int pmin, int pmax, int lmin)
  60. {
  61.     int mult;
  62.     float corr,temp_pit;
  63.     /* Verify pitch multiples for short pitches */
  64.     mult = 1;
  65.     while (pitch*mult < SHORT_PITCH)
  66.       mult++;
  67.     if (mult > 1) {
  68. temp_pit = pitch * mult;
  69. temp_pit = frac_pch(sig_in,&corr,temp_pit,0,pmin,pmax,lmin);
  70.     
  71. /* use smaller of two correlation values */
  72. if (corr < *pcorr)
  73.   *pcorr = corr;
  74.     }
  75. }
  76. #undef SHORT_PITCH
  77. /*                                                                  */
  78. /*  find_pitch.c: Determine pitch value.                            */
  79. /*                                                                  */
  80. float find_pitch(float sig_in[], float *pcorr, int lower, int upper, 
  81.  int length)
  82. {
  83.     int i,cbegin,ipitch,even_flag;
  84.     float corr,maxcorr;
  85.     float c0_0,cT_T;
  86.     /* Find beginning of correlation window centered on signal */
  87.     ipitch = lower;
  88.     maxcorr = 0.0;
  89.     even_flag = 1;
  90.     cbegin = - ((length+upper)/2);
  91.     c0_0 = v_magsq(&sig_in[cbegin],length);
  92.     cT_T = v_magsq(&sig_in[cbegin+upper],length);
  93.     for (i = upper; i >= lower; i--) {
  94. /* calculate normalized crosscorrelation */
  95. corr  = v_inner(&sig_in[cbegin],&sig_in[cbegin+i],length);
  96. if (corr > 0.01)
  97.   corr = (corr*corr) / (c0_0*cT_T);
  98. /* check if current maximum value */
  99. if (corr > maxcorr) {
  100.     maxcorr = corr;
  101.     ipitch = i;
  102. }
  103. /* update for next iteration */
  104. if (even_flag) {
  105.     even_flag = 0;
  106.     c0_0 += (sig_in[cbegin+length]*sig_in[cbegin+length]);
  107.     c0_0 -= (sig_in[cbegin]*sig_in[cbegin]);
  108.     cbegin++;
  109. }
  110. else {
  111.     even_flag = 1;
  112.     cT_T += (sig_in[cbegin+i-1]*sig_in[cbegin+i-1]);
  113.     cT_T -= (sig_in[cbegin+i-1+length]*sig_in[cbegin+i-1+length]);
  114. }
  115.     
  116.     }
  117.     /* Return full floating point pitch value and correlation*/
  118.     *pcorr = sqrt(maxcorr);
  119.     return((float) ipitch);
  120. }
  121. /*
  122.     Name: frac_pch.c
  123.     Description: Determine fractional pitch.
  124.     Inputs:
  125.       sig_in - input signal
  126.       fpitch - initial floating point pitch estimate
  127.       range - range for local integer pitch search (0=none)
  128.       pmin - minimum allowed pitch value
  129.       pmax - maximum allowed pitch value
  130.       lmin - minimum correlation length
  131.     Outputs:
  132.       pcorr - correlation at fractional pitch value
  133.     Returns: fpitch - fractional pitch value
  134.     Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
  135. */
  136. #define MAXFRAC 2.0
  137. #define MINFRAC -1.0
  138. float frac_pch(float sig_in[], float *pcorr, float fpitch, int range, int pmin, int pmax, int lmin)
  139. {
  140.     int length,cbegin,lower,upper,ipitch;
  141.     float c0_0,c0_T,c0_T1,cT_T,cT_T1,cT1_T1,c0_Tm1;
  142.     float frac,frac1;
  143.     float corr,denom;
  144.     /* Perform local integer pitch search for better fpitch estimate */
  145.     if (range > 0) {
  146. ipitch = fpitch + 0.5;
  147. lower = ipitch - range;
  148. upper = ipitch + range;
  149. if (upper > pmax)
  150.   upper = pmax;
  151. if (lower < pmin)
  152.   lower = pmin;
  153. if (lower < 0.75*ipitch)
  154.   lower = 0.75*ipitch;
  155. length = ipitch;
  156. if (length < lmin)
  157.   length = lmin;
  158. fpitch = find_pitch(sig_in,&corr,lower,upper,length);
  159.     }
  160.     /* Estimate needed crosscorrelations */
  161.     ipitch = fpitch + 0.5;
  162.     if (ipitch >= pmax)
  163.       ipitch = pmax - 1;
  164.     length = ipitch;
  165.     if (length < lmin)
  166.       length = lmin;
  167.     cbegin = - ((length+ipitch)/2);
  168.     c0_T = v_inner(&sig_in[cbegin],&sig_in[cbegin+ipitch],length);
  169.     c0_T1 = v_inner(&sig_in[cbegin],&sig_in[cbegin+ipitch+1],length);
  170.     c0_Tm1 = v_inner(&sig_in[cbegin],&sig_in[cbegin+ipitch-1],length);
  171.     if (c0_Tm1 > c0_T1) {
  172. /* fractional component should be less than 1, so decrement pitch */
  173. c0_T1 = c0_T;
  174. c0_T = c0_Tm1;
  175. ipitch-- ;
  176.     }
  177.     cT_T1 = v_inner(&sig_in[cbegin+ipitch],&sig_in[cbegin+ipitch+1],length);
  178.     c0_0 = v_inner(&sig_in[cbegin],&sig_in[cbegin],length);
  179.     cT_T = v_inner(&sig_in[cbegin+ipitch],&sig_in[cbegin+ipitch],length);
  180.     cT1_T1 = v_inner(&sig_in[cbegin+ipitch+1],&sig_in[cbegin+ipitch+1],length);
  181.     /* Find fractional component of pitch within integer range */
  182.     denom = c0_T1*(cT_T - cT_T1) + c0_T*(cT1_T1 - cT_T1);
  183.     if (fabs(denom) > 0.01) 
  184.       frac = (c0_T1*cT_T - c0_T*cT_T1) / denom;
  185.     else
  186.       frac = 0.5;
  187.     if (frac > MAXFRAC)
  188.       frac = MAXFRAC;
  189.     if (frac < MINFRAC)
  190.       frac = MINFRAC;
  191.     /* Make sure pitch is still within range */
  192.     fpitch = ipitch + frac;
  193.     if (fpitch > pmax)
  194.       fpitch = pmax;
  195.     if (fpitch < pmin)
  196.       fpitch = pmin;
  197.     frac = fpitch - ipitch;    
  198.     /* Calculate interpolated correlation strength */
  199.     frac1 = 1.0 - frac;
  200.     denom = c0_0*(frac1*frac1*cT_T + 2*frac*frac1*cT_T1 + frac*frac*cT1_T1);
  201.     denom = sqrt(denom);
  202.     if (fabs(denom) > 0.01)
  203.       *pcorr = (frac1*c0_T + frac*c0_T1) / denom;
  204.     else
  205.       *pcorr = 0.0;
  206.     /* Return full floating point pitch value */
  207.     return(fpitch);
  208. }
  209. #undef MAXFRAC
  210. #undef MINFRAC
  211. /*
  212.     Name: p_avg_update.c
  213.     Description: Update pitch average value.
  214.     Inputs:
  215.       pitch - current pitch value
  216.       pcorr - correlation strength at current pitch value
  217.       pthresh - pitch correlation threshold
  218.     Returns: pitch_avg - updated average pitch value
  219.     Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
  220. */
  221. /* Static constants */
  222. static float PDECAY;
  223. static float DEFAULT_PITCH;
  224. static int NUM_GOOD;
  225. /* Static data */
  226. static float *good_pitch;
  227. float p_avg_update(float pitch, float pcorr, float pthresh)
  228. {
  229.     int i;
  230.     float pitch_avg;
  231.     /* Strong correlation: update good pitch array */
  232.     if (pcorr > pthresh) {
  233. for (i = NUM_GOOD-1; i >= 1; i--)
  234.   good_pitch[i] = good_pitch[i-1];
  235. good_pitch[0] = pitch;
  236.     }
  237.     
  238.     /* Otherwise decay good pitch array to default value */
  239.     else {
  240. for (i = 0; i < NUM_GOOD; i++)
  241.   good_pitch[i] = (PDECAY*good_pitch[i]) +((1.0-PDECAY)*DEFAULT_PITCH);
  242.     }
  243.     
  244.     /* Pitch_avg = median of pitch values */
  245.     pitch_avg = median(good_pitch,NUM_GOOD);
  246.     return(pitch_avg);
  247. }
  248. void p_avg_init(float pdecay, float default_pitch, int num_good)
  249. {
  250.     /* Initialize constants */
  251.     PDECAY = pdecay;
  252.     DEFAULT_PITCH = default_pitch;
  253.     NUM_GOOD = num_good;
  254.     /* Allocate and initialize good pitch array */
  255.     MEM_ALLOC(malloc,good_pitch,NUM_GOOD,float);
  256.     fill(good_pitch,DEFAULT_PITCH,NUM_GOOD);
  257. }
  258. /*
  259.     Name: pitch_ana.c
  260.     Description: Pitch analysis
  261.     Inputs:
  262.       speech[] - input speech signal
  263.       resid[] - LPC residual signal
  264.       pitch_est - initial (floating point) pitch estimate
  265.       pitch_avg - average pitch value
  266.     Outputs: 
  267.       pcorr2 - pitch correlation strength
  268.     Returns: pitch - pitch estimate
  269.     Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
  270. */
  271. /* Compiler constants */
  272. #define UVMAX 0.55
  273. #define PDOUBLE1 0.75
  274. #define PDOUBLE2 0.5
  275. #define PDOUBLE3 0.9
  276. #define PDOUBLE4 0.7
  277. #define LONG_PITCH 100.0
  278. /* Static constants */
  279. static int PITCHMAX;
  280. static int PITCHMIN;
  281. static int FRAME;
  282. static int LPF_ORD;
  283. static int PITCH_FR;
  284. static int LMIN;
  285. /* External variables */
  286. extern float lpf_num[], lpf_den[];
  287. /* Static data */
  288. static float *lpres_del;
  289. static float *sigbuf;
  290. float pitch_ana(float speech[], float resid[], float pitch_est, float pitch_avg, float *pcorr2)
  291. {
  292.     float temp, temp2, pcorr, pitch;
  293.     /* Lowpass filter residual signal */
  294.     v_equ(&sigbuf[LPF_ORD],&resid[-PITCHMAX],PITCH_FR);
  295.     v_equ(sigbuf,lpres_del,LPF_ORD);
  296.     polflt(&sigbuf[LPF_ORD],lpf_den,&sigbuf[LPF_ORD],LPF_ORD,PITCH_FR);
  297.     v_equ(lpres_del,&sigbuf[FRAME],LPF_ORD);
  298.     zerflt(&sigbuf[LPF_ORD],lpf_num,&sigbuf[LPF_ORD],LPF_ORD,PITCH_FR);
  299.     /* Perform local search around pitch estimate */
  300.     temp = frac_pch(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr,
  301.     pitch_est,5,PITCHMIN,PITCHMAX,LMIN);
  302.     
  303.     if (pcorr < 0.6) {
  304. /* If correlation is too low, try speech signal instead */
  305. v_equ(&sigbuf[LPF_ORD],&speech[-PITCHMAX],PITCH_FR);
  306. temp = frac_pch(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr,
  307. pitch_est,0,PITCHMIN,PITCHMAX,LMIN);
  308. if (pcorr < UVMAX)
  309.   /* If correlation still too low, use average pitch */
  310.   pitch = pitch_avg;
  311. else {
  312.     /* Else check for pitch doubling (speech thresholds) */
  313.     temp2 = PDOUBLE3;
  314.     if (temp > LONG_PITCH)
  315.       /* longer pitches are more likely to be doubles */
  316.       temp2 = PDOUBLE4;
  317.     pitch = double_chk(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr,
  318.     temp,temp2,PITCHMIN,PITCHMAX,LMIN);
  319. }
  320.     }
  321.     
  322.     else {
  323. /* Else check for pitch doubling (residual thresholds) */
  324. temp2 = PDOUBLE1;
  325. if (temp > LONG_PITCH)
  326.   /* longer pitches are more likely to be doubles */
  327.   temp2 = PDOUBLE2;
  328. pitch = double_chk(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr,
  329. temp,temp2,PITCHMIN,PITCHMAX,LMIN);
  330.     }
  331.     
  332.     if (pcorr < UVMAX) {
  333. /* If correlation still too low, use average pitch */
  334. pitch = pitch_avg;
  335.     }
  336.     /* Return pitch and set correlation strength */
  337.     *pcorr2 = pcorr;
  338.     return(pitch);
  339. }
  340. void pitch_ana_init(int pmin, int pmax, int fr, int lpf_ord, int lmin)
  341. {
  342.     /* Initialize constants */
  343.     FRAME = fr;
  344.     PITCHMIN = pmin;
  345.     PITCHMAX = pmax;
  346.     LPF_ORD = lpf_ord;
  347.     LMIN = lmin;
  348.     PITCH_FR = ((2*PITCHMAX)+1);
  349.     /* Allocate and initialize delay memory */
  350.     MEM_ALLOC(malloc,lpres_del,LPF_ORD,float);
  351.     v_zap(lpres_del,LPF_ORD);
  352.     /* Allocate scratch buffer */
  353.     MEM_ALLOC(malloc,sigbuf,LPF_ORD+PITCH_FR,float);
  354. }