📄 dtx_dec.cpp
字号:
else { lsf[j] = (Word16)(L_lsf[j] >> 3); } } Lsf_lsp(lsf, st->lsp, M, pOverflow); /* make log_en speech coder mode independent */ /* added again later before synthesis */ st->log_en = sub(st->log_en, st->log_en_adjust, pOverflow); /* compute lsf variability vector */ Copy(st->lsf_hist, st->lsf_hist_mean, 80); for (i = M - 1; i >= 0; i--) { L_lsf_mean = 0; /* compute mean lsf */ for (j = 8 - 1; j >= 0; j--) { L_lsf_mean = L_add(L_lsf_mean, L_deposit_l(st->lsf_hist_mean[i+j*M]), pOverflow); } if (L_lsf_mean < 0) { lsf_mean = (Word16)(~((~L_lsf_mean) >> 3)); } else { lsf_mean = (Word16)(L_lsf_mean >> 3); } /* subtract mean and limit to within reasonable limits * * moreover the upper lsf's are attenuated */ for (j = 8 - 1; j >= 0; j--) { /* subtract mean */ st->lsf_hist_mean[i+j*M] = sub(st->lsf_hist_mean[i+j*M], lsf_mean, pOverflow); /* attenuate deviation from mean, especially for upper lsf's */ st->lsf_hist_mean[i+j*M] = mult(st->lsf_hist_mean[i+j*M], lsf_hist_mean_scale[i], pOverflow); /* limit the deviation */ if (st->lsf_hist_mean[i+j*M] < 0) { negative = 1; } else { negative = 0; } st->lsf_hist_mean[i+j*M] = abs_s(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 */ Copy(st->lsp, st->lsp_old, M); 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; } L_temp = ((Word32) tmp_int_length) << 10; if (L_temp != (Word32)((Word16) L_temp)) { *pOverflow = 1; L_temp = (Word32)((tmp_int_length > 0) ? MAX_16 : MIN_16); } temp = (Word16) L_temp; if (tmp_int_length >= 2) { st->true_sid_period_inv = div_s(1 << 10, temp); } else { st->true_sid_period_inv = 1 << 14; /* 0.5 it Q15 */ } Init_D_plsf_3(lsfState, parm[0]); D_plsf_3(lsfState, MRDTX, 0, &parm[1], st->lsp, pOverflow); Set_zero(lsfState->past_r_q, M); /* reset for next speech frame */ log_en_index = parm[4]; /* Q11 and divide by 4 */ if ((log_en_index > 63) || (log_en_index < -64)) { st->log_en = (log_en_index > 0) ? MAX_16 : MIN_16; } else { st->log_en = (log_en_index) << (11 - 2); } /* Subtract 2.5 in Q11 */ st->log_en = sub(st->log_en, (2560 * 2), pOverflow); /* 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)) { Copy(st->lsp, st->lsp_old, M); st->old_log_en = st->log_en; } } /* endif valid_data */ /* initialize gain predictor memory of other modes */ if (st->log_en < 0) { temp = ~((~st->log_en) >> 1); } else { temp = st->log_en >> 1; } ma_pred_init = sub(temp, 9000, pOverflow); if (ma_pred_init > 0) { ma_pred_init = 0; } else if (ma_pred_init < -14436) { ma_pred_init = -14436; } predState->past_qua_en[0] = ma_pred_init; predState->past_qua_en[1] = ma_pred_init; predState->past_qua_en[2] = ma_pred_init; predState->past_qua_en[3] = ma_pred_init; /* past_qua_en for other modes than MR122 */ ma_pred_init = mult(5443, ma_pred_init, pOverflow); /* scale down by factor 20*log10(2) in Q15 */ predState->past_qua_en_MR122[0] = ma_pred_init; predState->past_qua_en_MR122[1] = ma_pred_init; predState->past_qua_en_MR122[2] = ma_pred_init; predState->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]); */ if (dtx_log_en_adjust[mode] > 1023) { temp = MAX_16; } else if (dtx_log_en_adjust[mode] < -1024) { temp = MIN_16; } else { temp = mult((Word16)((Word32)dtx_log_en_adjust[mode] << 5), 3277, pOverflow); } if (temp < 0) { temp = ~((~temp) >> 5); } else { temp >>= 5; } st->log_en_adjust = add(mult(st->log_en_adjust, 29491, pOverflow), temp, pOverflow); /* Interpolate SID info */ int_fac = shl(add(1, st->since_last_sid, pOverflow), 10, pOverflow); /* Q10 */ int_fac = mult(int_fac, st->true_sid_period_inv, pOverflow); /* Q10 * Q15 -> Q10 */ /* Maximize to 1.0 in Q10 */ if (int_fac > 1024) { int_fac = 16384; } else if (int_fac < -2048) { int_fac = MIN_16; } else { int_fac <<= 4; /* Q10 -> Q14 */ } L_log_en_int = L_mult(int_fac, st->log_en, pOverflow); /* Q14 * Q11->Q26 */ for (i = M - 1; i >= 0; i--) { lsp_int[i] = mult(int_fac, st->lsp[i], pOverflow);/* Q14 * Q15 -> Q14 */ } int_fac = sub(16384, int_fac, pOverflow); /* 1-k in Q14 */ /* (Q14 * Q11 -> Q26) + Q26 -> Q26 */ L_log_en_int = L_mac(L_log_en_int, int_fac, st->old_log_en, pOverflow); for (i = M - 1; i >= 0; i--) { /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */ lsp_int[i] = add(lsp_int[i], mult(int_fac, st->lsp_old[i], pOverflow), pOverflow); L_temp = ((Word32) lsp_int[i]) << 1; /* Q14 -> Q15 */ if (L_temp != (Word32)((Word16) L_temp)) { *pOverflow = 1; L_temp = (Word32)((lsp_int[i] > 0) ? MAX_16 : MIN_16); } lsp_int[i] = (Word16) L_temp; } /* compute the amount of lsf variability */ lsf_variab_factor = sub(st->log_pg_mean, 2457, pOverflow); /* -0.6 in Q12 */ /* *0.3 Q12*Q15 -> Q12 */ lsf_variab_factor = sub(4096, mult(lsf_variab_factor, 9830, pOverflow), pOverflow); /* limit to values between 0..1 in Q12 */ if (lsf_variab_factor > 4095) { lsf_variab_factor = MAX_16; } else if (lsf_variab_factor < 0) { lsf_variab_factor = 0; } else { lsf_variab_factor <<= 3; /* -> Q15 */ } /* get index of vector to do variability with */ lsf_variab_index = pseudonoise(&st->L_pn_seed_rx, 3); /* convert to lsf */ Lsp_lsf(lsp_int, lsf_int, M, pOverflow); /* apply lsf variability */ Copy(lsf_int, lsf_int_variab, M); for (i = M - 1; i >= 0; i--) { lsf_int_variab[i] = add(lsf_int_variab[i], mult(lsf_variab_factor, st->lsf_hist_mean[i+lsf_variab_index*M], pOverflow) , pOverflow); } /* make sure that LSP's are ordered */ Reorder_lsf(lsf_int, LSF_GAP, M, pOverflow); Reorder_lsf(lsf_int_variab, LSF_GAP, M, pOverflow); /* copy lsf to speech decoders lsf state */ Copy(lsf_int, lsfState->past_lsf_q, M); /* convert to lsp */ Lsf_lsp(lsf_int, lsp_int, M, pOverflow); Lsf_lsp(lsf_int_variab, lsp_int_variab, M, pOverflow); /* Compute acoeffs Q12 acoeff is used for level * * normalization and postfilter, acoeff_variab is * * used for synthesis filter * * by doing this we make sure that the level * * in high frequenncies does not jump up and down */ Lsp_Az(lsp_int, acoeff, pOverflow); Lsp_Az(lsp_int_variab, acoeff_variab, pOverflow); /* For use in postfilter */ Copy(acoeff, &A_t[0], M + 1); Copy(acoeff, &A_t[M + 1], M + 1); Copy(acoeff, &A_t[2 * (M + 1)], M + 1); Copy(acoeff, &A_t[3 * (M + 1)], M + 1); /* Compute reflection coefficients Q15 */ A_Refl(&acoeff[1], refl, pOverflow); /* Compute prediction error in Q15 */ pred_err = MAX_16; /* 0.99997 in Q15 */ for (i = 0; i < M; i++) { L_temp = (((Word32) refl[i]) * refl[i]) >> 15; if (L_temp <= 0x00007fffL) { temp = MAX_16 - (Word16) L_temp; } else { *pOverflow = 1; temp = 0; } pred_err = mult(pred_err, temp, pOverflow); } /* compute logarithm of prediction gain */ Log2(L_deposit_l(pred_err), &log_pg_e, &log_pg_m, pOverflow); /* convert exponent and mantissa to Word16 Q12 */ log_pg = shl(sub(log_pg_e, 15, pOverflow), 12, pOverflow); /* Q12 */ log_pg = shr(sub(0, add(log_pg, shr(log_pg_m, 15 - 12, pOverflow), pOverflow), pOverflow), 1, pOverflow); st->log_pg_mean = add(mult(29491, st->log_pg_mean, pOverflow), mult(3277, log_pg, pOverflow), pOverflow); /* Compute interpolated log energy */ L_log_en_int = L_shr(L_log_en_int, 10, pOverflow); /* Q26 -> Q16 */ /* Add 4 in Q16 */ L_log_en_int = L_add(L_log_en_int, 4 * 65536L, pOverflow); /* subtract prediction gain */ L_log_en_int = L_sub(L_log_en_int, L_shl(L_deposit_l(log_pg), 4, pOverflow), pOverflow); /* adjust level to speech coder mode */ L_log_en_int = L_add(L_log_en_int, L_shl(L_deposit_l(st->log_en_adjust), 5, pOverflow), pOverflow); log_en_int_e = (Word16)(L_log_en_int >> 16); log_en_int_m = (Word16)(L_shr(L_sub(L_log_en_int, L_deposit_h(log_en_int_e), pOverflow), 1, pOverflow)); level = (Word16)(Pow2(log_en_int_e, log_en_int_m, pOverflow)); /* Q4 */ for (i = 0; i < 4; i++) { /* Compute innovation vector */ build_CN_code(&st->L_pn_seed_rx, ex, pOverflow); for (j = L_SUBFR - 1; j >= 0; j--) { ex[j] = mult(level, ex[j], pOverflow); } /* Synthesize */ Syn_filt(acoeff_variab, ex, &synth[i * L_SUBFR], L_SUBFR, mem_syn, 1); } /* next i */ /* reset codebook averaging variables */ averState->hangVar = 20; averState->hangCount = 0; if (new_state == DTX_MUTE) { /* mute comfort noise as it has been quite a long time since * last SID update was performed */ tmp_int_length = st->since_last_sid; if (tmp_int_length > 32) { tmp_int_length = 32; } else if (tmp_int_length <= 0) { /* safety guard against division by zero */ tmp_int_length = 8; } L_temp = ((Word32) tmp_int_length) << 10; if (L_temp != (Word32)((Word16) L_temp)) { *pOverflow = 1; L_temp = (Word32)((tmp_int_length > 0) ? MAX_16 : MIN_16); } temp = (Word16) L_temp; st->true_sid_period_inv = div_s(1 << 10, temp); st->since_last_sid = 0; Copy(st->lsp, st->lsp_old, M); st->old_log_en = st->log_en; /* subtract 1/8 in Q11 i.e -6/8 dB */ st->log_en = sub(st->log_en, 256, pOverflow); } /* reset interpolation length timer * if data has been updated. */ if ((st->sid_frame != 0) && ((st->valid_data != 0) || ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0))) { st->since_last_sid = 0; st->data_updated = 1; } return;}/****************************************************************************//*------------------------------------------------------------------------------ FUNCTION NAME: dtx_dec_activity_update------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: st = pointer to a structure of type dtx_decState lsf = frame = Outputs: st points to an updated structure of type dtx_decState Returns: None. Global Variables Used: None. Local Variables Needed: None.------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function updates the DTX parameters.------------------------------------------------------------------------------ REQUIREMENTS None------------------------------------------------------------------------------ REFERENCES dtx_dec.c, UMTS GSM AMR speech codec, R99 - Version 3.3.0, December 12, 2001------------------------------------------------------------------------------ PSEUDO-CODEvoid dtx_dec_activity_update(dtx_decState *st, Word16 lsf[], Word16 frame[]){ Word16 i; Word32 L_frame_en; Word16 log_en_e, log_en_m, log_en; // update lsp history st->lsf_hist_ptr = add(st->lsf_hist_ptr,M); if (sub(st->lsf_hist_ptr, 80) == 0) { st->lsf_hist_ptr = 0; } Copy(lsf, &st->lsf_hist[st->lsf_hist_ptr], M); // compute log energy based on frame energy L_frame_en = 0; // Q0 for (i=0; i < L_FRAME; i++) { L_frame_en = L_mac(L_frame_en, frame[i], frame[i]); } Log2(L_frame_en, &log_en_e, &log_en_m); // convert exponent and mantissa to Word16 Q10 log_en = shl(log_en_e, 10); // Q10 log_en = add(log_en, shr(log_en_m, 15-10));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -