# HG changeset patch # User Mychaela Falconia # Date 1715118347 0 # Node ID 357d1faad55d26650754dcb9d728f1f4234e7eac # Parent 7bef001cd8b8d9c7e16e106ae61170c7f3c5a10b libtwamr: implement decoder top level diff -r 7bef001cd8b8 -r 357d1faad55d libtwamr/Makefile --- a/libtwamr/Makefile Tue May 07 20:33:01 2024 +0000 +++ b/libtwamr/Makefile Tue May 07 21:45:47 2024 +0000 @@ -5,19 +5,19 @@ 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_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 + dec_amr.o dec_gain.o dec_lag3.o dec_lag6.o dec_main.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 \ diff -r 7bef001cd8b8 -r 357d1faad55d libtwamr/dec_main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/dec_main.c Tue May 07 21:45:47 2024 +0000 @@ -0,0 +1,82 @@ +/* + * This C module is the top level entity for our stateful decoder engine. + */ + +#include +#include +#include +#include "tw_amr.h" +#include "namespace.h" +#include "typedef.h" +#include "cnst.h" +#include "dec_amr.h" +#include "pstfilt.h" +#include "post_pro.h" +#include "bitno.h" + +struct amr_decoder_state { + Decoder_amrState dec; + Post_FilterState pstfilt; + Post_ProcessState posthp; + enum Mode prev_mode; + Flag is_homed; +}; + +struct amr_decoder_state *amr_decoder_create(void) +{ + struct amr_decoder_state *st; + + st = malloc(sizeof(struct amr_decoder_state)); + if (st) + amr_decoder_reset(st); + return st; +} + +void amr_decoder_reset(struct amr_decoder_state *st) +{ + Decoder_amr_reset(&st->dec, 0); + Post_Filter_reset(&st->pstfilt); + Post_Process_reset(&st->posthp); + st->prev_mode = (enum Mode) 0; + st->is_homed = 1; +} + +void amr_decode_frame(struct amr_decoder_state *st, + const struct amr_param_frame *frame, int16_t *pcm) +{ + enum Mode mode; + Word16 parm[MAX_PRM_SIZE]; + Word16 Az_dec[AZ_SIZE]; + Word16 i; + + /* fast home state handling needs to be first */ + if (st->is_homed && amr_check_dhf(frame, 1)) { + for (i = 0; i < L_FRAME; i++) + pcm[i] = EHF_MASK; + return; + } + /* "unpack" into internal form */ + if (frame->type == RX_NO_DATA) + mode = st->prev_mode; + else { + mode = frame->mode & 7; + st->prev_mode = mode; + } + memcpy(parm, frame->param, prmno[mode] * sizeof(int16_t)); + /* now we can call the guts of the decoder */ + Decoder_amr(&st->dec, mode, parm, frame->type, pcm, Az_dec); + Post_Filter(&st->pstfilt, mode, pcm, Az_dec); + Post_Process(&st->posthp, pcm, L_FRAME); + /* + * The 3 lsbs of each speech sample typically won't be all 0 + * out of Post_Process(), hence we have to clear them explicitly + * to maintain overall bit-exact operation. + */ + for (i = 0; i < L_FRAME; i++) + pcm[i] &= 0xFFF8; + /* final check for full DHF */ + if (amr_check_dhf(frame, 0)) + amr_decoder_reset(st); + else + st->is_homed = 0; +}