⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vq_lib.c

📁 2400bps MELP语音编解码源程序。
💻 C
📖 第 1 页 / 共 2 页
字号:

		d_cj = extract_h(L_temp);


                /* determine if d is less than the maximum candidate distortion                   i.e., is the distortion found better than the so-called
                   worst of the best */
		/* increment complexity for if statement */
		compare_nonzero();
                if (d_cj <= n_d[p_max])
                {
                    /* replace the worst with the values just found */
		    /* n_d is now a Q16 */
		    n_d[p_max] = d_cj;    data_move();

                    i = add(shr(extract_l(L_mult(p_max,stages)),1),s);
                    n_indices[i] = j;        data_move();
                    n_parents[p_max] = c;    data_move();

                    /* want to limit the number of times the inner loop
                       is entered (to reduce the *maximum* complexity) */
		    /* increment complexity for if statement */
		    compare_nonzero();
                    if (inner_counter < max_inner)
                    {
                        inner_counter = add(inner_counter,1);
			/* increment complexity for if statement */
			compare_nonzero();
		        if (inner_counter < max_inner)
			{
                            p_max = 0;    data_move();
                            /* find the new maximum */
		            for(i=1; i < ma; i++)
                            {
			        /* increment complexity for if statement */
			        compare_nonzero();
                                if (n_d[i] > n_d[p_max])
                                    p_max = i;    data_move();
		            }
		        }
			else /* inner_counter == max_inner */
                        {
                               /* The inner loop counter now exceeds the
                               maximum, and the inner loop will now not
                               be entered.  Instead of quitting the search
                               or doing something drastic, we simply keep
                               track of the best candidate (rather than the
                               M best) by setting p_max to equal the index
                               of the minimum distortion
                               i.e. only keep one candidate around
                                the MINIMUM distortion */
		            for(i=1; i < ma; i++)
                            {
			        /* increment complexity for if statement */
			        compare_nonzero();
                                if (n_d[i] < n_d[p_max])
                                    p_max = i;    data_move();
		            }
		        }
		    }
                }

            } /* for c */
        } /* for j */


        /* compute the error vectors for each node */
        for(c=0; c < ma; c++)
        {
            /* get the error from the parent node and subtract off
               the codebook value */
	    (void)v_equ(&n_errors[c*p],&p_errors[n_parents[c]*p],p);
	    (void)v_sub(&n_errors[c*p],
			&cb_currentstage[n_indices[c*stages+s]*p],p);
            /* get the indices that were used for the parent node */
            (void)v_equ(&n_indices[c*stages],
			&p_indices[n_parents[c]*stages],s);
        }

        /* increment complexity for if statement */
        compare_nonzero();  data_move();
        m = (m*levels[s] > ma) ? ma : m*levels[s];
    } /* for s */


    /* find the optimum candidate c */
    for(i=1,c=0; i < ma; i++)
    {
        /* increment complexity for if statement */
        compare_nonzero();
        if (n_d[i] < n_d[c])
	    c = i;    data_move();
    }

    d_opt = n_d[c];    data_move();
    
    if (a_indices)
    {
        (void)v_equ(a_indices,&n_indices[c*stages],stages);
    }
    if (u_hat)
    {
        if (u_est)
	    (void)v_equ(u_hat,u_est,p);
        else
	    (void)v_zap(u_hat,p);

        cb_currentstage = cb;
        for(s=0; s < stages; s++)
        {
	  cb_table = &cb_currentstage[n_indices[c*stages+s]*p];	  
	  for (i=0; i<p; i++)
	    u_hat[i] = add(u_hat[i], shr(cb_table[i],2));   data_move();  
	  cb_currentstage += levels[s]*p;
        }
    }

    
    MEM_FREE(FREE,parents);
    MEM_FREE(FREE,d);
    MEM_FREE(FREE,uhatw);
    MEM_FREE(FREE,errors);
    MEM_FREE(FREE,indices);
    MEM_FREE(FREE,tmp_p_e);

    return(d_opt);
} /* vq_ms4 */

/*
    VQ_MSD2-
        Tree search multi-stage VQ decoder

    Synopsis: vq_msd(cb,u,u_est,a,indices,levels,stages,p,conversion)
        Input:
            cb- one dimensional linear codebook array (codebook is structured 
                as [stages][levels for each stage][p])
            indices- the codebook indices (for each stage) indices[0..stages-1]
            levels- the number of levels (for each stage) levels[0..stages-1]
            u_est- dimension p, the estimated parameters or mean (if NULL, assume
               estimate is the all zero vector) (u_est[0..p-1])
            stages- the number of stages of msvq
            p- the predictor order
            conversion- the conversion constant (see lpc.h, lpc_conv.c)
	    diff_Q- the difference between Q value of codebook and u_est
        Output:
            u- dimension p, the decoded parameters (if NULL, use alternate
               temporary storage) (u[0..p-1])
            a- predictor parameters (a[0..p]), if NULL, don't compute
        Returns:
            pointer to reconstruction vector (u)
        Parameters:

*/

Shortword *vq_msd2(Shortword *cb, Shortword *u, Shortword *u_est, 
		   Shortword *a, Shortword *indices, Shortword *levels, 
		   Shortword stages, Shortword p, Shortword conversion,
		   Shortword diff_Q)
{
    Shortword *u_hat,*cb_currentstage,*cb_table;
    Shortword i,j;
    Longword *L_u_hat,L_temp;

    /* allocate memory (if required) */

    MEM_ALLOC(MALLOC,L_u_hat,p,Longword);

    if (u==(Shortword*)NULL)
    {
        MEM_ALLOC(MALLOC,u_hat,p,Shortword);
    }
    else
        u_hat = u;

    /* add estimate on (if non-null), or clear vector */
    if (u_est)
    {
        (void)v_equ(u_hat,u_est,p);
    }
    else
    {
        (void)v_zap(u_hat,p);
    }

    /* put u_hat to a long buffer */
    for (i = 0; i < p; i++)
      L_u_hat[i] = L_shl(L_deposit_l(u_hat[i]),diff_Q);

    /* add the contribution of each stage */
    cb_currentstage = cb;
    for(i=0; i < stages; i++)
    {
      /* (void)v_add(u_hat,&cb_currentstage[indices[i]*p],p); */
      cb_table = &cb_currentstage[indices[i]*p];	  
      for (j = 0; j < p; j++) {
	L_temp = L_deposit_l(cb_table[j]);
        L_u_hat[j] = L_add(L_u_hat[j],L_temp);
      }
      cb_currentstage += levels[i]*p;
    }

    /* convert long buffer back to u_hat */
    for (i = 0; i < p; i++)
      u_hat[i] = extract_l(L_shr(L_u_hat[i],diff_Q));

    MEM_FREE(FREE,L_u_hat);

    return(u);
}


/* VQ_ENC -
   encode vector with full VQ using unweighted Euclidean distance
    Synopsis: vq_enc(cb, u, levels, p, u_hat, indices)
        Input:
            cb- one dimensional linear codebook array
            u- dimension p, the parameters to be encoded (u[0..p-1])
            levels- the number of levels
            p- the predictor order
        Output:
            u_hat-   the reconstruction vector (if non null)
            a_indices- the codebook indices (for each stage) a_indices[0..stages-1]
        Parameters:
*/
/* Q values:
   cb - Q13
   u - Q13
   u_hat - Q13 */

Longword vq_enc(Shortword *cb,Shortword *u,Shortword levels,Shortword p, 
		Shortword *u_hat,Shortword *indices)
{
    Shortword i,j,index;
    Longword d,dmin;
    Shortword *p_cb;
    Shortword temp;
    
    /* Search codebook for minimum distance */
    index = 0;    data_move();
    dmin = LW_MAX;    L_data_move();
    p_cb = cb;
    for (i = 0; i < levels; i++) {
        d = 0;    data_move();
        for (j = 0; j < p; j++) {
	  temp = sub(u[j],*p_cb);
          d = L_mac(d,temp,temp);
          p_cb++;  
        }
	compare_nonzero();
        if (d < dmin) {
            dmin = d;    data_move();
            index = i;    data_move();
        }
    }

    /* Update index and quantized value, and return minimum distance */
    *indices = index;
    v_equ(u_hat,&cb[p*index],p);

    return(dmin);
} /* vq_enc */


/* VQ_FSW - 
   compute the weights for Euclidean distance of Fourier harmonics  */
/* Q values:
   w_fs - Q14
   pitch - Q9 */

void vq_fsw(Shortword *w_fs, Shortword num_harm, Shortword pitch)
{

    Shortword j;
    Shortword tempw0;
    Shortword temp,denom;
    Longword L_temp;

    /* Calculate fundamental frequency */
    /* w0 = TWOPI/pitch */
    /* tempw0 = w0/(0.25*PI) = 8/pitch */
    tempw0 = divide_s((Shortword)EIGHT_Q11,pitch);   /* tempw0 in Q17 */
    for(j=0; j < num_harm; j++) {

      /* Bark-scale weighting */
      /* w_fs[j] = 117.0 / (25.0 + 75.0*
	           pow(1.0 + 1.4*SQR(w0*(j+1)/(0.25*PI)),0.69)) */

      temp = shl(add(j,1),11);    /* Q11 */
      temp = extract_h(L_shl(L_mult(tempw0,temp),1));    /* Q14 */
      temp = mult(temp,temp);    /* Q13 */
      /* L_temp in Q28 */
      L_temp = L_add((Longword)ONE_Q28,L_mult((Shortword)X14_Q14,temp));
      temp = L_pow_fxp(L_temp,(Shortword)X069_Q15,28,13);     /* Q13 */
      denom = add((Shortword)X25_Q6,mult((Shortword)X75_Q8,temp));    /* Q6 */
      w_fs[j] = divide_s((Shortword)X117_Q5,denom);   /* Q14 */   data_move();
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -