changeset 441:ebe499058c63

libtwamr: implement API functions for RFC 4867 I/O
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 May 2024 07:06:31 +0000
parents bc736a8654af
children 6fa27df6903b
files libtwamr/Makefile libtwamr/ietf_fo.c libtwamr/ietf_in.c libtwamr/ietf_out.c libtwamr/if1_bit_order.c libtwamr/if1_func.h libtwamr/if1_pack.c libtwamr/if1_unpack.c libtwamr/namespace.list
diffstat 9 files changed, 479 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/libtwamr/Makefile	Thu May 09 00:13:05 2024 +0000
+++ b/libtwamr/Makefile	Thu May 09 07:06:31 2024 +0000
@@ -9,7 +9,8 @@
 	dhf_subst.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 fr_type_conv.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 \
+	hp_max.o ietf_fo.o ietf_in.o ietf_out.o if1_bit_order.o if1_pack.o \
+	if1_unpack.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 \
@@ -27,15 +28,16 @@
 	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
+	hp_max.h if1_func.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/ietf_fo.c	Thu May 09 07:06:31 2024 +0000
@@ -0,0 +1,23 @@
+/*
+ * The function implemented in this module groks the first octet of
+ * an RFC 4867 payload and tells the calling application how many more
+ * bytes need to be read, or if the frame type is invalid.
+ */
+
+#include <stdint.h>
+#include "tw_amr.h"
+
+static const uint8_t extra_bytes_per_ft[9] =
+		{12, 13, 15, 17, 19, 20, 26, 31, 5};
+
+int amr_ietf_grok_first_octet(uint8_t fo)
+{
+	uint8_t ft;
+
+	ft = (fo & 0x78) >> 3;
+	if (ft == AMR_FT_NODATA)
+		return 0;
+	if (ft > MRDTX)
+		return -1;
+	return extra_bytes_per_ft[ft];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/ietf_in.c	Thu May 09 07:06:31 2024 +0000
@@ -0,0 +1,49 @@
+/*
+ * The function implemented in this module is responsible for parsing
+ * an incoming RFC 4867 payload and turning it into struct amr_param_frame
+ * for decoding.
+ */
+
+#include <stdint.h>
+#include "tw_amr.h"
+#include "typedef.h"
+#include "namespace.h"
+#include "cnst.h"
+#include "int_defs.h"
+#include "if1_func.h"
+
+int amr_frame_from_ietf(const uint8_t *bytes, struct amr_param_frame *frame)
+{
+	Word16 ft, q, sti;
+	Word16 serial[MAX_SERIAL_SIZE];
+
+	ft = (bytes[0] & 0x78) >> 3;
+	q  = (bytes[0] & 0x04) >> 2;
+	if (ft == AMR_FT_NODATA) {
+		frame->type = RX_NO_DATA;
+		frame->mode = 0xFF;
+		return 0;
+	}
+	if (ft > MRDTX)
+		return -1;
+	if1_unpack_bytes(ft, bytes + 1, serial);
+	Bits2prm(ft, serial, frame->param);
+	if (ft != MRDTX) {
+		frame->type = q ? RX_SPEECH_GOOD : RX_SPEECH_BAD;
+		frame->mode = ft;
+	} else {
+		sti = (bytes[5] & 0x10) >> 4;
+		frame->mode = 0;
+		if (bytes[5] & 0x08)
+			frame->mode |= 1;
+		if (bytes[5] & 0x04)
+			frame->mode |= 2;
+		if (bytes[5] & 0x02)
+			frame->mode |= 4;
+		if (q)
+			frame->type = sti ? RX_SID_UPDATE : RX_SID_FIRST;
+		else
+			frame->type = RX_SID_BAD;
+	}
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/ietf_out.c	Thu May 09 07:06:31 2024 +0000
@@ -0,0 +1,57 @@
+/*
+ * The function implemented in this module is responsible for turning
+ * struct amr_param_frame (encoder output) into an RFC 4867 payload.
+ */
+
+#include <stdint.h>
+#include "tw_amr.h"
+#include "typedef.h"
+#include "namespace.h"
+#include "cnst.h"
+#include "int_defs.h"
+#include "if1_func.h"
+
+static const uint8_t total_bytes_per_ft[9] =
+		{13, 14, 16, 18, 20, 21, 27, 32, 6};
+
+static const uint8_t first_octet_per_ft[9] =
+		{0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34, 0x3C, 0x44};
+
+unsigned amr_frame_to_ietf(const struct amr_param_frame *frame, uint8_t *bytes)
+{
+	Word16 serial[MAX_SERIAL_SIZE];
+	Word16 sti;
+	enum Mode ft;
+
+	switch (frame->type) {
+	case TX_SPEECH_GOOD:
+		ft = frame->mode;
+		break;
+	case TX_SID_FIRST:
+		ft = MRDTX;
+		sti = 0;
+		break;
+	case TX_SID_UPDATE:
+		ft = MRDTX;
+		sti = 1;
+		break;
+	case TX_NO_DATA:
+	default:
+		bytes[0] = 0x7C;
+		return 1;
+	}
+	Prm2bits(ft, frame->param, serial);
+	bytes[0] = first_octet_per_ft[ft];
+	if1_pack_bytes(ft, serial, bytes + 1);
+	if (ft == MRDTX) {
+		if (sti)
+			bytes[5] |= 0x10;
+		if (frame->mode & 1)
+			bytes[5] |= 0x08;
+		if (frame->mode & 2)
+			bytes[5] |= 0x04;
+		if (frame->mode & 4)
+			bytes[5] |= 0x02;
+	}
+	return total_bytes_per_ft[ft];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/if1_bit_order.c	Thu May 09 07:06:31 2024 +0000
@@ -0,0 +1,158 @@
+/*
+ * The const tables supplied by this module are used by
+ * IF1 and RFC 4867 packing and unpacking functions.
+ */
+
+#include <stdint.h>
+#include "namespace.h"
+#include "if1_func.h"
+
+/* sorting tables for all modes */
+
+const uint8_t sort_475[95] = {
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+   10, 11, 12, 13, 14, 15, 23, 24, 25, 26,
+   27, 28, 48, 49, 61, 62, 82, 83, 47, 46,
+   45, 44, 81, 80, 79, 78, 17, 18, 20, 22,
+   77, 76, 75, 74, 29, 30, 43, 42, 41, 40,
+   38, 39, 16, 19, 21, 50, 51, 59, 60, 63,
+   64, 72, 73, 84, 85, 93, 94, 32, 33, 35,
+   36, 53, 54, 56, 57, 66, 67, 69, 70, 87,
+   88, 90, 91, 34, 55, 68, 89, 37, 58, 71,
+   92, 31, 52, 65, 86
+};
+
+const uint8_t sort_515[103] = {
+    7,  6,  5,   4,   3,   2,  1,  0, 15, 14,
+   13, 12, 11,  10,   9,   8, 23, 24, 25, 26,
+   27, 46, 65,  84,  45,  44, 43, 64, 63, 62,
+   83, 82, 81, 102, 101, 100, 42, 61, 80, 99,
+   28, 47, 66,  85,  18,  41, 60, 79, 98, 29,
+   48, 67, 17,  20,  22,  40, 59, 78, 97, 21,
+   30, 49, 68,  86,  19,  16, 87, 39, 38, 58,
+   57, 77, 35,  54,  73,  92, 76, 96, 95, 36,
+   55, 74, 93,  32,  51,  33, 52, 70, 71, 89,
+   90, 31, 50,  69,  88,  37, 56, 75, 94, 34,
+   53, 72, 91							
+};
+
+const uint8_t sort_59[118] = {
+    0,   1,   4,   5,   3,   6,   7,   2,  13,  15,
+    8,   9,  11,  12,  14,  10,  16,  28,  74,  29,
+   75,  27,  73,  26,  72,  30,  76,  51,  97,  50,
+   71,  96, 117,  31,  77,  52,  98,  49,  70,  95,
+  116,  53,  99,  32,  78,  33,  79,  48,  69,  94,
+  115,  47,  68,  93, 114,  46,  67,  92, 113,  19,
+   21,  23,  22,  18,  17,  20,  24, 111,  43,  89,
+  110,  64,  65,  44,  90,  25,  45,  66,  91, 112,
+   54, 100,  40,  61,  86, 107,  39,  60,  85, 106,
+   36,  57,  82, 103,  35,  56,  81, 102,  34,  55,
+   80, 101,  42,  63,  88, 109,  41,  62,  87, 108,
+   38,  59,  84, 105,  37,  58,  83, 104
+};
+
+const uint8_t sort_67[134] = {
+    0,   1,   4,   3,   5,   6,  13,   7,   2,   8,
+    9,  11,  15,  12,  14,  10,  28,  82,  29,  83,
+   27,  81,  26,  80,  30,  84,  16,  55, 109,  56,
+  110,  31,  85,  57, 111,  48,  73, 102, 127,  32,
+   86,  51,  76, 105, 130,  52,  77, 106, 131,  58,
+  112,  33,  87,  19,  23,  53,  78, 107, 132,  21,
+   22,  18,  17,  20,  24,  25,  50,  75, 104, 129,
+   47,  72, 101, 126,  54,  79, 108, 133,  46,  71,
+  100, 125, 128, 103,  74,  49,  45,  70,  99, 124,
+   42,  67,  96, 121,  39,  64,  93, 118,  38,  63,
+   92, 117,  35,  60,  89, 114,  34,  59,  88, 113,
+   44,  69,  98, 123,  43,  68,  97, 122,  41,  66,
+   95, 120,  40,  65,  94, 119,  37,  62,  91, 116,
+   36,  61,  90, 115						
+};
+
+const uint8_t sort_74[148] = {
+    0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
+   10,  11,  12,  13,  14,  15,  16,  26,  87,  27,
+   88,  28,  89,  29,  90,  30,  91,  51,  80, 112,
+  141,  52,  81, 113, 142,  54,  83, 115, 144,  55,
+   84, 116, 145,  58, 119,  59, 120,  21,  22,  23,
+   17,  18,  19,  31,  60,  92, 121,  56,  85, 117,
+  146,  20,  24,  25,  50,  79, 111, 140,  57,  86,
+  118, 147,  49,  78, 110, 139,  48,  77,  53,  82,
+  114, 143, 109, 138,  47,  76, 108, 137,  32,  33,
+   61,  62,  93,  94, 122, 123,  41,  42,  43,  44,
+   45,  46,  70,  71,  72,  73,  74,  75, 102, 103,
+  104, 105, 106, 107, 131, 132, 133, 134, 135, 136,
+   34,  63,  95, 124,  35,  64,  96, 125,  36,  65,
+   97, 126,  37,  66,  98, 127,	 38,  67,  99, 128,
+   39,  68, 100, 129,  40,  69, 101, 130
+};
+
+const uint8_t sort_795[159] = {
+    8,   7,   6,   5,   4,   3,   2,  14,  16,   9,
+   10,  12,  13,  15,  11,  17,  20,  22,  24,  23,
+   19,  18,  21,  56,  88, 122, 154,  57,  89, 123,
+  155,  58,  90, 124, 156,  52,  84, 118, 150,  53,
+   85, 119, 151,  27,  93,  28,  94,  29,  95,  30,
+   96,  31,  97,  61, 127,  62, 128,  63, 129,  59,
+   91, 125, 157,  32,  98,  64, 130,   1,   0,  25,
+   26,  33,  99,  34, 100,  65, 131,  66, 132,  54,
+   86, 120, 152,  60,  92, 126, 158,  55,  87, 121,
+  153, 117, 116, 115,  46,  78, 112, 144,  43,  75,
+  109, 141,  40,  72, 106, 138,  36,  68, 102, 134,
+  114, 149, 148, 147, 146,  83,  82,  81,  80,  51,
+   50,  49,  48,  47,  45,  44,  42,  39,  35,  79,
+   77,  76,  74,  71,  67, 113, 111, 110, 108, 105,
+  101, 145, 143, 142, 140, 137, 133,  41,  73, 107,
+  139,  37,  69, 103, 135,  38,  70, 104, 136
+};
+
+const uint8_t sort_102[204] = {
+    7,   6,   5,   4,   3,   2,   1,   0,  16,  15,
+   14,  13,  12,  11,  10,   9,   8,  26,  27,  28,
+   29,  30,  31, 115, 116, 117, 118, 119, 120,  72,
+   73, 161, 162,  65,  68,  69, 108, 111, 112, 154,
+  157, 158, 197, 200, 201,  32,  33, 121, 122,  74,
+   75, 163, 164,  66, 109, 155, 198,  19,  23,  21,
+   22,  18,  17,  20,  24,  25,  37,  36,  35,  34,
+   80,  79,  78,  77, 126, 125, 124, 123, 169, 168,
+  167, 166,  70,  67,  71, 113, 110, 114, 159, 156,
+  160, 202, 199, 203,  76, 165,  81,  82,  92,  91,
+   93,  83,  95,  85,  84,  94, 101, 102,  96, 104,
+   86, 103,  87,  97, 127, 128, 138, 137, 139, 129,
+  141, 131, 130, 140, 147, 148, 142, 150, 132, 149,
+  133, 143, 170, 171, 181, 180, 182, 172, 184, 174,
+  173, 183, 190, 191, 185, 193, 175, 192, 176, 186,
+   38,  39,  49,  48,  50,  40,  52,  42,  41,  51,
+   58,  59,  53,  61,  43,  60,  44,  54, 194, 179,
+  189, 196, 177, 195, 178, 187, 188, 151, 136, 146,
+  153, 134, 152, 135, 144, 145, 105,  90, 100, 107,
+   88, 106,  89,  98,  99,  62,  47,  57,  64,  45,
+   63,  46,  55,  56					
+};
+
+const uint8_t sort_122[244] = {
+    0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
+   10,  11,  12,  13,  14,  23,  15,  16,  17,  18,
+   19,  20,  21,  22,  24,  25,  26,  27,  28,  38,
+  141,  39, 142,  40, 143,  41, 144,  42, 145,  43,
+  146,  44, 147,  45, 148,  46, 149,  47,  97, 150,
+  200,  48,  98, 151, 201,  49,  99, 152, 202,  86,
+  136, 189, 239,  87, 137, 190, 240,  88, 138, 191,
+  241,  91, 194,  92, 195,  93, 196,  94, 197,  95,
+  198,  29,  30,  31,  32,  33,  34,  35,  50, 100,
+  153, 203,  89, 139, 192, 242,  51, 101, 154, 204,
+   55, 105, 158, 208,  90, 140, 193, 243,  59, 109,
+  162, 212,  63, 113, 166, 216,  67, 117, 170, 220,
+   36,  37,  54,  53,  52,  58,  57,  56,  62,  61,
+   60,  66,  65,  64,  70,  69,  68, 104, 103, 102,
+  108, 107, 106, 112, 111, 110, 116, 115, 114, 120,
+  119, 118, 157, 156, 155, 161, 160, 159, 165, 164,
+  163, 169, 168, 167, 173, 172, 171, 207, 206, 205,
+  211, 210, 209, 215, 214, 213, 219, 218, 217, 223,
+  222, 221,  73,  72,  71,  76,  75,  74,  79,  78,
+   77,  82,  81,  80,  85,  84,  83, 123, 122, 121,
+  126, 125, 124, 129, 128, 127, 132, 131, 130, 135,
+  134, 133, 176, 175, 174, 179, 178, 177, 182, 181,
+  180, 185, 184, 183, 188, 187, 186, 226, 225, 224,
+  229, 228, 227, 232, 231, 230, 235, 234, 233, 238,
+  237, 236,  96, 199						
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/if1_func.h	Thu May 09 07:06:31 2024 +0000
@@ -0,0 +1,28 @@
+/*
+ * This header file provides prototype declarations for AMR IF1
+ * packing and unpacking functions, as well as extern declarations
+ * for the set of const data tables they need.
+ */
+
+#ifndef	if1_func_h
+#define	if1_func_h
+
+#include <stdint.h>
+#include "tw_amr.h"
+#include "typedef.h"
+
+void if1_pack_bytes(enum Mode mode, const Word16 *serial_bits,
+		    uint8_t *if1_bytes);
+void if1_unpack_bytes(enum Mode mode, const uint8_t *if1_bytes,
+		      Word16 *serial_bits);
+
+extern const uint8_t sort_475[95];
+extern const uint8_t sort_515[103];
+extern const uint8_t sort_59[118];
+extern const uint8_t sort_67[134];
+extern const uint8_t sort_74[148];
+extern const uint8_t sort_795[159];
+extern const uint8_t sort_102[204];
+extern const uint8_t sort_122[244];
+
+#endif	/* include guard */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/if1_pack.c	Thu May 09 07:06:31 2024 +0000
@@ -0,0 +1,81 @@
+/*
+ * In this module we implement our function for packing AMR codec bits
+ * from an array containing them in the codec's natural bit order
+ * into the octet form of AMR IF1 and RFC 4867.
+ */
+
+#include <stdint.h>
+#include "tw_amr.h"
+#include "typedef.h"
+#include "namespace.h"
+#include "int_defs.h"
+#include "if1_func.h"
+
+static inline void msb_set_bit(uint8_t *buf, Word16 bn, Word16 bit)
+{
+	Word16 pos_byte = bn >> 3;
+	Word16 pos_bit  = 7 - (bn & 7);
+
+	if (bit)
+		buf[pos_byte] |= (1 << pos_bit);
+	else
+		buf[pos_byte] &= ~(1 << pos_bit);
+}
+
+static void pack_bits(uint8_t *if1_bytes, const Word16 *src_bits, Word16 nbits,
+		      const uint8_t *table)
+{
+	Word16 n, nb;
+
+	for (n = 0; n < nbits; n++) {
+		if (table)
+			nb = table[n];
+		else
+			nb = n;
+		msb_set_bit(if1_bytes, n, src_bits[nb]);
+	}
+}
+
+void if1_pack_bytes(enum Mode mode, const Word16 *serial_bits,
+		    uint8_t *if1_bytes)
+{
+	switch (mode) {
+	case MR475:
+		pack_bits(if1_bytes, serial_bits, AMR_NBITS_475, sort_475);
+		if1_bytes[11] &= 0xFE;
+		return;
+	case MR515:
+		pack_bits(if1_bytes, serial_bits, AMR_NBITS_515, sort_515);
+		if1_bytes[12] &= 0xFE;
+		return;
+	case MR59:
+		pack_bits(if1_bytes, serial_bits, AMR_NBITS_59, sort_59);
+		if1_bytes[14] &= 0xFC;
+		return;
+	case MR67:
+		pack_bits(if1_bytes, serial_bits, AMR_NBITS_67, sort_67);
+		if1_bytes[16] &= 0xFC;
+		return;
+	case MR74:
+		pack_bits(if1_bytes, serial_bits, AMR_NBITS_74, sort_74);
+		if1_bytes[18] &= 0xF0;
+		return;
+	case MR795:
+		pack_bits(if1_bytes, serial_bits, AMR_NBITS_795, sort_795);
+		if1_bytes[19] &= 0xFE;
+		return;
+	case MR102:
+		pack_bits(if1_bytes, serial_bits, AMR_NBITS_102, sort_102);
+		if1_bytes[25] &= 0xF0;
+		return;
+	case MR122:            
+		pack_bits(if1_bytes, serial_bits, AMR_NBITS_122, sort_122);
+		if1_bytes[30] &= 0xF0;
+		return;
+	case MRDTX:
+		pack_bits(if1_bytes, serial_bits, AMR_NBITS_SID,
+				(const uint8_t *) 0);
+		if1_bytes[4] &= 0xE0;
+		return;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtwamr/if1_unpack.c	Thu May 09 07:06:31 2024 +0000
@@ -0,0 +1,68 @@
+/*
+ * In this module we implement our function for unpacking bits from AMR IF1
+ * and reshuffling them into the codec's natural bit order.
+ */
+
+#include <stdint.h>
+#include "tw_amr.h"
+#include "typedef.h"
+#include "namespace.h"
+#include "int_defs.h"
+#include "if1_func.h"
+
+static inline Word16 msb_get_bit(const uint8_t *buf, Word16 bn)
+{
+	Word16 pos_byte = bn >> 3;
+	Word16 pos_bit  = 7 - (bn & 7);
+
+	return (buf[pos_byte] >> pos_bit) & 1;
+}
+
+static void unpack_bits(const uint8_t *if1_bytes, Word16 *codec_bits,
+			Word16 nbits, const uint8_t *table)
+{
+	Word16 n, nb;
+
+	for (n = 0; n < nbits; n++) {
+		if (table)
+			nb = table[n];
+		else
+			nb = n;
+		codec_bits[nb] = msb_get_bit(if1_bytes, n);
+	}
+}
+
+void if1_unpack_bytes(enum Mode mode, const uint8_t *if1_bytes,
+		      Word16 *serial_bits)
+{
+	switch (mode) {
+	case MR475:
+		unpack_bits(if1_bytes, serial_bits, AMR_NBITS_475, sort_475);
+		return;
+	case MR515:
+		unpack_bits(if1_bytes, serial_bits, AMR_NBITS_515, sort_515);
+		return;
+	case MR59:
+		unpack_bits(if1_bytes, serial_bits, AMR_NBITS_59, sort_59);
+		return;
+	case MR67:
+		unpack_bits(if1_bytes, serial_bits, AMR_NBITS_67, sort_67);
+		return;
+	case MR74:
+		unpack_bits(if1_bytes, serial_bits, AMR_NBITS_74, sort_74);
+		return;
+	case MR795:
+		unpack_bits(if1_bytes, serial_bits, AMR_NBITS_795, sort_795);
+		return;
+	case MR102:
+		unpack_bits(if1_bytes, serial_bits, AMR_NBITS_102, sort_102);
+		return;
+	case MR122:            
+		unpack_bits(if1_bytes, serial_bits, AMR_NBITS_122, sort_122);
+		return;
+	case MRDTX:
+		unpack_bits(if1_bytes, serial_bits, AMR_NBITS_SID,
+				(const uint8_t *) 0);
+		return;
+	}
+}
--- a/libtwamr/namespace.list	Thu May 09 00:13:05 2024 +0000
+++ b/libtwamr/namespace.list	Thu May 09 07:06:31 2024 +0000
@@ -84,3 +84,6 @@
 encoder_homing_frame_test
 ec_gain_code_reset ec_gain_code ec_gain_code_update
 ec_gain_pitch_reset ec_gain_pitch ec_gain_pitch_update
+
+sort_475 sort_515 sort_59 sort_67 sort_74 sort_795 sort_102 sort_122
+if1_pack_bytes if1_unpack_bytes