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

📄 qnt12.c

📁 MELPe 1200 bps, fixed point
💻 C
📖 第 1 页 / 共 4 页
字号:
				/* "err" already exceeds minErr, we can stop the loop and     */
				/* there is no need to compute the remaining ilsp0[] and      */
				/* ilsp1[] entries.  Hence the two for loops are joined.      */

				for (j = 0; j < LPC_ORD; j++){

					/*	ilsp0[j] = (inpCoef[i][j] * qplsp[j] +
							   (1.0 - inpCoef[i][j]) * lsp_cand[k][j]); */
					intfact = inpCoef[i][j];                           /* Q14 */
					acc = L_mult(intfact, qplsp[j]);                   /* Q30 */
					intfact = sub(ONE_Q14, intfact);                   /* Q14 */
					acc = L_mac(acc, intfact, lsp_cand[k][j]);         /* Q30 */
					ilsp0[j] = extract_h(L_shl(acc, 1));
					acc = L_sub(acc, L_shl(L_deposit_l(lsp[0][j]), 15));

					/*	ilsp1[j] = inpCoef[i][j + LPC_ORD] * qplsp[j] +
						   (1.0 - inpCoef[i][j + LPC_ORD]) * lsp_cand[k][j]; */
					intfact = inpCoef[i][j + LPC_ORD];                 /* Q14 */
					bcc = L_mult(intfact, qplsp[j]);
					intfact = sub(ONE_Q14, intfact);
					bcc = L_mac(bcc, intfact, lsp_cand[k][j]);         /* Q30 */
					ilsp1[j] = extract_h(L_shl(bcc, 1));
					bcc = L_sub(bcc, L_shl(L_deposit_l(lsp[1][j]), 15));

					/*	err += wgt0[j]*(lsp0[j] - ilsp0[j])*
									 (lsp0[j] - ilsp0[j]); */
					temp1 = norm_l(acc);
					temp2 = extract_h(L_shl(acc, temp1));
					if( temp2 == MONE_Q15 ) temp2 = -32767;
					temp2 = mult(temp2, temp2);
					acc = L_mult(temp2, wgt[0][j]);
					temp1 = shl(sub(1, temp1), 1);
					acc = L_shl(acc, sub(temp1, 3));                   /* Q24 */
					err = L_add(err, acc);

					/*	err += wgt1[j]*(lsp1[j] - ilsp1[j])*
									 (lsp1[j] - ilsp1[j]); */
					temp1 = norm_l(bcc);
					temp2 = extract_h(L_shl(bcc, temp1));
					if( temp2 == MONE_Q15 ) temp2 = -32767;
					temp2 = mult(temp2, temp2);
					bcc = L_mult(temp2, wgt[1][j]);
					temp1 = shl(sub(1, temp1), 1);
					bcc = L_shl(bcc, sub(temp1, 3));                   /* Q24 */
					err = L_add(err, bcc);
					
					/* computer the err for the last frame */
					acc = L_shl(L_deposit_l(lsp[2][j]), 15);
					acc = L_sub(acc, L_shl(L_deposit_l(lsp_cand[k][j]), 15));
					temp1 = norm_l(acc);
					temp2 = extract_h(L_shl(acc, temp1));
					if( temp2 == MONE_Q15 ) temp2 = -32767;
					temp2 = mult(temp2, temp2);
					acc = L_mult(temp2, wgt[2][j]);
					temp1 = shl(sub(1, temp1), 1);
					acc = L_shl(acc, sub(temp1, 3));                   /* Q24 */
					err = L_add(err, acc);
				}

				if (err < minErr){
					minErr = err;
					cand = k;
					inp_index_cand = i;
					v_equ(bestlsp0, ilsp0, LPC_ORD);
					v_equ(bestlsp1, ilsp1, LPC_ORD);
				}
			}
		}

		v_equ(lsp[2], lsp_cand[cand], LPC_ORD);
		v_equ(quant_par.lsf_index[0], &(lsp_index_cand[cand*tos]), tos);
		quant_par.lsf_index[1][0] = inp_index_cand;

		for (i = 0; i < LPC_ORD; i++){
			temp1 = sub(lsp[0][i], bestlsp0[i]);                       /* Q15 */
			temp2 = sub(lsp[1][i], bestlsp1[i]);                       /* Q15 */
			res[i] = shl(temp1, 2);                                    /* Q17 */
			res[i + LPC_ORD] = shl(temp2, 2);                          /* Q17 */
		}
		v_equ(mwgt, wgt[0], LPC_ORD);
		v_equ(mwgt + LPC_ORD, wgt[1], LPC_ORD);

		/* Note that in the following IF block, the lspVQ() is quantizing on  */
		/* res[] and res256x64x64x64[], and both of them are Q17 instead of   */
		/* Q15, unlike the other calling instances in this function.          */

		if (uv_config == 1)                       /* if (!uv1 && !uv2 && uv3) */
			lspVQ(res, mwgt, res, res256x64x64x64, 4, res_cb_size,
				  quant_par.lsf_index[2], 2*LPC_ORD, FALSE);
		else
			lspVQ(res, mwgt, res, res256x64x64x64, 2, res_cb_size,
				  quant_par.lsf_index[2], 2*LPC_ORD, FALSE);

		/* ---- reconstruct lsp for later stability check ---- */
		for (i = 0; i < LPC_ORD; i++){
			temp1 = shr(res[i], 2);
			lsp[0][i] = add(temp1, bestlsp0[i]);
			temp2 = shr(res[i + LPC_ORD], 2);
			lsp[1][i] = add(temp2, bestlsp1[i]);
		}
		break;
	}

	/* ---- Stability checking ---- */
	/* The sortings on lsp[0] and lsp[1] are not necessary because they are   */
	/* variables local to this function and they are discarded upon exit.     */
	/* We only check whether they fit the stability test and issue a warning. */

	(void) lspStable(lsp[0], LPC_ORD);
	(void) lspStable(lsp[1], LPC_ORD);
	if (! lspStable(lsp[2], LPC_ORD))
		lspSort(lsp[2], LPC_ORD);

	v_equ(qplsp, lsp[2], LPC_ORD);
}


