pit_lib.c
资源名称:melpfix.rar [点击查看]
上传用户:cxx_68
上传日期:2021-02-21
资源大小:161k
文件大小:25k
源码类别:
语音压缩
开发平台:
Visual C++
- /*
- 2.4 kbps MELP Proposed Federal Standard speech coder
- Fixed-point C code, version 1.0
- Copyright (c) 1998, Texas Instruments, Inc.
- Texas Instruments has intellectual property rights on the MELP
- algorithm. The Texas Instruments contact for licensing issues for
- commercial and non-government use is William Gordon, Director,
- Government Contracts, Texas Instruments Incorporated, Semiconductor
- Group (phone 972 480 7442).
- The fixed-point version of the voice codec Mixed Excitation Linear
- Prediction (MELP) is based on specifications on the C-language software
- simulation contained in GSM 06.06 which is protected by copyright and
- is the property of the European Telecommunications Standards Institute
- (ETSI). This standard is available from the ETSI publication office
- tel. +33 (0)4 92 94 42 58. ETSI has granted a license to United States
- Department of Defense to use the C-language software simulation contained
- in GSM 06.06 for the purposes of the development of a fixed-point
- version of the voice codec Mixed Excitation Linear Prediction (MELP).
- Requests for authorization to make other use of the GSM 06.06 or
- otherwise distribute or modify them need to be addressed to the ETSI
- Secretariat fax: +33 493 65 47 16.
- */
- /*
- pit_lib.c: pitch analysis subroutines
- */
- #include <stdio.h>
- #include <math.h>
- #include "spbstd.h"
- #include "mathhalf.h"
- #include "mathdp31.h"
- #include "wmops.h"
- #include "mat.h"
- #include "math_lib.h"
- #include "dsp_sub.h"
- #include "pit.h"
- #include "constant.h"
- extern int saturation; /* saturation flag */
- /* */
- /* double_chk.c: check for pitch doubling */
- /* and also verify pitch multiple for short pitches. */
- /* */
- /* Q values
- --------
- sig_in - Q0
- pcorr - Q14
- pitch - Q7
- pdouble - Q7
- */
- #define NUM_MULT 8
- Shortword double_chk(Shortword sig_in[],Shortword *pcorr,Shortword pitch,
- Shortword pdouble,Shortword pmin,Shortword pmax,
- Shortword pmin_q7,Shortword pmax_q7,
- Shortword lmin)
- {
- Shortword mult;
- Shortword corr,thresh;
- Shortword temp_pit;
- Shortword temp1,temp2;
- Longword L_temp;
- pitch = frac_pch(sig_in,pcorr,pitch,0,pmin,pmax,pmin_q7,pmax_q7,lmin);
- /* compute threshold Q14*Q7>>8 */
- /* extra right shift to compensate left shift of L_mult */
- L_temp = L_mult(*pcorr,pdouble);
- L_temp = L_shr(L_temp,8);
- thresh = extract_l(L_temp); /* Q14 */
- /* Check pitch submultiples from shortest to longest */
- for (mult = NUM_MULT; mult >= 2; mult--) {
- /* temp_pit = pitch / mult */
- temp1 = 0; data_move();
- temp2 = shl(mult,11); /* Q11 */ data_move();
- temp_pit = pitch; data_move();
- while (temp_pit > temp2) {
- /* increment complexity for while statement */
- compare_nonzero();
- temp_pit = shr(temp_pit,1); data_move();
- temp1 = add(temp1,1); data_move();
- }
- /* Q7*Q15/Q11 -> Q11 */
- temp2 = divide_s(temp_pit,temp2); data_move();
- temp1 = sub(4,temp1); data_move();
- /* temp_pit=pitch/mult in Q7 */
- temp_pit = shr(temp2,temp1); data_move();
- /* increment complexity for if statement */
- compare_nonzero();
- if (temp_pit >= pmin_q7) {
- temp_pit = frac_pch(sig_in,&corr,temp_pit,0,pmin,pmax,pmin_q7,
- pmax_q7,lmin);
- double_ver(sig_in,&corr,temp_pit,pmin,pmax,pmin_q7,
- pmax_q7,lmin);
- /* stop if submultiple greater than threshold */
- /* increment complexity for if statement */
- compare_nonzero();
- if (corr > thresh) {
- /* refine estimate one more time since previous window */
- /* may be off center slightly and temp_pit has moved */
- pitch = frac_pch(sig_in,pcorr,temp_pit,0,pmin,pmax,pmin_q7,
- pmax_q7,lmin);
- break;
- }
- }
- }
- /* Verify pitch multiples for short pitches */
- double_ver(sig_in,pcorr,pitch,pmin,pmax,pmin_q7,pmax_q7,lmin);
- /* Return full floating point pitch value and correlation*/
- return(pitch);
- }
- #undef NUM_MULT
- /* */
- /* double_ver.c: verify pitch multiple for short pitches. */
- /* */
- /* Q values
- --------
- pitch - Q7
- pcorr - Q14
- */
- #define SHORT_PITCH 3840 /* (30*(1<<7)) */ /* Q7 */
- void double_ver(Shortword sig_in[],Shortword *pcorr,Shortword pitch,
- Shortword pmin,Shortword pmax,Shortword pmin_q7,
- Shortword pmax_q7,Shortword lmin)
- {
- Shortword multiple;
- Shortword corr,temp_pit;
- /* Verify pitch multiples for short pitches */
- multiple = 1; data_move();
- while (extract_l(L_shr(L_mult(pitch,multiple),1)) < SHORT_PITCH) {
- /* increment complexity for while statement */
- compare_nonzero();
- multiple=add(multiple,1); data_move();
- }
- /* increment complexity for if statement */
- compare_nonzero();
- if (multiple > 1) {
- temp_pit = extract_l(L_shr(L_mult(pitch,multiple),1));
- temp_pit = frac_pch(sig_in,&corr,temp_pit,0,pmin,pmax,
- pmin_q7,pmax_q7,lmin);
- /* use smaller of two correlation values */
- /* increment complexity for if statement */
- compare_nonzero();
- if (corr < *pcorr) {
- *pcorr = corr; data_move();
- }
- }
- }
- #undef SHORT_PITCH
- /* */
- /* f_pitch_scale.c: Scale pitch signal buffer for best precision */
- /* */
- Shortword f_pitch_scale(Shortword sig_out[],Shortword sig_in[],
- Shortword length)
- {
- int sat_save;
- Shortword scale;
- Shortword *temp_buf;
- Longword corr;
- /* allocate scratch buffer */
- MEM_ALLOC(MALLOC,temp_buf,length,Shortword);
- /* Compute signal buffer scale factor */
- sat_save = saturation;
- scale = 0;
- corr = L_v_magsq(sig_in, length, 0, 1);
- if (saturation > sat_save) {
- /* saturation: right shift input signal and try again */
- scale = 5;
- v_equ_shr(temp_buf,sig_in,scale,length);
- corr = L_v_magsq(temp_buf, length, 0, 1);
- /* could add delta to compensate possible truncation error */
- /* reset saturation counter */
- saturation = sat_save;
- }
- scale = sub(scale,shr(norm_l(corr),1));
- /* Scale signal buffer */
- v_equ_shr(sig_out,sig_in,scale,length);
- /* free scratch buffer */
- MEM_FREE(FREE,temp_buf);
- /* return scale factor */
- return(scale);
- }
- /* */
- /* find_pitch.c: Determine pitch value. */
- /* */
- /* Q values:
- sig_in - Q0
- ipitch - Q0
- *pcorr - Q14 */
- /*
- WARNING: this function assumes the input buffer has been normalized
- by f_pitch_scale.
- */
- Shortword find_pitch(Shortword sig_in[],Shortword *pcorr,Shortword lower,
- Shortword upper,Shortword length)
- {
- Shortword i,cbegin,ipitch,even_flag;
- Shortword s_corr;
- Shortword shift1a,shift1b,shift2,shift;
- Longword c0_0,cT_T,corr;
- Longword denom,max_denom,num,max_num;
- /* Find beginning of correlation window centered on signal */
- ipitch = lower; data_move();
- max_num = 0; data_move();
- max_denom = 1; data_move();
- even_flag = 1; data_move();
- /* cbegin = -((length+upper)/2) */
- cbegin = negate(shr(add(length,upper),1)); data_move();
- c0_0 = L_v_magsq(&sig_in[cbegin],length, 0, 1); L_data_move();
- cT_T = L_v_magsq(&sig_in[cbegin+upper],length, 0, 1); L_data_move();
- for (i = upper; i >= lower; i--) {
- /* calculate normalized crosscorrelation */
- corr= L_v_inner(&sig_in[cbegin],&sig_in[cbegin+i],length,0,0,1);
- /* calculate normalization for numerator and denominator */
- shift1a = norm_s(extract_h(c0_0));
- shift1b = norm_s(extract_h(cT_T));
- shift = add(shift1a,shift1b);
- shift2 = shr(shift,1); /* shift2 = half of total shift */
- if (shl(shift2,1) != shift)
- shift1a = sub(shift1a,1);
- /* check if current maximum value */
- if (corr > 0) {
- s_corr = extract_h(L_shl(corr,shift2));
- num = extract_h(L_mult(s_corr,s_corr));
- }
- else
- num = 0;
- denom = extract_h(L_mult(extract_h(L_shl(c0_0,shift1a)),
- extract_h(L_shl(cT_T,shift1b))));
- if (denom < 1)
- denom = 1;
- L_compare_nonzero();
- if (L_mult((Shortword)num,(Shortword)max_denom) > L_mult((Shortword)max_num,(Shortword)denom)) {
- max_denom = denom; data_move();
- max_num = num; data_move();
- ipitch = i; data_move();
- }
- /* update for next iteration */
- /* increment complexity for if statement */
- compare_zero();
- if (even_flag) {
- even_flag = 0; data_move();
- c0_0 = L_msu(c0_0,sig_in[cbegin],sig_in[cbegin]); L_data_move();
- c0_0 = L_mac(c0_0,sig_in[cbegin+length],
- sig_in[cbegin+length]); L_data_move();
- cbegin = add(cbegin,1); data_move();
- }
- else {
- even_flag = 1; data_move();
- cT_T = L_msu(cT_T, sig_in[cbegin+i-1+length],
- sig_in[cbegin+i-1+length]); L_data_move();
- cT_T = L_mac(cT_T, sig_in[cbegin+i-1], sig_in[cbegin+i-1]);
- L_data_move();
- }
- }
- /* Return pitch value and correlation*/
- *pcorr = shr(sqrt_fxp(divide_s((Shortword)max_num,(Shortword)max_denom),15),1);
- data_move();
- return(ipitch);
- }
- /*
- Name: frac_pch.c
- Description: Determine fractional pitch.
- Inputs:
- sig_in - input signal
- fpitch - initial floating point pitch estimate
- range - range for local integer pitch search (0=none)
- pmin - minimum allowed pitch value
- pmax - maximum allowed pitch value
- lmin - minimum correlation length
- Outputs:
- pcorr - correlation at fractional pitch value
- Returns: fpitch - fractional pitch value
- Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved.
- */
- /* Q values
- --------
- ipitch - Q0
- fpitch - Q7
- sig_in - Q0
- *pcorr - Q14
- */
- /*
- WARNING: this function assumes the input buffer has been normalized
- by f_pitch_scale.
- */
- #define MAXFRAC 16384 /* (2.0*(1<<13)) */ /* Q13 */
- #define MINFRAC -8192 /* (-1.0*(1<<13)) */ /* Q13 */
- Shortword frac_pch(Shortword sig_in[],Shortword *pcorr,Shortword fpitch,
- Shortword range,Shortword pmin,Shortword pmax,
- Shortword pmin_q7,Shortword pmax_q7,Shortword lmin)
- {
- Shortword length,cbegin,lower,upper,ipitch;
- Shortword c0_0,c0_T,c0_T1,cT_T,cT_T1,cT1_T1,c0_Tm1;
- Shortword shift1a,shift1b,shift2,shift;
- Shortword frac,frac1,corr;
- Shortword temp;
- Longword denom,denom1,denom2,denom3,numer;
- Longword mag_sq;
- Longword L_temp1;
- /* Perform local integer pitch search for better fpitch estimate */
- /* increment complexity for if statement */
- compare_zero();
- if (range > 0) {
- ipitch = shift_r(fpitch, -7); data_move();
- lower = sub(ipitch,range); data_move();
- upper = add(ipitch,range); data_move();
- /* increment complexity for if statement */
- compare_nonzero();
- if (upper > pmax) {
- upper = pmax; data_move();
- }
- /* increment complexity for if statement */
- compare_nonzero();
- if (lower < pmin) {
- lower = pmin; data_move();
- }
- /* increment complexity for if statement */
- compare_nonzero();
- if (lower < add(shr(ipitch,1),shr(ipitch,2))) {
- lower = add(shr(ipitch,1),shr(ipitch,2)); data_move();
- }
- length = ipitch; data_move();
- /* increment complexity for if statement */
- compare_nonzero();
- if (length < lmin) {
- length = lmin; data_move();
- }
- fpitch = shl(find_pitch(sig_in,&corr,lower,upper,length),7);
- data_move();
- }
- /* Estimate needed crosscorrelations */
- ipitch = shift_r(fpitch,-7); data_move();
- /* increment complexity for if statement */
- compare_nonzero();
- if (ipitch >= pmax) {
- ipitch = sub(pmax,1); data_move();
- }
- length = ipitch; data_move();
- /* increment complexity for if statement */
- compare_nonzero();
- if (length < lmin) {
- length = lmin; data_move();
- }
- cbegin = negate(shr(add(length,ipitch),1)); data_move();
- /* Calculate normalization for numerator and denominator */
- mag_sq = L_v_magsq(&sig_in[cbegin],length,0,1);
- shift1a = norm_s(extract_h(mag_sq));
- shift1b = norm_s(extract_h(
- L_v_magsq(&sig_in[cbegin+ipitch-1],(Shortword)(length+2),0,1)));
- shift = add(shift1a,shift1b);
- shift2 = shr(shift,1); /* shift2 = half of total shift */
- if (shl(shift2,1) != shift)
- shift1a = sub(shift1a,1);
- /* Calculate correlations with appropriate normalization */
- c0_0 = extract_h(L_shl(mag_sq,shift1a));
- c0_T = extract_h(L_shl(L_v_inner(&sig_in[cbegin],
- &sig_in[cbegin+ipitch],length,
- 0,0,1),shift2));
- c0_T1 = extract_h(L_shl(L_v_inner(&sig_in[cbegin],
- &sig_in[cbegin+ipitch+1],
- length,0,0,1),shift2));
- c0_Tm1 = extract_h(L_shl(L_v_inner(&sig_in[cbegin],
- &sig_in[cbegin+ipitch-1],
- length,0,0,1),shift2));
- /* increment complexity for if statement */
- compare_nonzero();
- if (c0_Tm1 > c0_T1) {
- /* fractional component should be less than 1, so decrement pitch */
- c0_T1 = c0_T; data_move();
- c0_T = c0_Tm1; data_move();
- ipitch = sub(ipitch,1) ; data_move();
- }
- cT_T1 = extract_h(L_shl(L_v_inner(&sig_in[cbegin+ipitch],
- &sig_in[cbegin+ipitch+1],length,
- 0,0,1),shift1b));
- cT_T = extract_h(L_shl(L_v_inner(&sig_in[cbegin+ipitch],
- &sig_in[cbegin+ipitch],length,
- 0,0,1),shift1b));
- cT1_T1 = extract_h(L_shl(L_v_inner(&sig_in[cbegin+ipitch+1],
- &sig_in[cbegin+ipitch+1],length,
- 0,0,1),shift1b));
- /* Find fractional component of pitch within integer range */
- /* frac = Q13 */
- denom = L_add(L_mult(c0_T1,sub(shr(cT_T,1),shr(cT_T1,1))),
- L_mult(c0_T,sub(shr(cT1_T1,1),shr(cT_T1,1))));
- L_data_move();
- numer = L_sub(L_shr(L_mult(c0_T1,cT_T),1), L_shr(L_mult(c0_T,cT_T1),1));
- L_data_move();
- /* increment complexity for if statement */
- compare_zero();
- L_temp1 = L_abs(denom);
- if (L_temp1 > 0) {
- if (L_abs(L_shr(numer,2)) > L_temp1) {
- if (((numer>0)&&(denom<0)) || ((numer<0)&&(denom>0)))
- frac = (Shortword)MINFRAC;
- else
- frac = (Shortword)MAXFRAC;
- }
- else
- frac = L_divider2(numer,denom,2,0); data_move();
- }
- else {
- frac = (Shortword)X05_Q13; data_move();
- }
- /* increment complexity for if statement */
- compare_nonzero();
- if (frac > MAXFRAC) {
- frac = (Shortword)MAXFRAC; data_move();
- }
- /* increment complexity for if statement */
- compare_nonzero();
- if (frac < MINFRAC) {
- frac = (Shortword)MINFRAC; data_move();
- }
- /* Make sure pitch is still within range */
- fpitch = add(shl(ipitch,7), shr(frac,6)); data_move();
- /* increment complexity for if statement */
- compare_nonzero();
- if (fpitch > pmax_q7) {
- fpitch = pmax_q7; data_move();
- frac = shl(sub(fpitch, shl(ipitch,7)),6); data_move();
- }
- /* increment complexity for if statement */
- compare_nonzero();
- if (fpitch < pmin_q7) {
- fpitch = pmin_q7; data_move();
- frac = shl(sub(fpitch, shl(ipitch,7)),6); data_move();
- }
- /* Calculate interpolated correlation strength */
- frac1 = sub(ONE_Q13 ,frac); data_move();
- /* Calculate denominator */
- data_move(); data_move(); data_move(); data_move();
- denom1 = L_shr(L_mpy_ls(L_mult(cT_T,frac1),frac1),1); /* Q(X+11) */
- denom2 = L_mpy_ls(L_mult(cT_T1,frac1),frac);
- denom3 = L_shr(L_mpy_ls(L_mult(cT1_T1,frac),frac),1); /* Q(X+11) */
- denom = L_mpy_ls(L_add(L_add(denom1,denom2),denom3),c0_0); /* Q(2X-4) */
- temp = L_sqrt_fxp(denom,0); /* temp in Q(X-2) */ data_move();
- /* Calculate numerator */
- L_temp1 = L_mult(c0_T,frac1); /* Q(X+14) */
- L_temp1 = L_mac(L_temp1,c0_T1,frac);
- compare_zero();
- if (L_temp1 <= 0) {
- corr = 0; data_move();
- }
- else {
- corr = extract_h(L_temp1);
- }
- /* Q value of *pcorr = Q(L_temp1) X+14
- - extract_h - 16
- + scale in divide_s() + 15
- - Q(temp) -(X-2)
- = 15 */
- /* increment complexity for if statement */
- compare_nonzero();
- if (corr < temp) {
- *pcorr = shr(divide_s(corr,temp),1); data_move();
- }
- else if (temp <= 0) {
- *pcorr = 0; data_move();
- }
- else {
- *pcorr = ONE_Q14; data_move();
- }
- /* Return fractional pitch value */
- return(fpitch);
- }
- #undef MAXFRAC
- #undef MINFRAC
- /*
- Name: p_avg_update.c
- Description: Update pitch average value.
- Inputs:
- pitch - current pitch value
- pcorr - correlation strength at current pitch value
- pthresh - pitch correlation threshold
- Returns: pitch_avg - updated average pitch value
- Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved.
- */
- /* Static constants */
- static Shortword PDECAY_Q15;
- static Shortword DEFAULT_PITCH_Q7;
- static Shortword PDECAY_PITCH_Q7;
- static Shortword NUM_GOOD;
- /* Static data */
- static Shortword *good_pitch;
- Shortword p_avg_update(Shortword pitch, Shortword pcorr, Shortword pthresh)
- {
- Shortword i;
- Shortword pitch_avg;
- Shortword temp;
- /* Strong correlation: update good pitch array */
- if (pcorr > pthresh) {
- for (i = NUM_GOOD-1; i >= 1; i--)
- good_pitch[i] = good_pitch[i-1];
- good_pitch[0] = pitch;
- }
- /* Otherwise decay good pitch array to default value */
- else {
- for (i = 0; i < NUM_GOOD; i++) {
- /* good_pitch[i] =
- (PDECAY*good_pitch[i]) +((1.0-PDECAY)*DEFAULT_PITCH); */
- temp = mult(PDECAY_Q15,good_pitch[i]);
- good_pitch[i] = add(temp,PDECAY_PITCH_Q7);
- }
- }
- /* Pitch_avg = median of pitch values */
- pitch_avg = median(good_pitch,NUM_GOOD);
- return(pitch_avg);
- }
- void p_avg_init(Shortword pdecay, Shortword default_pitch,
- Shortword pdecay_pitch, Shortword num_good)
- {
- /* Initialize constants */
- PDECAY_Q15 = pdecay;
- DEFAULT_PITCH_Q7 = default_pitch;
- PDECAY_PITCH_Q7 = pdecay_pitch;
- NUM_GOOD = num_good;
- /* Allocate and initialize good pitch array */
- MEM_ALLOC(malloc,good_pitch,NUM_GOOD,Shortword);
- fill(good_pitch,DEFAULT_PITCH_Q7,NUM_GOOD);
- }
- /*
- Name: pitch_ana.c
- Description: Pitch analysis - outputs candidates
- Inputs:
- resid[] - input residual signal
- pitch_est - initial (floating point) pitch estimate
- Outputs:
- pitch_cand - pitch candidates for frame
- pcorr - pitch correlation strengths for candidates
- Returns: void
- See_Also:
- Includes:
- spbstd.h
- mat.h
- Organization:
- Speech Research, Corporate R&D
- Texas Instruments
- Author: Alan McCree
- Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved.
- */
- /* Compiler constants */
- /* Added 1 to variables which appear in comparison statements to make it
- bit-exact as tested version */
- #define UVMAX (9011+1) /* (0.55*(1<<14)) */ /* Q14 */
- #define PCORR_THR (9830+1) /* (0.6*(1<<14)) */ /* Q14 */
- #define PDOUBLE1 96 /* (0.75*(1<<7)) */ /* Q7 */
- #define PDOUBLE2 64 /* (0.5*(1<<7)) */ /* Q7 */
- #define PDOUBLE3 115 /* (0.9*(1<<7)) */ /* Q7 */
- #define PDOUBLE4 89 /* (0.7*(1<<7)) */ /* Q7 */
- #define LONG_PITCH 12800 /* (100.0*(1<<7)) */ /* Q7 */
- #define LPF_ORD_SOS 2
- /* Static constants */
- static Shortword PITCHMAX;
- static Shortword PITCHMIN;
- static Shortword PITCHMAX_Q7;
- static Shortword PITCHMIN_Q7;
- static Shortword FRAME;
- static Shortword LPF_ORD;
- static Shortword PITCH_FR;
- static Shortword LMIN;
- /* External variables */
- extern Shortword lpf_num[], lpf_den[];
- /* Static data */
- static Shortword *lpres_delin;
- static Shortword *lpres_delout;
- static Shortword *sigbuf;
- /* Q values
- --------
- speech - Q0
- resid - Q0
- pitch_est - Q7
- pitch_avg - Q7
- pcorr2 - Q14
- */
- Shortword pitch_ana(Shortword speech[],Shortword resid[],
- Shortword pitch_est,Shortword pitch_avg,
- Shortword *pcorr2)
- {
- Shortword i,section;
- Shortword temp, temp2, pcorr, pitch;
- Shortword *lpf_res;
- Shortword *temp_delin;
- Shortword *temp_delout;
- /* Allocate and initialize delay memory */
- MEM_ALLOC(malloc,temp_delin,LPF_ORD,Shortword);
- MEM_ALLOC(malloc,temp_delout,LPF_ORD,Shortword);
- /* Lowpass filter residual signal */
- v_equ(&sigbuf[LPF_ORD_SOS],&resid[-PITCHMAX],PITCH_FR);
- for (section=0; section<LPF_ORD/2; section++) {
- iir_2nd_s(&sigbuf[LPF_ORD_SOS],&lpf_den[section*3],
- &lpf_num[section*3],&sigbuf[LPF_ORD_SOS],
- &lpres_delin[section*2],&lpres_delout[section*2],FRAME);
- /* save delay buffers for the next overlapping frame */
- for (i = section*2; i < section*2+2; i++) {
- temp_delin[i] = lpres_delin[i]; data_move();
- temp_delout[i] = lpres_delout[i]; data_move();
- }
- iir_2nd_s(&sigbuf[LPF_ORD_SOS+FRAME],&lpf_den[section*3],
- &lpf_num[section*3],&sigbuf[LPF_ORD_SOS+FRAME],
- &lpres_delin[section*2],&lpres_delout[section*2],
- (Shortword)(PITCH_FR-FRAME));
- /* restore delay buffers for the next overlapping frame */
- for (i = section*2; i < section*2+2; i++) {
- lpres_delin[i] = temp_delin[i]; data_move();
- lpres_delout[i] = temp_delout[i]; data_move();
- }
- }
- lpf_res = &sigbuf[LPF_ORD_SOS+(PITCH_FR/2)];
- /* Scale lowpass residual for pitch correlations */
- f_pitch_scale(&sigbuf[LPF_ORD_SOS],&sigbuf[LPF_ORD_SOS],PITCH_FR);
- /* Perform local search around pitch estimate */
- temp = frac_pch(&sigbuf[LPF_ORD_SOS+(PITCH_FR/2)],&pcorr,
- pitch_est,5,PITCHMIN,PITCHMAX,PITCHMIN_Q7,
- PITCHMAX_Q7,LMIN);
- if (pcorr < PCORR_THR) {
- /* If correlation is too low, try speech signal instead */
- v_equ(&sigbuf[LPF_ORD],&speech[-PITCHMAX],PITCH_FR);
- /* Scale speech for pitch correlations */
- f_pitch_scale(&sigbuf[LPF_ORD_SOS],&sigbuf[LPF_ORD_SOS],PITCH_FR);
- temp = frac_pch(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr,
- pitch_est,0,PITCHMIN,PITCHMAX,PITCHMIN_Q7,
- PITCHMAX_Q7,LMIN);
- if (pcorr < UVMAX)
- /* If correlation still too low, use average pitch */
- pitch = pitch_avg;
- else {
- /* Else check for pitch doubling (speech thresholds) */
- temp2 = (Shortword)PDOUBLE3;
- if (temp > LONG_PITCH)
- /* longer pitches are more likely to be doubles */
- temp2 = (Shortword)PDOUBLE4;
- pitch = double_chk(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr,
- temp,temp2,PITCHMIN,PITCHMAX,PITCHMIN_Q7,
- PITCHMAX_Q7,LMIN);
- }
- }
- else {
- /* Else check for pitch doubling (residual thresholds) */
- temp2 = (Shortword)PDOUBLE1;
- if (temp > LONG_PITCH)
- /* longer pitches are more likely to be doubles */
- temp2 = (Shortword)PDOUBLE2;
- pitch = double_chk(&sigbuf[LPF_ORD+(PITCH_FR/2)],&pcorr,
- temp,temp2,PITCHMIN,PITCHMAX,PITCHMIN_Q7,
- PITCHMAX_Q7,LMIN);
- }
- if (pcorr < UVMAX) {
- /* If correlation still too low, use average pitch */
- pitch = pitch_avg;
- }
- MEM_FREE(FREE,temp_delin);
- MEM_FREE(FREE,temp_delout);
- /* Return pitch and set correlation strength */
- *pcorr2 = pcorr;
- return(pitch);
- } /* pitch_ana */
- void pitch_ana_init(Shortword pmin,Shortword pmax,Shortword fr,
- Shortword lpf_ord, Shortword lmin)
- {
- /* Initialize constants */
- FRAME = fr;
- PITCHMIN = pmin;
- PITCHMAX = pmax;
- PITCHMIN_Q7 = shl(pmin,7);
- PITCHMAX_Q7 = shl(pmax,7);
- LPF_ORD = lpf_ord;
- LMIN = lmin;
- PITCH_FR = ((2*PITCHMAX)+1);
- /* Allocate and initialize delay memory */
- MEM_ALLOC(malloc,lpres_delin,LPF_ORD,Shortword);
- MEM_ALLOC(malloc,lpres_delout,LPF_ORD,Shortword);
- v_zap(lpres_delin,LPF_ORD);
- v_zap(lpres_delout,LPF_ORD);
- /* Allocate scratch buffer */
- MEM_ALLOC(malloc,sigbuf,(LPF_ORD+PITCH_FR),Shortword);
- }