📄 dtx_dec.c
字号:
L_shl(L_deposit_l(st->log_en_adjust), 5)); move32(); log_en_int_e = extract_h(L_log_en_int); move16(); move16(); log_en_int_m = extract_l(L_shr(L_sub(L_log_en_int, L_deposit_h(log_en_int_e)), 1)); level = extract_l(Pow2(log_en_int_e, log_en_int_m)); /* Q4 */ move16(); for (i = 0; i < 4; i++) { /* Compute innovation vector */ build_CN_code(&st->L_pn_seed_rx, ex); for (j = 0; j < L_SUBFR; j++) { ex[j] = mult(level, ex[j]); move16(); } /* Synthesize */ Syn_filt(acoeff_variab, ex, &synth[i * L_SUBFR], L_SUBFR, mem_syn, 1); } /* next i */ /* reset codebook averaging variables */ averState->hangVar = 20; move16(); averState->hangCount = 0; move16(); test(); if (sub(new_state, DTX_MUTE) == 0) { /* mute comfort noise as it has been quite a long time since * last SID update was performed */ tmp_int_length = st->since_last_sid; move16(); test(); if (sub(tmp_int_length, 32) > 0) { tmp_int_length = 32; move16(); } /* safety guard against division by zero */ test(); if(tmp_int_length <= 0) { tmp_int_length = 8; move16(); } move16(); st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10)); st->since_last_sid = 0; move16(); Copy(st->lsp, st->lsp_old, M); st->old_log_en = st->log_en; move16(); /* subtract 1/8 in Q11 i.e -6/8 dB */ st->log_en = sub(st->log_en, 256); move16(); } /* reset interpolation length timer * if data has been updated. */ test(); test(); test(); test(); if ((st->sid_frame != 0) && ((st->valid_data != 0) || ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0))) { st->since_last_sid = 0; move16(); st->data_updated = 1; move16(); } return 0;}void 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); move16(); test(); if (sub(st->lsf_hist_ptr, 80) == 0) { st->lsf_hist_ptr = 0; move16(); } Copy(lsf, &st->lsf_hist[st->lsf_hist_ptr], M); /* compute log energy based on frame energy */ L_frame_en = 0; /* Q0 */ move32(); 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)); /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */ log_en = sub(log_en, 7497+1024); /* insert into log energy buffer, no division by two as * * log_en in decoder is Q11 */ st->log_en_hist_ptr = add(st->log_en_hist_ptr, 1); test(); if (sub(st->log_en_hist_ptr, DTX_HIST_SIZE) == 0) { st->log_en_hist_ptr = 0; move16(); } st->log_en_hist[st->log_en_hist_ptr] = log_en; /* Q11 */ move16();}/* Table of new SPD synthesis states | previous SPD_synthesis_state Incoming | frame_type | SPEECH | DTX | DTX_MUTE --------------------------------------------------------------- RX_SPEECH_GOOD , | | | RX_SPEECH_PR_DEGRADED | SPEECH | SPEECH | SPEECH ---------------------------------------------------------------- RX_SPEECH_BAD, | SPEECH | DTX | DTX_MUTE ---------------------------------------------------------------- RX_SID_FIRST, | DTX | DTX/(DTX_MUTE)| DTX_MUTE ---------------------------------------------------------------- RX_SID_UPDATE, | DTX | DTX | DTX ---------------------------------------------------------------- RX_SID_BAD, | DTX | DTX/(DTX_MUTE)| DTX_MUTE ---------------------------------------------------------------- RX_NO_DATA | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE |(class2 garb.)| | ---------------------------------------------------------------- RX_ONSET | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE |(class2 garb.)| | ----------------------------------------------------------------*/enum DTXStateType rx_dtx_handler( dtx_decState *st, /* i/o : State struct */ enum RXFrameType frame_type /* i : Frame type */ ){ enum DTXStateType newState; enum DTXStateType encState; /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */ test(); test(); test(); test(); test(); test(); test(); test(); if ((sub(frame_type, RX_SID_FIRST) == 0) || (sub(frame_type, RX_SID_UPDATE) == 0) || (sub(frame_type, RX_SID_BAD) == 0) || (((sub(st->dtxGlobalState, DTX) == 0) || (sub(st->dtxGlobalState, DTX_MUTE) == 0)) && ((sub(frame_type, RX_NO_DATA) == 0) || (sub(frame_type, RX_SPEECH_BAD) == 0) || (sub(frame_type, RX_ONSET) == 0)))) { newState = DTX; move16(); /* stay in mute for these input types */ test(); test(); test(); test(); test(); if ((sub(st->dtxGlobalState, DTX_MUTE) == 0) && ((sub(frame_type, RX_SID_BAD) == 0) || (sub(frame_type, RX_SID_FIRST) == 0) || (sub(frame_type, RX_ONSET) == 0) || (sub(frame_type, RX_NO_DATA) == 0))) { newState = DTX_MUTE; move16(); } /* evaluate if noise parameters are too old */ /* since_last_sid is reset when CN parameters have been updated */ st->since_last_sid = add(st->since_last_sid, 1); move16(); /* no update of sid parameters in DTX for a long while */ /* Due to the delayed update of st->since_last_sid counter SID_UPDATE frames need to be handled separately to avoid entering DTX_MUTE for late SID_UPDATE frames */ test(); test(); logic16(); if((sub(frame_type, RX_SID_UPDATE) != 0) && (sub(st->since_last_sid, DTX_MAX_EMPTY_THRESH) > 0)) { newState = DTX_MUTE; move16(); } } else { newState = SPEECH; move16(); st->since_last_sid = 0; move16(); } /* reset the decAnaElapsed Counter when receiving CNI data the first time, to robustify counter missmatch after handover this might delay the bwd CNI analysis in the new decoder slightly. */ test(); test(); if ((st->data_updated == 0) && (sub(frame_type, RX_SID_UPDATE) == 0)) { st->decAnaElapsedCount = 0; move16(); } /* update the SPE-SPD DTX hangover synchronization */ /* to know when SPE has added dtx hangover */ st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1); move16(); st->dtxHangoverAdded = 0; move16(); test(); test(); test(); test(); test(); if ((sub(frame_type, RX_SID_FIRST) == 0) || (sub(frame_type, RX_SID_UPDATE) == 0) || (sub(frame_type, RX_SID_BAD) == 0) || (sub(frame_type, RX_ONSET) == 0) || (sub(frame_type, RX_NO_DATA) == 0)) { encState = DTX; move16(); /* In frame errors simulations RX_NO_DATA may occasionally mean that a speech packet was probably sent by the encoder, the assumed _encoder_ state should be SPEECH in such cases. */ test(); logic16(); if((sub(frame_type, RX_NO_DATA) == 0) && (sub(newState, SPEECH) == 0)) { encState = SPEECH; move16(); } /* Note on RX_ONSET operation differing from RX_NO_DATA operation: If a RX_ONSET is received in the decoder (by "accident") it is still most likely that the encoder state for the "ONSET frame" was DTX. */ } else { encState = SPEECH; move16(); } test(); if (sub(encState, SPEECH) == 0) { st->dtxHangoverCount = DTX_HANG_CONST; move16(); } else { test(); if (sub(st->decAnaElapsedCount, DTX_ELAPSED_FRAMES_THRESH) > 0) { st->dtxHangoverAdded = 1; move16(); st->decAnaElapsedCount = 0; move16(); st->dtxHangoverCount = 0; move16(); } else if (test(), st->dtxHangoverCount == 0) { st->decAnaElapsedCount = 0; move16(); } else { st->dtxHangoverCount = sub(st->dtxHangoverCount, 1); move16(); } } if (sub(newState, SPEECH) != 0) { /* DTX or DTX_MUTE * CN data is not in a first SID, first SIDs are marked as SID_BAD * but will do backwards analysis if a hangover period has been added * according to the state machine above */ st->sid_frame = 0; move16(); st->valid_data = 0; move16(); test(); if (sub(frame_type, RX_SID_FIRST) == 0) { st->sid_frame = 1; move16(); } else if (test(), sub(frame_type, RX_SID_UPDATE) == 0) { st->sid_frame = 1; move16(); st->valid_data = 1; move16(); } else if (test(), sub(frame_type, RX_SID_BAD) == 0) { st->sid_frame = 1; move16(); st->dtxHangoverAdded = 0; /* use old data */ move16(); } } return newState; /* newState is used by both SPEECH AND DTX synthesis routines */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -