?? lsp.c
字號:
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 + -