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

📄 lpc_lib.c

📁 MELPe 1200 bps, fixed point
💻 C
📖 第 1 页 / 共 3 页
字号:
/*		Currently only supports 10 loops, which is too                        */
/*		complex and perhaps unneccesary.                                      */
/*                                                                            */
/*	Systems and Info. Science Lab                                             */
/*	Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.       */
/*                                                                            */
/*	Q values: lsp - Q15, delta - Q15                                          */

Shortword lpc_clmp(Shortword lsp[], Shortword delta, Shortword order)
{
	register Shortword	i, j;
	BOOLEAN		unsorted;
	Shortword	temp, d, step1, step2;


	/* sort the LSPs for 10 loops */
	for (j = 0, unsorted = TRUE; unsorted && (j < MAX_LOOPS); j++){
		for (i = 0, unsorted = FALSE; i < order - 1; i++)
			if (lsp[i] > lsp[i + 1]){
				temp = lsp[i + 1];
				lsp[i + 1] = lsp[i];
				lsp[i] = temp;
				unsorted = TRUE;
			}
	}

	/* ensure minimum separation */
	if (!unsorted){
		for (j = 0; j < MAX_LOOPS; j++){
			for (i = 0; i < order - 1; i++){
				d = sub(lsp[i + 1], lsp[i]);
				if (d < delta){
					step1 = step2 = shr(sub(delta, d), 1);

/* --> */			if (i == 0 && (lsp[i] < delta)){
						step1 = shr(lsp[i], 1);
					} else {
/* --> */				if (i > 0){
							temp = sub(lsp[i], lsp[i-1]);
							if (temp < delta){
								step1 = 0;
							} else {
								if (temp < shl(delta, 1))
									step1 = shr(sub(temp, delta), 1);
							}
						}
					}

/* --> */			if (i == (order - 2) && (lsp[i + 1] > sub(ONE_Q15, delta))){
						step2 = shr(sub(ONE_Q15, lsp[i + 1]), 1);
					} else {
/* --> */				if (i < (order - 2)){
							temp = sub(lsp[i + 2], lsp[i + 1]);
							if (temp < delta){
								step2 = 0;
							} else {
								if (temp < shl(delta, 1))
									step2 = shr(sub(temp, delta), 1);
							}
						}
					}
					lsp[i] = sub(lsp[i], step1);
					lsp[i + 1] = add(lsp[i + 1], step2);
				}
			}
		}
	}

	/* Debug: check if the minimum separation rule was met */
	temp = mult(32440, delta);                           /* temp = 0.99*delta */
	for (i = 0; i < order - 1; i++)
		if ((lsp[i + 1] - lsp[i]) < temp)
			fprintf(stderr, "%s: LSPs not separated enough (line %d)\n",
					__FILE__, __LINE__);

	if (unsorted)
		fprintf(stderr, "%s: Fxp LSPs still unsorted (line %d)\n",
				__FILE__, __LINE__);

	return(0);
}


/* 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:                                                                   */
/*		autocorr- autocorrelation vector (autocorr[0..p]).                    */
/*		order- order of lpc filter.                                           */
/*	Outputs:                                                                  */
/*		lpc-   predictor parameters    (can be NULL)                          */
/*	Returns:                                                                  */
/*		alphap- the minimum residual energy                                   */
/*	Includes:                                                                 */
/*		lpc.h                                                                 */
/*	See_Also:                                                                 */
/*		lpc_refl2pred(3l) in lpc.h or lpc(3l)                                 */
/*                                                                            */
/*	Q values:                                                                 */
/*	autocorr - Q0, lpc - Q12,                                                 */

/* Previously the output reflection coefficients refc[] is now changed to     */
/* local dynamic arrays because the calling environment does not need it nor  */
/* use it.                                                                    */

Shortword lpc_schr(Shortword autocorr[], Shortword lpc[], Shortword order)
{
	register Shortword	i, j;
	Shortword	shift, alphap;
	Shortword	*refc;                                                 /* Q15 */
	Longword	L_temp, *y1, *y2;
	Shortword	temp1, temp2;


	y1 = L_v_get(order);
	y2 = L_v_get((Shortword) (order + 1));
	refc = v_get(order);

	temp2 = abs_s(autocorr[1]);
	temp1 = abs_s(autocorr[0]);

	refc[0] = divide_s(temp2, temp1);

	/* if (((autocorr[1] < 0) && (autocorr[0] < 0)) ||
		   ((autocorr[1] > 0) && (autocorr[0] > 0))) */
	if ((autocorr[1] ^ autocorr[0]) >= 0){
		refc[0] = negate(refc[0]);
	}
	alphap = mult(autocorr[0], sub(ONE_Q15, mult(refc[0], refc[0])));

	y2[0] = L_deposit_h(autocorr[1]);
	y2[1] = L_add(L_deposit_h(autocorr[0]), L_mult(refc[0], autocorr[1]));

	for (i = 1; i < order; i++){
		y1[0] = L_deposit_h(autocorr[i + 1]);
		L_temp = L_deposit_h(autocorr[i + 1]);

		for (j = 0; j < i; j++){
			y1[j + 1] = L_add(y2[j], L_mpy_ls(L_temp, refc[j]));
			L_temp = L_add(L_temp, L_mpy_ls(y2[j], refc[j]));
		}

		/*	refc[i] = -temp/y2[i]; */
		/* Under normal conditions the condition for the following IF         */
		/* statement should never be true.                                    */

		if (L_temp > y2[i]){
			v_zap(&(refc[i]), (Shortword) (order - i));
			break;
		}

		shift = norm_l(y2[i]);
		temp1 = abs_s(extract_h(L_shl(L_temp, shift)));
		temp2 = abs_s(extract_h(L_shl(y2[i], shift)));

		refc[i] = divide_s(temp1, temp2);

		if ((L_temp ^ y2[i]) >= 0){
			refc[i] = negate(refc[i]);
		}

		y2[i + 1] = L_add(y2[i], L_mpy_ls(L_temp, refc[i]));
		L_v_equ(y2, y1, (Shortword) (i + 1));
	}

	lpc_refl2pred(refc, lpc, order);

	alphap = autocorr[0];
	for (i = 0; i < order; i++){
		alphap = mult(alphap, sub(ONE_Q15, mult(refc[i], refc[i])));
	}

	v_free(refc);
	v_free(y2);
	v_free(y1);

	return(alphap);                                           /* alhap in Q15 */
}


