static inline spx_word32_t cheb_poly_eva( spx_word16_t *coef, /* P or Q coefs in Q13 format */ spx_word16_t x, /* cos of freq (-1.0 to 1.0) in Q14 format */ int m, /* LPC order/2 */ char *stack ) { int i; spx_word16_t b0, b1; spx_word32_t sum; /*Prevents overflows*/ if (x>16383) x = 16383; if (x<-16383) x = -16383; /* Initialise values */ b1=16384; b0=x; /* Evaluate Chebyshev series formulation usin g iterative approach */ sum = ADD32(EXTEND32(coef[m]), EXTEND32(MULT16_16_P14(coef[m-1],x))); for(i=2;i<=m;i++) { spx_word16_t tmp=b0; b0 = SUB16(MULT16_16_Q13(x,b0), b1); b1 = tmp; sum = ADD32(sum, EXTEND32(MULT16_16_P14(coef[m-i],b0))); } return sum; }
/* returns minimum mean square error */ spx_word32_t _spx_lpc( spx_coef_t *lpc, /* out: [0...p-1] LPC coefficients */ const spx_word16_t *ac, /* in: [0...p] autocorrelation values */ int p ) { int i, j; spx_word16_t r; spx_word16_t error = ac[0]; if (ac[0] == 0) { for (i = 0; i < p; i++) lpc[i] = 0; return 0; } for (i = 0; i < p; i++) { /* Sum up this iteration's reflection coefficient */ spx_word32_t rr = NEG32(SHL32(EXTEND32(ac[i + 1]),13)); for (j = 0; j < i; j++) rr = SUB32(rr,MULT16_16(lpc[j],ac[i - j])); #ifdef FIXED_POINT r = DIV32_16(rr+PSHR32(error,1),ADD16(error,8)); #else r = rr/(error+.003*ac[0]); #endif /* Update LPC coefficients and total error */ lpc[i] = r; for (j = 0; j < i>>1; j++) { spx_word16_t tmp = lpc[j]; lpc[j] = MAC16_16_P13(lpc[j],r,lpc[i-1-j]); lpc[i-1-j] = MAC16_16_P13(lpc[i-1-j],r,tmp); } if (i & 1) lpc[j] = MAC16_16_P13(lpc[j],lpc[j],r); error = SUB16(error,MULT16_16_Q13(r,MULT16_16_Q13(error,r))); } return error; }
static inline spx_word32_t cheb_poly_eva(spx_word32_t *coef,spx_word16_t x,int m,char *stack) /* float coef[] coefficients of the polynomial to be evaluated */ /* float x the point where polynomial is to be evaluated */ /* int m order of the polynomial */ { int i; spx_word16_t *T; spx_word32_t sum; int m2=m>>1; spx_word16_t *coefn; /*Prevents overflows*/ if (x>16383) x = 16383; if (x<-16383) x = -16383; /* Allocate memory for Chebyshev series formulation */ T=PUSH(stack, m2+1, spx_word16_t); coefn=PUSH(stack, m2+1, spx_word16_t); for (i=0;i<m2+1;i++) { coefn[i] = coef[i]; /*printf ("%f ", coef[i]);*/ } /*printf ("\n");*/ /* Initialise values */ T[0]=16384; T[1]=x; /* Evaluate Chebyshev series formulation using iterative approach */ /* Evaluate polynomial and return value also free memory space */ sum = ADD32(coefn[m2], MULT16_16_P14(coefn[m2-1],x)); /*x *= 2;*/ for(i=2;i<=m2;i++) { T[i] = MULT16_16_Q13(x,T[i-1]) - T[i-2]; sum = ADD32(sum, MULT16_16_P14(coefn[m2-i],T[i])); /*printf ("%f ", sum);*/ } /*printf ("\n");*/ return sum; }