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

语音压缩

开发平台:

C/C++

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