lpc_lib.c
上传用户:csczyc
上传日期:2021-02-19
资源大小:1051k
文件大小:31k
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include "spbstd.h"
- #include "mathhalf.h"
- #include "mathdp31.h"
- #include "math_lib.h"
- #include "wmops.h"
- #include "mat.h"
- #include "lpc.h"
- #include "constant.h"
- extern Shortword frames;
- extern FILE *fp_outdat;
- #define PRINT 1
- #define ALMOST_ONE_Q14 16382
- Shortword lagw_cof[10] = {
- 32756,32721,32663,32582,32478,32351,32201,32030,31837,31622};
- void lpc_acor(Shortword input[],Shortword win_cof[],
- Shortword r[],Shortword hf_correction,
- Shortword lag_win,Shortword order,Shortword npts)
- {
- Shortword i,j;
- Longword L_temp;
- Shortword *inputw;
- Shortword norm_var, scale_fact, temp;
- Longword L_temp1,L_temp2,L_Prod;
- Shortword temp1;
- MEM_ALLOC(MALLOC,inputw,npts,Shortword);
- if (win_cof) {
- for(i=0; i < npts; i++) {
- L_temp1 = _shr2((Longword)(input[i]),(Longword)4);
- L_temp1 = _smpy(win_cof[i],(Shortword)(0x0000ffffL & L_temp1));
- inputw[i] = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- }
- }
- else {
- v_equ_shr(inputw,input,4,npts);
- }
-
- L_temp = L_v_magsq(inputw,npts,0,1);
- if (L_temp) {
- L_temp1 = _norm(L_temp);
- if (L_temp == 0){
- L_temp1 = (Shortword)0;
- }
- L_temp1 = _shr2(L_temp1,1);
- norm_var = (Shortword)(0x0000ffffL & L_temp1);
- norm_var = sub(4,norm_var);
- if (norm_var < 0)
- norm_var = 0;
- }
- else
- norm_var = 0;
- L_temp = L_v_magsq(inputw,npts,0,1);
- if (L_temp > 0) {
-
- L_temp1 = _norm(L_temp);
- norm_var = (Shortword) (0x0000ffffL & L_temp1);
- norm_var = sub(norm_var,1);
- L_temp = _sshvl(L_temp,norm_var);
- L_temp = _sadd(L_temp,L_mpy_ls(L_temp,hf_correction));
-
- temp1 = (Shortword) (0x0000ffffL & (L_temp >> 16));
- L_temp1 = (Longword) temp1 << 16;
- L_temp2 = _norm(L_temp1);
- temp = (Shortword) (0x0000ffffL & L_temp2);
- if (L_temp1 == 0){
- temp = (Shortword)0;
- }
- L_temp = _sshvl(L_temp,temp);
- L_temp1 = _sadd2((Longword)norm_var,(Longword)temp);
- norm_var = (Shortword) (0x0000ffffL & L_temp1);
- L_Prod = _sadd(L_temp, 0x00008000L);
- r[0] = (Shortword)(0x0000ffffL & (L_Prod >> 16));
- scale_fact = divide_s(ALMOST_ONE_Q14,r[0]);
- L_temp = _sshvl(L_mpy_ls(L_temp,scale_fact),1);
- L_Prod = _sadd(L_temp, 0x00008000L); /* round MSP */
- r[0] = (Shortword)(0x0000ffffL & (L_Prod >> 16));
- }
- else {
- norm_var = 0;
- r[0] = ONE_Q15;
- scale_fact = 0;
- }
- for(j=1; j <= order; j++)
- {
- L_temp = 0;
- for(i=j; i < npts; i++) {
- L_temp = _sadd(L_temp,_smpy(inputw[i],inputw[i-j]));
- }
- L_temp = _sshvl(L_temp,norm_var);
- L_temp = _sshvl(L_mpy_ls(L_temp,scale_fact),1);
-
- L_temp = L_mpy_ls(L_temp,lagw_cof[j-1]);
- L_Prod = _sadd(L_temp, 0x00008000L);
- r[j] = (Shortword)(0x0000ffffL & (L_Prod >> 16));
- }
-
- MEM_FREE(FREE,inputw);
- }
- #define LOW_LIMIT 54
- Longword lpc_aejw(Shortword *a,Shortword w, Shortword p)
- {
- Shortword i;
- Shortword c_re,c_im;
- Shortword cs,sn,temp;
- Shortword temp1,temp2;
- Longword L_temp;
- Longword L_temp1;
- if (p==0)
- return((Longword)ONE_Q19);
- cs = cos_fxp(w);
- sn = negate(sin_fxp(w));
- L_temp1 = _smpy(cs,a[p]);
- L_temp1 = _shr2(L_temp1,3);
- c_re = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- L_temp1 = _smpy(sn,a[p]);
- L_temp1 = _shr2(L_temp1,3);
- c_im = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- for(i=p-1; i > 0; i--)
- {
- L_temp1 = _shr2((Longword)a[i],3);
- L_temp1 = _sadd2((Longword)c_re,L_temp1);
- c_re = (Shortword) (0x0000ffffL & L_temp1);
- temp=c_im;
- L_temp1 = _smpy(cs,temp);
- temp1 = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- L_temp1 = _smpy(sn,c_re);
- temp2 = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- L_temp1 = _sadd2((Longword)temp1,(Longword)temp2);
- c_im = (Shortword) (0x0000ffffL & L_temp1);
- L_temp1 = _smpy(cs,c_re);
- temp1 = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- L_temp1 = _smpy(sn,temp);
- temp2 = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- c_re = sub(temp1,temp2);
- }
-
- L_temp1 = _sadd2((Longword)c_re,(Longword)ONE_Q9);
- c_re = (Shortword) (0x0000ffffL & L_temp1);
- L_temp = _sadd(_smpy(c_re,c_re),_smpy(c_im,c_im));
-
- if (L_temp<LOW_LIMIT)
- L_temp=(Longword)LOW_LIMIT;
-
- return(L_temp);
- }
- #undef LOW_LIMIT
- Shortword lpc_bwex(Shortword *a, Shortword *aw, Shortword gamma, Shortword p)
- {
- Shortword i;
- Shortword gk;
- Longword L_temp1,L_temp2;
- gk = gamma;
- for(i=1; i <= p; i++) {
- L_temp1 = _smpy(a[i],gk);
- aw[i] = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- L_temp2 = _smpy(gk,gamma);
- gk = (Shortword) (0x0000ffffL & (L_temp2 >> 16));
- }
- return((Shortword)0);
- }
- #define MAX_LOOPS 10
- Shortword lpc_clmp(Shortword *w, Shortword delta, Shortword p)
- {
- Shortword i,j,unsorted;
- Shortword temp,d,step1,step2;
- Longword L_temp;
-
- for (j=0,unsorted=TRUE; unsorted && (j < MAX_LOOPS); j++)
- {
- for(i=1,unsorted=FALSE; i < p; i++)
- if (w[i] > w[i+1])
- {
- temp = w[i+1];
- w[i+1] = w[i];
- w[i] = temp;
- unsorted = TRUE;
- }
- }
-
- if (!unsorted)
- {
- for(j=0; j < MAX_LOOPS; j++)
- {
- for(i=1; i < p; i++)
- {
- /* increment complexity for if statement */
- // compare_nonzero();mark del
- d = sub(w[i+1],w[i]);
- // data_move();
- if (d < delta)
- {
- // data_move();mark del
- // data_move();mark del
- step1 = step2 = shr_a(sub(delta,d),1);
- /* increment complexity for if statement */
- // compare_nonzero(); compare_nonzero(); mark del
- if (i==1 && (w[i] < delta)) {
- step1 = shr_a(w[i],1);
- // data_move(); mark del
- }
- else {
- /* increment complexity for if statement */
- // compare_nonzero();mark del
- if (i > 1)
- {
- /* increment complexity for if statement */
- // compare_nonzero();mark del
- temp = sub(w[i],w[i-1]);
- if (temp < delta) {
- step1 = 0; // data_move();mark del
- }
- else {
- /* increment complexity for if statement */
- // compare_nonzero(); compare_nonzero(); mark del
- if (temp < shl_a(delta,1)) {
- step1 = shr_a(sub(temp,delta),1);
- }
- }
- }
- }
- /* increment complexity for if statement */
- // compare_nonzero(); compare_nonzero(); mark del
- if (i==(p-1) && (w[i+1] > sub(ONE_Q15,delta))) {
- step2 = shr_a(sub(ONE_Q15,w[i+1]),1);
- // data_move();mark del
- }
- else {
- /* increment complexity for if statement */
- // compare_nonzero();mark del
- if (i < (p-1))
- {
- /* increment complexity for if statement */
- // compare_nonzero();mark del
- temp = sub(w[i+2],w[i+1]);
- if (temp < delta) {
- step2 = 0;
- // data_move();
- }
- else {
- /* increment complexity for if statement */
- // compare_nonzero();mark del
- if (temp < shl_a(delta,1)) {
- step2 = shr_a(sub(temp,delta),1);
- }
- }
- }
- }
- w[i] = sub(w[i],step1);
- // data_move();mark del
- /* w[i+1] = add(w[i+1],step2); */
- L_temp = _sadd2((Longword)w[i+1],(Longword)step2);
- w[i+1] = (Shortword) (0x0000ffffL & L_temp);
- // data_move();mark del
-
- }
- }
- }
- }
-
- /* Debug: check if the minimum separation rule was met */
- /* temp = mult(32440,delta); temp = 0.99*delta */
- L_temp = _smpy(32440,delta);
- temp = (Shortword) (0x0000ffffL & (L_temp >> 16));
- for(j=1; j < p; j++)
- if ((w[j+1]-w[j]) < temp)
- (void)fprintf(stderr,"%s: LSPs not separated by enough (line %d)n",
- __FILE__,__LINE__);
-
- if (unsorted)
- (void)fprintf(stderr,"%s: Fxp LSPs still unsorted (line %d)n",
- __FILE__,__LINE__);
- return((Shortword)0);
- } /* LPC_CLMP */
- /*
- Name: lpc_schr- Schur recursion (autocorrelations to refl coef)
- Aliases: lpc_schur
- Description:
- Compute reflection coefficients from autocorrelations
- based on schur recursion. Will also compute predictor
- parameters by calling lpc_refl2pred(3l) if necessary.
- Inputs:
- r- autocorrelation vector (r[0..p]).
- p- order of lpc filter.
- Outputs:
- a- predictor parameters (can be NULL)
- k_tmp- reflection coefficients (can be NULL)
- Returns:
- alphap- the minimum residual energy
- Includes:
- spbstd.h
- lpc.h
- See_Also:
- lpc_refl2pred(3l) in lpc.h or lpc(3l)
- Q values:
- r - Q0
- a - Q12
- k_tmp - Q15
- */
- Shortword lpc_schr(Shortword *r, Shortword *a, Shortword *k_tmp, Shortword p)
- {
- Shortword i,j;
- Shortword shift,alphap,*k;
- Longword L_temp, *y1, *y2;
- Shortword n_temp,n_y2,nr1,nr0;
- Longword L_temp1;
- Shortword temp;
-
-
- MEM_ALLOC(MALLOC,y1,p+2,Longword);
- MEM_ALLOC(MALLOC,y2,p+2,Longword);
- if (k_tmp == NULL)
- MEM_ALLOC(MALLOC,k,p+1,Shortword);
- else
- k = k_tmp;
- /* nr1 = abs_s(r[1]); */
- /* data_move();mark del */
- /* nr0 = abs_s(r[0]); */
- // data_move();mark del
- L_temp1 = _abs2((Longword)r[1]);
- nr1 = (Shortword) (0x0000ffffL & L_temp1);
- L_temp1 = _abs2((Longword)r[0]);
- nr0 = (Shortword) (0x0000ffffL & L_temp1);
- k[1] = divide_s(nr1,nr0);
- // data_move();mark del
- /* increment complexity for if statement */
- // logic(); compare_zero();mark del
- /* if (((r[1] < 0) && (r[0] < 0)) || ((r[1] > 0) && (r[0] > 0))) */
- if ((r[1] ^ r[0]) >= 0)
- {
- k[1] = negate(k[1]);
- // data_move();mark del
- }
- /* alphap = mult(r[0],sub(ONE_Q15,mult(k[1],k[1]))); */
- L_temp1 = _smpy(k[1],k[1]);
- temp = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- temp = sub(ONE_Q15,temp);
- L_temp1 = _smpy(r[0],temp);
- alphap = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- // data_move();mark del
- /* y2[1] = L_deposit_h(r[1]); */
- /* y2[2] = L_add(L_deposit_h(r[0]),L_mult(k[1],r[1])); */
- y2[1] = (Longword) r[1] << 16 ;
- L_temp1 = (Longword) r[0] << 16 ;
- y2[2] = _sadd(L_temp1,_smpy(k[1],r[1]));
- for(i=2; i <= p; i++)
- {
- /* y1[1] = L_deposit_h(r[i]); */
- /* L_temp = L_deposit_h(r[i]); */
- y1[1] = (Longword) r[i] << 16;
- L_temp = (Longword) r[i] << 16;
-
- for(j=1; j < i; j++)
- {
- y1[j+1] = _sadd(y2[j], L_mpy_ls(L_temp, k[j]));
- // L_data_move();mark del
- L_temp = _sadd(L_temp, L_mpy_ls(y2[j], k[j]));
- y2[j] = y1[j];
- // L_data_move();mark del
- }
- /* k[i] = -temp/y2[i]; */
- if (L_temp > y2[i]) {
- for (j = i; j <= p; j++)
- k[j] = 0;
- #if (PRINT)
- printf("nERROR: numerator bigger than denominator in lpc_schrn");
- printf("Reflection coefficients used in frame %d:n",frames);
- for (i = 1; i <= p; i++) {
- printf(" %5.8f ",(float)k[i]/(1<<15));
- }
- printf("n");
- #endif
- break;
- }
- /* shift = norm_l(y2[i]); */
- /* n_temp = abs_s(extract_h(L_shl(L_temp,shift))); */
- L_temp1 = _norm(y2[i]);
- if (y2[i] == 0){
- L_temp1 = (Longword)0;
- }
- shift = (Shortword) (0x0000ffffL & L_temp1);
- L_temp1 = _sshvl(L_temp,shift);
- L_temp1 = _abs2(L_temp1);
- n_temp = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- // data_move();mark del
- /* n_y2 = abs_s(extract_h(L_shl(y2[i],shift))); */
- L_temp1 = _sshvl(y2[i],shift);
- L_temp1 = _abs2(L_temp1);
- n_y2 = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- // data_move();mark del
- k[i] = divide_s(n_temp,n_y2);
- // data_move();mark del
- /* increment complexity for if statement */
- // L_logic(); compare_zero();mark del
- if ((L_temp ^ y2[i]) >= 0)
- {
- k[i] = negate(k[i]);
- // data_move();mark del
- }
- y2[i+1] = _sadd(y2[i], L_mpy_ls(L_temp, k[i]));
- // L_data_move();mark del
- y2[i] = y1[i];
- // L_data_move();mark del
-
- /* alphap = mult(alphap,sub(ONE_Q15,mult(k[i],k[i]))); */
- L_temp1 = _smpy(k[i],k[i]);
- temp = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- temp = sub(ONE_Q15,temp);
- L_temp1 = _smpy(alphap,temp);
- alphap = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- // data_move();mark del
- }
-
- if (a != NULL)
- {
- lpc_refl2pred(k,a,p);
- }
- if (k_tmp == NULL)
- MEM_FREE(FREE,k);
- MEM_FREE(FREE,y2);
- MEM_FREE(FREE,y1);
-
- return(alphap); /* alphap in Q15 */
- } /* LPC_SCHR */
- /* LPC_REFL2PRED
- get predictor coefficients from the reflection coeffs
- Synopsis: lpc_refl2pred(k,a,p)
- Input:
- k- the reflection coeffs
- p- the predictor order
- Output:
- a- the predictor coefficients
- Reference: Markel and Gray, Linear Prediction of Speech
- Q values:
- k - Q15
- a - Q12
- */
- Shortword lpc_refl2pred(Shortword *k,Shortword *a,Shortword p)
- {
- Shortword i,j;
- Shortword *a1;
- Longword L_temp,swRnd;
- Shortword temp;
- MEM_ALLOC(MALLOC,a1,p+1,Shortword);
- for(i=1; i <= p; i++)
- {
- /* refl to a recursion */
- /* a[i] = shift_r(k[i],-3); a in Q12 */
- L_temp = _shr2((Longword)k[i],2);
- swRnd = L_temp & (Longword)0x1;
- L_temp = _shr2((Longword)k[i],3);
- L_temp = _sadd2(L_temp,swRnd);
- a[i] = (Shortword) (0x0000ffffL & L_temp);
- // data_move();mark del
- for(j=1; j < i; j++) {
- a1[j] = a[j];
- // data_move();mark del
- }
- for(j=1; j < i; j++) {
- /* a[j] = add(a1[j],mult(k[i],a1[i-j])); */
- L_temp = _smpy(k[i],a1[i-j]);
- temp = (Shortword) (0x0000ffffL & (L_temp >> 16));
- L_temp = _sadd2((Longword)a1[j],(Longword)temp);
- a[j] = (Shortword) (0x0000ffff & L_temp);
- // data_move();mark del
- }
- }
- MEM_FREE(FREE,a1);
- return((Shortword)0);
- } /* LPC_REFL2PRED */
- /* minimum LSP separation-- a global variable */
- Shortword lsp_delta = 0;
- /* LPC_PRED2LSP
- get LSP coeffs from the predictor coeffs
- Input:
- a- the predictor coefficients
- p- the predictor order
- Output:
- w- the lsp coefficients
- This function uses a DFT to evaluate the P and Q polynomials,
- and is hard-coded to work only for 10th order LPC.
- Q values:
- a - Q12
- w - Q15
- */
- static void lsp_to_freq(Shortword lsp[restrict], Shortword w[restrict], Shortword order);
- #define LPC_ORD 10
- Shortword lpc_pred2lsp(Shortword *restrict a,Shortword *restrict w,Shortword p)
- {
- Shortword i,j;
- Shortword p_cof[LPC_ORD+1], q_cof[LPC_ORD+1],
- p_freq[LPC_ORD+1], q_freq[LPC_ORD+1];
- Longword L_p_cof[LPC_ORD+1], L_q_cof[LPC_ORD+1];
- Longword L_ai,L_api,L_temp;
- Longword L_temp1,L_Prod;
- /* Generate P' and Q' polynomials */
- L_p_cof[0] = (Longword)ONE_Q26;
- L_q_cof[0] = (Longword)ONE_Q26;
- for ( i = 1; i <= p; i++ ) {
- /* temp = sub(a[i],a[p+1-i]); */ /* temp in Q12 */
- /* L_ai = L_shr(L_deposit_h(a[i]),2); */
- L_ai =(Longword)(a[i] << 16);
- L_ai = _sshvr(L_ai,2);
- // L_data_move();mark del
- /* L_api = L_shr(L_deposit_h(a[p+1-i]),2); */
- L_api = (Longword) (a[p+1-i] << 16);
- L_api = _sshvr(L_api,2);
- // L_data_move(); mark del
- /* L_temp = L_sub(L_ai,L_api); L_temp in Q26 */
- /* L_p_cof[i] = L_add(L_temp,L_p_cof[i-1]); L_p_cof in Q26 */
- L_temp = _ssub(L_ai,L_api);
- L_p_cof[i] = _sadd(L_temp,L_p_cof[i-1]);
- /* temp = add(a[i],a[p+1-i]); */
- /* L_temp = L_add(L_ai,L_api); */
- /* L_q_cof[i] = L_sub(L_temp,L_q_cof[i-1]); L_q_cof in Q26 */
- L_temp = _sadd(L_ai,L_api);
- L_q_cof[i] = _ssub(L_temp,L_q_cof[i-1]); /* L_q_cof in Q26 */
- }
- /* Convert p_cof and q_cof to short */
- for ( i = 0; i <= p; i++ ) {
- /* p_cof[i] = round(L_p_cof[i]); p_cof in Q10 */
- L_Prod = _sadd(L_p_cof[i], 0x00008000L); /* round MSP */
- p_cof[i] = (Shortword) (0x0000ffffL & (L_Prod >> 16));
- /* q_cof[i] = round(L_q_cof[i]); q_cof in Q10 */
- L_temp1 = _sadd(L_q_cof[i], 0x00008000L); /* round MSP */
- q_cof[i] = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- }
- /* Find root frequencies of LSP polynomials */
- lsp_to_freq(p_cof,p_freq,p);
- lsp_to_freq(q_cof,q_freq,p);
- /* Combine frequencies into single array */
- w[0] = 0;
- j = 1;
- for (i = 0; i < (shr_a(p,1)); i++) {
- w[j++] = q_freq[i];
- // data_move();mark del
- w[j++] = p_freq[i];
- // data_move();mark del
- }
- return((Shortword)0);
- } /* LPC_PRED2LSP */
- /* */
- /* Subroutine LSP_TO_FREQ: Calculate Line Spectrum Pair */
- /* root frequencies from LSP polynomial. */
- /* */
- /* Q values:
- lsp - Q10
- w - Q15
- */
- #define DFTLENGTH 512
- #define DFTLENGTH_D2 (DFTLENGTH/2)
- #define DFTLENGTH_D4 (DFTLENGTH/4)
- static void lsp_to_freq(Shortword lsp[restrict], Shortword w[restrict], Shortword p)
- {
- Shortword i;
- Shortword p2, count, prev_less, j;
- static Shortword firstcall = 1;
- Longword mag0, mag1, mag2;
- Shortword s_mag0, s_mag1, s_mag2;
- Shortword *p_cos, *p_endlsp, *p_lsp, *p_begcos, *p_endcos;
- Shortword temp1, temp2;
- Longword L_temp1, L_temp2;
- Longword L_temp;
- static Shortword lsp_cos[DFTLENGTH]; /* cosine table */
- static Shortword default_w, default_w0;
- static Shortword cos_tab[129] =
- {
- 32767, 32766, 32758, 32746, 32729, 32706, 32679, 32647, 32610,
- 32568, 32522, 32470, 32413, 32352, 32286, 32214, 32138, 32058,
- 31972, 31881, 31786, 31686, 31581, 31471, 31357, 31238, 31114,
- 30986, 30853, 30715, 30572, 30425, 30274, 30118, 29957, 29792,
- 29622, 29448, 29269, 29086, 28899, 28707, 28511, 28311, 28106,
- 27897, 27684, 27467, 27246, 27020, 26791, 26557, 26320, 26078,
- 25833, 25583, 25330, 25073, 24812, 24548, 24279, 24008, 23732,
- 23453, 23170, 22884, 22595, 22302, 22006, 21706, 21403, 21097,
- 20788, 20475, 20160, 19841, 19520, 19195, 18868, 18538, 18205,
- 17869, 17531, 17190, 16846, 16500, 16151, 15800, 15447, 15091,
- 14733, 14373, 14010, 13646, 13279, 12910, 12540, 12167, 11793,
- 11417, 11039, 10660, 10279, 9896, 9512, 9127, 8740, 8351,
- 7962, 7571, 7180, 6787, 6393, 5998, 5602, 5205, 4808,
- 4410, 4011, 3612, 3212, 2811, 2411, 2009, 1608, 1206,
- 804, 402, 0
- };
- if (firstcall) {
- /* Initialization: fill cosine table */
- firstcall = 0;
- /* for (i = 0; i < DFTLENGTH; i++ )
- lsp_cos[i] = cos(i*(TWOPI / DFTLENGTH)); */
- for (i = 0; i < DFTLENGTH_D4; i++) {
- lsp_cos[i] = cos_tab[i];
- lsp_cos[i+DFTLENGTH_D4] = -cos_tab[DFTLENGTH_D4-i];
- lsp_cos[i+2*DFTLENGTH_D4] = -cos_tab[i];
- lsp_cos[i+3*DFTLENGTH_D4] = cos_tab[DFTLENGTH_D4-i];
- }
- /* compute default values for w[] */
- /* (1./p2) in Q15 */
- default_w = divide_s(ONE_Q11,shl_a(p,10));
- /* w[0] = (0.5/p2) in Q15 */
- /* default_w0 = shr(default_w,1); */
- L_temp = _shr2((Longword)default_w,1);
- default_w0 = (Shortword) (0x0000ffffL & L_temp);
- }
- prev_less = 1;
- mag0 = (Longword)0x7fffffff;
- // L_data_move();mark del
- mag1 = (Longword)0x7fffffff;
- // L_data_move();mark del
- s_mag0 = (Shortword)0x7fff;
- // data_move();mark del
- s_mag1 = (Shortword)0x7fff;
- // data_move();mark del
- /* p2 = shr(p,1); p/2 */
- L_temp = _shr2((Longword)p,1);
- p2 = (Shortword) (0x0000ffffL & L_temp);
- count = 0;
- // data_move(); mark del
- p_begcos = &lsp_cos[0];
- p_endcos = &lsp_cos[DFTLENGTH-1];
- p_endlsp = &lsp[p2];
- /* Search all frequencies for minima of Pc(w) */
- for (i = 0; i <= DFTLENGTH_D2; i++ ) {
- p_lsp = p_endlsp;
- p_cos = p_begcos++;
- /* mag2 = 0.5 * *(p_lsp--); */
- /* mag2 = L_mult(*(p_lsp--),(Shortword)X05_Q14); mag2 in Q25 */
- mag2 = _smpy(*(p_lsp--),(Shortword)X05_Q14); /* mag2 in Q25 */
- for (j = p2 - 1; j >= 0; j-- ) {
- /* L_temp1 = L_shr(L_mult(*(p_lsp--),*(p_cos)),1); */
- /* mag2 = L_add(mag2,L_temp1); */
- L_temp1 = _sshvr(_smpy(*(p_lsp--),*(p_cos)),1);
- mag2 = _sadd(mag2,L_temp1);
- // complexity -= 4; mark del /* this can be done with MAC on TMS320C5x */
- p_cos += i;
- if (p_cos > p_endcos)
- p_cos -= DFTLENGTH;
- }
- /* s_mag2 = extract_h(mag2); */
- /* mag2 = L_abs(mag2); */
- s_mag2 = (Shortword) (0x0000ffffL & (mag2 >> 16));
- mag2 = _abs(mag2);
- // L_compare_nonzero(); mark del
- if (mag2 < mag1) {
- prev_less = 1;
- // data_move();mark del
- }
- else {
- if (prev_less) {
- /* check for sign change */
- // logic(); compare_zero();mark del
- if ((s_mag0 ^ s_mag2) < 0) {
- /* Minimum frequency found */
- /*w[count] = i - 1 + (0.5 *
- (mag0 - mag2) / (mag0 + mag2 - 2*mag1) );
- w[count] *= (2. / DFTLENGTH) ;*/
- L_temp1 = _sshvr(L_sub(mag0,mag2),1);
- L_temp2 = _ssub(mag0,L_shl(mag1,1));
- L_temp2 = _sadd(L_temp2,mag2);
- temp1 = L_divider2(L_temp1,L_temp2,0,0); /* temp1 in Q15 */
- /* temp1 = shr(temp1,9); Q6 */
- L_temp = _shr2((Longword)temp1,9);
- temp1 = (Shortword) (0x0000ffffL & L_temp);
- temp2 = sub(i,1);
- temp1 = add(shl_a(temp2,6),temp1);
- w[count] = divide_s(temp1,shl_a(DFTLENGTH,5));
- // data_move();mark del
- /* count = add(count,1); */
- L_temp = _sadd2((Longword)count,(Longword)1);
- count = (Shortword) (0x0000ffffL & L_temp);
- }
- }
- prev_less = 0;
- // data_move();mark del
- }
- mag0 = mag1;
- // L_data_move();mark del
- mag1 = mag2;
- // L_data_move();mark del
- s_mag0 = s_mag1;
- // data_move();mark del
- s_mag1 = s_mag2;
- // data_move();mark del
- }
-
- /* Verify that all roots were found */
- if (count != p2) {
- #if (PRINT)
- printf("ERROR: couldn't find LSP frequencies in frame %d.n",frames);
- printf(" Found were ");
- for (i = 0; i < count; i++)
- printf(" %10.4f ",(float)w[i]/(1<<15));
- printf("n");
- #endif
- /* use default values */
- w[0] = default_w0;
- for (i = 1; i < p2; i++) {
- w[i] = w[i-1] + default_w;
- }
- }
- } /* LSP_TO_FREQ */
- #undef DFTLENGTH
- #undef DFTLENGTH_D2
- #undef DFTLENGTH_D4
- /* LPC_PRED2REFL
- get refl coeffs from the predictor coeffs
- Input:
- a- the predictor coefficients
- p- the predictor order
- Output:
- k- the reflection coefficients
- Returns:
- energy - energy of residual signal
- Reference: Markel and Gray, Linear Prediction of Speech
- Q values:
- *a - Q12
- *k - Q15
- energy - Q15
- */
- Shortword lpc_pred2refl(Shortword *a,Shortword *k,Shortword p)
- {
- Shortword *b,*b1, e;
- Shortword energy = ONE_Q15;
- Shortword i,j;
- Shortword shift;
- Shortword temp, n_temp, n_e;
- Longword L_temp,L_shift;
- Shortword temp1;
- MEM_ALLOC(MALLOC,b,p+1,Shortword);
- MEM_ALLOC(MALLOC,b1,p+1,Shortword);
- /* equate temporary variables (b = a) */
- for(i=1; i <= p; i++) {
- b[i] = a[i];
- // data_move();mark del
- }
- /* compute reflection coefficients */
- for(i=p; i > 0; i--)
- {
- k[i] = shl_a(b[i],3); /* Q12 -> Q15 */
- /* e = sub(ONE_Q15,mult(k[i],k[i])); */
- /* energy = mult(energy,e); */
- L_temp = _smpy(k[i],k[i]);
- temp1 = (Shortword) (0x0000ffffL & (L_temp >> 16));
- e = sub(ONE_Q15,temp1);
- L_temp = _smpy(energy,e);
- energy = (Shortword) (0x0000ffffL & (L_temp >> 16));
- for(j=1; j < i; j++) {
- b1[j] = b[j];
- // data_move();mark del
- }
- for(j=1; j < i; j++) {
- /* b[j] = (b1[j] - k[i]*b1[i-j])/e; */
- /* temp = mult(k[i],b1[i-j]); temp in Q12 */
- L_temp = _smpy(k[i],b1[i-j]);
- temp = (Shortword) (0x0000ffffL & (L_temp >> 16));
- temp = sub(b1[j],temp);
- /* check signs of temp and e before division */
- /* n_temp = abs_s(temp); */
- /* n_e = abs_s(e); */
- /* shift = norm_s(n_e); */
- L_temp = _abs2((Longword)temp);
- n_temp = (Shortword) (0x0000ffffL & L_temp);
- L_temp = _abs2((Longword)e);
- n_e = (Shortword) (0x0000ffffL & L_temp);
- L_temp = (Longword)n_e << 16;
- L_shift = _norm(L_temp);
- if (L_temp == 0){
- L_shift = (Longword)0;
- }
- shift = (Shortword) (0x0000ffffL & L_shift);
- n_e = shl(n_e,shift);
- if (n_temp > n_e) {
- /* n_temp = shr(n_temp,1); */
- /* shift = add(shift,1); */
- L_temp = _shr2((Longword)n_temp,1);
- n_temp = (Shortword) (0x0000ffffL & L_temp);
- L_shift = _sadd2((Longword)shift,(Longword)1);
- shift = (Shortword) (0x0000ffffL & L_shift);
- }
- b[j] = shl(divide_s(n_temp,n_e),shift); /* b[j] in Q12 */
- if ((temp ^ e) < 0)
- b[j] = negate(b[j]);
- }
- }
- MEM_FREE(FREE,b1);
- MEM_FREE(FREE,b);
- return(energy);
- } /* LPC_PRED2REFL */
- /* LPC_LSP2PRED
- get predictor coefficients from the LSPs
- Synopsis: lpc_lsp2pred(w,a,p)
- Input:
- w- the LSPs
- p- the predictor order
- Output:
- a- the predictor coefficients
- Reference: Kabal and Ramachandran
- */
- /* Q values:
- w - Q15
- a - Q12
- f - Q25
- c - Q14 */
- Shortword lpc_lsp2pred(Shortword *w,Shortword *a,Shortword p)
- {
- Shortword i,j,k,p2;
- Shortword c[2];
- Longword **f;
- Longword L_temp;
- Longword L_temp1;
- Shortword temp;
- /* ensure minimum separation and sort */
- (void)lpc_clmp(w,lsp_delta,p);
- /* p2 = p/2 */
- p2 = shr_a(p,1);
- // data_move();mark del
- MEM_2ALLOC(MALLOC,f,2,p2+1,Longword);
- /* f is Q25 */
- f[0][0] = f[1][0] = (Longword)ONE_Q25;
- // L_data_move(); L_data_move();mark del
- /* -2.0*cos((double)w[1]*M_PI) */
- /* f[0][1] = L_shr(L_deposit_h(negate(cos_fxp(w[1]))),5); */
- temp = negate(cos_fxp(w[1]));
- L_temp1 = (Longword)temp << 16;
- f[0][1] = _sshvr(L_temp1,5);
- // L_data_move();mark del
- /* f[1][1] = L_shr(L_deposit_h(negate(cos_fxp(w[2]))),5); */
- temp = negate(cos_fxp(w[2]));
- L_temp1 = (Longword)temp << 16;
- f[1][1] = _sshvr(L_temp1,5);
- // L_data_move();mark del
- k = 3;
- for(i=2; i <= p2; i++)
- {
- /* c is Q14 */
- /* multiply by 2 is considered as Q15->Q14 */
- c[0] = negate(cos_fxp(w[k++]));
- // data_move();mark del
- c[1] = negate(cos_fxp(w[k++]));
- // data_move();mark del
-
- f[0][i] = f[0][i-2];
- // L_data_move();mark del
- f[1][i] = f[1][i-2];
- // L_data_move();mark del
- for(j=i; j >= 2; j--)
- {
- /* f[0][j] += c[0]*f[0][j-1]+f[0][j-2] */
- L_temp = L_mpy_ls(f[0][j-1],c[0]);
- /* L_temp = L_add(L_shl(L_temp,1),f[0][j-2]); */
- /* f[0][j] = L_add(f[0][j],L_temp); */
- L_temp = _sadd(_sshvl(L_temp,1),f[0][j-2]);
- f[0][j] = _sadd(f[0][j],L_temp);
-
- // L_data_move();mark del
- /* f[1][j] += c[1]*f[1][j-1]+f[1][j-2] */
- L_temp = L_mpy_ls(f[1][j-1],c[1]);
- /* L_temp = L_add(L_shl(L_temp,1),f[1][j-2]); */
- /* f[1][j] = L_add(f[1][j],L_temp); */
- L_temp = _sadd(_sshvl(L_temp,1),f[1][j-2]);
- f[1][j] = _sadd(f[1][j],L_temp);
- // L_data_move();mark del
- }
- /* f[0][1] = L_add(f[0][1],L_shl(L_mpy_ls(f[0][0],c[0]),1)); */
- /* f[1][1] = L_add(f[1][1],L_shl(L_mpy_ls(f[1][0],c[1]),1)); */
- f[0][1] = _sadd(f[0][1],_sshl(L_mpy_ls(f[0][0],c[0]),1));
- f[1][1] = _sadd(f[1][1],_sshl(L_mpy_ls(f[1][0],c[1]),1));
- }
- for(i=p2; i > 0; i--)
- {
- /* short f (f is a Q14) */
- /* f[0][i] = L_add(f[0][i],f[0][i-1]); */
- /* f[1][i] = L_sub(f[1][i],f[1][i-1]); */
- f[0][i] = _sadd(f[0][i],f[0][i-1]);
- f[1][i] = _ssub(f[1][i],f[1][i-1]);
- /* a is Q12 */
- /* a[i] = 0.50*(f[0][i]+f[1][i]) */
- /* a[p+1-i] = 0.50*(f[0][i]-f[1][i]) */
- /* Q25 -> Q27 -> Q12 */
- /* a[i] = extract_h(L_shl(L_add(f[0][i],f[1][i]),2)); */
- /* a[p+1-i] = extract_h(L_shl(L_sub(f[0][i],f[1][i]),2)); */
- L_temp1 = _sshl(_sadd(f[0][i],f[1][i]),2);
- a[i] = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- L_temp1 = _sshl(_ssub(f[0][i],f[1][i]),2);
- a[p+1-i] = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- }
- MEM_2FREE(FREE,f);
- return((Shortword)0);
- } /* LPC_LSP2PRED */
- /*
- Name: lpc_syn- LPC synthesis filter.
- Aliases: lpc_synthesis
- Description:
- LPC all-pole synthesis filter
- for j = 0 to n-1
- y[j] = x[j] - sum(k=1 to p) y[j-k] a[k]
- Inputs:
- x- input vector (n samples, x[0..n-1])
- a- lpc vector (order p, a[1..p])
- p- order of lpc filter
- n- number of elements in vector which is to be filtered
- y[-p..-1]- filter memory (past outputs)
- Outputs:
- y- output vector (n samples, y[0..n-1])
- Returns: NULL
- Includes:
- spbstd.h
- lpc.h
- Systems and Info. Science Lab
- Copyright (c) 1995 by Texas Instruments, Inc. All rights reserved.
- */
- Shortword lpc_syn(Shortword *x,Shortword *y,Shortword *a,Shortword p,
- Shortword n)
- {
- Shortword i,j;
- Longword accum;
- Longword L_temp,L_Prod;
- for(j=0; j < n; j++) {
- /* accum = L_shr(L_deposit_h(x[j]),3); */
- L_temp = (Longword)(x[j]) << 16;
- accum = _sshvr(L_temp,3);
- for(i=p; i > 0; i--)
- accum = L_msu(accum,y[j-i],a[i]);
- /* Round off output */
- /* accum = L_shl(accum,3); */
- /* y[j] = round(accum); */
- accum = _sshl(accum,3);
- L_Prod = _sadd(accum, 0x00008000L); /* round MSP */
- y[j] = (Shortword)(0x0000ffffL & (L_Prod >> 16));
- }
- return((Shortword)0);
- }