📄 sp_enc.c
字号:
* Returns:
* void
*/
static void Reorder_lsf( Float32 *lsf, Float32 min_dist )
{
Float32 lsf_min;
Word32 i;
lsf_min = min_dist;
for ( i = 0; i < M; i++ ) {
if ( lsf[i] < lsf_min ) {
lsf[i] = lsf_min;
}
lsf_min = lsf[i] + min_dist;
}
}
/*
* Lsf_lsp
*
*
* Parameters:
* lsf I: vector of LSFs
* lsp O: vector of LSPs
*
* Function:
* Transformation lsf to lsp, order M
*
* Returns:
* void
*/
static void Lsf_lsp( Float32 lsf[], Float32 lsp[] )
{
Word32 i;
for ( i = 0; i < M; i++ ) {
lsp[i] = ( Float32 )cos( SCALE_FREQ_LSP * lsf[i] );
}
return;
}
/*
* Vq_subvec3
*
*
* Parameters:
* lsf_r1 I: 1st LSF residual vector
* dico I: quantization codebook
* wf1 I: 1st LSF weighting factors
* dico_size I: size of quantization codebook
* use_half I: use every second entry in codebook
*
* Function:
* Quantization of a 3 dimensional subvector
*
* Returns:
* index quantization index
*/
static Word16 Vq_subvec3( Float32 *lsf_r1, const Float32 *dico, Float32 *wf1,
Word16 dico_size, Word32 use_half )
{
Float64 dist, dist_min;
Float32 temp;
const Float32 *p_dico;
Word32 i, index = 0;
dist_min = FLT_MAX;
p_dico = dico;
if ( use_half == 0 ) {
for ( i = 0; i < dico_size; i++ ) {
temp = lsf_r1[0] - *p_dico++;
temp *= wf1[0];
dist = temp * temp;
temp = lsf_r1[1] - *p_dico++;
temp *= wf1[1];
dist += temp * temp;
temp = lsf_r1[2] - *p_dico++;
temp *= wf1[2];
dist += temp * temp;
if ( dist < dist_min ) {
dist_min = dist;
index = i;
}
}
p_dico = &dico[( 3 * index )];
}
else {
for ( i = 0; i < dico_size; i++ ) {
temp = lsf_r1[0] - *p_dico++;
temp *= wf1[0];
dist = temp * temp;
temp = lsf_r1[1] - *p_dico++;
temp *= wf1[1];
dist += temp * temp;
temp = lsf_r1[2] - *p_dico++;
temp *= wf1[2];
dist += temp * temp;
if ( dist < dist_min ) {
dist_min = dist;
index = i;
}
p_dico = p_dico + 3;
}
p_dico = &dico[6 * index];
}
/* Reading the selected vector */
lsf_r1[0] = *p_dico++;
lsf_r1[1] = *p_dico++;
lsf_r1[2] = *p_dico++;
return( Word16 )index;
}
/*
* Vq_subvec4
*
*
* Parameters:
* lsf_r1 I: 1st LSF residual vector
* dico I: quantization codebook
* wf1 I: 1st LSF weighting factors
* dico_size I: size of quantization codebook
*
* Function:
* Quantization of a 4 dimensional subvector
*
* Returns:
* index quantization index
*/
static Word16 Vq_subvec4( Float32 *lsf_r1, const Float32 *dico, Float32 *wf1,
Word16 dico_size )
{
Float64 dist, dist_min;
Float32 temp;
const Float32 *p_dico;
Word32 i, index = 0;
dist_min = FLT_MAX;
p_dico = dico;
for ( i = 0; i < dico_size; i++ ) {
temp = lsf_r1[0] - *p_dico++;
temp *= wf1[0];
dist = temp * temp;
temp = lsf_r1[1] - *p_dico++;
temp *= wf1[1];
dist += temp * temp;
temp = lsf_r1[2] - *p_dico++;
temp *= wf1[2];
dist += temp * temp;
temp = lsf_r1[3] - *p_dico++;
temp *= wf1[3];
dist += temp * temp;
if ( dist < dist_min ) {
dist_min = dist;
index = i;
}
}
/* Reading the selected vector */
p_dico = &dico[index << 2];
lsf_r1[0] = *p_dico++;
lsf_r1[1] = *p_dico++;
lsf_r1[2] = *p_dico++;
lsf_r1[3] = *p_dico++;
return( Word16 )index;
}
/*
* Q_plsf_3
*
*
* Parameters:
* mode I: AMR mode
* past_rq B: past quantized residual
* lsp1 I: 1st LSP vector
* lsp1_q O: quantized 1st LSP vector
* indice I: quantization indices of 5 matrices and
* one sign for 3rd
* pred_init_i O: init index for MA prediction in DTX mode
*
* Function:
* Quantization of LSF parameters with 1st order MA prediction and
* split by 3 vector quantization (split-VQ)
*
* Returns:
* void
*/
static void Q_plsf_3( enum Mode mode, Float32 *past_rq, Float32 *lsp1, Float32 *
lsp1_q, Word16 *indice, Word32 *pred_init_i )
{
Float32 lsf1[M], wf1[M], lsf_p[M], lsf_r1[M];
Float32 lsf1_q[M];
Float32 pred_init_err;
Float32 min_pred_init_err;
Float32 temp_r1[M];
Float32 temp_p[M];
Word32 j, i;
/* convert LSFs to normalize frequency domain */
Lsp_lsf( lsp1, lsf1 );
/* compute LSF weighting factors */
Lsf_wt( lsf1, wf1 );
/* Compute predicted LSF and prediction error */
if ( mode != MRDTX ) {
for ( i = 0; i < M; i++ ) {
lsf_p[i] = mean_lsf_3[i] + past_rq[i] * pred_fac[i];
lsf_r1[i] = lsf1[i] - lsf_p[i];
}
}
else {
/*
* DTX mode, search the init vector that yields
* lowest prediction resuidual energy
*/
*pred_init_i = 0;
min_pred_init_err = FLT_MAX;
for ( j = 0; j < PAST_RQ_INIT_SIZE; j++ ) {
pred_init_err = 0;
for ( i = 0; i < M; i++ ) {
temp_p[i] = mean_lsf_3[i] + past_rq_init[j * M + i];
temp_r1[i] = lsf1[i] - temp_p[i];
pred_init_err += temp_r1[i] * temp_r1[i];
} /* next i */
if ( pred_init_err < min_pred_init_err ) {
min_pred_init_err = pred_init_err;
memcpy( lsf_r1, temp_r1, M <<2 );
memcpy( lsf_p, temp_p, M <<2 );
memcpy( past_rq, &past_rq_init[j * M], M <<2 );
*pred_init_i = j;
}
}
}
/* Split-VQ of prediction error */
/* MR475, MR515 */
if ( ( mode == MR475 ) || ( mode == MR515 ) ) {
indice[0] = Vq_subvec3( &lsf_r1[0], dico1_lsf_3, &wf1[0], DICO1_SIZE_3, 0
);
indice[1] = Vq_subvec3( &lsf_r1[3], dico2_lsf_3, &wf1[3], DICO2_SIZE_3 /2,
1 );
indice[2] = Vq_subvec4( &lsf_r1[6], mr515_3_lsf, &wf1[6], MR515_3_SIZE );
}
/* MR795 */
else if ( mode == MR795 ) {
indice[0] = Vq_subvec3( &lsf_r1[0], mr795_1_lsf, &wf1[0], MR795_1_SIZE, 0
);
indice[1] = Vq_subvec3( &lsf_r1[3], dico2_lsf_3, &wf1[3], DICO2_SIZE_3, 0
);
indice[2] = Vq_subvec4( &lsf_r1[6], dico3_lsf_3, &wf1[6], DICO3_SIZE_3 );
}
/* MR59, MR67, MR74, MR102 , MRDTX */
else {
indice[0] = Vq_subvec3( &lsf_r1[0], dico1_lsf_3, &wf1[0], DICO1_SIZE_3, 0
);
indice[1] = Vq_subvec3( &lsf_r1[3], dico2_lsf_3, &wf1[3], DICO2_SIZE_3, 0
);
indice[2] = Vq_subvec4( &lsf_r1[6], dico3_lsf_3, &wf1[6], DICO3_SIZE_3 );
}
/* Compute quantized LSFs and update the past quantized residual */
for ( i = 0; i < M; i++ ) {
lsf1_q[i] = lsf_r1[i] + lsf_p[i];
past_rq[i] = lsf_r1[i];
}
/* verification that LSFs has mimimum distance of LSF_GAP 50 Hz */
Reorder_lsf( lsf1_q, 50.0F );
/* convert LSFs to the cosine domain */
Lsf_lsp( lsf1_q, lsp1_q );
}
/*
* Q_plsf_5
*
*
* Parameters:
* past_rq B: past quantized residual
* lsp1 I: 1st LSP vector
* lsp2 I: 2nd LSP vector
* lsp1_q O: quantized 1st LSP vector
* lsp2_q O: quantized 2nd LSP vector
* indice I: quantization indices of 5 matrices and
* one sign for 3rd
*
* Function:
* Quantization of 2 sets of LSF parameters using 1st order MA
* prediction and split by 5 matrix quantization (split-MQ).
*
* Returns:
* void
*/
static void Q_plsf_5( Float32 *past_rq, Float32 *lsp1, Float32 *lsp2, Float32 *
lsp1_q, Float32 *lsp2_q, Word16 *indice )
{
Float32 lsf1[M], lsf2[M], wf1[M], wf2[M], lsf_p[M], lsf_r1[M], lsf_r2[M];
Float32 lsf1_q[M], lsf2_q[M];
Word32 i;
/* convert LSFs to normalize frequency domain */
Lsp_lsf( lsp1, lsf1 );
Lsp_lsf( lsp2, lsf2 );
/* Compute LSF weighting factors */
Lsf_wt( lsf1, wf1 );
Lsf_wt( lsf2, wf2 );
/* Compute predicted LSF and prediction error */
for ( i = 0; i < M; i++ ) {
/* MR122 LSP prediction factor = 0.65 */
lsf_p[i] = mean_lsf_5[i] + past_rq[i] * 0.65F;
lsf_r1[i] = lsf1[i] - lsf_p[i];
lsf_r2[i] = lsf2[i] - lsf_p[i];
}
/* Split-MQ of prediction error */
indice[0] = Vq_subvec( &lsf_r1[0], &lsf_r2[0], dico1_lsf_5, &wf1[0], &wf2[0],
DICO1_SIZE_5 );
indice[1] = Vq_subvec( &lsf_r1[2], &lsf_r2[2], dico2_lsf_5, &wf1[2], &wf2[2],
DICO2_SIZE_5 );
indice[2] = Vq_subvec_s( &lsf_r1[4], &lsf_r2[4], dico3_lsf_5, &wf1[4], &wf2[4
], DICO3_SIZE_5 );
indice[3] = Vq_subvec( &lsf_r1[6], &lsf_r2[6], dico4_lsf_5, &wf1[6], &wf2[6],
DICO4_SIZE_5 );
indice[4] = Vq_subvec( &lsf_r1[8], &lsf_r2[8], dico5_lsf_5, &wf1[8], &wf2[8],
DICO5_SIZE_5 );
/* Compute quantized LSFs and update the past quantized residual */
for ( i = 0; i < M; i++ ) {
lsf1_q[i] = lsf_r1[i] + lsf_p[i];
lsf2_q[i] = lsf_r2[i] + lsf_p[i];
past_rq[i] = lsf_r2[i];
}
/* verification that LSFs has minimum distance of LSF_GAP 50hz */
Reorder_lsf( lsf1_q, 50.0F );
Reorder_lsf( lsf2_q, 50.0F );
/* convert LSFs to the cosine domain */
Lsf_lsp( lsf1_q, lsp1_q );
Lsf_lsp( lsf2_q, lsp2_q );
}
/*
* Int_lpc_1and3
*
*
* Parameters:
* lsp_old I: LSP vector at the 4th subfr. of past frame [M]
* lsp_mid I: LSP vector at the 2nd subframe of present frame [M]
* lsp_new I: LSP vector at the 4th subframe of present frame [M]
* az O: interpolated LP parameters in subframes 1 and 3
* [AZ_SIZE]
*
* Function:
* Interpolates the LSPs and converts to LPC parameters
* to get a different LP filter in each subframe.
*
* The 20 ms speech frame is divided into 4 subframes.
* The LSPs are quantized and transmitted at the 2nd and
* 4th subframes (twice per frame) and interpolated at the
* 1st and 3rd subframe.
*
* Returns:
* void
*/
static void Int_lpc_1and3( Float32 lsp_old[], Float32 lsp_mid[], Float32 lsp_new
[], Float32 az[] )
{
Word32 i;
Float32 lsp[M];
for ( i = 0; i < M; i++ ) {
lsp[i] = ( lsp_mid[i] + lsp_old[i] ) * 0.5F;
}
/* Subframe 1 */
Lsp_Az( lsp, az );
az += MP1;
/* Subframe 2 */
Lsp_Az( lsp_mid, az );
az += MP1;
for ( i = 0; i < M; i++ ) {
lsp[i] = ( lsp_mid[i] + lsp_new[i] ) * 0.5F;
}
/* Subframe 3 */
Lsp_Az( lsp, az );
az += MP1;
/* Subframe 4 */
Lsp_Az( lsp_new, az );
return;
}
/*
* Int_lpc_1to3_2
*
*
* Parameters:
* lsp_old I: LSP vector at the 4th subfr. of past frame [M]
* lsp_new I: LSP vector at the 4th subframe of present frame [M]
* az O: interpolated LP parameters in subframes 1, 2 and 3
* [AZ_SIZE]
*
* Function:
* Interpolation of the LPC parameters.
*
* Returns:
* void
*/
static void Int_lpc_1to3_2( Float32 lsp_old[], Float32 lsp_new[], Float32 az[] )
{
Float32 lsp[M];
Word32 i;
for ( i = 0; i < M; i += 2 ) {
lsp[i] = lsp_new[i] * 0.25F + lsp_old[i] * 0.75F;
lsp[i + 1] = lsp_new[i + 1] *0.25F + lsp_old[i + 1] *0.75F;
}
/* Subframe 1 */
Lsp_Az( lsp, az );
az += MP1;
for ( i = 0; i < M; i += 2 ) {
lsp[i] = ( lsp_old[i] + lsp_new[i] ) * 0.5F;
lsp[i + 1] = ( lsp_old[i + 1] +lsp_new[i+1] )*0.5F;
}
/* Subframe 2 */
Lsp_Az( lsp, az );
az += MP1;
for ( i = 0; i < M; i += 2 ) {
lsp[i] = lsp_old[i] * 0.25F + lsp_new[i] * 0.75F;
lsp[i + 1] = lsp_old[i + 1] *0.25F + lsp_new[i + 1] *0.75F;
}
/* Subframe 3 */
Lsp_Az( lsp, az );
return;
}
/*
* Int_lpc_1to3
*
*
* Parameters:
* lsp_old I: LSP vector at the 4th subfr. of past frame [M]
* lsp_new I: LSP vector at the 4th subframe of present frame [M]
* az O: interpolated LP parameters in all subframes
* [AZ_SIZE]
*
* Function:
* Interpolates the LSPs and converts to LPC parameters to get a different
* LP filter in each subframe.
*
* The 20 ms speech frame is divided into 4 subframes.
* The LSPs are quantized and transmitted at the 4th
* subframes (once per frame) and interpolated at the
* 1st, 2nd and 3rd subframe.
*
* Returns:
* void
*/
static void Int_lpc_1to3( Float32 lsp_old[], Float32 lsp_new[], Float32 az[] )
{
Float32 lsp[M];
Word32 i;
for ( i = 0; i < M; i++ ) {
lsp[i] = lsp_new[i] * 0.25F + lsp_old[i] * 0.75F;
}
/* Subframe 1 */
Lsp_Az( lsp, az );
az += MP1;
for ( i = 0; i < M; i++ ) {
lsp[i] = ( lsp_old[i] + lsp_new[i] ) * 0.5F;
}
/* Subframe 2 */
Lsp_Az( lsp, az );
az += MP1;
for ( i = 0; i < M; i++ ) {
lsp[i] = lsp_old[i] * 0.25F + lsp_new[i] * 0.75F;
}
/* Subframe 3 */
Lsp_Az( lsp, az );
az += MP1;
/* Subframe 4 */
Lsp_Az( lsp_new, az );
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -