FreeCalypso > hg > gsm-codec-lib
changeset 426:7bef001cd8b8
libtwamr: integrate dec_amr.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 07 May 2024 20:33:01 +0000 |
parents | 9499d12d315b |
children | 357d1faad55d |
files | libtwamr/Makefile libtwamr/dec_amr.c libtwamr/dec_amr.h libtwamr/namespace.list |
diffstat | 4 files changed, 1137 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/libtwamr/Makefile Tue May 07 19:18:57 2024 +0000 +++ b/libtwamr/Makefile Tue May 07 20:33:01 2024 +0000 @@ -5,36 +5,36 @@ c8_31pf.o c_g_aver.o calc_cor.o calc_en.o cbsearch.o cl_ltp.o cod_amr.o\ convolve.o cor_h.o d1035pf.o d2_11pf.o d2_9pf.o d3_14pf.o d4_17pf.o \ d8_31pf.o d_gain_c.o d_gain_p.o d_plsf.o d_plsf_3.o d_plsf_5.o \ - dec_gain.o dec_lag3.o dec_lag6.o dhf_check.o dhf_tables.o dtx_dec.o \ - dtx_enc.o e_homing.o ec_gains.o enc_lag3.o enc_lag6.o enc_main.o \ - ex_ctrl.o g_adapt.o g_code.o g_pitch.o gain_q.o gains_tab.o gc_pred.o \ - gmed_n.o graytab.o hp_max.o int_lpc.o int_lsf.o inter_36.o inv_sqrt.o \ - lag_wind.o levinson.o lflg_upd.o log2.o lpc.o lsfwt.o lsp.o lsp_avg.o \ - lsp_az.o lsp_lsf.o lsp_tab.o mac_32.o ol_ltp.o oper_32b.o p_ol_wgh.o \ - ph_disp.o pitch_fr.o pitch_ol.o post_pro.o pow2.o pre_big.o pre_proc.o \ - pred_lt.o preemph.o prm2bits.o prmno.o pstfilt.o q_gain_c.o q_gain_p.o \ - q_plsf.o q_plsf3_tab.o q_plsf5_tab.o q_plsf_3.o q_plsf_5.o qgain475.o \ - qgain795.o qua_gain.o qua_gain_tab.o r_fft.o reorder.o residu.o \ - s10_8pf.o set_sign.o sid_sync.o spreproc.o spstproc.o sqrt_l.o \ + dec_amr.o dec_gain.o dec_lag3.o dec_lag6.o dhf_check.o dhf_tables.o \ + dtx_dec.o dtx_enc.o e_homing.o ec_gains.o enc_lag3.o enc_lag6.o \ + enc_main.o ex_ctrl.o g_adapt.o g_code.o g_pitch.o gain_q.o gains_tab.o \ + gc_pred.o gmed_n.o graytab.o hp_max.o int_lpc.o int_lsf.o inter_36.o \ + inv_sqrt.o lag_wind.o levinson.o lflg_upd.o log2.o lpc.o lsfwt.o lsp.o \ + lsp_avg.o lsp_az.o lsp_lsf.o lsp_tab.o mac_32.o ol_ltp.o oper_32b.o \ + p_ol_wgh.o ph_disp.o pitch_fr.o pitch_ol.o post_pro.o pow2.o pre_big.o \ + pre_proc.o pred_lt.o preemph.o prm2bits.o prmno.o pstfilt.o q_gain_c.o \ + q_gain_p.o q_plsf.o q_plsf3_tab.o q_plsf5_tab.o q_plsf_3.o q_plsf_5.o \ + qgain475.o qgain795.o qua_gain.o qua_gain_tab.o r_fft.o reorder.o \ + residu.o s10_8pf.o set_sign.o sid_sync.o spreproc.o spstproc.o sqrt_l.o\ syn_filt.o tls_flags.o ton_stab.o tseq_out.o vad1.o vad2.o vad_reset.o \ weight_a.o window.o HDRS= a_refl.h agc.h autocorr.h az_lsp.h b_cn_cod.h basic_op.h bgnscd.h \ bitno.h bits2prm.h c1035pf.h c2_11pf.h c2_9pf.h c3_14pf.h c4_17pf.h \ c8_31pf.h c_g_aver.h calc_cor.h calc_en.h cbsearch.h cl_ltp.h cnst.h \ cnst_vad.h cod_amr.h convolve.h cor_h.h d1035pf.h d2_11pf.h d2_9pf.h \ - d3_14pf.h d4_17pf.h d8_31pf.h d_gain_c.h d_gain_p.h d_plsf.h dec_gain.h\ - dec_lag3.h dec_lag6.h dtx_common.h dtx_dec.h dtx_enc.h e_homing.h \ - ec_gains.h enc_lag3.h enc_lag6.h ex_ctrl.h g_adapt.h g_code.h g_pitch.h\ - gain_q.h gains_tab.h gc_pred.h gmed_n.h graytab.h hp_max.h int_defs.h \ - int_lpc.h int_lsf.h inter_36.h inv_sqrt.h lag_wind.h levinson.h log2.h \ - lpc.h lsfwt.h lsp.h lsp_avg.h lsp_az.h lsp_lsf.h lsp_tab.h mac_32.h \ - memops.h namespace.h no_count.h ol_ltp.h oper_32b.h p_ol_wgh.h \ - ph_disp.h pitch_fr.h pitch_ol.h post_pro.h pow2.h pre_big.h pre_proc.h \ - pred_lt.h preemph.h prm2bits.h pstfilt.h q_gain_c.h q_gain_p.h q_plsf.h\ - q_plsf3_tab.h q_plsf5_tab.h qgain475.h qgain795.h qua_gain.h \ - qua_gain_tab.h reorder.h residu.h s10_8pf.h set_sign.h sid_sync.h \ - spreproc.h spstproc.h sqrt_l.h syn_filt.h ton_stab.h tw_amr.h typedef.h\ - vad.h vad1.h vad2.h weight_a.h window.h + d3_14pf.h d4_17pf.h d8_31pf.h d_gain_c.h d_gain_p.h d_plsf.h dec_amr.h \ + dec_gain.h dec_lag3.h dec_lag6.h dtx_common.h dtx_dec.h dtx_enc.h \ + e_homing.h ec_gains.h enc_lag3.h enc_lag6.h ex_ctrl.h g_adapt.h \ + g_code.h g_pitch.h gain_q.h gains_tab.h gc_pred.h gmed_n.h graytab.h \ + hp_max.h int_defs.h int_lpc.h int_lsf.h inter_36.h inv_sqrt.h \ + lag_wind.h levinson.h log2.h lpc.h lsfwt.h lsp.h lsp_avg.h lsp_az.h \ + lsp_lsf.h lsp_tab.h mac_32.h memops.h namespace.h no_count.h ol_ltp.h \ + oper_32b.h p_ol_wgh.h ph_disp.h pitch_fr.h pitch_ol.h post_pro.h pow2.h\ + pre_big.h pre_proc.h pred_lt.h preemph.h prm2bits.h pstfilt.h \ + q_gain_c.h q_gain_p.h q_plsf.h q_plsf3_tab.h q_plsf5_tab.h qgain475.h \ + qgain795.h qua_gain.h qua_gain_tab.h reorder.h residu.h s10_8pf.h \ + set_sign.h sid_sync.h spreproc.h spstproc.h sqrt_l.h syn_filt.h \ + ton_stab.h tw_amr.h typedef.h vad.h vad1.h vad2.h weight_a.h window.h LIB= libtwamr.a INSTALL_PREFIX= /usr/local
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/dec_amr.c Tue May 07 20:33:01 2024 +0000 @@ -0,0 +1,976 @@ +/************************************************************************* +* +* GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 +* R99 Version 3.3.0 +* REL-4 Version 4.1.0 +* +***************************************************************************** +* +* File : dec_amr.c +* Purpose : Decoding of one speech frame using given codec mode +* +***************************************************************************** +*/ + +/* +***************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +***************************************************************************** +*/ +#include "namespace.h" +#include "dec_amr.h" + +#include "typedef.h" +#include "basic_op.h" +#include "no_count.h" +#include "cnst.h" +#include "memops.h" +#include "syn_filt.h" +#include "d_plsf.h" +#include "agc.h" +#include "int_lpc.h" +#include "dec_gain.h" +#include "dec_lag3.h" +#include "dec_lag6.h" +#include "d2_9pf.h" +#include "d2_11pf.h" +#include "d3_14pf.h" +#include "d4_17pf.h" +#include "d8_31pf.h" +#include "d1035pf.h" +#include "pred_lt.h" +#include "d_gain_p.h" +#include "d_gain_c.h" +#include "dec_gain.h" +#include "ec_gains.h" +#include "ph_disp.h" +#include "c_g_aver.h" +#include "int_lsf.h" +#include "lsp_lsf.h" +#include "lsp_avg.h" +#include "bgnscd.h" +#include "ex_ctrl.h" +#include "sqrt_l.h" + +#include "lsp_tab.h" +#include "bitno.h" +#include "b_cn_cod.h" + +/* +***************************************************************************** +* LOCAL VARIABLES AND TABLES +***************************************************************************** +*/ +/*-----------------------------------------------------------------* + * Decoder constant parameters (defined in "cnst.h") * + *-----------------------------------------------------------------* + * L_FRAME : Frame size. * + * L_FRAME_BY2 : Half the frame size. * + * L_SUBFR : Sub-frame size. * + * M : LPC order. * + * MP1 : LPC order+1 * + * PIT_MIN : Minimum pitch lag. * + * PIT_MIN_MR122 : Minimum pitch lag for the MR122 mode. * + * PIT_MAX : Maximum pitch lag. * + * L_INTERPOL : Length of filter for interpolation * + * PRM_SIZE : size of vector containing analysis parameters * + *-----------------------------------------------------------------*/ + +/* +***************************************************************************** +* PUBLIC PROGRAM CODE +***************************************************************************** +*/ + +/* +************************************************************************** +* +* Function : Decoder_amr_reset +* Purpose : Resets state memory +* +************************************************************************** +*/ +void Decoder_amr_reset (Decoder_amrState *state, Flag dtx_partial_reset) +{ + Word16 i; + + /* Initialize static pointer */ + state->exc = state->old_exc + PIT_MAX + L_INTERPOL; + + /* Static vectors to zero */ + Set_zero (state->old_exc, PIT_MAX + L_INTERPOL); + + if (!dtx_partial_reset) + Set_zero (state->mem_syn, M); + + /* initialize pitch sharpening */ + state->sharp = SHARPMIN; + state->old_T0 = 40; + + /* Initialize state->lsp_old [] */ + + if (!dtx_partial_reset) { + Copy(lsp_init_data, &state->lsp_old[0], M); + } + + /* 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 (!dtx_partial_reset) { + for (i=0;i<9;i++) + state->excEnergyHist[i] = 0; + } + + for (i = 0; i < 9; i++) + state->ltpGainHistory[i] = 0; + + Cb_gain_average_reset(&state->Cb_gain_averState); + if (!dtx_partial_reset) + lsp_avg_reset(&state->lsp_avg_st); + D_plsf_reset(&state->lsfState); + ec_gain_pitch_reset(&state->ec_gain_p_st); + ec_gain_code_reset(&state->ec_gain_c_st); + + if (!dtx_partial_reset) + gc_pred_reset(&state->pred_state); + + Bgn_scd_reset(&state->background_state); + state->nodataSeed = 21845; + ph_disp_reset(&state->ph_disp_st); + if (!dtx_partial_reset) + dtx_dec_reset(&state->dtxDecoderState); +} + +/* +************************************************************************** +* +* Function : Decoder_amr +* Purpose : Speech decoder routine. +* +************************************************************************** +*/ +int Decoder_amr ( + Decoder_amrState *st, /* i/o : State variables */ + enum Mode mode, /* i : AMR mode */ + Word16 parm[], /* i : vector of synthesis parameters + (PRM_SIZE) */ + enum RXFrameType frame_type, /* i : received frame type */ + Word16 synth[], /* o : synthesis speech (L_FRAME) */ + Word16 A_t[] /* o : decoded LP filter in 4 subframes + (AZ_SIZE) */ +) +{ + /* LPC coefficients */ + + Word16 *Az; /* Pointer on A_t */ + + /* LSPs */ + + Word16 lsp_new[M]; + Word16 lsp_mid[M]; + + /* LSFs */ + + Word16 prev_lsf[M]; + Word16 lsf_i[M]; + + /* Algebraic codevector */ + + Word16 code[L_SUBFR]; + + /* excitation */ + + Word16 excp[L_SUBFR]; + Word16 exc_enhanced[L_SUBFR]; + + /* Scalars */ + + Word16 i, i_subfr; + Word16 T0, T0_frac, index, index_mr475 = 0; + Word16 gain_pit, gain_code, gain_code_mix, pit_sharp, pit_flag, pitch_fac; + Word16 t0_min, t0_max; + Word16 delta_frc_low, delta_frc_range; + Word16 tmp_shift; + Word16 temp; + Word32 L_temp; + Word16 flag4; + Word16 carefulFlag; + Word16 excEnergy; + Word16 subfrNr; + Word16 evenSubfr = 0; + + Word16 bfi = 0; /* bad frame indication flag */ + Word16 pdfi = 0; /* potential degraded bad frame flag */ + + enum DTXStateType newDTXState; /* SPEECH , DTX, DTX_MUTE */ + + /* find the new DTX state SPEECH OR DTX */ + newDTXState = rx_dtx_handler(&st->dtxDecoderState, frame_type); + + /* DTX actions */ + if (sub(newDTXState, SPEECH) != 0 ) + { + Decoder_amr_reset (st, 1); + + dtx_dec(&st->dtxDecoderState, + st->mem_syn, + &st->lsfState, + &st->pred_state, + &st->Cb_gain_averState, + newDTXState, + mode, + parm, synth, A_t); + /* update average lsp */ + + Lsf_lsp(st->lsfState.past_lsf_q, st->lsp_old, M); + lsp_avg(&st->lsp_avg_st, st->lsfState.past_lsf_q); + goto the_end; + } + + /* SPEECH action state machine */ + if ((sub(frame_type, RX_SPEECH_BAD) == 0) || + (sub(frame_type, RX_NO_DATA) == 0) || + (sub(frame_type, RX_ONSET) == 0)) + { + bfi = 1; + if ((sub(frame_type, RX_NO_DATA) == 0) || + (sub(frame_type, RX_ONSET) == 0)) + { + build_CN_param(&st->nodataSeed, + prmno[mode], + bitno[mode], + parm); + } + } + else if (sub(frame_type, RX_SPEECH_DEGRADED) == 0) + { + pdfi = 1; + } + + if (bfi != 0) + { + st->state = add (st->state, 1); + } + else if (sub (st->state, 6) == 0) + { + st->state = 5; move16 (); + } + else + { + st->state = 0; move16 (); + } + + if (sub (st->state, 6) > 0) + { + st->state = 6; move16 (); + } + + /* If this frame is the first speech frame after CNI period, */ + /* set the BFH state machine to an appropriate state depending */ + /* on whether there was DTX muting before start of speech or not */ + /* If there was DTX muting, the first speech frame is muted. */ + /* If there was no DTX muting, the first speech frame is not */ + /* muted. The BFH state machine starts from state 5, however, to */ + /* keep the audible noise resulting from a SID frame which is */ + /* erroneously interpreted as a good speech frame as small as */ + /* possible (the decoder output in this case is quickly muted) */ + + if (sub(st->dtxDecoderState.dtxGlobalState, DTX) == 0) + { + st->state = 5; + st->prev_bf = 0; + } + else if (test (), sub(st->dtxDecoderState.dtxGlobalState, DTX_MUTE) == 0) + { + st->state = 5; + st->prev_bf = 1; + } + + /* save old LSFs for CB gain smoothing */ + Copy (st->lsfState.past_lsf_q, prev_lsf, M); + + /* decode LSF parameters and generate interpolated lpc coefficients + for the 4 subframes */ + if (sub (mode, MR122) != 0) + { + D_plsf_3(&st->lsfState, mode, bfi, parm, lsp_new); + + /* Advance synthesis parameters pointer */ + parm += 3; move16 (); + + Int_lpc_1to3(st->lsp_old, lsp_new, A_t); + } + else + { + D_plsf_5(&st->lsfState, bfi, parm, lsp_mid, lsp_new); + + /* Advance synthesis parameters pointer */ + parm += 5; move16 (); + + Int_lpc_1and3(st->lsp_old, lsp_mid, lsp_new, A_t); + } + + /* update the LSPs for the next frame */ + for (i = 0; i < M; i++) + { + st->lsp_old[i] = lsp_new[i]; move16 (); + } + + /*------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * + * times * + * - decode the pitch delay * + * - decode algebraic code * + * - decode pitch and codebook gains * + * - find the excitation and compute synthesis speech * + *------------------------------------------------------------------------*/ + + /* pointer to interpolated LPC parameters */ + Az = A_t; move16 (); + + evenSubfr = 0; move16(); + subfrNr = -1; move16(); + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) + { + subfrNr = add(subfrNr, 1); + evenSubfr = sub(1, evenSubfr); + + /* flag for first and 3th subframe */ + pit_flag = i_subfr; move16 (); + + test(); + if (sub (i_subfr, L_FRAME_BY2) == 0) + { + test(); test(); + if (sub(mode, MR475) != 0 && sub(mode, MR515) != 0) + { + pit_flag = 0; move16 (); + } + } + + /* pitch index */ + index = *parm++; move16 (); + + /*-------------------------------------------------------* + * - decode pitch lag and find adaptive codebook vector. * + *-------------------------------------------------------*/ + + test (); + if (sub(mode, MR122) != 0) + { + /* flag4 indicates encoding with 4 bit resolution; */ + /* this is needed for mode MR475, MR515, MR59 and MR67 */ + + flag4 = 0; move16 (); + test (); test (); test (); test (); + if ((sub (mode, MR475) == 0) || + (sub (mode, MR515) == 0) || + (sub (mode, MR59) == 0) || + (sub (mode, MR67) == 0) ) { + flag4 = 1; move16 (); + } + + /*-------------------------------------------------------* + * - get ranges for the t0_min and t0_max * + * - only needed in delta decoding * + *-------------------------------------------------------*/ + + delta_frc_low = 5; move16(); + delta_frc_range = 9; move16(); + + test (); + if ( sub(mode, MR795) == 0 ) + { + delta_frc_low = 10; move16(); + delta_frc_range = 19; move16(); + } + + t0_min = sub(st->old_T0, delta_frc_low); + test (); + if (sub(t0_min, PIT_MIN) < 0) + { + t0_min = PIT_MIN; move16(); + } + t0_max = add(t0_min, delta_frc_range); + test (); + if (sub(t0_max, PIT_MAX) > 0) + { + t0_max = PIT_MAX; move16(); + t0_min = sub(t0_max, delta_frc_range); + } + + Dec_lag3 (index, t0_min, t0_max, pit_flag, st->old_T0, + &T0, &T0_frac, flag4); + + st->T0_lagBuff = T0; move16 (); + + test (); + if (bfi != 0) + { + test (); + if (sub (st->old_T0, PIT_MAX) < 0) + { /* Graceful pitch */ + st->old_T0 = add(st->old_T0, 1); /* degradation */ + } + T0 = st->old_T0; move16 (); + T0_frac = 0; move16 (); + + test (); test (); test (); test (); test (); + if ( st->inBackgroundNoise != 0 && + sub(st->voicedHangover, 4) > 0 && + ((sub(mode, MR475) == 0 ) || + (sub(mode, MR515) == 0 ) || + (sub(mode, MR59) == 0) ) + ) + { + T0 = st->T0_lagBuff; move16 (); + } + } + + Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 1); + } + else + { + Dec_lag6 (index, PIT_MIN_MR122, + PIT_MAX, pit_flag, &T0, &T0_frac); + + test (); test (); test (); + if ( bfi == 0 && (pit_flag == 0 || sub (index, 61) < 0)) + { + } + else + { + st->T0_lagBuff = T0; move16 (); + T0 = st->old_T0; move16 (); + T0_frac = 0; move16 (); + } + + Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 0); + } + + /*-------------------------------------------------------* + * - (MR122 only: Decode pitch gain.) * + * - Decode innovative codebook. * + * - set pitch sharpening factor * + *-------------------------------------------------------*/ + + if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0) + { /* MR475, MR515 */ + index = *parm++; /* index of position */ move16 (); + i = *parm++; /* signs */ move16 (); + + decode_2i40_9bits (subfrNr, i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR59) == 0) + { /* MR59 */ + test (); + index = *parm++; /* index of position */ move16 (); + i = *parm++; /* signs */ move16 (); + + decode_2i40_11bits (i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR67) == 0) + { /* MR67 */ + test (); test (); + index = *parm++; /* index of position */ move16 (); + i = *parm++; /* signs */ move16 (); + + decode_3i40_14bits (i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR795) <= 0) + { /* MR74, MR795 */ + test (); test (); test (); + index = *parm++; /* index of position */ move16 (); + i = *parm++; /* signs */ move16 (); + + decode_4i40_17bits (i, index, code); + + pit_sharp = shl (st->sharp, 1); + } + else if (sub (mode, MR102) == 0) + { /* MR102 */ + test (); test (); test (); + + dec_8i40_31bits (parm, code); + parm += 7; move16 (); + + pit_sharp = shl (st->sharp, 1); + } + else + { /* MR122 */ + test (); test (); test (); + index = *parm++; move16 (); + test(); + if (bfi != 0) + { + ec_gain_pitch (&st->ec_gain_p_st, st->state, &gain_pit); + } + else + { + gain_pit = d_gain_pitch (mode, index); move16 (); + } + ec_gain_pitch_update (&st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + + dec_10i40_35bits (parm, code); + parm += 10; move16 (); + + /* pit_sharp = gain_pit; */ + /* if (pit_sharp > 1.0) pit_sharp = 1.0; */ + + pit_sharp = shl (gain_pit, 1); + } + + /*-------------------------------------------------------* + * - Add the pitch contribution to code[]. * + *-------------------------------------------------------*/ + for (i = T0; i < L_SUBFR; i++) + { + temp = mult (code[i - T0], pit_sharp); + code[i] = add (code[i], temp); + move16 (); + } + + /*------------------------------------------------------------* + * - Decode codebook gain (MR122) or both pitch * + * gain and codebook gain (all others) * + * - Update pitch sharpening "sharp" with quantized gain_pit * + *------------------------------------------------------------*/ + + if (test(), sub (mode, MR475) == 0) + { + /* read and decode pitch and code gain */ + test(); + if (evenSubfr != 0) + { + index_mr475 = *parm++; move16 (); /* index of gain(s) */ + } + + test(); + if (bfi == 0) + { + Dec_gain(&st->pred_state, mode, index_mr475, code, + evenSubfr, &gain_pit, &gain_code); + } + else + { + ec_gain_pitch (&st->ec_gain_p_st, st->state, &gain_pit); + ec_gain_code (&st->ec_gain_c_st, &st->pred_state, st->state, + &gain_code); + } + ec_gain_pitch_update (&st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + ec_gain_code_update (&st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; move16 (); + test (); + if (sub (pit_sharp, SHARPMAX) > 0) + { + pit_sharp = SHARPMAX; move16 (); + } + + } + else if (test(), test(), (sub (mode, MR74) <= 0) || + (sub (mode, MR102) == 0)) + { + /* read and decode pitch and code gain */ + index = *parm++; move16 (); /* index of gain(s) */ + + test(); + if (bfi == 0) + { + Dec_gain(&st->pred_state, mode, index, code, + evenSubfr, &gain_pit, &gain_code); + } + else + { + ec_gain_pitch (&st->ec_gain_p_st, st->state, &gain_pit); + ec_gain_code (&st->ec_gain_c_st, &st->pred_state, st->state, + &gain_code); + } + ec_gain_pitch_update (&st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + ec_gain_code_update (&st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; move16 (); + test (); + if (sub (pit_sharp, SHARPMAX) > 0) + { + pit_sharp = SHARPMAX; move16 (); + } + + if (sub (mode, MR102) == 0) + { + if (sub (st->old_T0, add(L_SUBFR, 5)) > 0) + { + pit_sharp = shr(pit_sharp, 2); + } + } + } + else + { + /* read and decode pitch gain */ + index = *parm++; move16 (); /* index of gain(s) */ + + test (); + if (sub (mode, MR795) == 0) + { + /* decode pitch gain */ + test(); + if (bfi != 0) + { + ec_gain_pitch (&st->ec_gain_p_st, st->state, &gain_pit); + } + else + { + gain_pit = d_gain_pitch (mode, index); move16 (); + } + ec_gain_pitch_update (&st->ec_gain_p_st, bfi, st->prev_bf, + &gain_pit); + + /* read and decode code gain */ + index = *parm++; move16 (); + test(); + if (bfi == 0) + { + d_gain_code (&st->pred_state, mode, index, code, &gain_code); + } + else + { + ec_gain_code (&st->ec_gain_c_st, &st->pred_state, st->state, + &gain_code); + } + ec_gain_code_update (&st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; move16 (); + test (); + if (sub (pit_sharp, SHARPMAX) > 0) + { + pit_sharp = SHARPMAX; move16 (); + } + } + else + { /* MR122 */ + test(); + if (bfi == 0) + { + d_gain_code (&st->pred_state, mode, index, code, &gain_code); + } + else + { + ec_gain_code (&st->ec_gain_c_st, &st->pred_state, st->state, + &gain_code); + } + ec_gain_code_update (&st->ec_gain_c_st, bfi, st->prev_bf, + &gain_code); + + pit_sharp = gain_pit; move16 (); + } + } + + /* store pitch sharpening for next subframe */ + /* (for modes which use the previous pitch gain for + pitch sharpening in the search phase) */ + /* do not update sharpening in even subframes for MR475 */ + test(); test(); + if (sub(mode, MR475) != 0 || evenSubfr == 0) + { + st->sharp = gain_pit; move16 (); + test (); + if (sub (st->sharp, SHARPMAX) > 0) + { + st->sharp = SHARPMAX; move16 (); + } + } + + pit_sharp = shl (pit_sharp, 1); + test (); + if (sub (pit_sharp, 16384) > 0) + { + for (i = 0; i < L_SUBFR; i++) + { + temp = mult (st->exc[i], pit_sharp); + L_temp = L_mult (temp, gain_pit); + test (); + if (sub(mode, MR122)==0) + { + L_temp = L_shr (L_temp, 1); + } + excp[i] = round (L_temp); move16 (); + } + } + + /*-------------------------------------------------------* + * - Store list of LTP gains needed in the source * + * characteristic detector (SCD) * + *-------------------------------------------------------*/ + test (); + if ( bfi == 0 ) + { + for (i = 0; i < 8; i++) + { + st->ltpGainHistory[i] = st->ltpGainHistory[i+1]; move16 (); + } + st->ltpGainHistory[8] = gain_pit; move16 (); + } + + /*-------------------------------------------------------* + * - Limit gain_pit if in background noise and BFI * + * for MR475, MR515, MR59 * + *-------------------------------------------------------*/ + + test (); test (); test (); test (); test (); test (); + if ( (st->prev_bf != 0 || bfi != 0) && st->inBackgroundNoise != 0 && + ((sub(mode, MR475) == 0) || + (sub(mode, MR515) == 0) || + (sub(mode, MR59) == 0)) + ) + { + test (); + if ( sub (gain_pit, 12288) > 0) /* if (gain_pit > 0.75) in Q14*/ + gain_pit = add( shr( sub(gain_pit, 12288), 1 ), 12288 ); + /* gain_pit = (gain_pit-0.75)/2.0 + 0.75; */ + + test (); + if ( sub (gain_pit, 14745) > 0) /* if (gain_pit > 0.90) in Q14*/ + { + gain_pit = 14745; move16 (); + } + } + + /*-------------------------------------------------------* + * Calculate CB mixed gain * + *-------------------------------------------------------*/ + Int_lsf(prev_lsf, st->lsfState.past_lsf_q, i_subfr, lsf_i); + gain_code_mix = Cb_gain_average( + &st->Cb_gain_averState, mode, gain_code, + lsf_i, st->lsp_avg_st.lsp_meanSave, bfi, + st->prev_bf, pdfi, st->prev_pdf, + st->inBackgroundNoise, st->voicedHangover); move16 (); + + /* make sure that MR74, MR795, MR122 have original code_gain*/ + test(); + if ((sub(mode, MR67) > 0) && (sub(mode, MR102) != 0) ) + /* MR74, MR795, MR122 */ + { + gain_code_mix = gain_code; move16 (); + } + + /*-------------------------------------------------------* + * - Find the total excitation. * + * - Find synthesis speech corresponding to st->exc[]. * + *-------------------------------------------------------*/ + test (); + if (sub(mode, MR102) <= 0) /* MR475, MR515, MR59, MR67, MR74, MR795, MR102*/ + { + pitch_fac = gain_pit; move16 (); + tmp_shift = 1; move16 (); + } + else /* MR122 */ + { + pitch_fac = shr (gain_pit, 1); move16 (); + tmp_shift = 2; move16 (); + } + + /* copy unscaled LTP excitation to exc_enhanced (used in phase + * dispersion below) and compute total excitation for LTP feedback + */ + for (i = 0; i < L_SUBFR; i++) + { + exc_enhanced[i] = st->exc[i]; move16 (); + + /* st->exc[i] = gain_pit*st->exc[i] + gain_code*code[i]; */ + L_temp = L_mult (st->exc[i], pitch_fac); + /* 12.2: Q0 * Q13 */ + /* 7.4: Q0 * Q14 */ + L_temp = L_mac (L_temp, code[i], gain_code); + /* 12.2: Q12 * Q1 */ + /* 7.4: Q13 * Q1 */ + L_temp = L_shl (L_temp, tmp_shift); /* Q16 */ + st->exc[i] = round (L_temp); move16 (); + } + + /*-------------------------------------------------------* + * - Adaptive phase dispersion * + *-------------------------------------------------------*/ + ph_disp_release(&st->ph_disp_st); /* free phase dispersion adaption */ + + test (); test (); test (); test (); test (); test (); + if ( ((sub(mode, MR475) == 0) || + (sub(mode, MR515) == 0) || + (sub(mode, MR59) == 0)) && + sub(st->voicedHangover, 3) > 0 && + st->inBackgroundNoise != 0 && + bfi != 0 ) + { + ph_disp_lock(&st->ph_disp_st); /* Always Use full Phase Disp. */ + } /* if error in bg noise */ + + /* apply phase dispersion to innovation (if enabled) and + compute total excitation for synthesis part */ + ph_disp(&st->ph_disp_st, mode, + exc_enhanced, gain_code_mix, gain_pit, code, + pitch_fac, tmp_shift); + + /*-------------------------------------------------------* + * - The Excitation control module are active during BFI.* + * - Conceal drops in signal energy if in bg noise. * + *-------------------------------------------------------*/ + + L_temp = 0; move32 (); + for (i = 0; i < L_SUBFR; i++) + { + L_temp = L_mac (L_temp, exc_enhanced[i], exc_enhanced[i] ); + } + + L_temp = L_shr (L_temp, 1); /* excEnergy = sqrt(L_temp) in Q0 */ + L_temp = sqrt_l_exp(L_temp, &temp); move32 (); /* function result */ + L_temp = L_shr(L_temp, add( shr(temp, 1), 15)); + L_temp = L_shr(L_temp, 2); /* To cope with 16-bit and */ + excEnergy = extract_l(L_temp); /* scaling in ex_ctrl() */ + + test (); test (); test (); test (); test (); + test (); test (); test (); test (); test (); + if ( ((sub (mode, MR475) == 0) || + (sub (mode, MR515) == 0) || + (sub (mode, MR59) == 0)) && + sub(st->voicedHangover, 5) > 0 && + st->inBackgroundNoise != 0 && + sub(st->state, 4) < 0 && + ( (pdfi != 0 && st->prev_pdf != 0) || + bfi != 0 || + st->prev_bf != 0) ) + { + carefulFlag = 0; move32 (); + test (); test (); + if ( pdfi != 0 && bfi == 0 ) + { + carefulFlag = 1; move16 (); + } + + Ex_ctrl(exc_enhanced, + excEnergy, + st->excEnergyHist, + st->voicedHangover, + st->prev_bf, + carefulFlag); + } + + test (); test (); test (); test (); + if ( st->inBackgroundNoise != 0 && + ( bfi != 0 || st->prev_bf != 0 ) && + sub(st->state, 4) < 0 ) + { + ; /* do nothing! */ + } + else + { + /* Update energy history for all modes */ + for (i = 0; i < 8; i++) + { + st->excEnergyHist[i] = st->excEnergyHist[i+1]; move16 (); + } + st->excEnergyHist[8] = excEnergy; move16 (); + } + /*-------------------------------------------------------* + * Excitation control module end. * + *-------------------------------------------------------*/ + + test (); + if (sub (pit_sharp, 16384) > 0) + { + for (i = 0; i < L_SUBFR; i++) + { + excp[i] = add (excp[i], exc_enhanced[i]); + move16 (); + } + agc2 (exc_enhanced, excp, L_SUBFR); + Overflow = 0; move16 (); + Syn_filt (Az, excp, &synth[i_subfr], L_SUBFR, + st->mem_syn, 0); + } + else + { + Overflow = 0; move16 (); + Syn_filt (Az, exc_enhanced, &synth[i_subfr], L_SUBFR, + st->mem_syn, 0); + } + + test (); + if (Overflow != 0) /* Test for overflow */ + { + for (i = 0; i < PIT_MAX + L_INTERPOL + L_SUBFR; i++) + { + st->old_exc[i] = shr(st->old_exc[i], 2); move16 (); + } + for (i = 0; i < L_SUBFR; i++) + { + exc_enhanced[i] = shr(exc_enhanced[i], 2); move16 (); + } + Syn_filt(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 1); + } + else + { + Copy(&synth[i_subfr+L_SUBFR-M], st->mem_syn, M); + } + + /*--------------------------------------------------* + * Update signal for next frame. * + * -> shift to the left by L_SUBFR st->exc[] * + *--------------------------------------------------*/ + + Copy (&st->old_exc[L_SUBFR], &st->old_exc[0], PIT_MAX + L_INTERPOL); + + /* interpolated LPC parameters for next subframe */ + Az += MP1; move16 (); + + /* store T0 for next subframe */ + st->old_T0 = T0; move16 (); + } + + /*-------------------------------------------------------* + * Call the Source Characteristic Detector which updates * + * st->inBackgroundNoise and st->voicedHangover. * + *-------------------------------------------------------*/ + + st->inBackgroundNoise = Bgn_scd(&st->background_state, + &(st->ltpGainHistory[0]), + &(synth[0]), + &(st->voicedHangover) ); + + dtx_dec_activity_update(&st->dtxDecoderState, + st->lsfState.past_lsf_q, + synth); + + /* store bfi for next subframe */ + st->prev_bf = bfi; move16 (); + st->prev_pdf = pdfi; move16 (); + + /*--------------------------------------------------* + * Calculate the LSF averages on the eight * + * previous frames * + *--------------------------------------------------*/ + + lsp_avg(&st->lsp_avg_st, st->lsfState.past_lsf_q); + +the_end: + st->dtxDecoderState.dtxGlobalState = newDTXState; + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/dec_amr.h Tue May 07 20:33:01 2024 +0000 @@ -0,0 +1,136 @@ +/* +***************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 +* R99 Version 3.3.0 +* REL-4 Version 4.1.0 +* +***************************************************************************** +* +* File : dec_amr.h +* Purpose : Speech decoder routine. +* +***************************************************************************** +*/ +#ifndef dec_amr_h +#define dec_amr_h "$Id $" + +/* +***************************************************************************** +* INCLUDE FILES +***************************************************************************** +*/ +#include "tw_amr.h" +#include "typedef.h" +#include "cnst.h" +#include "dtx_dec.h" +#include "d_plsf.h" +#include "gc_pred.h" +#include "ec_gains.h" +#include "ph_disp.h" +#include "c_g_aver.h" +#include "bgnscd.h" +#include "lsp_avg.h" + +/* +***************************************************************************** +* LOCAL VARIABLES AND TABLES +***************************************************************************** +*/ +/*---------------------------------------------------------------* + * Postfilter constant parameters (defined in "cnst.h") * + *---------------------------------------------------------------* + * L_FRAME : Frame size. * + * PIT_MAX : Maximum pitch lag. * + * L_INTERPOL : Length of filter for interpolation. * + * M : LPC order. * + *---------------------------------------------------------------*/ + +/* +***************************************************************************** +* DEFINITION OF DATA TYPES +***************************************************************************** +*/ +typedef struct{ + /* Excitation vector */ + Word16 old_exc[L_SUBFR + PIT_MAX + L_INTERPOL]; + Word16 *exc; + + /* Lsp (Line spectral pairs) */ + /* Word16 lsp[M]; */ /* Used by CN codec */ + Word16 lsp_old[M]; + + /* Filter's memory */ + Word16 mem_syn[M]; + + /* pitch sharpening */ + Word16 sharp; + Word16 old_T0; + + /* Memories for bad frame handling */ + Word16 prev_bf; + Word16 prev_pdf; + Word16 state; + Word16 excEnergyHist[9]; + + /* Variable holding received ltpLag, used in background noise and BFI */ + Word16 T0_lagBuff; + + /* Variables for the source characteristic detector (SCD) */ + Word16 inBackgroundNoise; + Word16 voicedHangover; + Word16 ltpGainHistory[9]; + + Bgn_scdState background_state; + Word16 nodataSeed; + + 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; + + +/* +***************************************************************************** +* DECLARATION OF PROTOTYPES +***************************************************************************** +*/ + +/* +************************************************************************** +* +* Function : Decoder_amr_reset +* Purpose : Resets state memory +* Returns : 0 on success +* +************************************************************************** +*/ +void Decoder_amr_reset (Decoder_amrState *st, Flag dtx_partial_reset); + +/* +************************************************************************** +* +* Function : Decoder_amr +* Purpose : Speech decoder routine. +* Returns : 0 +* +************************************************************************** +*/ +int Decoder_amr ( + Decoder_amrState *st, /* i/o : State variables */ + enum Mode mode, /* i : AMR mode */ + Word16 parm[], /* i : vector of synthesis parameters + (PRM_SIZE) */ + enum RXFrameType frame_type, /* i : received frame type */ + Word16 synth[], /* o : synthesis speech (L_FRAME) */ + Word16 A_t[] /* o : decoded LP filter in 4 subframes + (AZ_SIZE) */ +); + +#endif
--- a/libtwamr/namespace.list Tue May 07 19:18:57 2024 +0000 +++ b/libtwamr/namespace.list Tue May 07 20:33:01 2024 +0000 @@ -57,6 +57,7 @@ vad1 vad1_reset vad_complex_detection_update vad_tone_detection vad_tone_detection_update vad_pitch_detection vad2 vad2_reset r_fft LTP_flag_update vad_reset +Decoder_amr Decoder_amr_reset Bits2prm Prm2bits