📄 sp_enc.cpp
字号:
* 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, float *past_rq, float *lsp1,
float *lsp1_q, INT16 *indice, INT32 *pred_init_i )
{
float lsf1[LP_ORDER], wf1[LP_ORDER], lsf_p[LP_ORDER], lsf_r1[LP_ORDER];
float lsf1_q[LP_ORDER];
float pred_init_err;
float min_pred_init_err;
float temp_r1[LP_ORDER];
float temp_p[LP_ORDER];
INT32 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 < LP_ORDER; 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 < LP_ORDER; i++ )
{
temp_p[i] = mean_lsf_3[i] + past_rq_init[j * LP_ORDER + 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, LP_ORDER <<2 );
memcpy( lsf_p, temp_p, LP_ORDER <<2 );
memcpy( past_rq, &past_rq_init[j * LP_ORDER], LP_ORDER <<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 < LP_ORDER; 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( float *past_rq, float *lsp1, float *lsp2,
float *lsp1_q, float *lsp2_q, INT16 *indice )
{
float lsf1[LP_ORDER], lsf2[LP_ORDER], wf1[LP_ORDER], wf2[LP_ORDER], lsf_p[LP_ORDER], lsf_r1[LP_ORDER], lsf_r2[LP_ORDER];
float lsf1_q[LP_ORDER], lsf2_q[LP_ORDER];
INT32 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 < LP_ORDER; 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 < LP_ORDER; 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 [LP_ORDER]
* lsp_mid I: LSP vector at the 2nd subframe of present frame [LP_ORDER]
* lsp_new I: LSP vector at the 4th subframe of present frame [LP_ORDER]
* 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( float lsp_old[], float lsp_mid[], float lsp_new[], float az[] )
{
INT32 i;
float lsp[LP_ORDER];
for ( i = 0; i < LP_ORDER; i++ )
{
lsp[i] = ( lsp_mid[i] + lsp_old[i] ) * 0.5F;
}
/* Subframe 1 */
Lsp_Az( lsp, az );
az += LP_ORDER_PLUS;
/* Subframe 2 */
Lsp_Az( lsp_mid, az );
az += LP_ORDER_PLUS;
for ( i = 0; i < LP_ORDER; i++ )
{
lsp[i] = ( lsp_mid[i] + lsp_new[i] ) * 0.5F;
}
/* Subframe 3 */
Lsp_Az( lsp, az );
az += LP_ORDER_PLUS;
/* 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 [LP_ORDER]
* lsp_new I: LSP vector at the 4th subframe of present frame [LP_ORDER]
* 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( float lsp_old[], float lsp_new[], float az[] )
{
float lsp[LP_ORDER];
INT32 i;
for ( i = 0; i < LP_ORDER; 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 += LP_ORDER_PLUS;
for ( i = 0; i < LP_ORDER; 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 += LP_ORDER_PLUS;
for ( i = 0; i < LP_ORDER; 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 [LP_ORDER]
* lsp_new I: LSP vector at the 4th subframe of present frame [LP_ORDER]
* 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( float lsp_old[], float lsp_new[], float az[] )
{
float lsp[LP_ORDER];
INT32 i;
for ( i = 0; i < LP_ORDER; i++ )
{
lsp[i] = lsp_new[i] * 0.25F + lsp_old[i] * 0.75F;
}
/* Subframe 1 */
Lsp_Az( lsp, az );
az += LP_ORDER_PLUS;
for ( i = 0; i < LP_ORDER; i++ )
{
lsp[i] = ( lsp_old[i] + lsp_new[i] ) * 0.5F;
}
/* Subframe 2 */
Lsp_Az( lsp, az );
az += LP_ORDER_PLUS;
for ( i = 0; i < LP_ORDER; i++ )
{
lsp[i] = lsp_old[i] * 0.25F + lsp_new[i] * 0.75F;
}
/* Subframe 3 */
Lsp_Az( lsp, az );
az += LP_ORDER_PLUS;
/* Subframe 4 */
Lsp_Az( lsp_new, az );
return;
}
/*
* lsp
*
*
* Parameters:
* req_mode I: requested mode
* used_mode I: used mode
* lsp_old B: old LSP vector
* lsp_old_q B: old quantized LSP vector
* past_rq B: past quantized residual
* az B: interpolated LP parameters
* azQ O: quantization interpol. LP parameters
* lsp_new O: new lsp vector
* anap O: analysis parameters
*
* Function:
* From A(z) to lsp. LSP quantization and interpolation
*
* Returns:
* void
*/
static void lsp( enum Mode req_mode, enum Mode used_mode, float *lsp_old, float *lsp_old_q,
float *past_rq, float az[], float azQ[], float lsp_new[], INT16 **anap )
{
float lsp_new_q[LP_ORDER]; /* LSPs at 4th subframe */
float lsp_mid[LP_ORDER], lsp_mid_q[LP_ORDER]; /* LSPs at 2nd subframe */
INT32 pred_init_i; /* init index for MA prediction in DTX mode */
if ( req_mode == MR122 )
{
Az_lsp( &az[LP_ORDER_PLUS], lsp_mid, lsp_old );
Az_lsp( &az[LP_ORDER_PLUS * 3], lsp_new, lsp_mid );
/*
* Find interpolated LPC parameters in all subframes
* (both quantized and unquantized).
* The interpolated parameters are in array A_t[] of size (LP_ORDER+1)*4
* and the quantized interpolated parameters are in array Aq_t[]
*/
Int_lpc_1and3_2( lsp_old, lsp_mid, lsp_new, az );
if ( used_mode != MRDTX )
{
/* LSP quantization (lsp_mid[] and lsp_new[] jointly quantized) */
Q_plsf_5( past_rq, lsp_mid, lsp_new, lsp_mid_q, lsp_new_q, *anap );
Int_lpc_1and3( lsp_old_q, lsp_mid_q, lsp_new_q, azQ );
/* Advance analysis parameters pointer */
( *anap ) += 5;
}
}
else
{
/* From A(z) to lsp */
Az_lsp( &az[LP_ORDER_PLUS * 3], lsp_new, lsp_old );
/*
* Find interpolated LPC parameters in all subframes
* (both quantized and unquantized).
* The interpolated parameters are in array A_t[] of size (LP_ORDER+1)*4
* and the quantized interpolated parameters are in array Aq_t[]
*/
Int_lpc_1to3_2( lsp_old, lsp_new, az );
/* LSP quantization */
if ( used_mode != MRDTX )
{
Q_plsf_3( req_mode, past_rq, lsp_new, lsp_new_q, *anap, &pred_init_i );
Int_lpc_1to3( lsp_old_q, lsp_new_q, azQ );
/* Advance analysis parameters pointer */
( *anap ) += 3;
}
}
/* update the LSPs for the next frame */
memcpy( lsp_old, lsp_new, LP_ORDER <<2 );
memcpy( lsp_old_q, lsp_new_q, LP_ORDER <<2 );
}
/*
* check_lsp
*
*
* Parameters:
* count B: counter for resonance
* lsp B: LSP vector
*
* Function:
* Check the LSP's to detect resonances
*
* Resonances in the LPC filter are monitored to detect possible problem
* areas where divergence between the adaptive codebook memories in
* the encoder and the decoder could cause unstable filters in areas
* with highly correlated continuos signals. Typically, this divergence
* is due to channel errors.
* The monitoring of resonance signals is performed using unquantized LSPs
* q(i), i = 1,...,10. The algorithm utilises the fact that LSPs are
* closely located at a peak in the spectrum. First, two distances,
* dist 1 and dist 2 ,are calculated in two different regions,
* defined as
*
* dist1 = min[q(i) - q(i + 1)], i = 4,...,8
* dist2 = min[q(i) - q(i + 1)], i = 2,3
*
* Either of these two minimum distance conditions must be fulfilled
* to classify the frame as a resonance frame and increase the resonance
* counter.
*
* if(dist1 < TH1) || if (dist2 < TH2)
* counter++
* else
* counter = 0
*
* TH1 = 0.046
* TH2 = 0.018, q(2) > 0.98
* TH2 = 0.024, 0.93 < q(2) <= 0.98
* TH2 = 0.018, otherwise
*
* 12 consecutive resonance frames are needed to indicate possible
* problem conditions, otherwise the LSP_flag is cleared.
*
* Returns:
* resonance flag
*/
static INT16 check_lsp( INT16 *count, float *lsp )
{
float dist, dist_min1, dist_min2, dist_th;
INT32 i;
/*
* Check for a resonance:
* Find minimum distance between lsp[i] and lsp[i+1]
*/
dist_min1 = FLT_MAX;
for ( i = 3; i < 8; i++ )
{
dist = lsp[i] - lsp[i + 1];
if ( dist < dist_min1 )
{
dist_min1 = dist;
}
}
dist_min2 = FLT_MAX;
for ( i = 1; i < 3; i++ )
{
dist = lsp[i] - lsp[i + 1];
if ( dist < dist_min2 )
{
dist_min2 = dist;
}
}
if ( lsp[1] > 0.98F )
{
dist_th = 0.018F;
}
else if ( lsp[1] > 0.93F )
{
dist_th = 0.024F;
}
else
{
dist_th = 0.034F;
}
if ( ( dist_min1 < 0.046F ) || ( dist_min2 < dist_th ) )
{
*count += 1;
}
else
{
*count = 0;
}
/* Need 12 consecutive frames to set the flag */
if ( *count >= 12 )
{
*count = 12;
return 1;
}
else
{
return 0;
}
}
/*
* Weight_Ai
*
*
* Parameters:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -