📄 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, enum Mode 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, enum DTXStateType new_state, enum Mode 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 + -