Change in libosmocore[master]: codec: Add functions for AMR s->d bits and d->s bits

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Thu May 14 15:54:36 UTC 2020


laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/18246 )

Change subject: codec: Add functions for AMR s->d bits and d->s bits
......................................................................

codec: Add functions for AMR s->d bits and d->s bits

These functions implement re-ordering of bits as per TS 06.90 / 26.101
based on the already existing tables we've had in libosmocoding.

Change-Id: Ia4ac2aea2e96f9185f082a07ca64dfc5276efb46
---
M include/osmocom/codec/codec.h
M src/codec/Makefile.am
M src/codec/gsm690.c
M tests/codec/codec_test.c
M tests/codec/codec_test.ok
5 files changed, 165 insertions(+), 1 deletion(-)

Approvals:
  Jenkins Builder: Verified
  tnt: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved



diff --git a/include/osmocom/codec/codec.h b/include/osmocom/codec/codec.h
index 6a1bf9f..cbdad75 100644
--- a/include/osmocom/codec/codec.h
+++ b/include/osmocom/codec/codec.h
@@ -6,6 +6,7 @@
 #include <stdbool.h>
 
 #include <osmocom/core/utils.h>
+#include <osmocom/core/bits.h>
 
 /* TS 101318 Chapter 5.1: 260 bits + 4bit sig */
 #define GSM_FR_BYTES	33
@@ -51,6 +52,11 @@
        AMR_GOOD = 1
 };
 
+extern const uint8_t gsm690_bitlength[AMR_NO_DATA+1];
+
+int osmo_amr_s_to_d(ubit_t *out, const ubit_t *in, uint16_t n_bits, enum osmo_amr_type amr_mode);
+int osmo_amr_d_to_s(ubit_t *out, const ubit_t *in, uint16_t n_bits, enum osmo_amr_type amr_mode);
+
 /*! Check if given AMR Frame Type is a speech frame
  *  \param[in] ft AMR Frame Type
  *  \returns true if AMR with given Frame Type contains voice, false otherwise
diff --git a/src/codec/Makefile.am b/src/codec/Makefile.am
index ac33aa0..778eb2a 100644
--- a/src/codec/Makefile.am
+++ b/src/codec/Makefile.am
@@ -3,7 +3,7 @@
 # before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html
 LIBVERSION=2:0:2
 
-AM_CPPFLAGS = -I$(top_srcdir)/include $(TALLOC_CFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include $(TALLOC_CFLAGS)
 AM_CFLAGS = -Wall
 
 if ENABLE_PSEUDOTALLOC
diff --git a/src/codec/gsm690.c b/src/codec/gsm690.c
index 8ab1df1..cc6cdf0 100644
--- a/src/codec/gsm690.c
+++ b/src/codec/gsm690.c
@@ -2,6 +2,7 @@
  * GSM 06.90 - GSM AMR Codec. */
 /*
  * (C) 2010 Sylvain Munaut <tnt at 246tNt.com>
+ * (C) 2020 Harald Welte <laforge at gnumonks.org>
  *
  * All Rights Reserved
  *
@@ -29,6 +30,7 @@
 #include <stdlib.h>
 
 #include <osmocom/core/utils.h>
+#include <osmocom/core/bits.h>
 #include <osmocom/codec/codec.h>
 /*
  * These table map between the raw encoder parameter output and
@@ -216,6 +218,114 @@
 	 92,  31,  52,  65,  86,
 };
 
+/*! These constants refer to the length of one "AMR core frame" as per
+ *  TS 26.101 Section 4.2.2 / Table 2. */
+const uint8_t gsm690_bitlength[AMR_NO_DATA+1] = {
+	[AMR_4_75] = 95,
+	[AMR_5_15] = 103,
+	[AMR_5_90] = 118,
+	[AMR_6_70] = 134,
+	[AMR_7_40] = 148,
+	[AMR_7_95] = 159,
+	[AMR_10_2] = 204,
+	[AMR_12_2] = 244,
+	[AMR_SID] = 39,
+};
+
+struct ts26101_reorder_table {
+	/*! Table as per TS 26.101 Annex B to compute d-bits from s-bits */
+	const uint16_t *s_to_d;
+	/*! size of table */
+	uint8_t len;
+};
+
+static const struct ts26101_reorder_table ts26101_reorder_tables[8] = {
+	[AMR_4_75] = {
+		.s_to_d = gsm690_4_75_bitorder,
+		.len = ARRAY_SIZE(gsm690_4_75_bitorder),
+	},
+	[AMR_5_15] = {
+		.s_to_d = gsm690_5_15_bitorder,
+		.len = ARRAY_SIZE(gsm690_5_15_bitorder),
+	},
+	[AMR_5_90] = {
+		.s_to_d = gsm690_5_9_bitorder,
+		.len = ARRAY_SIZE(gsm690_5_9_bitorder),
+	},
+	[AMR_6_70] = {
+		.s_to_d = gsm690_6_7_bitorder,
+		.len = ARRAY_SIZE(gsm690_6_7_bitorder),
+	},
+	[AMR_7_40] = {
+		.s_to_d = gsm690_7_4_bitorder,
+		.len = ARRAY_SIZE(gsm690_7_4_bitorder),
+	},
+	[AMR_7_95] = {
+		.s_to_d = gsm690_7_95_bitorder,
+		.len = ARRAY_SIZE(gsm690_7_95_bitorder),
+	},
+	[AMR_10_2] = {
+		.s_to_d = gsm690_10_2_bitorder,
+		.len = ARRAY_SIZE(gsm690_10_2_bitorder),
+	},
+	[AMR_12_2] = {
+		.s_to_d = gsm690_12_2_bitorder,
+		.len = ARRAY_SIZE(gsm690_12_2_bitorder),
+	},
+};
+
+/*! Convert from S-bits (codec output) to d-bits.
+ *  \param[out] out user-provided output buffer for generated unpacked d-bits
+ *  \param[in] in input buffer for unpacked s-bits
+ *  \param[in] n_bits number of bits (in both in and out)
+ *  \param[in] AMR mode (0..7) */
+int osmo_amr_s_to_d(ubit_t *out, const ubit_t *in, uint16_t n_bits, enum osmo_amr_type amr_mode)
+{
+	const struct ts26101_reorder_table *tbl;
+	int i;
+
+	if (amr_mode >= ARRAY_SIZE(ts26101_reorder_tables))
+		return -ENODEV;
+
+	tbl = &ts26101_reorder_tables[amr_mode];
+
+	if (n_bits > tbl->len)
+		return -EINVAL;
+
+	for (i = 0; i < n_bits; i++) {
+		uint16_t n = tbl->s_to_d[i];
+		out[i] = in[n];
+	}
+
+	return n_bits;
+}
+
+/*! Convert from d-bits to s-bits (codec input).
+ *  \param[out] out user-provided output buffer for generated unpacked s-bits
+ *  \param[in] in input buffer for unpacked d-bits
+ *  \param[in] n_bits number of bits (in both in and out)
+ *  \param[in] AMR mode (0..7) */
+int osmo_amr_d_to_s(ubit_t *out, const ubit_t *in, uint16_t n_bits, enum osmo_amr_type amr_mode)
+{
+	const struct ts26101_reorder_table *tbl;
+	int i;
+
+	if (amr_mode >= ARRAY_SIZE(ts26101_reorder_tables))
+		return -ENODEV;
+
+	tbl = &ts26101_reorder_tables[amr_mode];
+
+	if (n_bits > tbl->len)
+		return -EINVAL;
+
+	for (i = 0; i < n_bits; i++) {
+		uint16_t n = tbl->s_to_d[i];
+		out[n] = in[i];
+	}
+
+	return n_bits;
+}
+
 /* See also RFC 4867 §3.6, Table 1, Column "Total speech bits" */
 static const uint8_t amr_len_by_ft[16] = {
 	12, 13, 15, 17, 19, 20, 26, 31, 5,  0,  0,  0,  0,  0,  0,  0
diff --git a/tests/codec/codec_test.c b/tests/codec/codec_test.c
index 7a10fc5..5579e99 100644
--- a/tests/codec/codec_test.c
+++ b/tests/codec/codec_test.c
@@ -190,6 +190,42 @@
 	}
 }
 
+
+
+static void test_amr_s_d(void)
+{
+	ubit_t in[244];
+	ubit_t mid[244];
+	ubit_t out[244];
+	int i, j;
+
+	for (j = AMR_4_75; j <= AMR_12_2; j++) {
+		unsigned int n_bits = gsm690_bitlength[j];
+
+		printf("=> AMR Mode %d (%d bits)\n", j, n_bits);
+		/* set a single bit in the input buffer */
+		for (i = 0; i < n_bits; i++) {
+
+			memset(in, 0, sizeof(in));
+			in[i] = 1;
+
+			/* re-order from s to d */
+			osmo_amr_s_to_d(mid, in, n_bits, j);
+
+			/* and back to d */
+			osmo_amr_d_to_s(out, mid, n_bits, j);
+
+			if (memcmp(in, out, n_bits)) {
+				printf("Error in bit %d of mode %d!\n", i, j);
+				printf("inp s-bits: %s\n", osmo_ubit_dump(in, n_bits));
+				printf("mid d-bits: %s\n", osmo_ubit_dump(mid, n_bits));
+				printf("out s-bits: %s\n", osmo_ubit_dump(out, n_bits));
+				//OSMO_ASSERT(0);
+			}
+		}
+	}
+}
+
 int main(int argc, char **argv)
 {
 	printf("AMR RTP payload decoder test:\n");
@@ -213,6 +249,9 @@
 	printf("FR RTP payload SID test:\n");
 	test_sid_fr();
 
+	printf("AMR s/d bit re-ordering test:\n");
+	test_amr_s_d();
+
 	return 0;
 }
 
diff --git a/tests/codec/codec_test.ok b/tests/codec/codec_test.ok
index b8cba19..7d8609b 100644
--- a/tests/codec/codec_test.ok
+++ b/tests/codec/codec_test.ok
@@ -30,3 +30,12 @@
 FR SID d8 62 a2 61 60 00 00 10 00 00 92 00 00 00 00 40 00 00 08 00 00 00 01 00 00 01 00 00 80 00 40 02 40 : 1
 FR SID d9 e4 c3 6d 12 00 00 80 00 20 00 40 00 00 00 00 00 10 00 00 00 10 48 00 10 48 00 00 00 00 2d 04 00 : 1
 FR SID d9 a4 c3 29 59 00 00 10 00 00 12 00 00 00 00 41 00 00 01 00 00 00 01 00 80 00 00 00 00 42 00 12 02 : 1
+AMR s/d bit re-ordering test:
+=> AMR Mode 0 (95 bits)
+=> AMR Mode 1 (103 bits)
+=> AMR Mode 2 (118 bits)
+=> AMR Mode 3 (134 bits)
+=> AMR Mode 4 (148 bits)
+=> AMR Mode 5 (159 bits)
+=> AMR Mode 6 (204 bits)
+=> AMR Mode 7 (244 bits)

-- 
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/18246
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: Ia4ac2aea2e96f9185f082a07ca64dfc5276efb46
Gerrit-Change-Number: 18246
Gerrit-PatchSet: 4
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: tnt <tnt at 246tNt.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200514/c47a9d27/attachment.htm>


More information about the gerrit-log mailing list