/* LPC_REFL2PRED                                                              */
/*	  get predictor coefficients from the reflection coeffs                   */
/* Synopsis: lpc_refl2pred(refc, lpc, order)                                  */
/*                                                                            */
/*	  Input:                                                                  */
/*		 refc- the reflection coeffs                                          */
/*		 order- the predictor order                                           */
/*	  Output:                                                                 */
/*		 lpc- the predictor coefficients                                      */
/* Reference:  Markel and Gray, Linear Prediction of Speech                   */
/*                                                                            */
/* Q values:                                                                  */
/* refc - Q15, lpc - Q12                                                      */

static Shortword	lpc_refl2pred(Shortword refc[], Shortword lpc[],
								  Shortword order)
{
	register Shortword	i, j;
	Shortword	*a1;


	a1 = v_get((Shortword) (order - 1));

	for (i = 0; i < order; i++){
		/* refl to a recursion */
		lpc[i] = shift_r(refc[i], -3);                          /* lpc in Q12 */
		v_equ(a1, lpc, i);
		for (j = 0; j < i; j++){
			lpc[j] = add(a1[j], mult(refc[i], a1[i - j - 1]));
		}
	}

	v_free(a1);
	return(0);
}


/* LPC_PRED2LSP                                                               */
/*	  get LSP coeffs from the predictor coeffs                                */
/*	  Input:                                                                  */
/*		 lpc- the predictor coefficients                                      */
/*		 order- the predictor order                                           */
/*	  Output:                                                                 */
/*		 lsf- 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:                                                                  */
/* lpc - Q12, lsf - Q15                                                       */

Shortword lpc_pred2lsp(Shortword lpc[], Shortword lsf[], Shortword order)
{
	register Shortword	i;
	Shortword	p_cof[LPC_ORD/2 + 1], q_cof[LPC_ORD/2 + 1],
				p_freq[LPC_ORD/2 + 1], q_freq[LPC_ORD/2 + 1];
	Longword	L_p_cof[LPC_ORD/2 + 1], L_q_cof[LPC_ORD/2 + 1];
	Longword	L_ai, L_api, L_temp;
	Shortword	p2;


	p2 = shr(order, 1);

	/* Generate P' and Q' polynomials.  We only compute for indices from 0 to */
	/* p2 = order/2 because lsp_to_freq() only uses p_cof[] and q_cof[] for   */
	/* for these indices, and hence L_p_cof[] and L_q_cof[] are needed only   */
	/* from 0 to order/2.                                                     */

	L_p_cof[0] = (Longword) ONE_Q26;
	L_q_cof[0] = (Longword) ONE_Q26;
	for (i = 1; i <= p2; i++){
		/*	temp = sub(lpc[i - 1], lpc[order - i]); */         /* temp in Q12 */
		L_ai = L_shr(L_deposit_h(lpc[i - 1]), 2);
		L_api = L_shr(L_deposit_h(lpc[order - i]), 2);
		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 */
		/*	temp = add(lpc[i - 1], lpc[order - 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 */
	}

	/* Convert p_cof and q_cof to short.  We only compute for indices from 0  */
	/* to p2 = order/2 because lsp_to_freq() only uses p_cof[] and q_cof[]    */
	/* for these indices.                                                     */

	for (i = 0; i <= p2; i++){
		p_cof[i] = round(L_p_cof[i]);                         /* p_cof in Q10 */
		q_cof[i] = round(L_q_cof[i]);                         /* q_cof in Q10 */
	}

	/* Find root frequencies of LSP polynomials */
	lsp_to_freq(p_cof, p_freq, order);
	lsp_to_freq(q_cof, q_freq, order);

	/* Combine frequencies into single array */

	for (i = 0; i < p2; i++){
		lsf[2*i] = q_freq[i];
		lsf[2*i + 1] = p_freq[i];
	}

	return(0);
}


/* Subroutine LSP_TO_FREQ: Calculate line spectrum pair	root frequencies from */
/* LSP polynomial.  Only lsp[0], ...... lsp[order/2] are used and the other   */
/* lsp[]'s are ignored.  Similarly, only freq[0], ...... freq[order/2] are    */
/* computed.                                                                  */
/*                                                                            */
/* Q values:                                                                  */
/* lsp - Q10, freq - Q15                                                      */

static void		lsp_to_freq(Shortword lsp[], Shortword freq[], Shortword order)

{
	register Shortword	i, j;
	static BOOLEAN	firstTime = TRUE;
	static Shortword	lsp_cos[DFTLENGTH];                   /* cosine table */
	static Shortword	default_w, default_w0;
	Shortword	p2, count;
    BOOLEAN		prev_less;
    Longword	mag[3];
    Shortword	s_mag[3];

⌨️ 快捷键说明

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