/*********************************************************************
**
** Name:  deqnt_msvq()
**
** Description:
**
**	Dequantization using codebook indices with multi-stages
**
** Arguments:
**
**	Shortword	qout[]	---- (output) quantized data (Q15/Q17)
**	Shortword	codebook[] 	---- codebooks,	 cb[0..numStages-1] (Q15/Q17)
**	Shortword 	tos 	----	the number of stages
**	short	*index	----	codebook index
**
** Return value:	None
**
***********************************************************************/
void deqnt_msvq(Shortword qout[], const Shortword codebook[], Shortword tos,
				const Shortword cb_size[], Shortword index[], Shortword dim)
{
	register Shortword	i;
	const Shortword		*cdbk_ptr;
	Shortword	temp;
	Longword	L_temp;


	/* ====== Clear output ====== */
	v_zap(qout, dim);

	/* ====== Add each stage ====== */
	cdbk_ptr = codebook;
	for (i = 0; i < tos; i++){
		/*	v_add(qout, cdbk_ptr + index[i]*dim, dim); */
		L_temp = L_mult(index[i], dim);
		L_temp = L_shr(L_temp, 1);
		temp = extract_l(L_temp);
		v_add(qout, cdbk_ptr + temp, dim);
		/*	cdbk_ptr += cb_size[i] * dim; */
		L_temp = L_mult(cb_size[i], dim);
		L_temp = L_shr(L_temp, 1);
		temp = extract_l(L_temp);
		cdbk_ptr += temp;
	}
}


/****************************************************************************
**
** Function:		quant_jitter
**
** Description: 	Jitter of three frames are quantized
**
** Arguments:
**
**	melp_param *par ---- input/output melp parameters
**
** Return value:	None
**
*****************************************************************************/
void quant_jitter(struct melp_param *par)
{
	register Shortword	i;
	Shortword	uv_config;
	BOOLEAN		flag_jitter;
	Shortword	cnt_jitter;
	Shortword	jitter[NF];                                            /* Q15 */


	/* Previously we use a BOOLEAN array uv[] for par[].uv_flag.  Now we use  */
	/* a Shortword uv_config and use its bits for BOOLEAN values.             */

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

	flag_jitter = FALSE;

	switch (uv_config){
	case 6:                                          /* uv_config == 110, UUV */
		if (jitter[2] == MAX_JITTER_Q15)
			flag_jitter = TRUE;
		break;
	case 5:                                          /* uv_config == 101, UVU */
	case 4:                                          /* uv_config == 100, UVV */
	case 1:                                          /* uv_config == 001, VVU */
		if (jitter[1] == MAX_JITTER_Q15)
			flag_jitter = TRUE;
		break;
	case 3:                                          /* uv_config == 011, VUU */
		if (jitter[0] == MAX_JITTER_Q15)
			flag_jitter = TRUE;
		break;
	case 0:                                          /* uv_config == 000, VVV */
		cnt_jitter = 0;
		for (i = 0; i < NF; i++)
			if (jitter[i] == MAX_JITTER_Q15)
				cnt_jitter++;

		if (cnt_jitter >= 2)
			flag_jitter = TRUE;
		break;
	}

	/* Decoding jitter flag, note that this is not exactly the inverse        */
	/* operation of the encoding part.                                        */

	for (i = 0; i < NF; i++){
		if (par[i].uv_flag)
			jitter[i] = MAX_JITTER_Q15;
		else
			jitter[i] = 0;
	}

	if (flag_jitter && (uv_config == 0))             /* uv_config == 000, VVV */
		jitter[0] = jitter[1] = jitter[2] = MAX_JITTER_Q15;

	for (i = 0; i < NF; i++)
		par[i].jitter = jitter[i];

	quant_par.jit_index[0] = flag_jitter;
}


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

void quant_fsmag(struct melp_param *par)
{
	static BOOLEAN	prev_uv = TRUE;
	register Shortword	i;
	static Shortword	prev_fsmag[NUM_HARM];
	Shortword	qmag[NUM_HARM];                                        /* Q13 */
	Shortword	temp1, temp2;
	Shortword	p_value, q_value;
	Shortword	count, last;


	count = 0; last = -1;
	for (i = 0; i < NF; i++){
		if (par[i].uv_flag)
			fill(par[i].fs_mag, ONE_Q13, NUM_HARM);
		else {
			window_Q(par[i].fs_mag, w_fs, par[i].fs_mag, NUM_HARM, 14);
			last = i;
			count++;
		}
	}

	/*	fsvq_enc(par[last].fs_mag, qmag, fs_vq_par); */
	/* Later it is found that we do not need the structured variable          */
	/* fs_vq_par at all.  References to its individual fields can be replaced */
	/* directly with constants or other variables.                            */

	if (count > 0)
		vq_enc(fsvq_cb, par[last].fs_mag, FS_LEVELS, NUM_HARM, qmag,
			   &quant_par.fs_index);

	if (count > 1){
		if (prev_uv || par[0].uv_flag){ 
			for (i = 0; i <= last; i++){
				if (!par[i].uv_flag)
					v_equ(par[i].fs_mag, qmag, NUM_HARM);
			}
		} else {
			if (par[1].uv_flag){                                     /* V VUV */
				v_equ(par[0].fs_mag, prev_fsmag, NUM_HARM);
				v_equ(par[last].fs_mag, qmag, NUM_HARM);
			} else if (par[2].uv_flag){                              /* V VVU */
				v_equ(par[1].fs_mag, qmag, NUM_HARM);
				for (i = 0; i < NUM_HARM; i++){
					/*	par[0].fs_mag[i] = 0.5*(qmag[i] + prev_fsmag[i]); */
					temp1 = shr(qmag[i], 1);              /* 0.5*qmag[i], Q13 */
					temp2 = shr(prev_fsmag[i], 1);                     /* Q13 */
					par[0].fs_mag[i] = add(temp1, temp2);              /* Q13 */
				}
			} else {                                                 /* V VVV */
				v_equ(par[2].fs_mag, qmag, NUM_HARM);
				for (i = 0; i < NUM_HARM; i++){
					p_value = prev_fsmag[i];
					q_value = qmag[i];                                 /* Q13 */

					/* Note that (par[0].fs_mag[i] + par[1].fs_mag[i]) ==     */
					/* (p + q).  We might replace some multiplications with   */
					/* additions.                                             */

					/*	par[0].fs_mag[i] = (p + p + q)/3.0; */
					temp1 = mult(p_value, X0667_Q15);                  /* Q13 */
					temp2 = mult(q_value, X0333_Q15);                  /* Q13 */
					par[0].fs_mag[i] = add(temp1, temp2);
					/*	par[1].fs_mag[i] = (p + q + q)/3.0; */
					temp1 = mult(p_value, X0333_Q15);
					temp2 = mult(q_value, X0667_Q15);
					par[1].fs_mag[i] = add(temp1, temp2);
				}
			}
		}
	} else if (count == 1)
		v_equ(par[last].fs_mag, qmag, NUM_HARM);

	prev_uv = par[NF - 1].uv_flag;
	if (prev_uv)
		fill(prev_fsmag, ONE_Q13, NUM_HARM);
	else
		v_equ(prev_fsmag, par[NF - 1].fs_mag, NUM_HARM);
}

⌨️ 快捷键说明

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