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