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

📄 qnt12.c

📁 MELPe 1200 bps, fixed point
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* x[]'s, it will be okay to simply treat both x[] and target[] as Q15.   */
	/* This will make the returned value incorrect in scaling, but it will    */
	/* not affect the relative magnitudes.  Returning a Shortword in Q11      */
	/* seems to be fine according to some rough statistics collected.         */

	distortion = 0;
	half_n = shr(n, 1);
	for (i = 0; i < half_n; i++){
		save_saturation();
		temp = sub(x[i], target[i]);                                   /* Q15 */
		temp = mult(temp, temp);                                       /* Q15 */
		restore_saturation();
		distortion = L_mac(distortion, weight[i], temp);               /* Q27 */
	}

	if (round(distortion) >= max_dMin)      /* if this situation takes place, */
		return(SW_MAX);                    /* distortion will exceed max_dMin */
                                                         /* and we can leave. */

	for (i = half_n; i < n; i++){
		save_saturation();
		temp = sub(x[i], target[i]);                                   /* Q15 */
		temp = mult(temp, temp);                                       /* Q15 */
		restore_saturation();
		distortion = L_mac(distortion, weight[i], temp);               /* Q27 */
	}

	temp = round(distortion);
	return(temp);
}


/********************************************************************
**
** Function: InsertCand ()
**
** Description:
**
**	Inserts the indeces corresponding to a candidate into the
**	candidate index list, which is sorted in order of increasing
**	distortion.
**
** Arguments:
**
**	Shortword c1		: index of candidate to insert into list
**	Shortword s1		: index of current stage we are searching
**	Shortword dMin[]	: list of distortions of best nc candidates (Q11)
**	Shortword distortion[]	: distortion of candidate c when used with
**							  "entry" from current stage (Q11)
**	Shortword entry		: current stage entry which results in lower
**						  distortion
**	Shortword	**index	: list of past indices for each candidate
**	Shortword	**nextIndex : indices for next stage (output)
**
** Return value:	Shortword
**
***********************************************************************/
static Shortword	InsertCand(Shortword c1, Shortword s1, Shortword dMin[], 
							Shortword distortion, Shortword entry, 
							Shortword nextIndex[], Shortword index[])
{
	register Shortword	i, j;
	Shortword	ptr_offset;
	Shortword	temp1, temp2;
	Shortword	*ptr1, *ptr2;
	Longword	L_temp;


	/*==================================================================*
	*	First find the index into the distortion array where this		*
	*	candidate fits. Note that we assume it has been previously		*
	*	verified that this error falls in the range of the candidate	*
	*	errors. 														*
	*==================================================================*/
	for (i = 0; (i < LSP_VQ_CAND) && (distortion > dMin[i]); i++);

	/* shift the distortions and indices down to make room for the new one */
	/*	ptr_offset = (LSP_VQ_CAND - 1) * vq_stages; */

	
	L_temp = L_mult((LSP_VQ_CAND - 1) , LSP_VQ_STAGES);
	L_temp = L_shr(L_temp, 1);
	ptr_offset = extract_l(L_temp);
	temp2 = add(s1, 1);
	for (j = (LSP_VQ_CAND - 1); j > i; j--){
		dMin[j] = dMin[j - 1];
		temp1 = sub(ptr_offset, LSP_VQ_STAGES);
		ptr1 = nextIndex + ptr_offset;                /* Pointer arithmetics. */
		ptr2 = nextIndex + temp1;
		/*	v_equ(nextIndex + j * vq_stages, nextIndex + (j - 1)*vq_stages,
				  s1 + 1); */
		v_equ(ptr1, ptr2, temp2);
		ptr_offset = temp1;
	}

	/* insert the index and distortion into the ith candidate */
	dMin[i] = distortion;
	/*	v_equ(nextIndex + i * vq_stages, index + c1 * vq_stages, s1); */
	L_temp = L_mult(i, LSP_VQ_STAGES);                  /* temp1 = i * vq_stages; */
	L_temp = L_shr(L_temp, 1);
	temp1 = extract_l(L_temp);
	L_temp = L_mult(c1, LSP_VQ_STAGES);
	L_temp = L_shr(L_temp, 1);
	temp2 = extract_l(L_temp);
	ptr1 = nextIndex + temp1;                         /* Pointer arithmetics. */
	ptr2 = index + temp2;
	v_equ(ptr1, ptr2, s1);
	/*	*(nextIndex + i*vq_stages + s1) = entry; */
	ptr1 += s1;                                       /* Pointer arithmetics. */
	*ptr1 = entry;

	return (dMin[LSP_VQ_CAND - 1]);
}


/*********************************************************************
** NAME: lspStable
**
** DESCRIPTION:
**	This routines checks the stability of a set of LSP parameters
**	by ensuring that all parameters are in the correct order. For
**	LSPs, the LSP frequencies must be monotonically increasing.
**
** INPUTS:
**	Shortword lsp[]	: the LSP coefficients lsp[0..order - 1] (Q15)
**	Shortword order	: order of the LSP coeffs
**
** OUTPUTS: BOOLEAN : TRUE == stable;	FALSE == unstable
**
**********************************************************************/
BOOLEAN lspStable(Shortword lsp[], Shortword order)
{
	register Shortword	i;
	BOOLEAN		stable;
	Shortword	temp;


	/* The following loop attempts to ensure lsp[0] is at least 6.37,         */
	/* lsp[order - 1] is at most 3992.0, and each consecutive pair of lsp[]   */
	/* is separated by at least 25.0.  The sampling frequency is assumed to   */
	/* be 8000.0.                                                             */

	if (lsp[0] < 52)                       /* 52 == (6.37/4000.0 * (1 << 15)) */
		lsp[0] = (Shortword) 52;
	for (i = 0; i < order - 1; i++){
		temp = add(lsp[i], 205);
		if (lsp[i + 1] < temp)
			lsp[i + 1] = temp;
	}
                                          /* 205 == (25.0/4000.0 * (1 << 15)) */
	if (lsp[order - 1] > 32702)
		lsp[order - 1] = (Shortword) 32702;
                                      /* 32702 == (3992.0/4000.0 * (1 << 15)) */

	/* Previously here we use a loop checking whether (lsp[i] < lsp[i - 1])   */
	/* for any of the pairs from i = 1 to i < order.  It is not needed.  The  */
	/* for loop above essentially guarantees the monotonic ascending of       */
	/* lsp[]'s (with a guaranteed gap of 25.0 (Hz)).  The only possible       */
	/* violation is between lsp[order - 2] and lsp[order - 1] because of the  */
	/* modification of lsp[order - 1] after the loop.  So now we only check   */
	/* this pair.                                                             */

	if (lsp[order - 1] < lsp[order - 2])
		stable = FALSE;
	else
		stable = TRUE;

	if (!stable)      /* Warning message moved from lspSort() to lspStable(). */
		fprintf(stderr, "Unstable filter found in lspStable()...\n");

	return(stable);
}


/*********************************************************************
**
** Name:  lspSort()
**
** Description:
**
**	Uses the very slow Straight Insertion technique...so only
**	use for, say, n < 50.  This routine is taken from the
**	Numerical Recipes in C book.
**
** Arguments:
**
**	Shortword lsp[]	: array to be sorted  arr[1..n] (input/output) (Q15)
**	Shortword n		: number of samples to sort
**
** Return value:	None
**
***********************************************************************/
void lspSort(Shortword lsp[], Shortword order)
{
	register Shortword	i, j;
	Shortword	temp;                                                  /* Q15 */


	for (j = 1; j < order; j++){
		temp = lsp[j];
		i = (Shortword) (j - 1);
		while (i >= 0 && lsp[i] > temp){
			lsp[i + 1] = lsp[i];
			i--;
		}
		lsp[i + 1] = temp;
	}
}


/****************************************************************************
**
** Function:		lsf_vq
**
** Description: 	lsfs of three frames are vector quantized
**
** Arguments:
**
**	melp_param *par ---- input/output melp parameters
**
** Return value:	None
**
*****************************************************************************/

void lsf_vq(struct melp_param *par)
{
	register Shortword	i, j, k;
	static BOOLEAN	firstTime = TRUE;
	static Shortword	qplsp[LPC_ORD];                                /* Q15 */
	const Shortword		melp_cb_size[4] = {256, 64, 32, 32}; /* !!! (12/15/99) */
	const Shortword		res_cb_size[4] = {256, 64, 64, 64};
	const Shortword		melp_uv_cb_size[1] = {512};
	Shortword	uv_config;     /* Bits of uv_config replace uv1, uv2 and cuv. */
	Shortword	*lsp[NF];
	Longword	err, minErr, acc, bcc; /* !!! (12/15/99), Q11 */
	Shortword	temp1, temp2;
	Shortword	lpc[LPC_ORD];                                          /* Q12 */
	Shortword	wgt[NF][LPC_ORD];                                      /* Q11 */
	Shortword	mwgt[2*LPC_ORD];                                       /* Q11 */
	Shortword	bestlsp0[LPC_ORD], bestlsp1[LPC_ORD];                  /* Q15 */
	Shortword	res[2*LPC_ORD];                                        /* Q17 */

	/* The original program declares lsp_cand[LSP_VQ_CAND][] and              */
	/* lsp_index_cand[LSP_VQ_CAND*LSP_VQ_STAGES] with LSP_VQ_CAND == 8.  The  */
	/* program only uses up to LSP_INP_CAND == 5 and the declaration is       */
	/* modified.                                                              */

	Shortword	lsp_cand[LSP_INP_CAND][LPC_ORD];                       /* Q15 */
	Shortword	lsp_index_cand[LSP_INP_CAND*LSP_VQ_STAGES];
	Shortword	ilsp0[LPC_ORD], ilsp1[LPC_ORD];                        /* Q15 */
	Shortword	cand, inp_index_cand, tos, intfact;


	if (firstTime){
		temp2 = shl(LPC_ORD, 10);                                      /* Q10 */
		temp1 = X08_Q10;                                               /* Q10 */
		for (i = 0; i < LPC_ORD; i++){
			/*	qplsp[i] = (i+1)*0.8/LPC_ORD; */
			qplsp[i] = divide_s(temp1, temp2);
			temp1 = add(temp1, X08_Q10);
		}
		firstTime = FALSE;
	}

	/* ==== Compute weights ==== */
	for (i = 0; i < NF; i++){
		lsp[i] = par[i].lsf;
		lpc_lsp2pred(lsp[i], lpc, LPC_ORD);
		vq_lspw(wgt[i], lsp[i], lpc, LPC_ORD);
	}

	uv_config = 0;
	for (i = 0; i < NF; i++){
		uv_config = shl(uv_config, 1);
		if (par[i].uv_flag){
			uv_config |= 0x0001;

			/* ==== Adjust weights ==== */
			if (i == 0)                    /* Testing for par[0].uv_flag == 1 */
				v_scale(wgt[0], X02_Q15, LPC_ORD);
			else if (i == 1)
				v_scale(wgt[1], X02_Q15, LPC_ORD);
		}
	}

	/* ==== Quantize the lsp according to the UV decisions ==== */
	switch (uv_config){
	case 7:                            /* 111, all frames are NOT voiced ---- */
		lspVQ(lsp[0], wgt[0], lsp[0], lsp_uv_9, 1, melp_uv_cb_size,
			  quant_par.lsf_index[0], LPC_ORD, FALSE);
		lspVQ(lsp[1], wgt[1], lsp[1], lsp_uv_9, 1, melp_uv_cb_size,
			  quant_par.lsf_index[1], LPC_ORD, FALSE);
		lspVQ(lsp[2], wgt[2], lsp[2], lsp_uv_9, 1, melp_uv_cb_size,
			  quant_par.lsf_index[2], LPC_ORD, FALSE);
		break;
	case 6:                                                            /* 110 */
		lspVQ(lsp[0], wgt[0], lsp[0], lsp_uv_9, 1, melp_uv_cb_size,
			  quant_par.lsf_index[0], LPC_ORD, FALSE);
		lspVQ(lsp[1], wgt[1], lsp[1], lsp_uv_9, 1, melp_uv_cb_size,
			  quant_par.lsf_index[1], LPC_ORD, FALSE);
		lspVQ(lsp[2], wgt[2], lsp[2], lsp_v_256x64x32x32, 4, melp_cb_size,	/* !!! (12/15/99) */
			  quant_par.lsf_index[2], LPC_ORD, FALSE);
		break;
	case 5:                                                            /* 101 */
		lspVQ(lsp[0], wgt[0], lsp[0], lsp_uv_9, 1, melp_uv_cb_size,
			  quant_par.lsf_index[0], LPC_ORD, FALSE);
		lspVQ(lsp[1], wgt[1], lsp[1], lsp_v_256x64x32x32, 4, melp_cb_size,  /* !!! (12/15/99) */
			  quant_par.lsf_index[1], LPC_ORD, FALSE);
		lspVQ(lsp[2], wgt[2], lsp[2], lsp_uv_9, 1, melp_uv_cb_size,
			  quant_par.lsf_index[2], LPC_ORD, FALSE);
		break;
	case 3:                                                            /* 011 */
		lspVQ(lsp[0], wgt[0], lsp[0], lsp_v_256x64x32x32, 4, melp_cb_size, /* !!! (12/15/99) */
			  quant_par.lsf_index[0], LPC_ORD, FALSE);
		lspVQ(lsp[1], wgt[1], lsp[1], lsp_uv_9, 1, melp_uv_cb_size,
			  quant_par.lsf_index[1], LPC_ORD, FALSE);
		lspVQ(lsp[2], wgt[2], lsp[2], lsp_uv_9, 1, melp_uv_cb_size,
			  quant_par.lsf_index[2], LPC_ORD, FALSE);
		break;
	default:
		if (uv_config == 1){           /* 001 case, if (!uv1 && !uv2 && uv3). */
			/* ---- Interpolation [4 inp + (8+6+6+6) res + 9 uv] ---- */
			tos = 1;
			lspVQ(lsp[2], wgt[2], lsp_cand[0], lsp_uv_9, tos, melp_uv_cb_size,
				  lsp_index_cand, LPC_ORD, TRUE);
		} else {
			tos = 4;
			lspVQ(lsp[2], wgt[2], lsp_cand[0], lsp_v_256x64x32x32, tos, /* !!! (12/15/99) */
			 	 melp_cb_size, lsp_index_cand, LPC_ORD, TRUE);
		}

		minErr = LW_MAX;
		cand = 0;
		inp_index_cand = 0;
		for (k = 0; k < LSP_INP_CAND; k++){
			for (i = 0; i < 16; i++){

				err = 0;

				/* Originally we have two for loops here.  One computes       */
				/* ilsp0[] and ilsp1[] and the other one computes "err".  If  */

⌨️ 快捷键说明

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