📄 enc_lpc.c
字号:
* void
*/
void E_LPC_a_isp_conversion(Float32 *a, Float32 *isp, Float32 *old_isp,
Word32 m)
{
Float32 f1[(M >> 1) + 1], f2[M >> 1];
Float32 *pf;
Float32 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
Word32 j, i, nf, ip, order, nc;
nc = m >> 1;
/*
* find the sum and diff polynomials F1(z) and F2(z)
* F1(z) = [A(z) + z^m A(z^-1)]
* F2(z) = [A(z) - z^m A(z^-1)]/(1-z^-2)
*/
for (i=0; i < nc; i++)
{
f1[i] = a[i] + a[m - i];
f2[i] = a[i] - a[m - i];
}
f1[nc] = 2.0F * a[nc];
/* divide by (1 - z^-2) */
for (i = 2; i < nc; i++)
{
f2[i] += f2[i - 2];
}
/*
* Find the ISPs (roots of F1(z) and F2(z) ) using the
* Chebyshev polynomial evaluation.
* The roots of F1(z) and F2(z) are alternatively searched.
* We start by finding the first root of F1(z) then we switch
* to F2(z) then back to F1(z) and so on until all roots are found.
*
* - Evaluate Chebyshev pol. at E_ROM_grid polongs and check for sign change.
* - If sign change track the root by subdividing the Word32erval
* 4 times and ckecking sign change.
*/
nf=0; /* number of found frequencies */
ip=0; /* flag to first polynomial */
pf = f1; /* start with F1(z) */
order = nc;
xlow = E_ROM_grid[0];
ylow = E_LPC_chebyshev(xlow, pf, nc);
j = 0;
while ( (nf < m - 1) && (j < NO_POINTS) )
{
j++;
xhigh = xlow;
yhigh = ylow;
xlow = E_ROM_grid[j];
ylow = E_LPC_chebyshev(xlow, pf, order);
if (ylow * yhigh <= 0.0F) /* if sign change new root exists */
{
j--;
/* divide the Word32erval of sign change by NO_ITER */
for (i = 0; i < NO_ITER; i++)
{
xmid = 0.5F * (xlow + xhigh);
ymid = E_LPC_chebyshev(xmid, pf, order);
if (ylow * ymid <= 0.0F)
{
yhigh = ymid;
xhigh = xmid;
}
else
{
ylow = ymid;
xlow = xmid;
}
}
/* linear interpolation for evaluating the root */
xint = xlow - ylow * (xhigh - xlow) / (yhigh - ylow);
isp[nf] = xint; /* new root */
nf++;
ip = 1 - ip; /* flag to other polynomial */
pf = ip ? f2 : f1; /* pointer to other polynomial */
order = ip ? (nc - 1) : nc; /* order of other polynomial */
xlow = xint;
ylow = E_LPC_chebyshev(xlow, pf, order);
}
}
isp[m - 1] = a[m];
/*
* Check if m-1 roots found
* if not use the ISPs from previous frame
*/
if (nf < m - 1)
{
for(i = 0; i < m; i++)
{
isp[i] = old_isp[i];
}
}
return;
}
/*
* E_LPC_isp_isf_conversion
*
* Parameters:
* isp I: isp[m] (range: -1 <= val < 1) (Q15)
* isf O: isf[m] normalized (range: 0 <= val <= 6400)
* m I: LPC order
*
* Function:
* Transformation isp to isf
*
* ISP are immitance spectral pair in cosine domain (-1 to 1).
* ISF are immitance spectral pair in frequency domain (0 to 6400).
* Returns:
* energy of prediction error
*/
void E_LPC_isp_isf_conversion(Float32 isp[], Float32 isf[], Word32 m)
{
Word32 i;
/* convert ISPs to frequency domain 0..6400 */
for(i = 0; i < (m - 1); i++)
{
isf[i] = (Float32)(acos(isp[i]) * SCALE1);
}
isf[m - 1] = (Float32)(acos(isp[m - 1]) * SCALE1 * 0.5F);
return;
}
/*
* E_LPC_stage1_isf_vq
*
* Parameters:
* x I: ISF residual vector
* dico I: quantisation codebook
* dim I: dimension of vector
* dico_size I: size of quantization codebook
* index O: indices of survivors
* surv I: number of survivor
*
* Function:
* 1st stage VQ with split-by-2.
*
* Returns:
* void
*/
static void E_LPC_stage1_isf_vq(Float32 *x, const Float32 *E_ROM_dico,
Word32 dim, Word32 E_ROM_dico_size,
Word32 *index, Word32 surv)
{
Float32 dist_min[N_SURV_MAX];
Float32 dist, temp1, temp2;
const Float32 *p_E_ROM_dico;
Word32 i, j, k, l;
for (i = 0; i < surv; i++)
{
dist_min[i] = 1.0e30F;
}
for (i = 0; i < surv; i++)
{
index[i] = i;
}
p_E_ROM_dico = E_ROM_dico;
for (i = 0; i < E_ROM_dico_size; i++)
{
dist = x[0] - *p_E_ROM_dico++;
dist *= dist;
for (j = 1; j < dim; j += 2)
{
temp1 = x[j] - *p_E_ROM_dico++;
temp2 = x[j + 1] - *p_E_ROM_dico++;
dist += temp1 * temp1 + temp2 * temp2;
}
for (k = 0; k < surv; k++)
{
if (dist < dist_min[k])
{
for (l = surv - 1; l > k; l--)
{
dist_min[l] = dist_min[l - 1];
index[l] = index[l - 1];
}
dist_min[k] = dist;
index[k] = i;
break;
}
}
}
return;
}
/*
* E_LPC_isf_2s3s_quantise
*
* Parameters:
* isf1 I: ISF in the frequency domain (0..6400)
* isf_q O: quantized ISF
* past_isfq I/O: past ISF quantizer
* indice O: quantisation indices (5 words)
* nb_surv I: number of survivor (1, 2, 3 or 4)
*
* Function:
* Quantization of isf parameters with prediction. (36 bits)
*
* The isf vector is quantized using two-stage VQ with split-by-2 in
* 1st stage and split-by-3 in the second stage.
* Returns:
* void
*/
void E_LPC_isf_2s3s_quantise(Float32 *isf1, Word16 *isf_q, Word16 *past_isfq,
Word32 *indice, Word32 nb_surv)
{
Float32 isf[ORDER], isf_stage2[ORDER];
Float32 temp, min_err, distance;
Word32 surv1[N_SURV_MAX]; /* indices of survivors from 1st stage */
Word32 tmp_ind[5];
Word32 i, k;
for (i = 0; i < ORDER; i++)
{
isf[i] = (Float32)((isf1[i] - E_ROM_f_mean_isf[i]) -
F_MU * past_isfq[i] * 0.390625F);
}
E_LPC_stage1_isf_vq(&isf[0], E_ROM_dico1_isf, 9, SIZE_BK1, surv1, nb_surv);
distance = 1.0e30F;
for (k = 0; k < nb_surv; k++)
{
for (i = 0; i < 9; i++)
{
isf_stage2[i] = isf[i] - E_ROM_dico1_isf[i + surv1[k] * 9];
}
tmp_ind[0] = E_LPC_isf_sub_vq(&isf_stage2[0], E_ROM_dico21_isf_36b, 5,
SIZE_BK21_36b, &min_err);
temp = min_err;
tmp_ind[1] = E_LPC_isf_sub_vq(&isf_stage2[5], E_ROM_dico22_isf_36b, 4,
SIZE_BK22_36b, &min_err);
temp += min_err;
if (temp < distance)
{
distance = temp;
indice[0] = surv1[k];
for (i = 0; i < 2; i++)
{
indice[i + 2] = tmp_ind[i];
}
}
}
E_LPC_stage1_isf_vq(&isf[9], E_ROM_dico2_isf, 7, SIZE_BK2, surv1, nb_surv);
distance = 1.0e30F;
for (k = 0; k < nb_surv; k++)
{
for (i = 0; i < 7; i++)
{
isf_stage2[i] = isf[9 + i] - E_ROM_dico2_isf[i + surv1[k] * 7];
}
tmp_ind[0] = E_LPC_isf_sub_vq(&isf_stage2[0], E_ROM_dico23_isf_36b, 7,
SIZE_BK23_36b, &min_err);
temp = min_err;
if (temp < distance)
{
distance = temp;
indice[1] = surv1[k];
indice[4]= tmp_ind[0];
}
}
/* decoding the ISF */
E_LPC_isf_2s3s_decode(indice, isf_q, past_isfq);
return;
}
/*
* E_LPC_isf_2s5s_quantise
*
* Parameters:
* isf1 I: ISF in the frequency domain (0..6400)
* isf_q O: quantized ISF
* past_isfq I/O: past ISF quantizer
* indice O: quantisation indices (5 words)
* nb_surv I: number of survivor (1, 2, 3 or 4)
*
* Function:
* Quantization of isf parameters with prediction. (46 bits)
*
* The isf vector is quantized using two-stage VQ with split-by-2 in
* 1st stage and split-by-5 in the second stage.
* Returns:
* void
*/
void E_LPC_isf_2s5s_quantise(Float32 *isf1, Word16 *isf_q, Word16 *past_isfq,
Word32 *indice, Word32 nb_surv)
{
Float32 isf[ORDER], isf_stage2[ORDER];
Float32 temp, min_err, distance;
Word32 surv1[N_SURV_MAX]; /* indices of survivors from 1st stage */
Word32 tmp_ind[5];
Word32 i, k;
for (i=0; i<ORDER; i++)
{
isf[i] = (Float32)((isf1[i] - E_ROM_f_mean_isf[i]) -
F_MU * past_isfq[i] * 0.390625F);
}
E_LPC_stage1_isf_vq(&isf[0], E_ROM_dico1_isf, 9, SIZE_BK1, surv1, nb_surv);
distance = 1.0e30F;
for (k = 0; k < nb_surv; k++)
{
for (i = 0; i < 9; i++)
{
isf_stage2[i] = isf[i] - E_ROM_dico1_isf[i + surv1[k] * 9];
}
tmp_ind[0] = E_LPC_isf_sub_vq(&isf_stage2[0], E_ROM_dico21_isf, 3,
SIZE_BK21, &min_err);
temp = min_err;
tmp_ind[1] = E_LPC_isf_sub_vq(&isf_stage2[3], E_ROM_dico22_isf, 3,
SIZE_BK22, &min_err);
temp += min_err;
tmp_ind[2] = E_LPC_isf_sub_vq(&isf_stage2[6], E_ROM_dico23_isf, 3,
SIZE_BK23, &min_err);
temp += min_err;
if (temp < distance)
{
distance = temp;
indice[0] = surv1[k];
for (i = 0; i < 3; i++)
{
indice[i + 2] = tmp_ind[i];
}
}
}
E_LPC_stage1_isf_vq(&isf[9], E_ROM_dico2_isf, 7, SIZE_BK2, surv1, nb_surv);
distance = 1.0e30F;
for (k=0; k<nb_surv; k++)
{
for (i = 0; i < 7; i++)
{
isf_stage2[i] = isf[9+i] - E_ROM_dico2_isf[i+surv1[k]*7];
}
tmp_ind[0] = E_LPC_isf_sub_vq(&isf_stage2[0], E_ROM_dico24_isf, 3,
SIZE_BK24, &min_err);
temp = min_err;
tmp_ind[1] = E_LPC_isf_sub_vq(&isf_stage2[3], E_ROM_dico25_isf, 4,
SIZE_BK25, &min_err);
temp += min_err;
if (temp < distance)
{
distance = temp;
indice[1] = surv1[k];
for (i = 0; i < 2; i++)
{
indice[i + 5]= tmp_ind[i];
}
}
}
/* decoding the ISFs */
E_LPC_isf_2s5s_decode(indice, isf_q, past_isfq);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -