sp_dec.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:157k
- /*
- * ===================================================================
- * TS 26.104
- * R99 V3.4.0 2002-02
- * REL-4 V4.3.0 2002-02
- * 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 "hlxclib/stdio.h"
- #include "hlxclib/stdlib.h"
- #include "hlxclib/memory.h"
- #include "hlxclib/math.h"
- #include "sp_dec.h"
- #include "rom_dec.h"
- /*
- * Declare structure types
- */
- enum DTXStateType
- {
- SPEECH = 0, DTX, DTX_MUTE
- };
- /*
- * Decoder memory structure
- */
- 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;
- /*
- * CodAmrReset
- *
- *
- * 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;
- for ( i = 0; i < 5; i++ )
- state->ec_gain_p_st->pbuf[i] = 1640;
- state->ec_gain_p_st->past_gain_pit = 0;
- state->ec_gain_p_st->prev_gp = 16384;
- for ( i = 0; i < 5; i++ )
- state->ec_gain_c_st->gbuf[i] = 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;
- }
- /*
- * rx_dtx_handler
- *
- *
- * Parameters:
- * st->dtxGlobalState I: DTX state
- * st->since_last_sid B: Frames after last SID frame
- * st->data_updated I: SID update flag
- * st->decAnaElapsedCount B: state machine that synch with the GSMEFR txDtx machine
- * st->dtxHangoverAdded B: DTX hangover
- * st->sid_frame O: SID frame indicator
- * st->valid_data O: Vaild data indicator
- * frame_type O: Frame type
- *
- * Function:
- * 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 ((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 += 1;
- st->dtxHangoverAdded = 0;
- encState = SPEECH;
- if ( table_DTX[frame_type] ) {
- encState = DTX;
- if( ( frame_type == RX_NO_DATA ) & ( newState == SPEECH ) ) {
- 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;
- /* use old data */
- st->dtxHangoverAdded = 0;
- }
- }
- /* newState is used by both SPEECH AND DTX synthesis routines */
- return newState;
- }
- /*
- * Lsf_lsp
- *
- *
- * Parameters:
- * lsf I: vector of LSFs
- * lsp O: vector of LSPs
- *
- * Function:
- * Transformation lsf to lsp, order M
- *
- * Returns:
- * void
- */
- static void Lsf_lsp( Word32 lsf[], Word32 lsp[] )
- {
- Word32 i, ind, offset, tmp;
- for ( i = 0; i < M; i++ ) {
- /* ind = b8-b15 of lsf[i] */
- ind = lsf[i] >> 8;
- /* offset = b0-b7 of lsf[i] */
- offset = lsf[i] & 0x00ff;
- /* lsp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 256 */
- tmp = ( ( cos_table[ind+1]-cos_table[ind] )*offset ) << 1;
- lsp[i] = cos_table[ind] + ( tmp >> 9 );
- }
- return;
- }
- /*
- * D_plsf_3
- *
- *
- * Parameters:
- * st->past_lsf_q I: Past dequantized LFSs
- * st->past_r_q B: past quantized residual
- * mode I: AMR mode
- * bfi B: bad frame indicator
- * indice I: quantization indices of 3 submatrices, Q0
- * lsp1_q O: quantized 1st LSP vector
- *
- * Function:
- * Decodes the LSP parameters using the received quantization indices.
- * 1st order MA prediction and split by 3 vector quantization (split-VQ)
- *
- * Returns:
- * void
- */
- static void D_plsf_3( D_plsfState *st, enum Mode mode, Word16 bfi, Word16 *
- indice, Word32 *lsp1_q )
- {
- Word32 lsf1_r[M], lsf1_q[M];
- Word32 i, index, temp;
- const Word32 *p_cb1, *p_cb2, *p_cb3, *p_dico;
- /* if bad frame */
- if ( bfi != 0 ) {
- /* use the past LSFs slightly shifted towards their mean */
- for ( i = 0; i < M; i++ ) {
- /* lsfi_q[i] = ALPHA*past_lsf_q[i] + ONE_ALPHA*meanLsf[i]; */
- lsf1_q[i] = ( ( st->past_lsf_q[i] * ALPHA ) >> 15 ) + ( ( mean_lsf_3[i]
- * ONE_ALPHA ) >> 15 );
- }
- /* estimate past quantized residual to be used in next frame */
- if ( mode != MRDTX ) {
- for ( i = 0; i < M; i++ ) {
- /* temp = meanLsf[i] + pastR2_q[i] * pred_fac; */
- temp = mean_lsf_3[i] + ( ( st->past_r_q[i] * pred_fac[i] ) >> 15 );
- st->past_r_q[i] = lsf1_q[i] - temp;
- }
- }
- else {
- for ( i = 0; i < M; i++ ) {
- /* temp = meanLsf[i] + pastR2_q[i]; */
- temp = mean_lsf_3[i] + st->past_r_q[i];
- st->past_r_q[i] = lsf1_q[i] - temp;
- }
- }
- }
- /* if good LSFs received */
- else {
- if ( ( mode == MR475 ) | ( mode == MR515 ) ) {
- /* MR475, MR515 */
- p_cb1 = dico1_lsf_3;
- p_cb2 = dico2_lsf_3;
- p_cb3 = mr515_3_lsf;
- }
- else if ( mode == MR795 ) {
- /* MR795 */
- p_cb1 = mr795_1_lsf;
- p_cb2 = dico2_lsf_3;
- p_cb3 = dico3_lsf_3;
- }
- else {
- /* MR59, MR67, MR74, MR102, MRDTX */
- p_cb1 = dico1_lsf_3;
- p_cb2 = dico2_lsf_3;
- p_cb3 = dico3_lsf_3;
- }
- /* decode prediction residuals from 3 received indices */
- index = *indice++;
- p_dico = &p_cb1[index + index + index];
- index = *indice++;
- lsf1_r[0] = *p_dico++;
- lsf1_r[1] = *p_dico++;
- lsf1_r[2] = *p_dico++;
- if ( ( mode == MR475 ) | ( mode == MR515 ) ) {
- /* MR475, MR515 only using every second entry */
- index = index << 1;
- }
- p_dico = &p_cb2[index + index + index];
- index = *indice++;
- lsf1_r[3] = *p_dico++;
- lsf1_r[4] = *p_dico++;
- lsf1_r[5] = *p_dico++;
- p_dico = &p_cb3[index << 2];
- lsf1_r[6] = *p_dico++;
- lsf1_r[7] = *p_dico++;
- lsf1_r[8] = *p_dico++;
- lsf1_r[9] = *p_dico++;
- /* Compute quantized LSFs and update the past quantized residual */
- if ( mode != MRDTX ) {
- for ( i = 0; i < M; i++ ) {
- lsf1_q[i] = lsf1_r[i] + ( mean_lsf_3[i] + ( ( st->past_r_q[i] *
- pred_fac[i] ) >> 15 ) );
- }
- memcpy( st->past_r_q, lsf1_r, M <<2 );
- }
- else {
- for ( i = 0; i < M; i++ ) {
- lsf1_q[i] = lsf1_r[i] + ( mean_lsf_3[i] + st->past_r_q[i] );
- }
- memcpy( st->past_r_q, lsf1_r, M <<2 );
- }
- }
- /* verification that LSFs has minimum distance of LSF_GAP Hz */
- temp = LSF_GAP;
- for ( i = 0; i < M; i++ ) {
- if ( lsf1_q[i] < temp ) {
- lsf1_q[i] = temp;
- }
- temp = lsf1_q[i] + LSF_GAP;
- }
- memcpy( st->past_lsf_q, lsf1_q, M <<2 );
- /* convert LSFs to the cosine domain */
- Lsf_lsp( lsf1_q, lsp1_q );
- return;
- }
- /*
- * pseudonoise
- *
- *
- * Parameters:
- * shift_reg B: Old CN generator shift register state
- * no_bits I: Number of bits
- *
- * Function:
- * pseudonoise
- *
- * Returns:
- * noise_bits
- */
- static Word32 pseudonoise( Word32 *shift_reg, Word32 no_bits )
- {
- Word32 noise_bits, Sn, i;
- Word32 s_reg;
- s_reg = *shift_reg;
- noise_bits = 0;
- for ( i = 0; i < no_bits; i++ ) {
- /* State n == 31 */
- Sn = s_reg & 0x00000001L;
- /* State n == 3 */
- if ( s_reg & 0x10000000L ) {
- Sn = Sn ^ 0x1L;
- }
- else {
- Sn = Sn ^ 0x0L;
- }
- noise_bits = ( noise_bits << 1 ) | ( s_reg & 1 );
- s_reg = s_reg >> 1;
- if ( Sn & 1 ) {
- s_reg = s_reg | 0x40000000L;
- }
- }
- *shift_reg = s_reg;
- return noise_bits;
- }
- /*
- * Lsp_lsf
- *
- *
- * Parameters:
- * lsp I: LSP vector (range: -1<=val<1)
- * lsf O: LSF vector Old CN generator shift register state
- *
- * Function:
- * Transformation lsp to lsf, LPC order M
- * lsf[i] = arccos(lsp[i])/(2*pi)
- *
- * Returns:
- * void
- */
- static void Lsp_lsf( Word32 lsp[], Word32 lsf[] )
- {
- Word32 i, ind = 63; /* begin at end of table -1 */
- for ( i = M - 1; i >= 0; i-- ) {
- /* find value in table that is just greater than lsp[i] */
- while ( cos_table[ind] < lsp[i] ) {
- ind--;
- }
- lsf[i] = ( ( ( ( lsp[i] - cos_table[ind] ) * acos_slope[ind] ) + 0x800 )
- >> 12 ) + ( ind << 8 );
- }
- return;
- }
- /*
- * Reorder_lsf
- *
- *
- * Parameters:
- * lsf B: vector of LSFs (range: 0<=val<=0.5)
- * min_dist I: minimum required distance
- *
- * Function:
- * Make sure that the LSFs are properly ordered and to keep a certain minimum
- * distance between adjacent LSFs. LPC order = M.
- *
- * Returns:
- * void
- */
- static void Reorder_lsf( Word32 *lsf, Word32 min_dist )
- {
- Word32 lsf_min, i;
- lsf_min = min_dist;
- for ( i = 0; i < M; i++ ) {
- if ( lsf[i] < lsf_min ) {
- lsf[i] = lsf_min;
- }
- lsf_min = lsf[i] + min_dist;
- }
- }
- /* VC5.0 Global optimization does not work with this function */
- #if _MSC_VER == 1100
- #pragma optimize( "g", off )
- #endif
- /*
- * Get_lsp_pol
- *
- *
- * Parameters:
- * lsp I: line spectral frequencies
- * f O: polynomial F1(z) or F2(z)
- *
- * Function:
- * Find the polynomial F1(z) or F2(z) from the LSPs.
- *
- * F1(z) = product ( 1 - 2 lsp[i] z^-1 + z^-2 )
- * i=0,2,4,6,8
- * F2(z) = product ( 1 - 2 lsp[i] z^-1 + z^-2 )
- * i=1,3,5,7,9
- *
- * where lsp[] is the LSP vector in the cosine domain.
- *
- * The expansion is performed using the following recursion:
- *
- * f[0] = 1
- * b = -2.0 * lsp[0]
- * f[1] = b
- * for i=2 to 5 do
- * b = -2.0 * lsp[2*i-2];
- * f[i] = b*f[i-1] + 2.0*f[i-2];
- * for j=i-1 down to 2 do
- * f[j] = f[j] + b*f[j-1] + f[j-2];
- * f[1] = f[1] + b;
- *
- * Returns:
- * void
- */
- static void Get_lsp_pol( Word32 *lsp, Word32 *f )
- {
- volatile Word32 f0, f1, f2, f3, f4, f5;
- Word32 l1, l2, l3, l4;
- /* f[0] = 1.0; */
- f0 = 16777216L;
- /* f1 = *lsp * -1024; */
- f1 = -lsp[0] << 10;
- l1 = lsp[2];
- l2 = lsp[4];
- l3 = lsp[6];
- l4 = lsp[8];
- f2 = f0 << 1;
- f2 -= ( ( ( f1 >> 16 ) * l1 ) + ( ( ( f1 & 0xFFFE ) * l1 ) >> 16 ) ) << 2;
- f1 -= l1 << 10;
- f3 = f1 << 1;
- f3 -= ( ( ( f2 >> 16 ) * l2 ) + ( ( ( f2 & 0xFFFE ) * l2 ) >> 16 ) ) << 2;
- f2 += f0;
- f2 -= ( ( ( f1 >> 16 ) * l2 ) + ( ( ( f1 & 0xFFFE ) * l2 ) >> 16 ) ) << 2;
- f1 -= l2 << 10;
- f4 = f2 << 1;
- f4 -= ( ( ( f3 >> 16 ) * l3 ) + ( ( ( f3 & 0xFFFE ) * l3 ) >> 16 ) ) << 2;
- f3 += f1;
- f3 -= ( ( ( f2 >> 16 ) * l3 ) + ( ( ( f2 & 0xFFFE ) * l3 ) >> 16 ) ) << 2;
- f2 += f0;
- f2 -= ( ( ( f1 >> 16 ) * l3 ) + ( ( ( f1 & 0xFFFE ) * l3 ) >> 16 ) ) << 2;
- f1 -= l3 << 10;
- f5 = f3 << 1;
- f5 -= ( ( ( f4 >> 16 ) * l4 ) + ( ( ( f4 & 0xFFFE ) * l4 ) >> 16 ) ) << 2;
- f4 += f2;
- f4 -= ( ( ( f3 >> 16 ) * l4 ) + ( ( ( f3 & 0xFFFE ) * l4 ) >> 16 ) ) << 2;
- f3 += f1;
- f3 -= ( ( ( f2 >> 16 ) * l4 ) + ( ( ( f2 & 0xFFFE ) * l4 ) >> 16 ) ) << 2;
- f2 += f0;
- f2 -= ( ( ( f1 >> 16 ) * l4 ) + ( ( ( f1 & 0xFFFE ) * l4 ) >> 16 ) ) << 2;
- f1 -= l4 << 10;
- f[0] = f0;
- f[1] = f1;
- f[2] = f2;
- f[3] = f3;
- f[4] = f4;
- f[5] = f5;
- return;
- }
- #if _MSC_VER == 1100
- #pragma optimize( "", on )
- #endif
- /*
- * Lsp_Az
- *
- *
- * Parameters:
- * lsp I: Line spectral frequencies
- * a O: Predictor coefficients
- *
- * Function:
- * Converts from the line spectral pairs (LSP) to LP coefficients,
- * for a 10th order filter.
- *
- * Find the coefficients of F1(z) and F2(z)
- * Multiply F1(z) by 1+z^{-1} and F2(z) by 1-z^{-1}
- * A(z) = ( F1(z) + F2(z) ) / 2
- *
- * Returns:
- * void
- */
- static void Lsp_Az( Word32 lsp[], Word32 a[] )
- {
- Word32 f1[6], f2[6];
- Word32 T0, i, j;
- Get_lsp_pol( &lsp[0], f1 );
- Get_lsp_pol( &lsp[1], f2 );
- for ( i = 5; i > 0; i-- ) {
- f1[i] += f1[i - 1];
- f2[i] -= f2[i - 1];
- }
- a[0] = 4096;
- for ( i = 1, j = 10; i <= 5; i++, j-- ) {
- T0 = f1[i] + f2[i];
- a[i] = (Word16)(T0 >> 13); /* emulate fixed point bug */
- if ( ( T0 & 4096 ) != 0 ) {
- a[i]++;
- }
- T0 = f1[i] - f2[i];
- a[j] = (Word16)(T0 >> 13); /* emulate fixed point bug */
- if ( ( T0 & 4096 ) != 0 ) {
- a[j]++;
- }
- }
- return;
- }
- /*
- * A_Refl
- *
- *
- * Parameters:
- * a I: Directform coefficients
- * refl O: Reflection coefficients
- *
- * Function:
- * Converts from the directform coefficients to reflection coefficients
- *
- * Returns:
- * void
- */
- static void A_Refl( Word32 a[], Word32 refl[] )
- {
- /* local variables */
- int normShift;
- Word32 aState[M], bState[M];
- Word32 normProd, acc, temp, mult, scale, i, j;
- /* initialize states */
- memcpy( aState, a, M <<2 );
- /* backward Levinson recursion */
- for ( i = M - 1; i >= 0; i-- ) {
- if ( labs( aState[i] ) >= 4096 ) {
- goto ExitRefl;
- }
- refl[i] = aState[i] << 3;
- temp = ( refl[i] * refl[i] ) << 1;
- acc = ( MAX_32 - temp );
- normShift=0;
- if (acc != 0){
- temp = acc;
- while (!(temp & 0x40000000))
- {
- normShift++;
- temp = temp << 1;
- }
- }
- else{
- normShift = 0;
- }
- scale = 15 - normShift;
- acc = ( acc << normShift );
- temp = ( acc + ( Word32 )0x00008000L );
- if ( temp > 0 ) {
- normProd = temp >> 16;
- mult = 0x20000000L / normProd;
- }
- else
- mult = 16384;
- for ( j = 0; j < i; j++ ) {
- acc = aState[j] << 16;
- acc -= ( refl[i] * aState[i - j - 1] ) << 1;
- temp = ( acc + ( Word32 )0x00008000L ) >> 16;
- temp = ( mult * temp ) << 1;
- if ( scale > 0 ) {
- if ( ( temp & ( ( Word32 )1 << ( scale - 1 ) ) ) != 0 ) {
- temp = ( temp >> scale ) + 1;
- }
- else
- temp = ( temp >> scale );
- }
- else
- temp = ( temp >> scale );
- if ( labs( temp ) > 32767 ) {
- goto ExitRefl;
- }
- bState[j] = temp;
- }
- memcpy( aState, bState, i <<2 );
- }
- return;
- ExitRefl:
- memset( refl, 0, M <<2 );
- }
- /*
- * Log2_norm
- *
- *
- * Parameters:
- * x I: input value
- * exp I: exponent
- * exponent O: Integer part of Log2. (range: 0<=val<=30)
- * fraction O: Fractional part of Log2. (range: 0<=val<1)
- *
- * Function:
- * Computes log2
- *
- * Computes log2(L_x, exp), where L_x is positive and
- * normalized, and exp is the normalisation exponent
- * If L_x is negative or zero, the result is 0.
- *
- * The function Log2(L_x) is approximated by a table and linear
- * interpolation. The following steps are used to compute Log2(L_x)
- *
- * exponent = 30-normExponent
- * i = bit25-b31 of L_x; 32<=i<=63 (because of normalization).
- * a = bit10-b24
- * i -=32
- * fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
- *
- * Returns:
- * void
- */
- static void Log2_norm( Word32 x, Word32 exp, Word32 *exponent, Word32 *
- fraction )
- {
- Word32 y, i, a;
- if ( x <= 0 ) {
- *exponent = 0;
- *fraction = 0;
- return;
- }
- /* Extract b25-b31 */
- i = x >> 25;
- i = i - 32;
- /* Extract b10-b24 of fraction */
- a = x >> 9;
- a = a & 0xFFFE; /* 2a */
- /* fraction */
- y = ( log2_table[i] << 16 ) - a * ( log2_table[i] - log2_table[i + 1] );
- *fraction = y >> 16;
- *exponent = 30 - exp;
- return;
- }
- /*
- * Log2
- *
- *
- * Parameters:
- * x I: input value
- * exponent O: Integer part of Log2. (range: 0<=val<=30)
- * fraction O: Fractional part of Log2. (range: 0<=val<1)
- *
- * Function:
- * Computes log2(L_x)
- * If x is negative or zero, the result is 0.
- *
- * Returns:
- * void
- */
- static void Log2( Word32 x, Word32 *exponent, Word32 *fraction )
- {
- int tmp, exp=0;
- if (x != 0){
- tmp = x;
- while (!((tmp & 0x80000000) ^ ((tmp & 0x40000000) << 1)))
- {
- exp++;
- tmp = tmp << 1;
- }
- }
- 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;
- /* (Q14 * Q11 -> Q26) + Q26 -> Q26 */
- log_en_int += ( int_fac * st->old_log_en ) << 1;
- for ( i = 0; i < M; i++ ) {
- /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */
- lsp_int[i] = lsp_int[i] + ( ( int_fac * st->lsp_old[i] ) >> 15 );
- /* Q14 -> Q15 */
- lsp_int[i] = lsp_int[i] << 1;
- }
- /* compute the amount of lsf variability */
- /* -0.6 in Q12 */
- lsf_variab_factor = st->log_pg_mean - 2457;
- /* *0.3 Q12*Q15 -> Q12 */
- lsf_variab_factor = 4096 - ( ( lsf_variab_factor * 9830 ) >> 15 );
- /* limit to values between 0..1 in Q12 */
- if ( lsf_variab_factor >= 4096 ) {
- lsf_variab_factor = 32767;
- }
- else if ( lsf_variab_factor < 0 ) {
- lsf_variab_factor = 0;
- }
- else
- lsf_variab_factor = lsf_variab_factor << 3; /* -> Q15 */
- /* get index of vector to do variability with */
- lsf_variab_index = pseudonoise( &st->pn_seed_rx, 3 );
- /* convert to lsf */
- Lsp_lsf( lsp_int, lsf_int );
- /* apply lsf variability */
- memcpy( lsf_int_variab, lsf_int, M <<2 );
- for ( i = 0; i < M; i++ ) {
- lsf_int_variab[i] = lsf_int_variab[i] + ( ( lsf_variab_factor * st->
- lsf_hist_mean[i + lsf_variab_index * M] ) >> 15 );
- }
- /* make sure that LSP's are ordered */
- Reorder_lsf( lsf_int, LSF_GAP );
- Reorder_lsf( lsf_int_variab, LSF_GAP );
- /* copy lsf to speech decoders lsf state */
- memcpy( lsfState->past_lsf_q, lsf_int, M <<2 );
- /* convert to lsp */
- Lsf_lsp( lsf_int, lsp_int );
- Lsf_lsp( lsf_int_variab, lsp_int_variab );
- /* Compute acoeffs Q12 acoeff is used for level
- * normalization and Post_Filter, 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 );
- Lsp_Az( lsp_int_variab, acoeff_variab );
- /* For use in Post_Filter */
- memcpy( &A_t[0], acoeff, MP1 <<2 );
- memcpy( &A_t[MP1], acoeff, MP1 <<2 );
- memcpy( &A_t[MP1 <<1], acoeff, MP1 <<2 );
- memcpy( &A_t[MP1 + MP1 + MP1], acoeff, MP1 <<2 );
- /* Compute reflection coefficients Q15 */
- A_Refl( &acoeff[1], refl );
- /* Compute prediction error in Q15 */
- /* 0.99997 in Q15 */
- pred_err = MAX_16;
- for ( i = 0; i < M; i++ ) {
- pred_err = ( pred_err * ( MAX_16 - ( ( refl[i] * refl[i] ) >> 15 ) ) ) >>
- 15;
- }
- /* compute logarithm of prediction gain */
- Log2( pred_err, &log_pg_e, &log_pg_m );
- /* convert exponent and mantissa to Word16 Q12 */
- /* Q12 */
- log_pg = ( log_pg_e - 15 ) << 12;
- /* saturate */
- if (log_pg < -32768) {
- log_pg = -32768;
- }
- log_pg = ( -( log_pg + ( log_pg_m >> 3 ) ) ) >> 1;
- st->log_pg_mean = ( Word16 )( ( ( 29491*st->log_pg_mean ) >> 15 ) + ( ( 3277
- * log_pg ) >> 15 ) );
- /* Compute interpolated log energy */
- /* Q26 -> Q16 */
- log_en_int = log_en_int >> 10;
- /* Add 4 in Q16 */
- log_en_int += 262144L;
- /* subtract prediction gain */
- log_en_int = log_en_int - ( log_pg << 4 );
- /* adjust level to speech coder mode */
- log_en_int += st->log_en_adjust << 5;
- log_en_int_e = ( Word16 )( log_en_int >> 16 );
- log_en_int_m = ( Word16 )( ( log_en_int - ( log_en_int_e << 16 ) ) >> 1 );
- /* Q4 */
- level = ( Word16 )( Pow2( log_en_int_e, log_en_int_m ) );
- for ( i = 0; i < 4; i++ ) {
- /* Compute innovation vector */
- Build_CN_code( &st->pn_seed_rx, ex );
- for ( j = 0; j < L_SUBFR; j++ ) {
- ex[j] = ( level * ex[j] ) >> 15;
- }
- /* 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
- */
- Word32 num, denom;
- tmp_int_length = st->since_last_sid;
- if ( tmp_int_length > 32 ) {
- tmp_int_length = 32;
- }
- if ( tmp_int_length == 1 ) {
- st->true_sid_period_inv = MAX_16;
- }
- else {
- num = 1024;
- denom = ( tmp_int_length << 10 );
- st->true_sid_period_inv = 0;
- for ( i = 0; i < 15; i++ ) {
- st->true_sid_period_inv <<= 1;
- num <<= 1;
- if ( num >= denom ) {
- num = num - denom;
- st->true_sid_period_inv += 1;
- }
- }
- }
- st->since_last_sid = 0;
- memcpy( st->lsp_old, st->lsp, M << 2 );
- st->old_log_en = st->log_en;
- /* subtract 1/8 in Q11 i.e -6/8 dB */
- st->log_en = st->log_en - 256;
- if (st->log_en < -32768) st->log_en = -32768;
- }
- /*
- * 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;
- }
- /*
- * lsp_avg
- *
- *
- * Parameters:
- * st->lsp_meanSave B: LSP averages
- * lsp I: LSPs
- *
- * Function:
- * Calculate the LSP averages
- *
- * Returns:
- * void
- */
- static void lsp_avg( lsp_avgState *st, Word32 *lsp )
- {
- Word32 i, tmp;
- for ( i = 0; i < M; i++ ) {
- /* mean = 0.84*mean */
- tmp = ( st->lsp_meanSave[i] << 16 );
- tmp -= ( EXPCONST * st->lsp_meanSave[i] ) << 1;
- /* Add 0.16 of newest LSPs to mean */
- tmp += ( EXPCONST * lsp[i] ) << 1;
- /* Save means */
- tmp += 0x00008000L;
- st->lsp_meanSave[i] = tmp >> 16;
- }
- return;
- }
- /*
- * Int_lpc_1and3
- *
- *
- * Parameters:
- * lsp_old I: LSP vector at the 4th subfr. of past frame [M]
- * lsp_mid I: LSP vector at the 2nd subframe of present frame [M]
- * lsp_new I: LSP vector at the 4th subframe of present frame [M]
- * Az O: interpolated LP parameters in subframes 1 and 3
- * [AZ_SIZE]
- *
- * Function:
- * Interpolates the LSPs and converts to LPC parameters
- * to get a different LP filter in each subframe.
- *
- * The 20 ms speech frame is divided into 4 subframes.
- * The LSPs are quantized and transmitted at the 2nd and
- * 4th subframes (twice per frame) and interpolated at the
- * 1st and 3rd subframe.
- *
- * Returns:
- * void
- */
- static void Int_lpc_1and3( Word32 lsp_old[], Word32 lsp_mid[], Word32 lsp_new[],
- Word32 Az[] )
- {
- Word32 lsp[M];
- Word32 i;
- /* lsp[i] = lsp_mid[i] * 0.5 + lsp_old[i] * 0.5 */
- for ( i = 0; i < 10; i++ ) {
- lsp[i] = ( lsp_mid[i] >> 1 ) + ( lsp_old[i] >> 1 );
- }
- /* Subframe 1 */
- Lsp_Az( lsp, Az );
- Az += MP1;
- /* Subframe 2 */
- Lsp_Az( lsp_mid, Az );
- Az += MP1;
- for ( i = 0; i < 10; i++ ) {
- lsp[i] = ( lsp_mid[i] >> 1 ) + ( lsp_new[i] >> 1 );
- }
- /* Subframe 3 */
- Lsp_Az( lsp, Az );
- Az += MP1;
- /* Subframe 4 */
- Lsp_Az( lsp_new, Az );
- return;
- }
- /*
- * Int_lpc_1to3
- *
- *
- * Parameters:
- * lsp_old I: LSP vector at the 4th subframe of past frame [M]
- * lsp_new I: LSP vector at the 4th subframe of present frame [M]
- * Az O: interpolated LP parameters in all subframes
- * [AZ_SIZE]
- *
- * Function:
- * Interpolates the LSPs and converts to LPC parameters to get a different
- * LP filter in each subframe.
- *
- * The 20 ms speech frame is divided into 4 subframes.
- * The LSPs are quantized and transmitted at the 4th
- * subframes (once per frame) and interpolated at the
- * 1st, 2nd and 3rd subframe.
- *
- * Returns:
- * void
- */
- static void Int_lpc_1to3( Word32 lsp_old[], Word32 lsp_new[], Word32 Az[] )
- {
- Word32 lsp[M];
- Word32 i;
- for ( i = 0; i < 10; i++ ) {
- lsp[i] = ( lsp_new[i] >> 2 ) + ( lsp_old[i] - ( lsp_old[i] >> 2 ) );
- }
- /* Subframe 1 */
- Lsp_Az( lsp, Az );
- Az += MP1;
- for ( i = 0; i < 10; i++ ) {
- lsp[i] = ( lsp_old[i] >> 1 ) + ( lsp_new[i] >> 1 );
- }
- /* Subframe 2 */
- Lsp_Az( lsp, Az );
- Az += MP1;
- for ( i = 0; i < 10; i++ ) {
- lsp[i] = ( lsp_old[i] >> 2 ) + ( lsp_new[i] - ( lsp_new[i] >> 2 ) );
- }
- /* Subframe 3 */
- Lsp_Az( lsp, Az );
- Az += MP1;
- /* Subframe 4 */
- Lsp_Az( lsp_new, Az );
- return;
- }
- /*
- * D_plsf_5
- *
- *
- * Parameters:
- * st->past_lsf_q I: Past dequantized LFSs
- * st->past_r_q B: past quantized residual
- * bfi B: bad frame indicator
- * indice I: quantization indices of 3 submatrices, Q0
- * lsp1_q O: quantized 1st LSP vector
- * lsp2_q O: quantized 2nd LSP vector
- *
- * Function:
- * Decodes the 2 sets of LSP parameters in a frame
- * using the received quantization indices.
- *
- * Returns:
- * void
- */
- static void D_plsf_5( D_plsfState *st, Word16 bfi, Word16 *indice, Word32 *lsp1_q
- , Word32 *lsp2_q )
- {
- Word32 lsf1_r[M], lsf2_r[M], lsf1_q[M], lsf2_q[M];
- Word32 i, temp1, temp2, sign;
- const Word32 *p_dico;
- /* if bad frame */
- if ( bfi != 0 ) {
- /* use the past LSFs slightly shifted towards their mean */
- for ( i = 0; i < M; i += 2 ) {
- /* lsfi_q[i] = ALPHA*st->past_lsf_q[i] + ONE_ALPHA*meanLsf[i]; */
- lsf1_q[i] = ( ( st->past_lsf_q[i] * ALPHA_122 ) >> 15 ) + ( ( mean_lsf_5[i]
- * ONE_ALPHA_122 ) >> 15 );
- lsf1_q[i + 1] = ( ( st->past_lsf_q[i + 1] * ALPHA_122 ) >> 15 ) + ( (
- mean_lsf_5[i + 1] * ONE_ALPHA_122 ) >> 15 );
- }
- memcpy( lsf2_q, lsf1_q, M <<2 );
- /* estimate past quantized residual to be used in next frame */
- for ( i = 0; i < M; i += 2 ) {
- /* temp = meanLsf[i] + st->past_r_q[i] * LSPPpred_facMR122; */
- temp1 = mean_lsf_5[i] + ( ( st->past_r_q[i] * LSP_PRED_FAC_MR122 ) >>
- 15 );
- temp2 = mean_lsf_5[i + 1] +( ( st->past_r_q[i + 1] *LSP_PRED_FAC_MR122
- ) >> 15 );
- st->past_r_q[i] = lsf2_q[i] - temp1;
- st->past_r_q[i + 1] = lsf2_q[i + 1] -temp2;
- }
- }
- /* if good LSFs received */
- else {
- /* decode prediction residuals from 5 received indices */
- p_dico = &dico1_lsf_5[indice[0] << 2];
- lsf1_r[0] = *p_dico++;
- lsf1_r[1] = *p_dico++;
- lsf2_r[0] = *p_dico++;
- lsf2_r[1] = *p_dico++;
- p_dico = &dico2_lsf_5[indice[1] << 2];
- lsf1_r[2] = *p_dico++;
- lsf1_r[3] = *p_dico++;
- lsf2_r[2] = *p_dico++;
- lsf2_r[3] = *p_dico++;
- sign = ( Word16 )( indice[2] & 1 );
- i = indice[2] >> 1;
- p_dico = &dico3_lsf_5[i << 2];
- if ( sign == 0 ) {
- lsf1_r[4] = *p_dico++;
- lsf1_r[5] = *p_dico++;
- lsf2_r[4] = *p_dico++;
- lsf2_r[5] = *p_dico++;
- }
- else {
- lsf1_r[4] = ( Word16 )( -( *p_dico++ ) );
- lsf1_r[5] = ( Word16 )( -( *p_dico++ ) );
- lsf2_r[4] = ( Word16 )( -( *p_dico++ ) );
- lsf2_r[5] = ( Word16 )( -( *p_dico++ ) );
- }
- p_dico = &dico4_lsf_5[( indice[3]<<2 )];
- lsf1_r[6] = *p_dico++;
- lsf1_r[7] = *p_dico++;
- lsf2_r[6] = *p_dico++;
- lsf2_r[7] = *p_dico++;
- p_dico = &dico5_lsf_5[( indice[4]<<2 )];
- lsf1_r[8] = *p_dico++;
- lsf1_r[9] = *p_dico++;
- lsf2_r[8] = *p_dico++;
- lsf2_r[9] = *p_dico++;
- /* Compute quantized LSFs and update the past quantized residual */
- for ( i = 0; i < M; i++ ) {
- temp1 = mean_lsf_5[i] + ( ( st->past_r_q[i] * LSP_PRED_FAC_MR122 ) >>
- 15 );
- lsf1_q[i] = lsf1_r[i] + temp1;
- lsf2_q[i] = lsf2_r[i] + temp1;
- st->past_r_q[i] = lsf2_r[i];
- }
- }
- /* verification that LSFs have minimum distance of LSF_GAP Hz */
- Reorder_lsf( lsf1_q, LSF_GAP );
- Reorder_lsf( lsf2_q, LSF_GAP );
- memcpy( st->past_lsf_q, lsf2_q, M <<2 );
- /* convert LSFs to the cosine domain */
- Lsf_lsp( lsf1_q, lsp1_q );
- Lsf_lsp( lsf2_q, lsp2_q );
- return;
- }
- /*
- * Dec_lag3
- *
- *
- * Parameters:
- * index I: received pitch index
- * t0_min I: minimum of search range
- * t0_max I: maximum of search range
- * i_subfr I: subframe flag
- * T0_prev I: integer pitch delay of last subframe used
- * in 2nd and 4th subframes
- * T0 O: integer part of pitch lag
- * T0_frac O : fractional part of pitch lag
- * flag4 I : flag for encoding with 4 bits
- * Function:
- * Decoding of fractional pitch lag with 1/3 resolution.
- * Extract the integer and fraction parts of the pitch lag from
- * the received adaptive codebook index.
- *
- * The fractional lag in 1st and 3rd subframes is encoded with 8 bits
- * while that in 2nd and 4th subframes is relatively encoded with 4, 5
- * and 6 bits depending on the mode.
- *
- * Returns:
- * void
- */
- static void Dec_lag3( Word32 index, Word32 t0_min, Word32 t0_max, Word32 i_subfr
- , Word32 T0_prev, Word32 *T0, Word32 *T0_frac, Word32 flag4 )
- {
- Word32 i, tmp_lag;
- /* if 1st or 3rd subframe */
- if ( i_subfr == 0 ) {
- if ( index < 197 ) {
- *T0 = ( ( ( index + 2 ) * 10923 ) >> 15 ) + 19;
- i = *T0 + *T0 + *T0;
- *T0_frac = ( index - i ) + 58;
- }
- else {
- *T0 = index - 112;
- *T0_frac = 0;
- }
- }
- /* 2nd or 4th subframe */
- else {
- if ( flag4 == 0 ) {
- /* 'normal' decoding: either with 5 or 6 bit resolution */
- i = ( ( ( index + 2 ) * 10923 ) >> 15 ) - 1;
- *T0 = i + t0_min;
- i = i + i + i;
- *T0_frac = ( index - 2 ) - i;
- }
- else {
- /* decoding with 4 bit resolution */
- tmp_lag = T0_prev;
- if ( ( tmp_lag - t0_min ) > 5 )
- tmp_lag = t0_min + 5;
- if ( ( t0_max - tmp_lag ) > 4 )
- tmp_lag = t0_max - 4;
- if ( index < 4 ) {
- i = ( tmp_lag - 5 );
- *T0 = i + index;
- *T0_frac = 0;
- }
- else {
- if ( index < 12 ) {
- i = ( ( ( index - 5 ) * 10923 ) >> 15 ) - 1;
- *T0 = i + tmp_lag;
- i = i + i + i;
- *T0_frac = ( index - 9 ) - i;
- }
- else {
- i = ( index - 12 ) + tmp_lag;
- *T0 = i + 1;
- *T0_frac = 0;
- }
- }
- } /* end if (decoding with 4 bit resolution) */
- }
- return;
- }
- /*
- * Pred_lt_3or6_40
- *
- *
- * Parameters:
- * exc B: excitation buffer
- * T0 I: integer pitch lag
- * frac I: fraction of lag
- * flag3 I: if set, upsampling rate = 3 (6 otherwise)
- *
- * Function:
- * Compute the result of long term prediction with fractional
- * interpolation of resolution 1/3 or 1/6. (Interpolated past excitation).
- *
- * Once the fractional pitch lag is determined,
- * the adaptive codebook vector v(n) is computed by interpolating
- * the past excitation signal u(n) at the given integer delay k
- * and phase (fraction) :
- *
- * 9 9
- * v(n) = SUM[ u(n-k-i) * b60(t+i*6) ] + SUM[ u(n-k+1+i) * b60(6-t+i*6) ],
- * i=0 i=0
- * n = 0, ...,39, t = 0, ...,5.
- *
- * The interpolation filter b60 is based on a Hamming windowed sin(x)/x
- * function truncated at