📄 qnt12.c
字号:
/* "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 + -