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

语音压缩

开发平台:

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. #include <stdio.h>
  24. #include "spbstd.h"
  25. #include "mathhalf.h"
  26. #include "wmops.h"
  27. #include "mat.h"
  28. #include "math_lib.h"
  29. #include "lpc.h"
  30. #include "vq.h"
  31. #include "constant.h"
  32. /* VQ_LSPW- compute LSP weighting vector-
  33.     Atal's method:
  34.         From Atal and Paliwal (ICASSP 1991)
  35.         (Note: Paliwal and Atal used w(k)^2(u(k)-u_hat(k))^2,
  36.          and we use w(k)(u(k)-u_hat(k))^2 so our weights are different
  37.          but the method (i.e. the weighted MSE) is the same.
  38.                 */
  39. /* Q values:
  40.    w is Q11
  41.    lsp is Q15
  42.    a is Q12 */
  43. Shortword *vq_lspw(Shortword *w, Shortword *lsp, Shortword *a, 
  44.    Shortword p)
  45. {
  46.     Shortword j;
  47.     Longword L_temp;
  48.     
  49.     for(j = 0; j < p; j++)
  50.       {
  51. L_temp = lpc_aejw(a,lsp[j],p);    /* L_temp in Q19 */
  52. w[j] = L_pow_fxp(L_temp,(Shortword)XN03_Q15,19,11);
  53. if (j == 8)
  54.   w[j] = mult(w[j], (Shortword)X064_Q15);
  55. else if (j == 9)
  56.   w[j] = mult(w[j], (Shortword)X016_Q15);
  57.       }
  58.     return(w);
  59. } /* VQ_LSPW */
  60. /*
  61.     VQ_MS4-
  62.         Tree search multi-stage VQ encoder (optimized for speed
  63.         should be compatible with VQ_MS)
  64.     Synopsis: vq_ms4(cb,u,u_est,levels,ma,stages,p,w,u_hat,a_indices)
  65.         Input:
  66.             cb- one dimensional linear codebook array (codebook is structured 
  67.                 as [stages][levels for each stage][p])
  68.             u- dimension p, the parameters to be encoded (u[0..p-1])
  69.             u_est- dimension p, the estimated parameters or mean (if NULL, assume
  70.                estimate is the all zero vector) (u_est[0..p-1])
  71.             levels- the number of levels at each stage (levels[0..stages-1])
  72.             ma- the tree search size (keep ma candidates from one stage to the
  73.                next)
  74.             stages- the number of stages of msvq
  75.             p- the predictor order
  76.             w- the weighting vector (w[0..p-1])
  77.             max_inner- the maximum number of times the swapping procedure
  78.                        in the inner loop can be executed
  79.         Output:
  80.             u_hat-   the reconstruction vector (if non null)
  81.             a_indices- the codebook indices (for each stage) a_indices[0..stages-1]
  82.         Parameters:
  83. */
  84. #define P_SWAP(x,y,type) do{type u__p;u__p = x;x = y;y = u__p;}while(0)
  85. /* cb is Q17
  86.    u is Q15
  87.    u_est is Q15
  88.    w is Q11
  89.    u_hat is Q15 */
  90. Shortword vq_ms4(Shortword *cb, Shortword *u, Shortword *u_est, 
  91.  Shortword *levels, Shortword ma, Shortword stages, 
  92.  Shortword p, Shortword *w, Shortword *u_hat, 
  93.  Shortword *a_indices, Shortword max_inner)
  94. {
  95.     Shortword tmp,*u_tmp,*uhatw,uhatw_sq;
  96.     Shortword d_cj,d_opt;
  97.     Shortword *d,*p_d,*n_d,*p_distortion,*cb_currentstage,*cbp, *cb_table;
  98.     Shortword *errors,*p_errors,*n_errors,*p_e;
  99.     Shortword i,j,m,s,c,p_max,inner_counter;
  100.     Shortword *indices,*p_indices,*n_indices;
  101.     Shortword *parents,*p_parents,*n_parents;
  102.     Shortword *tmp_p_e;
  103.     Shortword temp;
  104.     Longword L_temp,L_temp1;
  105.     
  106.     /* make sure weights don't get too big */
  107. #define MAXWT  4096           /* w[i] < 2.0 to avoid saturation */
  108. #define MAXWT2 (MAXWT*2)
  109. #define MAXWT4 (MAXWT*4)
  110.     j = 0;    data_move();
  111.     for (i = 0; i < p; i++) {
  112.       if (w[i] > MAXWT4) {
  113.         /* increment complexity for if statement */
  114.         compare_nonzero();
  115. j = 3;    data_move();
  116. break;
  117.       }
  118.       else if (w[i] > MAXWT2) {
  119.         /* increment complexity for if statement */
  120.         compare_nonzero();
  121. j = 2;    data_move();
  122.       }
  123.       else if (w[i] > MAXWT) {
  124.         /* increment complexity for if statement */
  125.         compare_nonzero();
  126. /* increment complexity for if statement */
  127.         compare_zero();
  128. if (j == 0) {
  129.   j = 1;    data_move();
  130. }
  131.       }
  132.     }
  133.     for (i = 0; i < p; i++) {
  134.       w[i] = shr(w[i],j);    data_move();
  135.     }
  136.     /* allocate memory for the current node and
  137.        parent node (thus, the factors of two everywhere)
  138.        The parents and current nodes are allocated contiguously */
  139.     MEM_ALLOC(MALLOC,indices,2*ma*stages,Shortword);
  140.     MEM_ALLOC(MALLOC,errors,2*ma*p,Shortword);
  141.     MEM_ALLOC(MALLOC,uhatw,p,Shortword);
  142.     MEM_ALLOC(MALLOC,d,2*ma,Shortword);
  143.     MEM_ALLOC(MALLOC,parents,2*ma,Shortword);
  144.     MEM_ALLOC(MALLOC,tmp_p_e,ma*p,Shortword);
  145.     
  146.     /* initialize memory */
  147.     v_zap(indices,(Shortword)(2*stages*ma));
  148.     v_zap(parents,(Shortword)(2*ma));
  149.     
  150.     /* initialize inner loop counter */
  151.     inner_counter = 0;  data_move();
  152.     
  153.     /* set up memory */
  154.     p_indices = &indices[0];  data_move();
  155.     n_indices = &indices[ma*stages];  data_move();
  156.     p_errors = &errors[0];  data_move();
  157.     n_errors = &errors[ma*p];  data_move();
  158.     p_d = &d[0];  data_move();
  159.     n_d = &d[ma];  data_move();
  160.     p_parents = &parents[0];  data_move();
  161.     n_parents = &parents[ma];  data_move();
  162.     
  163.     /* u_tmp is the input vector (i.e. if u_est is non-null, it
  164.        is subtracted off) */
  165.     MEM_ALLOC(MALLOC,u_tmp,p+1,Shortword);
  166.     /* u_tmp is Q15 */
  167.     (void)v_equ(u_tmp,u,p);
  168.     if (u_est)
  169.       (void)v_sub(u_tmp,u_est,p);
  170.     /* change u_tmp from Q15 to Q17 */
  171.     for (j=0; j<p; j++)
  172.       u_tmp[j] = shl(u_tmp[j], 2);  data_move();
  173.     /* L_temp is Q31 */
  174.     L_temp = 0;  data_move();
  175.     for(j = 0 ; j < p; j++) {
  176.       temp = mult(u_tmp[j],w[j]);    /* temp = Q13 */
  177.       L_temp = L_mac(L_temp,temp,u_tmp[j]);
  178.     }
  179.     /* tmp in Q15 */
  180.     tmp = extract_h(L_temp);
  181.     /* set up inital error vectors (i.e. error vectors = u_tmp) */
  182.     for(c=0; c < ma; c++)
  183.     {
  184. /* n_errors is Q17
  185.    n_d is Q15 */
  186. (void)v_equ(&n_errors[c*p],u_tmp,p);
  187. n_d[c] = tmp;   data_move();
  188.     }
  189.     /* no longer need memory so free it here */
  190.     MEM_FREE(FREE,u_tmp);
  191.     /* codebook pointer is set to point to first stage */
  192.     cbp = cb;
  193.     /* set m to 1 for the first stage
  194.        and loop over all stages */
  195.     for(m=1,s=0; s < stages; s++)
  196.     {
  197.         /* Save the pointer to the beginning of the
  198.            current stage.  Note: cbp is only incremented in
  199.            one spot, and it is incremented all the way through
  200.            all the stages. */
  201.         cb_currentstage = cbp;
  202.         /* set up pointers to the parent and current nodes */
  203.         P_SWAP(p_indices,n_indices,Shortword*);
  204.         P_SWAP(p_parents,n_parents,Shortword*);
  205. P_SWAP(p_errors,n_errors,Shortword*);
  206. P_SWAP(p_d,n_d,Shortword*);
  207.         /* p_max is the pointer to the maximum distortion
  208.            node over all candidates.  The so-called worst
  209.            of the best. */
  210.         p_max = 0;  data_move();
  211. /* store errors in Q15 in tmp_p_e */
  212. for (i = 0; i < m*p; i++) {
  213.   tmp_p_e[i] = shr(p_errors[i],2);  data_move();
  214. }
  215.         /* set the distortions to a large value */
  216.         for(c=0; c < ma; c++) {
  217.     n_d[c] = SW_MAX;  data_move();
  218. }
  219.         for(j=0; j < levels[s]; j++)
  220.         {
  221.             /* compute weighted codebook element, increment codebook pointer */
  222.     /* L_temp is Q31 */
  223.     L_temp = 0;    data_move();
  224.     for(i=0 ; i < p; i++,cbp++)
  225.             {
  226.         /* Q17*Q11<<1 = Q29 */
  227.         L_temp1 = L_mult(*cbp,w[i]);
  228. /* uhatw[i] = -2*tmp */
  229. /* uhatw is Q15 (shift 3 to take care of *2)*/
  230. uhatw[i] = negate(extract_h(L_shl(L_temp1,3)));
  231. /* tmp is now Q13 */
  232. tmp = extract_h(L_temp1);
  233. L_temp = L_mac(L_temp,*cbp,tmp);
  234.             }
  235.     /* uhatw_sq is Q15 */
  236.     uhatw_sq = extract_h(L_temp);
  237.             /* p_e points to the error vectors and p_distortion
  238.                points to the node distortions.  Note: the error
  239.                vectors are contiguous in memory, as are the distortions.
  240.                Thus, the error vector for the 2nd node comes immediately
  241.                after the error for the first node.  (This saves on
  242.                repeated initializations) */
  243.     /* p_e is Q15 */
  244.     p_e = tmp_p_e;
  245.             p_distortion = p_d;
  246.     
  247.             /* iterate over all parent nodes */
  248.             for(c=0; c < m; c++)
  249.             {
  250. /* L_temp is Q31
  251.    p_distortion is same Q as n_d 
  252.    p_e is Q15 */
  253. L_temp = L_deposit_h(add(*p_distortion++,uhatw_sq));
  254.                 for(i=0; i < p; i++) {
  255.   L_temp = L_mac(L_temp,*p_e++,uhatw[i]);
  256. }
  257. /* d_cj is Q15 */
  258. d_cj = extract_h(L_temp);
  259.                 /* determine if d is less than the maximum candidate distortion                   i.e., is the distortion found better than the so-called
  260.                    worst of the best */
  261. /* increment complexity for if statement */
  262. compare_nonzero();
  263.                 if (d_cj <= n_d[p_max])
  264.                 {
  265.                     /* replace the worst with the values just found */
  266.     /* n_d is now a Q16 */
  267.     n_d[p_max] = d_cj;    data_move();
  268.                     i = add(shr(extract_l(L_mult(p_max,stages)),1),s);
  269.                     n_indices[i] = j;        data_move();
  270.                     n_parents[p_max] = c;    data_move();
  271.                     /* want to limit the number of times the inner loop
  272.                        is entered (to reduce the *maximum* complexity) */
  273.     /* increment complexity for if statement */
  274.     compare_nonzero();
  275.                     if (inner_counter < max_inner)
  276.                     {
  277.                         inner_counter = add(inner_counter,1);
  278. /* increment complexity for if statement */
  279. compare_nonzero();
  280.         if (inner_counter < max_inner)
  281. {
  282.                             p_max = 0;    data_move();
  283.                             /* find the new maximum */
  284.             for(i=1; i < ma; i++)
  285.                             {
  286.         /* increment complexity for if statement */
  287.         compare_nonzero();
  288.                                 if (n_d[i] > n_d[p_max])
  289.                                     p_max = i;    data_move();
  290.             }
  291.         }
  292. else /* inner_counter == max_inner */
  293.                         {
  294.                                /* The inner loop counter now exceeds the
  295.                                maximum, and the inner loop will now not
  296.                                be entered.  Instead of quitting the search
  297.                                or doing something drastic, we simply keep
  298.                                track of the best candidate (rather than the
  299.                                M best) by setting p_max to equal the index
  300.                                of the minimum distortion
  301.                                i.e. only keep one candidate around
  302.                                 the MINIMUM distortion */
  303.             for(i=1; i < ma; i++)
  304.                             {
  305.         /* increment complexity for if statement */
  306.         compare_nonzero();
  307.                                 if (n_d[i] < n_d[p_max])
  308.                                     p_max = i;    data_move();
  309.             }
  310.         }
  311.     }
  312.                 }
  313.             } /* for c */
  314.         } /* for j */
  315.         /* compute the error vectors for each node */
  316.         for(c=0; c < ma; c++)
  317.         {
  318.             /* get the error from the parent node and subtract off
  319.                the codebook value */
  320.     (void)v_equ(&n_errors[c*p],&p_errors[n_parents[c]*p],p);
  321.     (void)v_sub(&n_errors[c*p],
  322. &cb_currentstage[n_indices[c*stages+s]*p],p);
  323.             /* get the indices that were used for the parent node */
  324.             (void)v_equ(&n_indices[c*stages],
  325. &p_indices[n_parents[c]*stages],s);
  326.         }
  327.         /* increment complexity for if statement */
  328.         compare_nonzero();  data_move();
  329.         m = (m*levels[s] > ma) ? ma : m*levels[s];
  330.     } /* for s */
  331.     /* find the optimum candidate c */
  332.     for(i=1,c=0; i < ma; i++)
  333.     {
  334.         /* increment complexity for if statement */
  335.         compare_nonzero();
  336.         if (n_d[i] < n_d[c])
  337.     c = i;    data_move();
  338.     }
  339.     d_opt = n_d[c];    data_move();
  340.     
  341.     if (a_indices)
  342.     {
  343.         (void)v_equ(a_indices,&n_indices[c*stages],stages);
  344.     }
  345.     if (u_hat)
  346.     {
  347.         if (u_est)
  348.     (void)v_equ(u_hat,u_est,p);
  349.         else
  350.     (void)v_zap(u_hat,p);
  351.         cb_currentstage = cb;
  352.         for(s=0; s < stages; s++)
  353.         {
  354.   cb_table = &cb_currentstage[n_indices[c*stages+s]*p];   
  355.   for (i=0; i<p; i++)
  356.     u_hat[i] = add(u_hat[i], shr(cb_table[i],2));   data_move();  
  357.   cb_currentstage += levels[s]*p;
  358.         }
  359.     }
  360.     
  361.     MEM_FREE(FREE,parents);
  362.     MEM_FREE(FREE,d);
  363.     MEM_FREE(FREE,uhatw);
  364.     MEM_FREE(FREE,errors);
  365.     MEM_FREE(FREE,indices);
  366.     MEM_FREE(FREE,tmp_p_e);
  367.     return(d_opt);
  368. } /* vq_ms4 */
  369. /*
  370.     VQ_MSD2-
  371.         Tree search multi-stage VQ decoder
  372.     Synopsis: vq_msd(cb,u,u_est,a,indices,levels,stages,p,conversion)
  373.         Input:
  374.             cb- one dimensional linear codebook array (codebook is structured 
  375.                 as [stages][levels for each stage][p])
  376.             indices- the codebook indices (for each stage) indices[0..stages-1]
  377.             levels- the number of levels (for each stage) levels[0..stages-1]
  378.             u_est- dimension p, the estimated parameters or mean (if NULL, assume
  379.                estimate is the all zero vector) (u_est[0..p-1])
  380.             stages- the number of stages of msvq
  381.             p- the predictor order
  382.             conversion- the conversion constant (see lpc.h, lpc_conv.c)
  383.     diff_Q- the difference between Q value of codebook and u_est
  384.         Output:
  385.             u- dimension p, the decoded parameters (if NULL, use alternate
  386.                temporary storage) (u[0..p-1])
  387.             a- predictor parameters (a[0..p]), if NULL, don't compute
  388.         Returns:
  389.             pointer to reconstruction vector (u)
  390.         Parameters:
  391. */
  392. Shortword *vq_msd2(Shortword *cb, Shortword *u, Shortword *u_est, 
  393.    Shortword *a, Shortword *indices, Shortword *levels, 
  394.    Shortword stages, Shortword p, Shortword conversion,
  395.    Shortword diff_Q)
  396. {
  397.     Shortword *u_hat,*cb_currentstage,*cb_table;
  398.     Shortword i,j;
  399.     Longword *L_u_hat,L_temp;
  400.     /* allocate memory (if required) */
  401.     MEM_ALLOC(MALLOC,L_u_hat,p,Longword);
  402.     if (u==(Shortword*)NULL)
  403.     {
  404.         MEM_ALLOC(MALLOC,u_hat,p,Shortword);
  405.     }
  406.     else
  407.         u_hat = u;
  408.     /* add estimate on (if non-null), or clear vector */
  409.     if (u_est)
  410.     {
  411.         (void)v_equ(u_hat,u_est,p);
  412.     }
  413.     else
  414.     {
  415.         (void)v_zap(u_hat,p);
  416.     }
  417.     /* put u_hat to a long buffer */
  418.     for (i = 0; i < p; i++)
  419.       L_u_hat[i] = L_shl(L_deposit_l(u_hat[i]),diff_Q);
  420.     /* add the contribution of each stage */
  421.     cb_currentstage = cb;
  422.     for(i=0; i < stages; i++)
  423.     {
  424.       /* (void)v_add(u_hat,&cb_currentstage[indices[i]*p],p); */
  425.       cb_table = &cb_currentstage[indices[i]*p];   
  426.       for (j = 0; j < p; j++) {
  427. L_temp = L_deposit_l(cb_table[j]);
  428.         L_u_hat[j] = L_add(L_u_hat[j],L_temp);
  429.       }
  430.       cb_currentstage += levels[i]*p;
  431.     }
  432.     /* convert long buffer back to u_hat */
  433.     for (i = 0; i < p; i++)
  434.       u_hat[i] = extract_l(L_shr(L_u_hat[i],diff_Q));
  435.     MEM_FREE(FREE,L_u_hat);
  436.     return(u);
  437. }
  438. /* VQ_ENC -
  439.    encode vector with full VQ using unweighted Euclidean distance
  440.     Synopsis: vq_enc(cb, u, levels, p, u_hat, indices)
  441.         Input:
  442.             cb- one dimensional linear codebook array
  443.             u- dimension p, the parameters to be encoded (u[0..p-1])
  444.             levels- the number of levels
  445.             p- the predictor order
  446.         Output:
  447.             u_hat-   the reconstruction vector (if non null)
  448.             a_indices- the codebook indices (for each stage) a_indices[0..stages-1]
  449.         Parameters:
  450. */
  451. /* Q values:
  452.    cb - Q13
  453.    u - Q13
  454.    u_hat - Q13 */
  455. Longword vq_enc(Shortword *cb,Shortword *u,Shortword levels,Shortword p, 
  456. Shortword *u_hat,Shortword *indices)
  457. {
  458.     Shortword i,j,index;
  459.     Longword d,dmin;
  460.     Shortword *p_cb;
  461.     Shortword temp;
  462.     
  463.     /* Search codebook for minimum distance */
  464.     index = 0;    data_move();
  465.     dmin = LW_MAX;    L_data_move();
  466.     p_cb = cb;
  467.     for (i = 0; i < levels; i++) {
  468.         d = 0;    data_move();
  469.         for (j = 0; j < p; j++) {
  470.   temp = sub(u[j],*p_cb);
  471.           d = L_mac(d,temp,temp);
  472.           p_cb++;  
  473.         }
  474. compare_nonzero();
  475.         if (d < dmin) {
  476.             dmin = d;    data_move();
  477.             index = i;    data_move();
  478.         }
  479.     }
  480.     /* Update index and quantized value, and return minimum distance */
  481.     *indices = index;
  482.     v_equ(u_hat,&cb[p*index],p);
  483.     return(dmin);
  484. } /* vq_enc */
  485. /* VQ_FSW - 
  486.    compute the weights for Euclidean distance of Fourier harmonics  */
  487. /* Q values:
  488.    w_fs - Q14
  489.    pitch - Q9 */
  490. void vq_fsw(Shortword *w_fs, Shortword num_harm, Shortword pitch)
  491. {
  492.     Shortword j;
  493.     Shortword tempw0;
  494.     Shortword temp,denom;
  495.     Longword L_temp;
  496.     /* Calculate fundamental frequency */
  497.     /* w0 = TWOPI/pitch */
  498.     /* tempw0 = w0/(0.25*PI) = 8/pitch */
  499.     tempw0 = divide_s((Shortword)EIGHT_Q11,pitch);   /* tempw0 in Q17 */
  500.     for(j=0; j < num_harm; j++) {
  501.       /* Bark-scale weighting */
  502.       /* w_fs[j] = 117.0 / (25.0 + 75.0*
  503.            pow(1.0 + 1.4*SQR(w0*(j+1)/(0.25*PI)),0.69)) */
  504.       temp = shl(add(j,1),11);    /* Q11 */
  505.       temp = extract_h(L_shl(L_mult(tempw0,temp),1));    /* Q14 */
  506.       temp = mult(temp,temp);    /* Q13 */
  507.       /* L_temp in Q28 */
  508.       L_temp = L_add((Longword)ONE_Q28,L_mult((Shortword)X14_Q14,temp));
  509.       temp = L_pow_fxp(L_temp,(Shortword)X069_Q15,28,13);     /* Q13 */
  510.       denom = add((Shortword)X25_Q6,mult((Shortword)X75_Q8,temp));    /* Q6 */
  511.       w_fs[j] = divide_s((Shortword)X117_Q5,denom);   /* Q14 */   data_move();
  512.     }
  513. }