📄 dtx_dec.cpp
字号:
// 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); if (sub(st->log_en_hist_ptr, DTX_HIST_SIZE) == 0) { st->log_en_hist_ptr = 0; } st->log_en_hist[st->log_en_hist_ptr] = log_en; // Q11}------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name]------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function]------------------------------------------------------------------------------*/void dtx_dec_activity_update(dtx_decState *st, Word16 lsf[], Word16 frame[], Flag *pOverflow){ Word16 i; Word32 L_frame_en; Word32 L_temp; Word16 log_en_e; Word16 log_en_m; Word16 log_en; /* update lsp history */ st->lsf_hist_ptr += M; if (st->lsf_hist_ptr == 80) { 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 = L_FRAME - 1; i >= 0; i--) { L_temp = ((Word32) frame[i]) * frame[i]; if (L_temp != (Word32) 0x40000000L) { L_temp = L_temp << 1; } else { L_temp = MAX_32; } L_frame_en = L_add(L_frame_en, L_temp, pOverflow); } Log2(L_frame_en, &log_en_e, &log_en_m, pOverflow); /* convert exponent and mantissa to Word16 Q10 */ L_temp = ((Word32) log_en_e) << 10; if (L_temp != (Word32)((Word16) L_temp)) { *pOverflow = 1; L_temp = (Word32)((log_en_e > 0) ? MAX_16 : MIN_16); } log_en_e = (Word16) L_temp; if (log_en_m < 0) { log_en_m = ~((~log_en_m) >> 5); } else { log_en_m >>= 5; } log_en = add(log_en_e, log_en_m, pOverflow); /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */ log_en = sub(log_en, 7497 + 1024, pOverflow); /* insert into log energy buffer, no division by two as * * log_en in decoder is Q11 */ st->log_en_hist_ptr += 1; if (st->log_en_hist_ptr == DTX_HIST_SIZE) { st->log_en_hist_ptr = 0; } st->log_en_hist[st->log_en_hist_ptr] = log_en; /* Q11 */ return;}/****************************************************************************//*------------------------------------------------------------------------------ FUNCTION NAME: rx_dtx_handler------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: st = pointer to a structure of type dtx_decState frame_type = RX frame type Returns: newState = variable of type DTXStateType Outputs: st points to an updated structure of type dtx_decState Global Variables Used: None. Local Variables Needed: None.------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function determines the new state of the decoder based on the frame_type and sets up the decoder parameters according to newState. 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_PR_BAD, | | | 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.)| | ---------------------------------------------------------------------------------------------------------------------------------------------- REQUIREMENTS None------------------------------------------------------------------------------ REFERENCES dtx_dec.c, UMTS GSM AMR speech codec, R99 - Version 3.3.0, December 12, 2001------------------------------------------------------------------------------ PSEUDO-CODEenum 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) 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; // stay in mute for these input types 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; } // 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); // 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 if((sub(frame_type, RX_SID_UPDATE) != 0) && (sub(st->since_last_sid, DTX_MAX_EMPTY_THRESH) > 0)) { newState = DTX_MUTE; } } else { newState = SPEECH; st->since_last_sid = 0; } // 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. if ((st->data_updated == 0) && (sub(frame_type, RX_SID_UPDATE) == 0)) { st->decAnaElapsedCount = 0; } // update the SPE-SPD DTX hangover synchronization // to know when SPE has added dtx hangover st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1); st->dtxHangoverAdded = 0; 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; // 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. if((sub(frame_type, RX_NO_DATA) == 0) && (sub(newState, SPEECH) == 0)) { encState = SPEECH; } // 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; } if (sub(encState, SPEECH) == 0) { st->dtxHangoverCount = DTX_HANG_CONST; } else { if (sub(st->decAnaElapsedCount, DTX_ELAPSED_FRAMES_THRESH) > 0) { st->dtxHangoverAdded = 1; st->decAnaElapsedCount = 0; st->dtxHangoverCount = 0; } else if (st->dtxHangoverCount == 0) { st->decAnaElapsedCount = 0; } else { st->dtxHangoverCount = sub(st->dtxHangoverCount, 1); } } 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; st->valid_data = 0; if (sub(frame_type, RX_SID_FIRST) == 0) { st->sid_frame = 1; } else if (sub(frame_type, RX_SID_UPDATE) == 0) { st->sid_frame = 1; st->valid_data = 1; } else if (sub(frame_type, RX_SID_BAD) == 0) { st->sid_frame = 1; st->dtxHangoverAdded = 0; // use old data } } return newState; // newState is used by both SPEECH AND DTX synthesis routines}------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name]------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function]------------------------------------------------------------------------------*/enum DTXStateType rx_dtx_handler( dtx_decState *st, /* i/o : State struct */ enum RXFrameType frame_type,/* i : Frame type */ Flag *pOverflow){ enum DTXStateType newState; enum DTXStateType encState; /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */ if ((frame_type == RX_SID_FIRST) || (frame_type == RX_SID_UPDATE) || (frame_type == RX_SID_BAD) || (((st->dtxGlobalState == DTX) || (st->dtxGlobalState == DTX_MUTE)) && ((frame_type == RX_NO_DATA) || (frame_type == RX_SPEECH_BAD) || (frame_type == RX_ONSET)))) { newState = DTX; /* stay in mute for these input types */ if ((st->dtxGlobalState == DTX_MUTE) && ((frame_type == RX_SID_BAD) || (frame_type == RX_SID_FIRST) || (frame_type == RX_ONSET) || (frame_type == RX_NO_DATA))) { newState = DTX_MUTE; } /* 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, pOverflow); /* 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 */ if ((frame_type != RX_SID_UPDATE) && (st->since_last_sid > DTX_MAX_EMPTY_THRESH)) { newState = DTX_MUTE; } } else { newState = SPEECH; st->since_last_sid = 0; } /* 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. */ if ((st->data_updated == 0) && (frame_type == RX_SID_UPDATE)) { st->decAnaElapsedCount = 0; } /* update the SPE-SPD DTX hangover synchronization */ /* to know when SPE has added dtx hangover */ st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1, pOverflow); st->dtxHangoverAdded = 0; if ((frame_type == RX_SID_FIRST) || (frame_type == RX_SID_UPDATE) || (frame_type == RX_SID_BAD) || (frame_type == RX_ONSET) || (frame_type == RX_NO_DATA)) { encState = DTX; /* 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. */ if ((frame_type == RX_NO_DATA) && (newState == SPEECH)) { encState = SPEECH; } /* 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; } if (encState == SPEECH) { st->dtxHangoverCount = DTX_HANG_CONST; } else { if (st->decAnaElapsedCount > DTX_ELAPSED_FRAMES_THRESH) { st->dtxHangoverAdded = 1; st->decAnaElapsedCount = 0; st->dtxHangoverCount = 0; } else if (st->dtxHangoverCount == 0) { st->decAnaElapsedCount = 0; } else { st->dtxHangoverCount -= 1; } } if (newState != SPEECH) { /* 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; st->valid_data = 0; if (frame_type == RX_SID_FIRST) { st->sid_frame = 1; } else if (frame_type == RX_SID_UPDATE) { st->sid_frame = 1; st->valid_data = 1; } else if (frame_type == RX_SID_BAD) { st->sid_frame = 1; st->dtxHangoverAdded = 0; /* use old data */ } } /* newState is used by both SPEECH AND DTX synthesis routines */ return(newState);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -