diff libtwamr/dec_main.c @ 427:357d1faad55d

libtwamr: implement decoder top level
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 07 May 2024 21:45:47 +0000
parents libtwamr/enc_main.c@2a094af3d384
children
line wrap: on
line diff
--- /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 <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#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;
+}