lpc_lib.c
上传用户:cxx_68
上传日期:2021-02-21
资源大小:161k
文件大小:29k
源码类别:

语音压缩

开发平台:

Visual C++

  1. /*
  2. 2.4 kbps MELP Proposed Federal Standard speech coder
  3. Fixed-point C code, version 1.0
  4. Copyright (c) 1998, Texas Instruments, Inc.  
  5. Texas Instruments has intellectual property rights on the MELP
  6. algorithm.  The Texas Instruments contact for licensing issues for
  7. commercial and non-government use is William Gordon, Director,
  8. Government Contracts, Texas Instruments Incorporated, Semiconductor
  9. Group (phone 972 480 7442).
  10. The fixed-point version of the voice codec Mixed Excitation Linear
  11. Prediction (MELP) is based on specifications on the C-language software
  12. simulation contained in GSM 06.06 which is protected by copyright and
  13. is the property of the European Telecommunications Standards Institute
  14. (ETSI). This standard is available from the ETSI publication office
  15. tel. +33 (0)4 92 94 42 58. ETSI has granted a license to United States
  16. Department of Defense to use the C-language software simulation contained
  17. in GSM 06.06 for the purposes of the development of a fixed-point
  18. version of the voice codec Mixed Excitation Linear Prediction (MELP).
  19. Requests for authorization to make other use of the GSM 06.06 or
  20. otherwise distribute or modify them need to be addressed to the ETSI
  21. Secretariat fax: +33 493 65 47 16.
  22. */
  23. /*  
  24.   lpc_lib.c: LPC subroutines.
  25. */
  26. /*  compiler include files  */
  27. #include        <stdio.h>
  28. #include        <stdlib.h>
  29. #include        <math.h>
  30. #include "spbstd.h"
  31. #include "mathhalf.h"
  32. #include "mathdp31.h"
  33. #include "math_lib.h"
  34. #include "wmops.h"
  35. #include "mat.h"
  36. #include "lpc.h"
  37. #include "constant.h"
  38. extern int complexity;
  39. extern Shortword frames;
  40. extern FILE *fp_outdat;
  41. #define PRINT 1
  42. #define ALMOST_ONE_Q14   16382    /* ((1<<14)-2) */
  43. /* Lag window coefficients */
  44. Shortword lagw_cof[10] = {
  45. 32756,32721,32663,32582,32478,32351,32201,32030,31837,31622};
  46. /*
  47.     LPC_ACOR
  48.         Compute autocorrelations based on windowed speech frame
  49.     Synopsis: lpc_acor(s,window,r,hf_correction,lag_win,p,nx)
  50.         Input:
  51.             input- input vector (npts samples, s[0..npts-1])
  52.             win_cof- window vector (npts samples, s[0..npts-1])
  53.             hf_correction- high frequency correction value
  54.             lag_win- lag window value (for bandwidth expansion
  55.                      factor is BeqT, where T is the sampling rate)
  56.      NOT used in this function
  57.             order- order of lpc filter
  58.             npts- number of elements in window
  59.         Output:
  60.             r- output autocorrelation vector (order+1 samples, r[0..order])
  61.     Q values:
  62.     input - Q0
  63.     win_cof - Q15
  64.     hf_correction - Q15
  65. */
  66. void lpc_acor(Shortword input[],Shortword win_cof[],
  67.       Shortword r[],Shortword hf_correction,
  68.       Shortword lag_win,Shortword order,Shortword npts)
  69. {
  70.     Shortword i,j;
  71.     Longword L_temp;
  72.     Shortword *inputw;
  73.     Shortword norm_var, scale_fact, temp;
  74.     /* window optimized for speed and readability
  75.        does windowing and autocorrelation sequentially
  76.        and in the usual manner
  77.     */ 
  78.     MEM_ALLOC(MALLOC,inputw,npts,Shortword);
  79.     if (win_cof) {
  80.       for(i=0; i < npts; i++) {
  81. inputw[i] = mult(win_cof[i],shr(input[i],4));   data_move();
  82.       }
  83.     }
  84.     else {
  85.       v_equ_shr(inputw,input,4,npts);
  86.     }
  87.     
  88.     /* Find scaling factor */
  89.     L_temp = L_v_magsq(inputw,npts,0,1);
  90.     compare_zero();
  91.     if (L_temp) {
  92.       norm_var = norm_l(L_temp);
  93.       norm_var = sub(4,shr(norm_var,1));
  94.       if (norm_var < 0)
  95. norm_var = 0;
  96.     }
  97.     else
  98.       norm_var = 0;
  99.     /* increment complexity for if statement */
  100.     compare_zero();
  101.     if (win_cof) {
  102.       for(i=0; i < npts; i++) {
  103. inputw[i] = shr(mult(win_cof[i],input[i]),norm_var);    data_move();
  104.       }
  105.     }
  106.     else
  107.       v_equ_shr(inputw,input,norm_var,npts);
  108.     /* Compute r[0] */
  109.     L_temp = L_v_magsq(inputw,npts,0,1);
  110.     compare_zero();
  111.     if (L_temp > 0) {
  112.       /* normalize with 1 bit of headroom */
  113.       norm_var = norm_l(L_temp);
  114.       norm_var = sub(norm_var,1);
  115.       L_temp = L_shl(L_temp,norm_var);
  116.       /* High frequency correction */
  117.       L_temp = L_add(L_temp,L_mpy_ls(L_temp,hf_correction));
  118.       /* normalize result */
  119.       temp = norm_s(extract_h(L_temp));
  120.       L_temp = L_shl(L_temp,temp);
  121.       norm_var = add(norm_var,temp);
  122.       r[0] = round(L_temp);
  123.       /* Multiply by 1/r[0] for full normalization */
  124.       scale_fact = divide_s(ALMOST_ONE_Q14,r[0]);
  125.       L_temp = L_shl(L_mpy_ls(L_temp,scale_fact),1);
  126.       r[0] = round(L_temp);
  127.     }
  128.     else {
  129.       norm_var = 0;    data_move();
  130.       r[0] = ONE_Q15;   /* 1 in Q15 */    data_move();
  131.       scale_fact = 0;      data_move();
  132.     }  
  133.     /* Compute remaining autocorrelation terms */
  134.     for(j=1; j <= order; j++)
  135.     {
  136. L_temp = 0;    data_move();
  137.         for(i=j; i < npts; i++) {
  138.     L_temp = L_mac(L_temp,inputw[i],inputw[i-j]);
  139. }
  140. L_temp = L_shl(L_temp,norm_var);
  141. /* Scaling */
  142. L_temp = L_shl(L_mpy_ls(L_temp,scale_fact),1);
  143. /* Lag windowing */
  144. L_temp = L_mpy_ls(L_temp,lagw_cof[j-1]);
  145. r[j] = round(L_temp);
  146.     }
  147.     
  148.     MEM_FREE(FREE,inputw);
  149. } /* lpc_acor */
  150. /* 
  151.     Name: lpc_aejw- Compute square of A(z) evaluated at exp(jw)
  152.     Description:
  153.         Compute the magnitude squared of the z-transform of 
  154.         A(z) = 1+a(1)z^-1 + ... +a(p)z^-p
  155.         evaluated at z=exp(jw)
  156.      Inputs:
  157.         a- LPC filter (a[0] is undefined, a[1..p])
  158.         w- radian frequency
  159.         p- predictor order
  160.      Returns:
  161.         |A(exp(jw))|^2
  162.      See_Also: cos(3), sin(3)
  163.      Includes:
  164.         spbstd.h
  165.         lpc.h
  166.      Systems and Info. Science Lab
  167.      Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
  168. */
  169. /* Q values
  170.    --------
  171.    a - Q12
  172.    w - Q15
  173.    return - Q19
  174. */
  175. /* lower limit of return value to prevent overflow of weighting function */
  176. #define LOW_LIMIT 54
  177. Longword lpc_aejw(Shortword *a,Shortword w, Shortword p)
  178. {
  179.     Shortword i;
  180.     Shortword c_re,c_im;
  181.     Shortword cs,sn,temp;
  182.     Shortword temp1,temp2;
  183.     Longword L_temp;
  184.     
  185.     if (p==0)
  186.         return((Longword)ONE_Q19);
  187.     /* use horners method
  188.     A(exp(jw)) = 1+ e(-jw)[a(1)+e(-jw)[a(2)+e(-jw)[a(3)+..
  189.             ...[a(p-1)+e(-jw)a(p)]]]]
  190.     */
  191.     cs = cos_fxp(w);     data_move();    /* temp in Q15 */
  192.     sn = negate(sin_fxp(w));     data_move();    /* temp in Q15 */
  193.     c_re = shr(mult(cs,a[p]),3);     data_move();  /* -> Q9 */
  194.     c_im = shr(mult(sn,a[p]),3);     data_move();  /* -> Q9 */
  195.     for(i=p-1; i > 0; i--)
  196.     {
  197.         /* add a[i] */
  198.         temp = shr(a[i],3);
  199.         c_re = add(c_re,temp);     data_move();
  200.         /* multiply by exp(-jw) */
  201. temp=c_im;
  202. temp1 = mult(cs,temp);     data_move();   /* temp1 in Q9 */
  203. temp2 = mult(sn,c_re);     data_move();   /* temp2 in Q9 */
  204.         c_im = add(temp1, temp2);     data_move();
  205. temp1 = mult(cs,c_re);     data_move();   /* temp1 in Q9 */
  206. temp2 = mult(sn,temp);     data_move();   /* temp2 in Q9 */
  207.         c_re = sub(temp1,temp2);     data_move();
  208.     }
  209.     /* add one */
  210.     c_re = add(c_re, ONE_Q9);     data_move();
  211.     /* L_temp in Q19 */
  212.     L_temp = L_add(L_mult(c_re,c_re),L_mult(c_im,c_im));
  213.     if (L_temp<LOW_LIMIT)
  214.       L_temp=(Longword)LOW_LIMIT;
  215.     
  216.     return(L_temp);
  217. } /* LPC_AEJW */
  218. #undef LOW_LIMIT
  219. /*
  220.     Name: lpc_bwex- Move the zeros of A(z) toward the origin.
  221.     Aliases: lpc_bw_expand
  222.     Description:
  223.         Expand the zeros of the LPC filter by gamma, which
  224.         moves each zero radially into the origin.
  225. <nf>
  226.         for j = 1 to p
  227.             aw[j] = a[j]*gamma^j
  228. </nf>
  229.         (Can also be used to perform an exponential windowing procedure).
  230.     Inputs:
  231.         a- lpc vector (order p, a[1..p])
  232.         gamma- the bandwidth expansion factor
  233.         p- order of lpc filter
  234.     Outputs:
  235.         aw- the bandwidth expanded LPC filter
  236.     Returns: NULL
  237.     See_Also: lpc_lagw(3l)
  238.     Includes:
  239.         spbstd.h
  240.         lpc.h
  241.     Systems and Info. Science Lab
  242.     Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
  243.     Q values:
  244.     *a,*aw - Q12
  245.     gamma - Q15
  246.     gk - Q15
  247. */
  248. Shortword lpc_bwex(Shortword *a, Shortword *aw, Shortword gamma, Shortword p)
  249. {
  250.     Shortword i;
  251.     Shortword gk;
  252.     gk = gamma;      data_move();
  253.     for(i=1; i <= p; i++) {
  254.         aw[i] = mult(a[i],gk);
  255. gk = mult(gk,gamma);
  256.     }
  257.     return((Shortword)0);
  258. }
  259. /*
  260.     Name: lpc_clmp- Sort and ensure minimum separation in LSPs.
  261.     Aliases: lpc_clamp
  262.     Description:
  263.         Ensure that all LSPs are ordered and separated
  264.         by at least delta.  The algorithm isn't guarenteed
  265.         to work, so it prints an error message when it fails
  266.         to sort the LSPs properly.
  267.     Inputs:
  268.         w- lsp vector (order p, w[1..p])
  269.         delta- the clamping factor
  270.         p- order of lpc filter
  271.     Outputs:
  272.         w- the sorted and clamped lsps
  273.     Returns: NULL
  274.     See_Also:
  275.     Includes:
  276.         spbstd.h
  277.         lpc.h
  278.     Bugs: 
  279.         Currently only supports 10 loops, which is too
  280.         complex and perhaps unneccesary.
  281.     Systems and Info. Science Lab
  282.     Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
  283. */
  284. /*  Q values:
  285.     w - Q15
  286.     delta - Q15 */
  287. #define MAX_LOOPS 10
  288. Shortword lpc_clmp(Shortword *w, Shortword delta, Shortword p)
  289. {
  290.     Shortword i,j,unsorted;
  291.     Shortword temp,d,step1,step2;
  292.     /* sort the LSPs for 10 loops */  
  293.     for (j=0,unsorted=TRUE; unsorted && (j < MAX_LOOPS); j++)
  294.     {
  295.         for(i=1,unsorted=FALSE; i < p; i++)
  296.             if (w[i] > w[i+1])
  297.             {
  298.                 temp = w[i+1];
  299.                 w[i+1] = w[i];
  300.                 w[i] = temp;
  301.                 unsorted = TRUE;
  302.             }
  303.     }
  304.     /* ensure minimum separation */
  305.     if (!unsorted) 
  306.     {
  307.         for(j=0; j < MAX_LOOPS; j++)
  308.         {
  309.             for(i=1; i < p; i++)
  310.             {
  311.         /* increment complexity for if statement */
  312.         compare_nonzero();
  313. d = sub(w[i+1],w[i]);     data_move();
  314.                 if (d < delta)
  315.                 {
  316.     data_move();    data_move();
  317.                     step1 = step2 = shr(sub(delta,d),1);
  318.     /* increment complexity for if statement */
  319.     compare_nonzero();    compare_nonzero();
  320.                     if (i==1 && (w[i] < delta)) {
  321.       step1 = shr(w[i],1);    data_move();
  322.     }
  323.                     else {
  324.       /* increment complexity for if statement */
  325.       compare_nonzero();
  326.       if (i > 1)
  327.       {
  328.         /* increment complexity for if statement */
  329.         compare_nonzero();
  330. temp = sub(w[i],w[i-1]);
  331.                         if (temp < delta) {
  332.   step1 = 0;    data_move();
  333. }
  334.                         else {
  335.   /* increment complexity for if statement */
  336.   compare_nonzero();    compare_nonzero();
  337.   if (temp < shl(delta,1)) {
  338.     step1 = shr(sub(temp,delta),1);
  339.   }
  340. }
  341.       }
  342.                     }
  343.     /* increment complexity for if statement */
  344.     compare_nonzero();    compare_nonzero();
  345.                     if (i==(p-1) && (w[i+1] > sub(ONE_Q15,delta))) {
  346.                         step2 = shr(sub(ONE_Q15,w[i+1]),1);    data_move();
  347.     }
  348.                     else {
  349.       /* increment complexity for if statement */
  350.       compare_nonzero();
  351.       if (i < (p-1))
  352.       {
  353.         /* increment complexity for if statement */
  354.         compare_nonzero();
  355. temp = sub(w[i+2],w[i+1]);
  356.                         if (temp < delta) {
  357.   step2 = 0;    data_move();
  358. }
  359.                         else {
  360.   /* increment complexity for if statement */
  361.   compare_nonzero();
  362.   if (temp < shl(delta,1)) {
  363.                             step2 = shr(sub(temp,delta),1);
  364.   }
  365. }
  366.       }
  367.                     }
  368.                     w[i] = sub(w[i],step1);    data_move();
  369.                     w[i+1] = add(w[i+1],step2);    data_move();
  370.                     
  371.                 }
  372.             }
  373.         }
  374.     }  
  375.     
  376.     /* Debug: check if the minimum separation rule was met */
  377.     temp = mult(32440,delta);   /* temp = 0.99*delta */
  378.     for(j=1; j < p; j++)
  379.       if ((w[j+1]-w[j]) < temp)
  380.           (void)fprintf(stderr,"%s: LSPs not separated by enough (line %d)n",
  381.               __FILE__,__LINE__);
  382.     
  383.     if (unsorted)
  384.       (void)fprintf(stderr,"%s: Fxp LSPs still unsorted (line %d)n",
  385.                     __FILE__,__LINE__);
  386.     return((Shortword)0);
  387. } /* LPC_CLMP */
  388. /*  
  389.     Name: lpc_schr- Schur recursion (autocorrelations to refl coef)
  390.     Aliases: lpc_schur
  391.     Description:
  392.         Compute reflection coefficients from autocorrelations
  393.         based on schur recursion.  Will also compute predictor
  394.         parameters by calling lpc_refl2pred(3l) if necessary.
  395.     Inputs:
  396.         r- autocorrelation vector (r[0..p]).
  397.         p- order of lpc filter.
  398.     Outputs:
  399.         a-     predictor parameters    (can be NULL)
  400.         k_tmp- reflection coefficients (can be NULL)
  401.     Returns:
  402.         alphap- the minimum residual energy
  403.     Includes:
  404.         spbstd.h
  405.         lpc.h
  406.     See_Also:
  407.         lpc_refl2pred(3l) in lpc.h or lpc(3l)
  408.     Q values:
  409.     r - Q0
  410.     a - Q12
  411.     k_tmp - Q15
  412. */
  413. Shortword lpc_schr(Shortword *r, Shortword *a, Shortword *k_tmp, Shortword p)
  414. {
  415.     Shortword i,j;
  416.     Shortword shift,alphap,*k;
  417.     Longword L_temp, *y1, *y2;
  418.     Shortword n_temp,n_y2,nr1,nr0;
  419.     
  420.  
  421.     MEM_ALLOC(MALLOC,y1,p+2,Longword);
  422.     MEM_ALLOC(MALLOC,y2,p+2,Longword);
  423.     if (k_tmp == NULL)
  424.   MEM_ALLOC(MALLOC,k,p+1,Shortword);
  425.     else
  426. k = k_tmp;
  427.     nr1 = abs_s(r[1]);    data_move();
  428.     nr0 = abs_s(r[0]);    data_move();
  429.     k[1] = divide_s(nr1,nr0);    data_move();
  430.     /* increment complexity for if statement */
  431.     logic(); compare_zero();
  432.     /* if (((r[1] < 0) && (r[0] < 0)) || ((r[1] > 0) && (r[0] > 0))) */
  433.     if ((r[1] ^ r[0]) >= 0)
  434.     {
  435.       k[1] = negate(k[1]);    data_move();
  436.     }
  437.     alphap = mult(r[0],sub(ONE_Q15,mult(k[1],k[1])));    data_move();
  438.     y2[1] = L_deposit_h(r[1]);
  439.     y2[2] = L_add(L_deposit_h(r[0]),L_mult(k[1],r[1]));
  440.     for(i=2; i <= p; i++)
  441.     {
  442. y1[1] = L_deposit_h(r[i]);
  443. L_temp = L_deposit_h(r[i]);
  444.         for(j=1; j < i; j++)
  445.         {  
  446.     y1[j+1] = L_add(y2[j], L_mpy_ls(L_temp, k[j]));    L_data_move();
  447.     L_temp = L_add (L_temp, L_mpy_ls(y2[j], k[j]));
  448.     y2[j] = y1[j];    L_data_move();
  449. }
  450.         /* k[i] = -temp/y2[i]; */
  451.         if (L_temp > y2[i]) {
  452.   for (j = i; j <= p; j++)
  453.     k[j] = 0;
  454. #if (PRINT)
  455.   printf("nERROR: numerator bigger than denominator in lpc_schrn");
  456.   printf("Reflection coefficients used in frame %d:n",frames);
  457.   for (i = 1; i <= p; i++) {
  458.     printf(" %5.8f ",(float)k[i]/(1<<15));
  459.   }
  460.   printf("n");
  461. #endif
  462.   break;
  463. }
  464. shift = norm_l(y2[i]);
  465. n_temp = abs_s(extract_h(L_shl(L_temp,shift)));    data_move();
  466. n_y2 = abs_s(extract_h(L_shl(y2[i],shift)));    data_move();
  467. k[i] = divide_s(n_temp,n_y2);    data_move();
  468. /* increment complexity for if statement */
  469. L_logic(); compare_zero();
  470. if ((L_temp ^ y2[i]) >= 0)
  471. {
  472.     k[i] = negate(k[i]);    data_move();
  473. }
  474. y2[i+1] = L_add(y2[i], L_mpy_ls(L_temp, k[i]));    L_data_move();
  475. y2[i] = y1[i];    L_data_move();
  476. alphap = mult(alphap,sub(ONE_Q15,mult(k[i],k[i])));    data_move();
  477.     }
  478.     
  479.     if (a != NULL)
  480.     {
  481. lpc_refl2pred(k,a,p);
  482.     }
  483.     if (k_tmp == NULL) 
  484. MEM_FREE(FREE,k);
  485.     MEM_FREE(FREE,y2);
  486.     MEM_FREE(FREE,y1);
  487.     
  488.     return(alphap);   /* alphap in Q15 */
  489. } /* LPC_SCHR */
  490. /* LPC_REFL2PRED
  491.       get predictor coefficients from the reflection coeffs
  492.    Synopsis: lpc_refl2pred(k,a,p)
  493.       Input:
  494.          k- the reflection coeffs
  495.          p- the predictor order
  496.       Output:
  497.          a- the predictor coefficients
  498.    Reference:  Markel and Gray, Linear Prediction of Speech
  499.    Q values:
  500.    k - Q15
  501.    a - Q12
  502. */
  503. Shortword lpc_refl2pred(Shortword *k,Shortword *a,Shortword p)
  504. {
  505.     Shortword i,j;
  506.     Shortword *a1;
  507.     MEM_ALLOC(MALLOC,a1,p+1,Shortword);
  508.     for(i=1; i <= p; i++)
  509.     {
  510.         /* refl to a recursion */
  511.         a[i] = shift_r(k[i],-3);      /* a in Q12 */    data_move();
  512.         for(j=1; j < i; j++) {
  513.   a1[j] = a[j];    data_move();
  514. }
  515.         for(j=1; j < i; j++) {
  516.             a[j] = add(a1[j],mult(k[i],a1[i-j]));    data_move();
  517. }
  518.     }
  519.     MEM_FREE(FREE,a1);
  520.     return((Shortword)0);
  521. } /* LPC_REFL2PRED */
  522. /* minimum LSP separation-- a global variable */
  523. Shortword lsp_delta = 0;
  524. /* LPC_PRED2LSP
  525.       get LSP coeffs from the predictor coeffs
  526.       Input:
  527.          a- the predictor coefficients
  528.          p- the predictor order
  529.       Output:
  530.          w- the lsp coefficients
  531.       This function uses a DFT to evaluate the P and Q polynomials,
  532.       and is hard-coded to work only for 10th order LPC.
  533.    Q values:
  534.    a - Q12
  535.    w - Q15
  536. */
  537. static void lsp_to_freq(Shortword lsp[], Shortword w[], Shortword order);
  538. #define LPC_ORD 10
  539. Shortword lpc_pred2lsp(Shortword *a,Shortword *w,Shortword p)
  540. {
  541.     Shortword i,j;
  542.     Shortword p_cof[LPC_ORD+1], q_cof[LPC_ORD+1],
  543.               p_freq[LPC_ORD+1], q_freq[LPC_ORD+1];
  544.     Longword L_p_cof[LPC_ORD+1], L_q_cof[LPC_ORD+1];
  545.     Longword L_ai,L_api,L_temp;
  546.     /* Generate P' and Q' polynomials   */
  547.     L_p_cof[0] = (Longword)ONE_Q26;
  548.     L_q_cof[0] = (Longword)ONE_Q26;
  549.     for ( i = 1; i <= p; i++ ) {
  550.         /* temp = sub(a[i],a[p+1-i]); */     /* temp in Q12 */
  551.         L_ai = L_shr(L_deposit_h(a[i]),2);     L_data_move();
  552. L_api = L_shr(L_deposit_h(a[p+1-i]),2);     L_data_move();
  553. L_temp = L_sub(L_ai,L_api);       /* L_temp in Q26 */
  554.         L_p_cof[i] = L_add(L_temp,L_p_cof[i-1]);      /* L_p_cof in Q26 */
  555. /* temp = add(a[i],a[p+1-i]); */
  556. L_temp = L_add(L_ai,L_api);
  557.         L_q_cof[i] = L_sub(L_temp,L_q_cof[i-1]);      /* L_q_cof in Q26 */
  558.     }
  559.     /* Convert p_cof and q_cof to short */
  560.     for ( i = 0; i <= p; i++ ) {
  561.       p_cof[i] = round(L_p_cof[i]);     /* p_cof in Q10 */
  562.       q_cof[i] = round(L_q_cof[i]);     /* q_cof in Q10 */
  563.     }
  564.     /* Find root frequencies of LSP polynomials */
  565.     lsp_to_freq(p_cof,p_freq,p);
  566.     lsp_to_freq(q_cof,q_freq,p);
  567.     /* Combine frequencies into single array    */
  568.     w[0] = 0;
  569.     j = 1;
  570.     for (i = 0; i < (shr(p,1)); i++) {
  571.         w[j++] = q_freq[i];      data_move();
  572.         w[j++] = p_freq[i];      data_move();
  573.     }
  574.     return((Shortword)0);
  575. } /* LPC_PRED2LSP */
  576. /*                                                              */
  577. /*      Subroutine LSP_TO_FREQ: Calculate Line Spectrum Pair    */
  578. /*      root frequencies from LSP polynomial.                   */
  579. /*                                                              */
  580. /* Q values:
  581.    lsp - Q10
  582.    w - Q15 
  583. */
  584. #define DFTLENGTH       512
  585. #define DFTLENGTH_D2    (DFTLENGTH/2)
  586. #define DFTLENGTH_D4    (DFTLENGTH/4)
  587. static void lsp_to_freq(Shortword lsp[], Shortword w[], Shortword p)
  588. {
  589.     Shortword i;
  590.     Shortword p2, count, prev_less, j;
  591.     static Shortword firstcall = 1;
  592.     Longword mag0, mag1, mag2;
  593.     Shortword s_mag0, s_mag1, s_mag2;
  594.     Shortword *p_cos, *p_endlsp, *p_lsp, *p_begcos, *p_endcos;
  595.     Shortword temp1, temp2;
  596.     Longword L_temp1, L_temp2;
  597.     static Shortword lsp_cos[DFTLENGTH];    /* cosine table */
  598.     static Shortword default_w, default_w0;
  599.     static Shortword cos_tab[129] =
  600.     { 
  601.         32767, 32766, 32758, 32746, 32729, 32706, 32679, 32647, 32610,
  602.         32568, 32522, 32470, 32413, 32352, 32286, 32214, 32138, 32058,
  603.         31972, 31881, 31786, 31686, 31581, 31471, 31357, 31238, 31114,
  604.         30986, 30853, 30715, 30572, 30425, 30274, 30118, 29957, 29792,
  605.         29622, 29448, 29269, 29086, 28899, 28707, 28511, 28311, 28106,
  606.         27897, 27684, 27467, 27246, 27020, 26791, 26557, 26320, 26078,
  607.         25833, 25583, 25330, 25073, 24812, 24548, 24279, 24008, 23732,
  608.         23453, 23170, 22884, 22595, 22302, 22006, 21706, 21403, 21097,
  609.         20788, 20475, 20160, 19841, 19520, 19195, 18868, 18538, 18205,
  610.         17869, 17531, 17190, 16846, 16500, 16151, 15800, 15447, 15091,
  611.         14733, 14373, 14010, 13646, 13279, 12910, 12540, 12167, 11793,
  612.         11417, 11039, 10660, 10279,  9896,  9512,  9127,  8740,  8351,
  613.         7962,   7571,  7180,  6787,  6393,  5998,  5602,  5205,  4808,
  614.         4410,   4011,  3612,  3212,  2811,  2411,  2009,  1608,  1206,
  615.         804,     402,     0
  616.     };
  617.     if (firstcall) {
  618.         /* Initialization: fill cosine table */
  619.         firstcall = 0;
  620. /* for (i = 0; i < DFTLENGTH; i++ )
  621.      lsp_cos[i] = cos(i*(TWOPI / DFTLENGTH)); */
  622. for (i = 0; i < DFTLENGTH_D4; i++) {
  623.   lsp_cos[i] = cos_tab[i];
  624.   lsp_cos[i+DFTLENGTH_D4] = -cos_tab[DFTLENGTH_D4-i];
  625.   lsp_cos[i+2*DFTLENGTH_D4] = -cos_tab[i];
  626.   lsp_cos[i+3*DFTLENGTH_D4] = cos_tab[DFTLENGTH_D4-i];
  627. }
  628. /* compute default values for w[] */
  629. /* (1./p2) in Q15 */
  630. default_w = divide_s(ONE_Q11,shl(p,10));
  631. /* w[0] = (0.5/p2) in Q15 */
  632. default_w0 = shr(default_w,1);
  633.     }
  634.     prev_less = 1;
  635.     mag0 = (Longword)0x7fffffff;      L_data_move();
  636.     mag1 = (Longword)0x7fffffff;      L_data_move();
  637.     s_mag0 = (Shortword)0x7fff;      data_move();
  638.     s_mag1 = (Shortword)0x7fff;      data_move();
  639.     p2 = shr(p,1);      /* p/2 */
  640.     count = 0;      data_move();
  641.     p_begcos = &lsp_cos[0];
  642.     p_endcos = &lsp_cos[DFTLENGTH-1];
  643.     p_endlsp = &lsp[p2];
  644.     /*  Search all frequencies for minima of Pc(w) */
  645.     for (i = 0; i <= DFTLENGTH_D2; i++ ) {
  646.         p_lsp = p_endlsp;
  647.         p_cos = p_begcos++;
  648. /* mag2 = 0.5 * *(p_lsp--); */
  649. mag2 = L_mult(*(p_lsp--),(Shortword)X05_Q14);     /* mag2 in Q25 */
  650.         for (j = p2 - 1; j >= 0; j-- ) {
  651.     L_temp1 = L_shr(L_mult(*(p_lsp--),*(p_cos)),1);
  652.             mag2 = L_add(mag2,L_temp1);
  653.     complexity -= 4;    /* this can be done with MAC on TMS320C5x */
  654.             p_cos += i;
  655.             if (p_cos > p_endcos)
  656.                 p_cos -= DFTLENGTH;
  657.         }
  658. s_mag2 = extract_h(mag2);
  659.         mag2 = L_abs(mag2);
  660. L_compare_nonzero();
  661.         if (mag2 < mag1) {
  662.     prev_less = 1;      data_move();
  663. }
  664.         else {
  665.             if (prev_less) {
  666.       /* check for sign change */
  667.       logic();    compare_zero();
  668.       if ((s_mag0 ^ s_mag2) < 0) {
  669. /* Minimum frequency found */
  670. /*w[count] = i - 1 + (0.5 *
  671.              (mag0 - mag2) / (mag0 + mag2 - 2*mag1) );
  672.      w[count] *= (2. / DFTLENGTH) ;*/
  673. L_temp1 = L_shr(L_sub(mag0,mag2),1);
  674. L_temp2 = L_sub(mag0,L_shl(mag1,1));
  675. L_temp2 = L_add(L_temp2,mag2);
  676. temp1 = L_divider2(L_temp1,L_temp2,0,0);  /* temp1 in Q15 */
  677. temp1 = shr(temp1,9);    /* Q6 */
  678. temp2 = sub(i,1);
  679. temp1 = add(shl(temp2,6),temp1);
  680. w[count] = divide_s(temp1,shl(DFTLENGTH,5));      data_move();
  681. count = add(count,1);
  682.       }
  683.     }
  684.     prev_less = 0;      data_move();
  685.         }
  686.         mag0 = mag1;      L_data_move();
  687.         mag1 = mag2;      L_data_move();
  688. s_mag0 = s_mag1;      data_move();
  689. s_mag1 = s_mag2;      data_move();
  690.     }
  691.     
  692.     /*  Verify that all roots were found                */
  693.     if (count != p2) {
  694. #if (PRINT)
  695.         printf("ERROR: couldn't find LSP frequencies in frame %d.n",frames);
  696.         printf(" Found were ");
  697.         for (i = 0; i < count; i++) 
  698.             printf(" %10.4f ",(float)w[i]/(1<<15));
  699.         printf("n");
  700. #endif
  701.         /* use default values */
  702.         w[0] = default_w0;
  703.         for (i = 1; i < p2; i++) {
  704.             w[i] = w[i-1] + default_w;
  705.         }
  706.     }
  707. } /* LSP_TO_FREQ */
  708. #undef  DFTLENGTH
  709. #undef  DFTLENGTH_D2
  710. #undef  DFTLENGTH_D4
  711. /* LPC_PRED2REFL
  712.       get refl coeffs from the predictor coeffs
  713.       Input:
  714.          a- the predictor coefficients
  715.          p- the predictor order
  716.       Output:
  717.          k- the reflection coefficients
  718.       Returns:
  719.          energy - energy of residual signal
  720.    Reference:  Markel and Gray, Linear Prediction of Speech
  721.    Q values:
  722.    *a - Q12
  723.    *k - Q15
  724.    energy - Q15
  725. */
  726. Shortword lpc_pred2refl(Shortword *a,Shortword *k,Shortword p)
  727. {
  728.     Shortword *b,*b1, e;
  729.     Shortword energy = ONE_Q15;
  730.     Shortword i,j;
  731.     Shortword shift;
  732.     Shortword temp, n_temp, n_e;
  733.     MEM_ALLOC(MALLOC,b,p+1,Shortword);
  734.     MEM_ALLOC(MALLOC,b1,p+1,Shortword);
  735.     /* equate temporary variables (b = a) */
  736.     for(i=1; i <= p; i++) {
  737.       b[i] = a[i];      data_move();
  738.     }
  739.     /* compute reflection coefficients */
  740.     for(i=p; i > 0; i--)
  741.     {
  742.         k[i] = shl(b[i],3);     /* Q12 -> Q15 */
  743.         e = sub(ONE_Q15,mult(k[i],k[i]));
  744.         energy = mult(energy,e);
  745.         for(j=1; j < i; j++) {
  746.             b1[j] = b[j];      data_move();
  747. }
  748.         for(j=1; j < i; j++) {
  749.     /* b[j] = (b1[j] - k[i]*b1[i-j])/e; */
  750.     temp = mult(k[i],b1[i-j]);    /* temp in Q12 */
  751.     temp = sub(b1[j],temp);
  752.     /* check signs of temp and e before division */
  753.     n_temp = abs_s(temp);
  754.     n_e = abs_s(e);
  755.     shift = norm_s(n_e);
  756.     n_e = shl(n_e,shift);
  757.     if (n_temp > n_e) {
  758.       n_temp = shr(n_temp,1);
  759.       shift = add(shift,1);
  760.     }
  761.     b[j] = shl(divide_s(n_temp,n_e),shift);    /* b[j] in Q12 */
  762.     if ((temp ^ e) < 0)
  763.       b[j] = negate(b[j]);
  764. }
  765.     }
  766.     MEM_FREE(FREE,b1);
  767.     MEM_FREE(FREE,b);
  768.     return(energy);
  769. } /* LPC_PRED2REFL */
  770. /* LPC_LSP2PRED
  771.       get predictor coefficients from the LSPs
  772.    Synopsis: lpc_lsp2pred(w,a,p)
  773.       Input:
  774.          w- the LSPs
  775.          p- the predictor order
  776.       Output:
  777.          a- the predictor coefficients
  778.    Reference:  Kabal and Ramachandran
  779. */
  780. /* Q values:
  781.    w - Q15
  782.    a - Q12
  783.    f - Q25
  784.    c - Q14 */
  785. Shortword lpc_lsp2pred(Shortword *w,Shortword *a,Shortword p)
  786. {
  787.     Shortword i,j,k,p2;
  788.     Shortword c[2];
  789.     Longword **f;
  790.     Longword L_temp;
  791.     /* ensure minimum separation and sort */
  792.     (void)lpc_clmp(w,lsp_delta,p);
  793.     /* p2 = p/2 */
  794.     p2 = shr(p,1);     data_move();
  795.     MEM_2ALLOC(MALLOC,f,2,p2+1,Longword);
  796.     /* f is Q25 */
  797.     f[0][0] = f[1][0] = (Longword)ONE_Q25;    L_data_move();    L_data_move();
  798.     /* -2.0*cos((double)w[1]*M_PI) */
  799.     f[0][1] = L_shr(L_deposit_h(negate(cos_fxp(w[1]))),5);  L_data_move();
  800.     f[1][1] = L_shr(L_deposit_h(negate(cos_fxp(w[2]))),5);  L_data_move();
  801.     k = 3;
  802.     for(i=2; i <= p2; i++)
  803.       { 
  804.         /* c is Q14 */
  805.         /* multiply by 2 is considered as Q15->Q14 */
  806.         c[0] = negate(cos_fxp(w[k++]));    data_move();
  807.         c[1] = negate(cos_fxp(w[k++]));    data_move();
  808.        
  809.         f[0][i] = f[0][i-2];    L_data_move();
  810.         f[1][i] = f[1][i-2];    L_data_move();
  811.         for(j=i; j >= 2; j--)
  812.           {
  813.     /* f[0][j] += c[0]*f[0][j-1]+f[0][j-2] */
  814.     L_temp = L_mpy_ls(f[0][j-1],c[0]);
  815.     L_temp = L_add(L_shl(L_temp,1),f[0][j-2]);
  816.             f[0][j] = L_add(f[0][j],L_temp);    L_data_move();
  817.             /* f[1][j] += c[1]*f[1][j-1]+f[1][j-2] */
  818.     L_temp = L_mpy_ls(f[1][j-1],c[1]);
  819.     L_temp = L_add(L_shl(L_temp,1),f[1][j-2]);
  820.             f[1][j] = L_add(f[1][j],L_temp);    L_data_move();
  821.           }
  822.         f[0][1] = L_add(f[0][1],L_shl(L_mpy_ls(f[0][0],c[0]),1));
  823.         f[1][1] = L_add(f[1][1],L_shl(L_mpy_ls(f[1][0],c[1]),1));
  824.       }
  825.     for(i=p2; i > 0; i--)
  826.       {
  827.         /* short f (f is a Q14) */
  828.         f[0][i] = L_add(f[0][i],f[0][i-1]);
  829.         f[1][i] = L_sub(f[1][i],f[1][i-1]);
  830.         /* a is Q12 */
  831.         /* a[i] = 0.50*(f[0][i]+f[1][i]) */
  832. /* a[p+1-i] = 0.50*(f[0][i]-f[1][i]) */
  833. /* Q25 -> Q27 -> Q12 */
  834.         a[i] = extract_h(L_shl(L_add(f[0][i],f[1][i]),2));
  835.         a[p+1-i] = extract_h(L_shl(L_sub(f[0][i],f[1][i]),2));
  836.     }
  837.     MEM_2FREE(FREE,f);
  838.     return((Shortword)0);
  839. } /* LPC_LSP2PRED */
  840. /*
  841.     Name: lpc_syn- LPC synthesis filter.
  842.     Aliases: lpc_synthesis
  843.     Description:
  844.         LPC all-pole synthesis filter
  845.         for j = 0 to n-1
  846.             y[j] = x[j] - sum(k=1 to p) y[j-k] a[k]
  847.     Inputs:
  848.         x- input vector (n samples, x[0..n-1])
  849.         a- lpc vector (order p, a[1..p])
  850.         p- order of lpc filter
  851.         n- number of elements in vector which is to be filtered
  852.         y[-p..-1]- filter memory (past outputs)
  853.     Outputs:
  854.         y- output vector (n samples, y[0..n-1])
  855.     Returns: NULL
  856.     Includes:
  857.         spbstd.h
  858.         lpc.h
  859.     Systems and Info. Science Lab
  860.     Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
  861. */
  862. Shortword lpc_syn(Shortword *x,Shortword *y,Shortword *a,Shortword p,
  863.   Shortword n)
  864. {
  865.     Shortword i,j;
  866.     Longword accum;
  867.     for(j=0; j < n; j++) {
  868.         accum = L_shr(L_deposit_h(x[j]),3);
  869. for(i=p; i > 0; i--)
  870.     accum = L_msu(accum,y[j-i],a[i]);
  871. /* Round off output */
  872. accum = L_shl(accum,3);
  873. y[j] = round(accum);
  874.     }
  875.     return((Shortword)0);
  876. }