📄 lsp.c
字号:
#endif px = P; /* re-initialise ptrs */ qx = Q; /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z). Keep alternating between the two polynomials as each zero is found */ xr = 0; /* initialise xr to zero */ xl = FREQ_SCALE; /* start at point xl = 1 */ for(j=0;j<lpcrdr;j++){ if(j&1) /* determines whether P' or Q' is eval. */ pt = qx; else pt = px; psuml = cheb_poly_eva(pt,xl,lpcrdr,stack); /* evals poly. at xl */ flag = 1; while(flag && (xr >= -FREQ_SCALE)){ spx_word16_t dd; /* Modified by JMV to provide smaller steps around x=+-1 */#ifdef FIXED_POINT dd = MULT16_16_Q15(delta,SUB16(FREQ_SCALE, MULT16_16_Q14(MULT16_16_Q14(xl,xl),14000))); if (psuml<512 && psuml>-512) dd = PSHR16(dd,1);#else dd=delta*(1-.9*xl*xl); if (fabs(psuml)<.2) dd *= .5;#endif xr = SUB16(xl, dd); /* interval spacing */ psumr = cheb_poly_eva(pt,xr,lpcrdr,stack);/* poly(xl-delta_x) */ temp_psumr = psumr; temp_xr = xr; /* if no sign change increment xr and re-evaluate poly(xr). Repeat til sign change. if a sign change has occurred the interval is bisected and then checked again for a sign change which determines in which interval the zero lies in. If there is no sign change between poly(xm) and poly(xl) set interval between xm and xr else set interval between xl and xr and repeat till root is located within the specified limits */ if(SIGN_CHANGE(psumr,psuml)) { roots++; psumm=psuml; for(k=0;k<=nb;k++){#ifdef FIXED_POINT xm = ADD16(PSHR16(xl,1),PSHR16(xr,1)); /* bisect the interval */#else xm = .5*(xl+xr); /* bisect the interval */#endif psumm=cheb_poly_eva(pt,xm,lpcrdr,stack); /*if(psumm*psuml>0.)*/ if(!SIGN_CHANGE(psumm,psuml)) { psuml=psumm; xl=xm; } else { psumr=psumm; xr=xm; } } /* once zero is found, reset initial interval to xr */ freq[j] = X2ANGLE(xm); xl = xm; flag = 0; /* reset flag for next search */ } else{ psuml=temp_psumr; xl=temp_xr; } } } return(roots);}/*---------------------------------------------------------------------------*\ FUNCTION....: lsp_to_lpc() AUTHOR......: David Rowe DATE CREATED: 24/2/93 lsp_to_lpc: This function converts LSP coefficients to LPC coefficients.\*---------------------------------------------------------------------------*/#ifdef FIXED_POINTvoid lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)/* float *freq array of LSP frequencies in the x domain *//* float *ak array of LPC coefficients *//* int lpcrdr order of LPC coefficients */{ int i,j; spx_word32_t xout1,xout2,xin1,xin2; VARDECL(spx_word32_t *Wp); spx_word32_t *pw,*n1,*n2,*n3,*n4=NULL; VARDECL(spx_word16_t *freqn); int m = lpcrdr>>1; ALLOC(freqn, lpcrdr, spx_word16_t); for (i=0;i<lpcrdr;i++) freqn[i] = ANGLE2X(freq[i]); ALLOC(Wp, 4*m+2, spx_word32_t); pw = Wp; /* initialise contents of array */ for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */ *pw++ = 0; } /* Set pointers up */ pw = Wp; xin1 = 1048576; xin2 = 1048576; /* reconstruct P(z) and Q(z) by cascading second order polynomials in form 1 - 2xz(-1) +z(-2), where x is the LSP coefficient */ for(j=0;j<=lpcrdr;j++){ spx_word16_t *fr=freqn; for(i=0;i<m;i++){ n1 = pw+(i<<2); n2 = n1 + 1; n3 = n2 + 1; n4 = n3 + 1; xout1 = ADD32(SUB32(xin1, MULT16_32_Q14(*fr,*n1)), *n2); fr++; xout2 = ADD32(SUB32(xin2, MULT16_32_Q14(*fr,*n3)), *n4); fr++; *n2 = *n1; *n4 = *n3; *n1 = xin1; *n3 = xin2; xin1 = xout1; xin2 = xout2; } xout1 = xin1 + *(n4+1); xout2 = xin2 - *(n4+2); /* FIXME: perhaps apply bandwidth expansion in case of overflow? */ if (j>0) { if (xout1 + xout2>SHL32(EXTEND32(32766),8)) ak[j-1] = 32767; else if (xout1 + xout2 < -SHL32(EXTEND32(32766),8)) ak[j-1] = -32767; else ak[j-1] = EXTRACT16(PSHR32(ADD32(xout1,xout2),8)); } else {/*speex_warning_int("ak[0] = ", EXTRACT16(PSHR32(ADD32(xout1,xout2),8)));*/} *(n4+1) = xin1; *(n4+2) = xin2; xin1 = 0; xin2 = 0; }}#elsevoid lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)/* float *freq array of LSP frequencies in the x domain *//* float *ak array of LPC coefficients *//* int lpcrdr order of LPC coefficients */{ int i,j; float xout1,xout2,xin1,xin2; VARDECL(float *Wp); float *pw,*n1,*n2,*n3,*n4=NULL; VARDECL(float *x_freq); int m = lpcrdr>>1; ALLOC(Wp, 4*m+2, float); pw = Wp; /* initialise contents of array */ for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */ *pw++ = 0.0; } /* Set pointers up */ pw = Wp; xin1 = 1.0; xin2 = 1.0; ALLOC(x_freq, lpcrdr, float); for (i=0;i<lpcrdr;i++) x_freq[i] = ANGLE2X(freq[i]); /* reconstruct P(z) and Q(z) by cascading second order polynomials in form 1 - 2xz(-1) +z(-2), where x is the LSP coefficient */ for(j=0;j<=lpcrdr;j++){ int i2=0; for(i=0;i<m;i++,i2+=2){ n1 = pw+(i*4); n2 = n1 + 1; n3 = n2 + 1; n4 = n3 + 1; xout1 = xin1 - 2.f*x_freq[i2] * *n1 + *n2; xout2 = xin2 - 2.f*x_freq[i2+1] * *n3 + *n4; *n2 = *n1; *n4 = *n3; *n1 = xin1; *n3 = xin2; xin1 = xout1; xin2 = xout2; } xout1 = xin1 + *(n4+1); xout2 = xin2 - *(n4+2); if (j>0) ak[j-1] = (xout1 + xout2)*0.5f; *(n4+1) = xin1; *(n4+2) = xin2; xin1 = 0.0; xin2 = 0.0; }}#endif#ifdef FIXED_POINT/*Makes sure the LSPs are stable*/void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin){ int i; spx_word16_t m = margin; spx_word16_t m2 = 25736-margin; if (lsp[0]<m) lsp[0]=m; if (lsp[len-1]>m2) lsp[len-1]=m2; for (i=1;i<len-1;i++) { if (lsp[i]<lsp[i-1]+m) lsp[i]=lsp[i-1]+m; if (lsp[i]>lsp[i+1]-m) lsp[i]= SHR16(lsp[i],1) + SHR16(lsp[i+1]-m,1); }}void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes){ int i; spx_word16_t tmp = DIV32_16(SHL32(EXTEND32(1 + subframe),14),nb_subframes); spx_word16_t tmp2 = 16384-tmp; for (i=0;i<len;i++) { interp_lsp[i] = MULT16_16_P14(tmp2,old_lsp[i]) + MULT16_16_P14(tmp,new_lsp[i]); }}#else/*Makes sure the LSPs are stable*/void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin){ int i; if (lsp[0]<LSP_SCALING*margin) lsp[0]=LSP_SCALING*margin; if (lsp[len-1]>LSP_SCALING*(M_PI-margin)) lsp[len-1]=LSP_SCALING*(M_PI-margin); for (i=1;i<len-1;i++) { if (lsp[i]<lsp[i-1]+LSP_SCALING*margin) lsp[i]=lsp[i-1]+LSP_SCALING*margin; if (lsp[i]>lsp[i+1]-LSP_SCALING*margin) lsp[i]= .5f* (lsp[i] + lsp[i+1]-LSP_SCALING*margin); }}void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes){ int i; float tmp = (1.0f + subframe)/nb_subframes; for (i=0;i<len;i++) { interp_lsp[i] = (1-tmp)*old_lsp[i] + tmp*new_lsp[i]; }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -