📄 sp_dec.c
字号:
/*
* ===================================================================
* TS 26.104
* R99 V3.3.0 2001-09
* REL-4 V4.2.0 2001-09
* 3GPP AMR Floating-point Speech Codec
* ===================================================================
*
*/
/***************************************************************************************
* sp_dec.c
*
*
* Project:
* AMR Floating-Point Codec
*
* Contains:
* This module contains all the functions needed decoding AMR
* encoder parameters to 16-bit speech samples
*
**************************************************************************************/
/** include files*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include "sp_dec.h"
#include "rom_dec.h"
enum DTXStateType
{
SPEECH = 0, DTX, DTX_MUTE
};
typedef struct
{
/* history vector of past synthesis speech energy */
Word32 frameEnergyHist[L_ENERGYHIST];
/* state flags */
Word16 bgHangover; /* counter; number of frames after last speech frame */
}Bgn_scdState;
typedef struct
{
Word32 hangCount; /* counter; */
/* history vector of past synthesis speech energy */
Word32 cbGainHistory[L_CBGAINHIST];
Word16 hangVar; /* counter; */
}Cb_gain_averageState;
typedef struct
{
Word32 lsp_meanSave[M]; /* Averaged LSPs saved for efficiency */
}lsp_avgState;
typedef struct
{
Word32 past_r_q[M]; /* Past quantized prediction error, Q15 */
Word32 past_lsf_q[M]; /* Past dequantized lsfs, Q15 */
}D_plsfState;
typedef struct
{
Word32 pbuf[5];
Word32 past_gain_pit;
Word32 prev_gp;
}ec_gain_pitchState;
typedef struct
{
Word32 gbuf[5];
Word32 past_gain_code;
Word32 prev_gc;
}ec_gain_codeState;
typedef struct
{
/*
* normal MA predictor memory, Q10
* (contains 20*log10(quaErr))
*/
Word32 past_qua_en[4];
/*
* MA predictor memory for MR122 mode, Q10
* (contains log2(quaErr))
*/
Word32 past_qua_en_MR122[4];
}gc_predState;
typedef struct
{
Word32 gainMem[PHDGAINMEMSIZE];
Word32 prevCbGain;
Word32 prevState;
Word16 lockFull;
Word16 onset;
}ph_dispState;
typedef struct
{
enum DTXStateType dtxGlobalState; /* contains previous state */
Word32 log_en;
Word32 old_log_en;
Word32 pn_seed_rx;
Word32 lsp[M];
Word32 lsp_old[M];
Word32 lsf_hist[M * DTX_HIST_SIZE];
Word32 lsf_hist_mean[M * DTX_HIST_SIZE];
Word32 log_en_hist[DTX_HIST_SIZE];
Word32 true_sid_period_inv;
Word16 since_last_sid;
Word16 lsf_hist_ptr;
Word16 log_pg_mean;
Word16 log_en_hist_ptr;
Word16 log_en_adjust;
Word16 dtxHangoverCount;
Word16 decAnaElapsedCount;
Word16 sid_frame;
Word16 valid_data;
Word16 dtxHangoverAdded;
/* updated in main decoder */
Word16 data_updated; /* marker to know if CNI data is ever renewed */
}dtx_decState;
typedef struct
{
Word32 past_gain;
}agcState;
typedef struct
{
/* Excitation vector */
Word32 old_exc[L_SUBFR + PIT_MAX + L_INTERPOL];
Word32 *exc;
Word32 lsp_old[M];
/* Filter's memory */
Word32 mem_syn[M];
/* pitch sharpening */
Word32 sharp;
Word32 old_T0;
/* Variable holding received ltpLag, used in background noise and BFI */
Word32 T0_lagBuff;
/* Variables for the source characteristic detector (SCD) */
Word32 inBackgroundNoise;
Word32 voicedHangover;
Word32 ltpGainHistory[9];
/* Memories for bad frame handling */
Word32 excEnergyHist[9];
Word16 prev_bf;
Word16 prev_pdf;
Word16 state;
Word16 nodataSeed;
Bgn_scdState * background_state;
Cb_gain_averageState * Cb_gain_averState;
lsp_avgState * lsp_avg_st;
D_plsfState * lsfState;
ec_gain_pitchState * ec_gain_p_st;
ec_gain_codeState * ec_gain_c_st;
gc_predState * pred_state;
ph_dispState * ph_disp_st;
dtx_decState * dtxDecoderState;
}Decoder_amrState;
typedef struct
{
Word32 res2[L_SUBFR];
Word32 mem_syn_pst[M];
Word32 synth_buf[M + L_FRAME];
Word32 preemph_state_mem_pre;
agcState * agc_state;
}Post_FilterState;
typedef struct
{
Word32 y2_hi;
Word32 y2_lo;
Word32 y1_hi;
Word32 y1_lo;
Word32 x0;
Word32 x1;
}Post_ProcessState;
typedef struct
{
Decoder_amrState * decoder_amrState;
Post_FilterState * post_state;
Post_ProcessState * postHP_state;
}Speech_Decode_FrameState;
/*************************************************************************************
* Decoder_amr_reset
*
*
* Parameters:
* state B: state structure
* mode I: AMR mode
*
* Function:
* Resets state memory
*
* Returns:
* void
***************************************************************************************/
static void Decoder_amr_reset( Decoder_amrState *state, enum Mode mode )
{
Word32 i;
/* Cb_gain_average_reset */
memset(state->Cb_gain_averState->cbGainHistory, 0, L_CBGAINHIST << 2);
state->Cb_gain_averState->hangVar = 0;
state->Cb_gain_averState->hangCount= 0;
/* Initialize static pointer */
state->exc = state->old_exc + PIT_MAX + L_INTERPOL;
/* Static vectors to zero */
memset( state->old_exc, 0, ( PIT_MAX + L_INTERPOL )<<2 );
if ( mode != MRDTX )
memset( state->mem_syn, 0, M <<2 );
/* initialize pitch sharpening */
state->sharp = SHARPMIN;
state->old_T0 = 40;
/* Initialize state->lsp_old [] */
if ( mode != MRDTX )
{
state->lsp_old[0] = 30000;
state->lsp_old[1] = 26000;
state->lsp_old[2] = 21000;
state->lsp_old[3] = 15000;
state->lsp_old[4] = 8000;
state->lsp_old[5] = 0;
state->lsp_old[6] = -8000;
state->lsp_old[7] = -15000;
state->lsp_old[8] = -21000;
state->lsp_old[9] = -26000;
}
/* Initialize memories of bad frame handling */
state->prev_bf = 0;
state->prev_pdf = 0;
state->state = 0;
state->T0_lagBuff = 40;
state->inBackgroundNoise = 0;
state->voicedHangover = 0;
if ( mode != MRDTX )
memset( state->excEnergyHist, 0, 9 <<2 );
memset( state->ltpGainHistory, 0, 9 <<2 );
if ( mode != MRDTX )
{
state->lsp_avg_st->lsp_meanSave[0] = 1384;
state->lsp_avg_st->lsp_meanSave[1] = 2077;
state->lsp_avg_st->lsp_meanSave[2] = 3420;
state->lsp_avg_st->lsp_meanSave[3] = 5108;
state->lsp_avg_st->lsp_meanSave[4] = 6742;
state->lsp_avg_st->lsp_meanSave[5] = 8122;
state->lsp_avg_st->lsp_meanSave[6] = 9863;
state->lsp_avg_st->lsp_meanSave[7] = 11092;
state->lsp_avg_st->lsp_meanSave[8] = 12714;
state->lsp_avg_st->lsp_meanSave[9] = 13701;
}
memset( state->lsfState->past_r_q, 0, M <<2 );
/* Past dequantized lsfs */
state->lsfState->past_lsf_q[0] = 1384;
state->lsfState->past_lsf_q[1] = 2077;
state->lsfState->past_lsf_q[2] = 3420;
state->lsfState->past_lsf_q[3] = 5108;
state->lsfState->past_lsf_q[4] = 6742;
state->lsfState->past_lsf_q[5] = 8122;
state->lsfState->past_lsf_q[6] = 9863;
state->lsfState->past_lsf_q[7] = 11092;
state->lsfState->past_lsf_q[8] = 12714;
state->lsfState->past_lsf_q[9] = 13701;
state->ec_gain_p_st->pbuf[0] = 1640;
state->ec_gain_p_st->pbuf[1] = 1640;
state->ec_gain_p_st->pbuf[2] = 1640;
state->ec_gain_p_st->pbuf[3] = 1640;
state->ec_gain_p_st->pbuf[4] = 1640;
state->ec_gain_p_st->past_gain_pit = 0;
state->ec_gain_p_st->prev_gp = 16384;
state->ec_gain_c_st->gbuf[0] = 1;
state->ec_gain_c_st->gbuf[1] = 1;
state->ec_gain_c_st->gbuf[2] = 1;
state->ec_gain_c_st->gbuf[3] = 1;
state->ec_gain_c_st->gbuf[4] = 1;
state->ec_gain_c_st->past_gain_code = 0;
state->ec_gain_c_st->prev_gc = 1;
if ( mode != MRDTX )
{
for ( i = 0; i < NPRED; i++ )
{
state->pred_state->past_qua_en[i] = MIN_ENERGY;
state->pred_state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
}
}
state->nodataSeed = 21845;
/* Static vectors to zero */
memset( state->background_state->frameEnergyHist, 0, L_ENERGYHIST <<2 );
/* Initialize hangover handling */
state->background_state->bgHangover = 0;
/* phDispReset */
memset( state->ph_disp_st->gainMem, 0, PHDGAINMEMSIZE <<2 );
state->ph_disp_st->prevState = 0;
state->ph_disp_st->prevCbGain = 0;
state->ph_disp_st->lockFull = 0;
state->ph_disp_st->onset = 0; /* assume no onset in start */
if ( mode != MRDTX )
{
state->dtxDecoderState->since_last_sid = 0;
state->dtxDecoderState->true_sid_period_inv = 8192;
state->dtxDecoderState->log_en = 3500;
state->dtxDecoderState->old_log_en = 3500;
/* low level noise for better performance in DTX handover cases*/
state->dtxDecoderState->pn_seed_rx = PN_INITIAL_SEED;
/* Initialize state->lsp [] */
state->dtxDecoderState->lsp[0] = 30000;
state->dtxDecoderState->lsp[1] = 26000;
state->dtxDecoderState->lsp[2] = 21000;
state->dtxDecoderState->lsp[3] = 15000;
state->dtxDecoderState->lsp[4] = 8000;
state->dtxDecoderState->lsp[5] = 0;
state->dtxDecoderState->lsp[6] = -8000;
state->dtxDecoderState->lsp[7] = -15000;
state->dtxDecoderState->lsp[8] = -21000;
state->dtxDecoderState->lsp[9] = -26000;
/* Initialize state->lsp_old [] */
state->dtxDecoderState->lsp_old[0] = 30000;
state->dtxDecoderState->lsp_old[1] = 26000;
state->dtxDecoderState->lsp_old[2] = 21000;
state->dtxDecoderState->lsp_old[3] = 15000;
state->dtxDecoderState->lsp_old[4] = 8000;
state->dtxDecoderState->lsp_old[5] = 0;
state->dtxDecoderState->lsp_old[6] = -8000;
state->dtxDecoderState->lsp_old[7] = -15000;
state->dtxDecoderState->lsp_old[8] = -21000;
state->dtxDecoderState->lsp_old[9] = -26000;
state->dtxDecoderState->lsf_hist_ptr = 0;
state->dtxDecoderState->log_pg_mean = 0;
state->dtxDecoderState->log_en_hist_ptr = 0;
/* initialize decoder lsf history */
state->dtxDecoderState->lsf_hist[0] = 1384;
state->dtxDecoderState->lsf_hist[1] = 2077;
state->dtxDecoderState->lsf_hist[2] = 3420;
state->dtxDecoderState->lsf_hist[3] = 5108;
state->dtxDecoderState->lsf_hist[4] = 6742;
state->dtxDecoderState->lsf_hist[5] = 8122;
state->dtxDecoderState->lsf_hist[6] = 9863;
state->dtxDecoderState->lsf_hist[7] = 11092;
state->dtxDecoderState->lsf_hist[8] = 12714;
state->dtxDecoderState->lsf_hist[9] = 13701;
for ( i = 1; i < DTX_HIST_SIZE; i++ )
{
memcpy( &state->dtxDecoderState->lsf_hist[M * i], &state->
dtxDecoderState->lsf_hist[0], M <<2 );
}
memset( state->dtxDecoderState->lsf_hist_mean, 0, M * DTX_HIST_SIZE <<2 );
/* initialize decoder log frame energy */
for ( i = 0; i < DTX_HIST_SIZE; i++ )
{
state->dtxDecoderState->log_en_hist[i] = state->dtxDecoderState->log_en;
}
state->dtxDecoderState->log_en_adjust = 0;
state->dtxDecoderState->dtxHangoverCount = DTX_HANG_CONST;
state->dtxDecoderState->decAnaElapsedCount = 31;
state->dtxDecoderState->sid_frame = 0;
state->dtxDecoderState->valid_data = 0;
state->dtxDecoderState->dtxHangoverAdded = 0;
state->dtxDecoderState->dtxGlobalState = DTX;
state->dtxDecoderState->data_updated = 0;
}
return;
}
/************************************************************************************
* Function: rx_dtx_handler
*
*
*input Parameters:
* st->dtxGlobalState DTX state
* st->since_last_sid Frames after last SID frame
* st->data_updated SID update flag
* st->decAnaElapsedCount state machine that synch with the GSMEFR txDtx machine
* st->dtxHangoverAdded DTX hangover
*out Parameters:
* st->sid_frame SID frame indicator
* st->valid_data Vaild data indicator
* frame_type Frame type
*
* description:
* Find the new DTX state
*
* Returns:
* DTXStateType DTX, DTX_MUTE or SPEECH
*************************************************************************************/
static enum DTXStateType rx_dtx_handler( dtx_decState *st, enum RXFrameType frame_type )
{
enum DTXStateType newState;
enum DTXStateType encState;
/* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */
if ( table_SID[frame_type] | ( ( st->dtxGlobalState != SPEECH ) &
table_speech_bad[frame_type] ) )
{
newState = DTX;
/* stay in mute for these input types */
if ( ( st->dtxGlobalState == DTX_MUTE ) & table_mute[frame_type] )
{
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 += 1;
/* no update of sid parameters in DTX for a long while */
if ( 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 += 1;
st->dtxHangoverAdded = 0;
encState = SPEECH;
if ( table_DTX[frame_type] )
{
encState = DTX;
}
if ( encState == SPEECH )
{
st->dtxHangoverCount = DTX_HANG_CONST;
}
else
{
if ( st->decAnaElapsedCount > DTX_ELAPSED_FRAMES_THRESH )
{
st->dtxHangoverAdded = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -