📄 sp_dec.c
字号:
}
}
Log2_norm( x <<exp, exp, exponent, fraction );
}
/*
* Pow2
*
*
* Parameters:
* exponent I: Integer part. (range: 0<=val<=30)
* fraction O: Fractional part. (range: 0.0<=val<1.0)
*
* Function:
* pow(2.0, exponent.fraction)
*
* The function Pow2(L_x) is approximated by a table and linear interpolation.
*
* i = bit10-b15 of fraction, 0 <= i <= 31
* a = biT0-b9 of fraction
* x = table[i]<<16 - (table[i] - table[i+1]) * a * 2
* x = L_x >> (30-exponent) (with rounding)
*
* Returns:
* result (range: 0<=val<=0x7fffffff)
*/
static Word32 Pow2( Word32 exponent, Word32 fraction )
{
Word32 i, a, tmp, x, exp;
/* Extract b10-b16 of fraction */
i = fraction >> 10;
/* Extract b0-b9 of fraction */
a = ( fraction << 5 ) & 0x7fff;
/* table[i] << 16 */
x = pow2_table[i] << 16;
/* table[i] - table[i+1] */
tmp = pow2_table[i] - pow2_table[i + 1];
/* L_x -= tmp*a*2 */
x -= ( tmp * a ) << 1;
if ( exponent >= -1 ) {
exp = ( 30 - exponent );
/* Rounding */
if ( ( x & ( ( Word32 )1 << ( exp - 1 ) ) ) != 0 ) {
x = ( x >> exp ) + 1;
}
else
x = x >> exp;
}
else
x = 0;
return( x );
}
/*
* Build_CN_code
*
*
* Parameters:
* seed B: Old CN generator shift register state
* cod O: Generated CN fixed codebook vector
*
* Function:
* Generate CN fixed codebook vector
*
* Returns:
* void
*/
static void Build_CN_code( Word32 *seed, Word32 cod[] )
{
Word32 i, j, k;
memset( cod, 0, L_SUBFR <<2 );
for ( k = 0; k < 10; k++ ) {
i = pseudonoise( seed, 2 ); /* generate pulse position */
i = ( i * 20 ) >> 1;
i = ( i + k );
j = pseudonoise( seed, 1 ); /* generate sign */
if ( j > 0 ) {
cod[i] = 4096;
}
else {
cod[i] = -4096;
}
}
return;
}
/*
* Build_CN_param
*
*
* Parameters:
* seed B: Old CN generator shift register state
* nParam I: number of params
* paramSizeTable I: size of params
* parm O: CN Generated params
*
* Function:
* Generate parameters for comfort noise generation
*
* Returns:
* void
*/
static void Build_CN_param( Word16 *seed, int mode, Word16 parm[] )
{
Word32 i;
const Word32 *p;
*seed = ( Word16 )( ( *seed * 31821 ) + 13849L );
p = &window_200_40[ * seed & 0x7F];
switch ( mode ) {
case MR122:
for ( i = 0; i < PRMNO_MR122; i++ ) {
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR122[i] ) );
}
break;
case MR102:
for ( i = 0; i < PRMNO_MR102; i++ ) {
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR102[i] ) );
}
break;
case MR795:
for ( i = 0; i < PRMNO_MR795; i++ ) {
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR795[i] ) );
}
break;
case MR74:
for ( i = 0; i < PRMNO_MR74; i++ ) {
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR74[i] ) );
}
break;
case MR67:
for ( i = 0; i < PRMNO_MR67; i++ ) {
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR67[i] ) );
}
break;
case MR59:
for ( i = 0; i < PRMNO_MR59; i++ ) {
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR59[i] ) );
}
break;
case MR515:
for ( i = 0; i < PRMNO_MR515; i++ ) {
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR515[i] ) );
}
break;
case MR475:
for ( i = 0; i < PRMNO_MR475; i++ ) {
parm[i] = ( Word16 )( *p++ & ~( 0xFFFF << bitno_MR475[i] ) );
}
break;
}
}
/*
* Syn_filt
*
*
* Parameters:
* a I: prediction coefficients [M+1]
* x I: input signal
* y O: output signal
* lg I: size of filtering
* mem B: memory associated with this filtering
* update I: 0=no update, 1=update of memory.
*
* Function:
* Perform synthesis filtering through 1/A(z).
*
* Returns:
* void
*/
static Word32 Syn_filt( Word32 a[], Word32 x[], Word32 y[], Word32 lg, Word32 mem[]
, Word32 update )
{
Word32 tmp[50]; /* malloc is slow */
Word32 s, a0, overflow = 0;
Word32 *yy, *yy_limit;
/* Copy mem[] to yy[] */
memcpy( tmp, mem, 40 );
yy = tmp + M;
yy_limit = yy + lg;
a0 = a[0];
/* Do the filtering. */
while ( yy < yy_limit ) {
s = *x++ * a0;
s -= yy[-1] * a[1];
s -= yy[-2] * a[2];
s -= yy[-3] * a[3];
s -= yy[-4] * a[4];
s -= yy[-5] * a[5];
s -= yy[-6] * a[6];
s -= yy[-7] * a[7];
s -= yy[-8] * a[8];
s -= yy[-9] * a[9];
s -= yy[-10] * a[10];
if ( labs( s ) < 0x7ffffff )
*yy = ( s + 0x800L ) >> 12;
else if ( s > 0 ) {
*yy = 32767;
overflow = 1;
}
else {
*yy = -32768;
overflow = 1;
}
yy++;
}
memcpy( y, &tmp[M], lg <<2 );
/* Update of memory if update==1 */
if ( update ) {
memcpy( mem, &y[lg - M], 40 );
}
return overflow;
}
/*
* Syn_filt_overflow
*
*
* Parameters:
* a I: prediction coefficients [M+1]
* x I: input signal
* y O: output signal
* lg I: size of filtering
* mem B: memory associated with this filtering
* update I: 0=no update, 1=update of memory.
*
* Function:
* Perform synthesis filtering through 1/A(z).
* Saturate after every multiplication.
* Returns:
* void
*/
static void Syn_filt_overflow( Word32 a[], Word32 x[], Word32 y[], Word32 lg, Word32 mem[]
, Word32 update )
{
Word32 tmp[50]; /* malloc is slow */
Word32 i, j, s, a0;
Word32 *yy;
/* Copy mem[] to yy[] */
memcpy( tmp, mem, 40 );
yy = tmp + M;
a0 = a[0];
/* Do the filtering. */
for ( i = 0; i < lg; i++ ) {
s = x[i] * a0;
for ( j = 1; j <= M; j++ ) {
s -= a[j] * yy[ - j];
if (s > 1073741823){
s = 1073741823;
}
else if ( s < -1073741824) {
s = -1073741824;
}
}
if ( labs( s ) < 0x7FFE800 )
*yy = ( s + 0x800L ) >> 12;
else if ( s > 0 ) {
*yy = 32767;
}
else {
*yy = -32768;
}
yy++;
}
memcpy( y, &tmp[M], lg <<2 );
/* Update of memory if update==1 */
if ( update ) {
memcpy( mem, &y[lg - M], 40 );
}
return;
}
/*
* dtx_dec
*
*
* Parameters:
* st B: DTX state struct
* mem_syn I: AMR decoder state
* lsfState B: LSF state struct
* pred_state->past_qua_en O: table of past quantized energies
* pred_state->past_qua_en_MR122 O: table of past quantized energies MR122
* averState->hangVar O:
* averState->hangCount O: hangover variable
* new_state I: new DTX state
* mode I: AMR mode
* parm I: vector of synthesis parameters
* synth O: synthesised speech
* A_t O: decoded LP filter in 4 subframes
*
* Function:
* DTX
*
* Returns:
* void
*/
static void dtx_dec( dtx_decState *st, Word32 *mem_syn, D_plsfState *lsfState,
gc_predState *pred_state, Cb_gain_averageState *averState, int new_state,
int mode, Word16 parm[], Word32 synth[],
Word32 A_t[] )
{
Word32 ex[L_SUBFR], acoeff[11], acoeff_variab[M + 1], lsp_int[M];
Word32 refl[M], lsf[M], lsf_int[M], lsf_int_variab[M], lsp_int_variab[M];
Word32 i, j, int_fac, log_en_int, pred_err, log_pg_e, log_pg_m, log_pg;
Word32 negative, lsf_mean, lsf_variab_index, lsf_variab_factor, ptr;
Word16 log_en_index, log_en_int_e, log_en_int_m, level, ma_pred_init,
tmp_int_length;
if ( ( st->dtxHangoverAdded != 0 ) & ( st->sid_frame != 0 ) ) {
/*
* sidFirst after dtx hangover period
* or sidUpd after dtxhangover
*/
/* set log_en_adjust to correct value */
st->log_en_adjust = dtx_log_en_adjust[mode];
ptr = st->lsf_hist_ptr + M;
if ( ptr == 80 ) {
ptr = 0;
}
memcpy( &st->lsf_hist[ptr], &st->lsf_hist[st->lsf_hist_ptr], M <<2 );
ptr = st->log_en_hist_ptr + 1;
if ( ptr == DTX_HIST_SIZE ) {
ptr = 0;
}
st->log_en_hist[ptr] = st->log_en_hist[st->log_en_hist_ptr]; /* Q11 */
/*
* compute mean log energy and lsp
* from decoded signal (SID_FIRST)
*/
st->log_en = 0;
memset( lsf, 0, M <<2 );
/* average energy and lsp */
for ( i = 0; i < DTX_HIST_SIZE; i++ ) {
st->log_en = st->log_en + ( st->log_en_hist[i] >> 3 );
for ( j = 0; j < M; j++ ) {
lsf[j] += st->lsf_hist[i * M + j];
}
}
for ( j = 0; j < M; j++ ) {
lsf[j] = lsf[j] >> 3; /* divide by 8 */
}
Lsf_lsp( lsf, st->lsp );
/*
* make log_en speech coder mode independent
* added again later before synthesis
*/
st->log_en = st->log_en - st->log_en_adjust;
/* compute lsf variability vector */
memcpy( st->lsf_hist_mean, st->lsf_hist, 80 <<2 );
for ( i = 0; i < M; i++ ) {
lsf_mean = 0;
/* compute mean lsf */
for ( j = 0; j < 8; j++ ) {
lsf_mean += st->lsf_hist_mean[i + j * M];
}
lsf_mean = lsf_mean >> 3;
/*
* subtract mean and limit to within reasonable limits
* moreover the upper lsf's are attenuated
*/
for ( j = 0; j < 8; j++ ) {
/* subtract mean */
st->lsf_hist_mean[i + j * M] = st->lsf_hist_mean[i + j * M] -
lsf_mean;
/* attenuate deviation from mean, especially for upper lsf's */
st->lsf_hist_mean[i + j * M] = ( st->lsf_hist_mean[i + j * M] *
lsf_hist_mean_scale[i] ) >> 15;
/* limit the deviation */
if ( st->lsf_hist_mean[i + j * M] < 0 ) {
negative = 1;
}
else {
negative = 0;
}
st->lsf_hist_mean[i + j * M] = labs( st->lsf_hist_mean[i + j * M] );
/* apply soft limit */
if ( st->lsf_hist_mean[i + j * M] > 655 ) {
st->lsf_hist_mean[i + j * M] = 655 + ( ( st->lsf_hist_mean[i + j
* M] - 655 ) >> 2 );
}
/* apply hard limit */
if ( st->lsf_hist_mean[i + j * M] > 1310 ) {
st->lsf_hist_mean[i + j * M] = 1310;
}
if ( negative != 0 ) {
st->lsf_hist_mean[i + j * M] = -st->lsf_hist_mean[i + j * M];
}
}
}
}
if ( st->sid_frame != 0 ) {
/*
* Set old SID parameters, always shift
* even if there is no new valid_data
*/
memcpy( st->lsp_old, st->lsp, M <<2 );
st->old_log_en = st->log_en;
if ( st->valid_data != 0 ) /* new data available (no CRC) */ {
/* Compute interpolation factor, since the division only works
* for values of since_last_sid < 32 we have to limit the
* interpolation to 32 frames
*/
tmp_int_length = st->since_last_sid;
st->since_last_sid = 0;
if ( tmp_int_length > 32 ) {
tmp_int_length = 32;
}
if ( tmp_int_length >= 2 ) {
st->true_sid_period_inv = 0x2000000 / ( tmp_int_length
<< 10 );
}
else {
st->true_sid_period_inv = 16384; /* 0.5 it Q15 */
}
memcpy( lsfState->past_r_q, &past_rq_init[parm[0] * M], M <<2 );
D_plsf_3( lsfState, MRDTX, 0, &parm[1], st->lsp );
/* reset for next speech frame */
memset( lsfState->past_r_q, 0, M <<2 );
log_en_index = parm[4];
/* Q11 and divide by 4 */
st->log_en = ( Word16 )( log_en_index << 9 );
/* Subtract 2.5 in Q11 */
st->log_en = ( Word16 )( st->log_en - 5120 );
/* Index 0 is reserved for silence */
if ( log_en_index == 0 ) {
st->log_en = MIN_16;
}
/*
* no interpolation at startup after coder reset
* or when SID_UPD has been received right after SPEECH
*/
if ( ( st->data_updated == 0 ) || ( st->dtxGlobalState == SPEECH ) ) {
memcpy( st->lsp_old, st->lsp, M <<2 );
st->old_log_en = st->log_en;
}
} /* endif valid_data */
/* initialize gain predictor memory of other modes */
ma_pred_init = ( Word16 )( ( st->log_en >> 1 ) - 9000 );
if ( ma_pred_init > 0 ) {
ma_pred_init = 0;
}
if ( ma_pred_init < - 14436 ) {
ma_pred_init = -14436;
}
pred_state->past_qua_en[0] = ma_pred_init;
pred_state->past_qua_en[1] = ma_pred_init;
pred_state->past_qua_en[2] = ma_pred_init;
pred_state->past_qua_en[3] = ma_pred_init;
/* past_qua_en for other modes than MR122 */
ma_pred_init = ( Word16 )( ( 5443*ma_pred_init ) >> 15 );
/* scale down by factor 20*log10(2) in Q15 */
pred_state->past_qua_en_MR122[0] = ma_pred_init;
pred_state->past_qua_en_MR122[1] = ma_pred_init;
pred_state->past_qua_en_MR122[2] = ma_pred_init;
pred_state->past_qua_en_MR122[3] = ma_pred_init;
} /* endif sid_frame */
/*
* CN generation
* recompute level adjustment factor Q11
* st->log_en_adjust = 0.9*st->log_en_adjust +
* 0.1*dtx_log_en_adjust[mode]);
*/
st->log_en_adjust = ( Word16 )( ( ( st->log_en_adjust * 29491 ) >> 15 ) + ( (
( dtx_log_en_adjust[mode] << 5 ) * 3277 ) >> 20 ) );
/* Interpolate SID info */
/* Q10 */
if ( st->since_last_sid > 30 )
int_fac = 32767;
else
int_fac = ( Word16 )( (st->since_last_sid + 1) << 10 );
/* Q10 * Q15 -> Q10 */
int_fac = ( int_fac * st->true_sid_period_inv ) >> 15;
/* Maximize to 1.0 in Q10 */
if ( int_fac > 1024 ) {
int_fac = 1024;
}
/* Q10 -> Q14 */
int_fac = ( Word16 )( int_fac << 4 );
/* Q14 * Q11->Q26 */
log_en_int = ( int_fac * st->log_en ) << 1;
for ( i = 0; i < M; i++ ) {
/* Q14 * Q15 -> Q14 */
lsp_int[i] = ( int_fac * st->lsp[i] ) >> 15;
}
/* 1-k in Q14 */
int_fac = 16384 - int_fac;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -