Change in libosmocore[master]: dtx: add functions to determine DTX frame types

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/.

dexter gerrit-no-reply at lists.osmocom.org
Thu Feb 6 13:28:39 UTC 2020


dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/17095 )


Change subject: dtx: add functions to determine DTX frame types
......................................................................

dtx: add functions to determine DTX frame types

gsm0503_coding contains AMR decoder functions for HR and FR. Those can
only decode AMR payload frames but not amr DTX frames. Lets add some
detector functionality to be able to detect AMR DTX frames so that the
caller can be informed about this

Related: OS#2978
Change-Id: I2bbdb39ea20461ca08b2e6f1a33532cb55cd5195
---
M include/Makefile.am
A include/osmocom/coding/gsm0503_amr_dtx.h
M include/osmocom/coding/gsm0503_coding.h
M src/coding/Makefile.am
A src/coding/gsm0503_amr_dtx.c
M src/coding/gsm0503_coding.c
M src/coding/libosmocoding.map
M tests/Makefile.am
A tests/dtx/dtx_gsm0503_test.c
A tests/dtx/dtx_gsm0503_test.ok
M tests/testsuite.at
11 files changed, 553 insertions(+), 1 deletion(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/95/17095/1

diff --git a/include/Makefile.am b/include/Makefile.am
index b341ee3..572c880 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -90,6 +90,7 @@
                        osmocom/coding/gsm0503_mapping.h \
                        osmocom/coding/gsm0503_interleaving.h \
                        osmocom/coding/gsm0503_coding.h \
+                       osmocom/coding/gsm0503_amr_dtx.h \
                        osmocom/gsm/gsm0808.h \
                        osmocom/gsm/gsm29205.h \
                        osmocom/gsm/gsm0808_utils.h \
diff --git a/include/osmocom/coding/gsm0503_amr_dtx.h b/include/osmocom/coding/gsm0503_amr_dtx.h
new file mode 100644
index 0000000..7cf6857
--- /dev/null
+++ b/include/osmocom/coding/gsm0503_amr_dtx.h
@@ -0,0 +1,38 @@
+/*! \file gsm0503_amr_dtx.h
+ *  GSM TS 05.03 coding
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <osmocom/core/defs.h>
+#include <osmocom/core/bits.h>
+
+/*! \addtogroup coding
+ *  @{
+ * \file gsm0503_amr_dtx.h */
+
+enum gsm0503_amr_dtx_frames {
+	AFS_SID_FIRST,
+	AFS_SID_UPDATE,
+	AFS_ONSET,
+	AHS_SID_UPDATE,
+	AHS_SID_FIRST_P1,
+	AHS_SID_FIRST_P2,
+	AHS_ONSET,
+	AHS_SID_FIRST_INH,
+	AHS_SID_UPDATE_INH,
+	AMR_OTHER,
+};
+
+extern const struct value_string gsm0503_amr_dtx_frame_names[];
+static inline const char *gsm0503_amr_dtx_frame_name(uint8_t frame)
+{
+	return get_value_string(gsm0503_amr_dtx_frame_names, frame);
+}
+
+uint8_t gsm0503_detect_afs_dtx_frame(ubit_t * ubits);
+uint8_t gsm0503_detect_ahs_dtx_frame(ubit_t * ubits);
+
+/*! @} */
diff --git a/include/osmocom/coding/gsm0503_coding.h b/include/osmocom/coding/gsm0503_coding.h
index 98038f8..2afa049 100644
--- a/include/osmocom/coding/gsm0503_coding.h
+++ b/include/osmocom/coding/gsm0503_coding.h
@@ -58,12 +58,18 @@
 int gsm0503_tch_afs_decode(uint8_t *tch_data, const sbit_t *bursts,
 	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
 	uint8_t *cmr, int *n_errors, int *n_bits_total);
+int gsm0503_tch_afs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts,
+	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
+	uint8_t *cmr, int *n_errors, int *n_bits_total, uint8_t *dtx);
 
 int gsm0503_tch_ahs_encode(ubit_t *bursts, const uint8_t *tch_data, int len,
 	int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, uint8_t cmr);
 int gsm0503_tch_ahs_decode(uint8_t *tch_data, const sbit_t *bursts, int odd,
 	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
 	uint8_t *cmr, int *n_errors, int *n_bits_total);
+int gsm0503_tch_ahs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts, int odd,
+	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
+	uint8_t *cmr, int *n_errors, int *n_bits_total, uint8_t *dtx);
 
 int gsm0503_rach_ext_encode(ubit_t *burst, uint16_t ra, uint8_t bsic, bool is_11bit);
 int gsm0503_rach_encode(ubit_t *burst, const uint8_t *ra, uint8_t bsic) OSMO_DEPRECATED("Use gsm0503_rach_ext_encode() instead");
diff --git a/src/coding/Makefile.am b/src/coding/Makefile.am
index f47fe45..b023668 100644
--- a/src/coding/Makefile.am
+++ b/src/coding/Makefile.am
@@ -20,7 +20,8 @@
 	gsm0503_mapping.c \
 	gsm0503_tables.c \
 	gsm0503_parity.c \
-	gsm0503_coding.c
+	gsm0503_coding.c \
+	gsm0503_amr_dtx.c
 libosmocoding_la_LDFLAGS = \
 	$(LTLDFLAGS_OSMOCODING) \
 	-version-info \
diff --git a/src/coding/gsm0503_amr_dtx.c b/src/coding/gsm0503_amr_dtx.c
new file mode 100644
index 0000000..57aaf80
--- /dev/null
+++ b/src/coding/gsm0503_amr_dtx.c
@@ -0,0 +1,282 @@
+/*
+ * (C) 2016 by sysmocom - s.f.m.c. GmbH, Author: Philipp Maier
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/coding/gsm0503_amr_dtx.h>
+
+const struct value_string gsm0503_amr_dtx_frame_names[] = {
+	{ AFS_SID_FIRST, "AFS_SID_FIRST" },
+	{ AFS_SID_UPDATE, "AFS_SID_UPDATE" },
+	{ AFS_ONSET, "AFS_ONSET" },
+	{ AHS_SID_UPDATE, "AHS_SID_UPDATE" },
+	{ AHS_SID_FIRST_P1, "AHS_SID_FIRST_P1" },
+	{ AHS_SID_FIRST_P2, "AHS_SID_FIRST_P2" },
+	{ AHS_ONSET, "AHS_ONSET" },
+	{ AHS_SID_FIRST_INH, "AHS_SID_FIRST_INH" },
+	{ AHS_SID_UPDATE_INH, "AHS_SID_UPDATE_INH" },
+	{ AMR_OTHER, "NON DTX FRAME (OTHER)" },
+	{ 0, NULL }
+};
+
+static bool detect_afs_id_marker(ubit_t * ubits, uint8_t offset, uint8_t count)
+{
+	unsigned int i, k;
+	ubit_t id_marker[] = { 0, 1, 0, 0, 1, 1, 1, 1, 0 };
+	unsigned int id_bit_nr = 0;
+	unsigned int errors = 0;
+
+	/* Override coded in-band data */
+	ubits += offset;
+
+	/* Check for identification marker bits */
+	for (i = 0; i < count; i++) {
+		for (k = 0; k < 4; k++) {
+			if (id_marker[id_bit_nr % 9] != *ubits)
+				errors++;
+			id_bit_nr++;
+			ubits++;
+		}
+		ubits += 4;
+	}
+
+	/* The identification marker bits are unprotected, so it is likely
+	 * that some of them are errornous, we will tolerate up to 1/8
+	 * of errors in total */
+	if (errors < count * 4 / 8)
+		return true;
+	return false;
+}
+
+static bool detect_ahs_id_marker(ubit_t * ubits, ubit_t * id_marker)
+{
+	unsigned int i, k;
+	unsigned int errors = 0;
+
+	/* Override coded in-band data */
+	ubits += 16;
+
+	/* Check for identification marker bits */
+	for (i = 0; i < 23; i++) {
+		for (k = 0; k < 9; k++) {
+			if (id_marker[k] != *ubits)
+				errors++;
+			ubits++;
+		}
+	}
+
+	/* Tolerate up to 1/8 errornous bits */
+	if (errors < 23 * 8 / 8)
+		return true;
+	return false;
+}
+
+static bool detect_interleaved_ahs_id_marker(ubit_t * ubits, ubit_t * id_marker)
+{
+	unsigned int i, k;
+	unsigned int errors = 0;
+
+	/* Override coded in-band data */
+	ubits += 16 * 2;
+
+	/* Align to even bits */
+	ubits++;
+
+	/* Check for identification marker bits */
+	for (i = 0; i < 23; i++) {
+		for (k = 0; k < 9; k++) {
+			if (id_marker[k] != *ubits)
+				errors++;
+			ubits += 2;
+		}
+	}
+
+	/* Tolerate up to 1/8 errornous bits */
+	if (errors < 23 * 8 / 8)
+		return true;
+	return false;
+}
+
+static unsigned int check_afs_coded_inband_bits(ubit_t * ubits, uint8_t offset)
+{
+	unsigned int i, k;
+	unsigned int ones[4] = { 0, 0, 0, 0 };
+	unsigned int error = 0;
+
+	ubits += 4 + offset;
+
+	for (i = 0; i < 14; i++) {
+		for (k = 0; k < 4; k++) {
+			ones[k] += ubits[k];
+		}
+
+		ubits += 32;
+	}
+
+	for (k = 0; k < 4; k++) {
+		if (ones[k] > 7)
+			error += 14 - ones[k];
+		else
+			error += ones[k];
+	}
+	return error;
+}
+
+static unsigned int check_ahs_coded_inband_bits(ubit_t * ubits, bool even_bits)
+{
+	unsigned int i, k;
+	unsigned int ones[16] =
+	    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+	unsigned int error = 0;
+
+	if (even_bits)
+		ubits++;
+
+	for (i = 0; i < 7; i++) {
+		for (k = 0; k < 16; k++) {
+			ones[k] += ubits[0];
+			ubits += 2;
+		}
+	}
+
+	for (k = 0; k < 16; k++) {
+		if (ones[k] > 3)
+			error += 7 - ones[k];
+		else
+			error += ones[k];
+	}
+
+	return error;
+}
+
+/* Detect a an FR AMR SID_FIRST frame by its identifcation marker */
+static inline bool detect_afs_sid_first(ubit_t * ubits)
+{
+	return detect_afs_id_marker(ubits, 32, 53);
+}
+
+/* Detect an FR AMR SID_FIRST frame by its identification marker */
+static inline bool detect_afs_sid_update(ubit_t * ubits)
+{
+	return detect_afs_id_marker(ubits, 36, 36);
+}
+
+/* Detect an FR AMR SID_FIRST frame by its repeating coded inband data */
+static inline bool detect_afs_onset(ubit_t * ubits)
+{
+	unsigned int error = 0;
+
+	error += check_afs_coded_inband_bits(ubits, 0);
+	error += check_afs_coded_inband_bits(ubits, 8);
+	error += check_afs_coded_inband_bits(ubits, 16);
+	error += check_afs_coded_inband_bits(ubits, 24);
+
+	if (error > 14 * 4 * 4 / 8)
+		return false;
+	return true;
+}
+
+/* Detect an HR AMR SID UPDATE frame by its identification marker */
+static inline bool detect_ahs_sid_update(ubit_t * ubits)
+{
+	ubit_t id_marker[] = { 1, 0, 1, 1, 0, 0, 0, 0, 1 };
+	return detect_ahs_id_marker(ubits, id_marker);
+}
+
+/* Detect an HR AMR SID FIRST (part 1) frame by its identification marker */
+static inline bool detect_ahs_sid_first_p1(ubit_t * ubits)
+{
+	ubit_t id_marker[] = { 0, 1, 0, 0, 1, 1, 1, 1, 0 };
+	return detect_ahs_id_marker(ubits, id_marker);
+}
+
+/* Detect an HR AMR SID FIRST (part 2) frame by its repeating coded inband data */
+static inline bool detect_ahs_sid_first_p2(ubit_t * ubits)
+{
+	unsigned int error = 0;
+	error = check_ahs_coded_inband_bits(ubits, false);
+	if (error > 7 * 16 / 8)
+		return false;
+	return true;
+}
+
+/* Detect an HR AMR ONSET frame by its repeating coded inband data */
+static inline bool detect_ahs_onset(ubit_t * ubits)
+{
+	unsigned int error = 0;
+	error = check_ahs_coded_inband_bits(ubits, true);
+	if (error > 7 * 16 / 8)
+		return false;
+	return true;
+}
+
+/* Detect an HR AMR SID FIRST INHIBIT frame by its identification marker */
+static inline bool detect_ahs_sid_first_inh(ubit_t * ubits)
+{
+	ubit_t id_marker[] = { 1, 0, 1, 1, 0, 0, 0, 0, 1 };
+	return detect_interleaved_ahs_id_marker(ubits, id_marker);
+}
+
+/* Detect an HR AMR SID UPDATE INHIBIT frame by its identification marker */
+static inline bool detect_ahs_sid_update_inh(ubit_t * ubits)
+{
+	ubit_t id_marker[] = { 0, 1, 0, 0, 1, 1, 1, 1, 0 };
+	return detect_interleaved_ahs_id_marker(ubits, id_marker);
+}
+
+/*! Detect FR AMR DTX frame in unmapped, deinterleaved frame bits
+ *  \param[in] ubits input bits (456 bit max)
+ *  \returns dtx frame type */
+uint8_t gsm0503_detect_afs_dtx_frame(ubit_t * ubits)
+{
+	if (detect_afs_sid_first(ubits))
+		return AFS_SID_FIRST;
+	if (detect_afs_sid_update(ubits))
+		return AFS_SID_UPDATE;
+	if (detect_afs_onset(ubits))
+		return AFS_ONSET;
+	return AMR_OTHER;
+}
+
+/*! Detect HR AMR DTX frame in unmapped, deinterleaved frame bits
+ *  \param[in] ubits input bits (456 bit max)
+ *  \returns dtx frame type */
+uint8_t gsm0503_detect_ahs_dtx_frame(ubit_t * ubits)
+{
+	if (detect_ahs_sid_update(ubits))
+		return AHS_SID_UPDATE;
+	if (detect_ahs_sid_first_inh(ubits))
+		return AHS_SID_FIRST_INH;
+	if (detect_ahs_sid_update_inh(ubits))
+		return AHS_SID_UPDATE_INH;
+	if (detect_ahs_sid_first_p1(ubits))
+		return AHS_SID_FIRST_P1;
+	if (detect_ahs_sid_first_p2(ubits))
+		return AHS_SID_FIRST_P2;
+	if (detect_ahs_onset(ubits))
+		return AHS_ONSET;
+
+	return AMR_OTHER;
+}
diff --git a/src/coding/gsm0503_coding.c b/src/coding/gsm0503_coding.c
index 7385d23..d95bcaf 100644
--- a/src/coding/gsm0503_coding.c
+++ b/src/coding/gsm0503_coding.c
@@ -47,6 +47,7 @@
 #include <osmocom/coding/gsm0503_tables.h>
 #include <osmocom/coding/gsm0503_coding.h>
 #include <osmocom/coding/gsm0503_parity.h>
+#include <osmocom/coding/gsm0503_amr_dtx.h>
 
 /*! \mainpage libosmocoding Documentation
  *
@@ -2094,6 +2095,7 @@
  *  \param[out] cmr Output in \a codec_mode_req = 1
  *  \param[out] n_errors Number of detected bit errors
  *  \param[out] n_bits_total Total number of bits
+ *  \param[out] dtx DTX frame type
  *  \returns (>=4) length of bytes used in \a tch_data output buffer; ([0,3])
  *  	     codec out of range; negative on error
  */
@@ -2101,9 +2103,33 @@
 	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
 	uint8_t *cmr, int *n_errors, int *n_bits_total)
 {
+	return gsm0503_tch_afs_decode_dtx(tch_data, bursts, codec_mode_req,
+					  codec, codecs, ft, cmr, n_errors,
+					  n_bits_total, NULL);
+}
+
+/*! Perform channel decoding of a TCH/AFS channel according TS 05.03
+ *  \param[out] tch_data Codec frame in RTP payload format
+ *  \param[in] bursts buffer containing the symbols of 8 bursts
+ *  \param[in] codec_mode_req is this CMR (1) or CMC (0)
+ *  \param[in] codec array of active codecs (active codec set)
+ *  \param[in] codecs number of codecs in \a codec
+ *  \param ft Frame Type; Input if \a codec_mode_req = 1, Output *  otherwise
+ *  \param[out] cmr Output in \a codec_mode_req = 1
+ *  \param[out] n_errors Number of detected bit errors
+ *  \param[out] n_bits_total Total number of bits
+ *  \param[out] dtx DTX frame type
+ *  \returns (>=4) length of bytes used in \a tch_data output buffer; ([0,3])
+ *  	     codec out of range; negative on error
+ */
+int gsm0503_tch_afs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts,
+	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
+	uint8_t *cmr, int *n_errors, int *n_bits_total, uint8_t *dtx)
+{
 	sbit_t iB[912], cB[456], h;
 	ubit_t d[244], p[6], conv[250];
 	int i, j, k, best = 0, rv, len, steal = 0, id = 0;
+	ubit_t cBd[456];
 	*n_errors = 0; *n_bits_total = 0;
 
 	for (i=0; i<8; i++) {
@@ -2133,6 +2159,15 @@
 		}
 	}
 
+	/* Determine the DTX frame type (SID_UPDATE, ONSET etc...) */
+	if (dtx) {
+		osmo_sbit2ubit(cBd, cB, 456);
+		for (i = 0; i < 456; i++)
+			printf("%u", cBd[i]);
+		printf("\n");
+		*dtx = gsm0503_detect_afs_dtx_frame(cBd);
+	}
+
 	/* Check if indicated codec fits into range of codecs */
 	if (id >= codecs) {
 		/* Codec mode out of range, return id */
@@ -2480,9 +2515,34 @@
 	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
 	uint8_t *cmr, int *n_errors, int *n_bits_total)
 {
+	return gsm0503_tch_ahs_decode_dtx(tch_data, bursts, odd, codec_mode_req,
+					  codec, codecs, ft, cmr, n_errors,
+					  n_bits_total, NULL);
+}
+
+/*! Perform channel decoding of a TCH/AFS channel according TS 05.03
+ *  \param[out] tch_data Codec frame in RTP payload format
+ *  \param[in] bursts buffer containing the symbols of 8 bursts
+ *  \param[in] odd Is this an odd (1) or even (0) frame number?
+ *  \param[in] codec_mode_req is this CMR (1) or CMC (0)
+ *  \param[in] codec array of active codecs (active codec set)
+ *  \param[in] codecs number of codecs in \a codec
+ *  \param ft Frame Type; Input if \a codec_mode_req = 1, Output *  otherwise
+ *  \param[out] cmr Output in \a codec_mode_req = 1
+ *  \param[out] n_errors Number of detected bit errors
+ *  \param[out] n_bits_total Total number of bits
+ *  \param[out] dtx DTX frame type
+ *  \returns (>=4) length of bytes used in \a tch_data output buffer; ([0,3])
+ *  	     codec out of range; negative on error
+ */
+int gsm0503_tch_ahs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts, int odd,
+	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
+	uint8_t *cmr, int *n_errors, int *n_bits_total, uint8_t *dtx)
+{
 	sbit_t iB[912], cB[456], h;
 	ubit_t d[244], p[6], conv[135];
 	int i, j, k, best = 0, rv, len, steal = 0, id = 0;
+	ubit_t cBd[456];
 
 	/* only unmap the stealing bits */
 	if (!odd) {
@@ -2536,6 +2596,15 @@
 		}
 	}
 
+	/* Determine the DTX frame type (SID_UPDATE, ONSET etc...) */
+	if (dtx) {
+		osmo_sbit2ubit(cBd, cB, 456);
+		for (i = 0; i < 456; i++)
+			printf("%u", cBd[i]);
+		printf("\n");
+		*dtx = gsm0503_detect_ahs_dtx_frame(cBd);
+	}
+
 	/* Check if indicated codec fits into range of codecs */
 	if (id >= codecs) {
 		/* Codec mode out of range, return id */
diff --git a/src/coding/libosmocoding.map b/src/coding/libosmocoding.map
index 87b3886..42f34e4 100644
--- a/src/coding/libosmocoding.map
+++ b/src/coding/libosmocoding.map
@@ -106,8 +106,10 @@
 gsm0503_tch_hr_decode;
 gsm0503_tch_afs_encode;
 gsm0503_tch_afs_decode;
+gsm0503_tch_afs_decode_dtx;
 gsm0503_tch_ahs_encode;
 gsm0503_tch_ahs_decode;
+gsm0503_tch_ahs_decode_dtx;
 gsm0503_rach_ext_encode;
 gsm0503_rach_ext_decode;
 gsm0503_rach_ext_decode_ber;
@@ -116,6 +118,10 @@
 gsm0503_rach_decode_ber;
 gsm0503_sch_encode;
 gsm0503_sch_decode;
+gsm0503_amr_dtx_frame_names;
+gsm0503_amr_dtx_frame_name;
+gsm0503_detect_afs_dtx_frame;
+gsm0503_detect_ahs_dtx_frame;
 
 local: *;
 };
diff --git a/tests/Makefile.am b/tests/Makefile.am
index bf7017b..0d0327a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -34,6 +34,7 @@
 		 use_count/use_count_test				\
 		 context/context_test					\
                  gsm0502/gsm0502_test					\
+                 dtx/dtx_gsm0503_test					\
 		 $(NULL)
 
 if ENABLE_MSGFILE
@@ -114,6 +115,10 @@
 gsm0502_gsm0502_test_SOURCES = gsm0502/gsm0502_test.c
 gsm0502_gsm0502_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la
 
+dtx_dtx_gsm0503_test_SOURCES = dtx/dtx_gsm0503_test.c
+dtx_dtx_gsm0503_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la \
+			     $(top_builddir)/src/coding/libosmocoding.la
+
 conv_conv_gsm0503_test_SOURCES = conv/conv_gsm0503_test.c conv/conv.c conv/gsm0503_test_vectors.c
 conv_conv_gsm0503_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libgsmint.la
 conv_conv_gsm0503_test_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/tests/conv
@@ -339,6 +344,7 @@
 	     use_count/use_count_test.ok use_count/use_count_test.err \
 	     context/context_test.ok \
 	     gsm0502/gsm0502_test.ok \
+	     dtx/dtx_gsm0503_test.ok \
 	     exec/exec_test.ok exec/exec_test.err \
 	     $(NULL)
 
diff --git a/tests/dtx/dtx_gsm0503_test.c b/tests/dtx/dtx_gsm0503_test.c
new file mode 100644
index 0000000..7e634e2
--- /dev/null
+++ b/tests/dtx/dtx_gsm0503_test.c
@@ -0,0 +1,126 @@
+/*
+ * (C) 2019 by sysmocom s.f.m.c. GmbH <info at sysmocom.de>
+ * Author: Philipp Maier <pmaier at sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/coding/gsm0503_amr_dtx.h>
+
+char sample_afs_sid_frame[] =
+    {
+"111111110000000011001100101010100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001"
+};
+
+char sample_afs_sid_update_frame[] =
+    {
+"111111110000000011001100101010100000010000001111111100101011011110001001000000110111110000001001011111101111010011001111100000101000011111001001111100110111110011111001001111101100010001001111000000100100011100111001100000111000110000111001010011101111010011111111010000101100011100111001111100110111110011111001110011101000010010001111110000100000011111001001011100110011110010111001101111100011010001111111001100100100011111111001000000110000110000001001"
+};
+
+char sample_afs_onset_frame[] =
+    {
+"111111110000000011001100101010100000111100000000111111000100101000111111100000000111110010001010001111110100000011111100111110100100111111000000110011001011101001001111011100001011110000001010010011111100000000111100111110101000111110110000111111000000101011111111010000001100110000111010111111111000000010111100000010100100111100110000100011001000101000111111101100001011110000111010011111110011000010111100101110101100111111000000010011001111101000001111"
+};
+
+char sample_ahs_sid_update_frame[] =
+    {
+"111100001100101010110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110100011001000011010000000000000001111010010000000000001000000000010110000000011001000000000000000100000101000000000000000001010100000010010000000000010000111110001110110110011001101000000000100100011001000001010000100100000000011"
+};
+
+char sample_ahs_sid_first_p1_frame[] =
+    {
+"111100001100101001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001001011010110001101100101001110001111001110100110010000111101110110110000100100011111001001110000011110110001010010101100001010100000111101110110001010000111110001110110110011001101001111000011101001010011100011000111010110000011"
+};
+
+char sample_ahs_sid_first_p2_frame[] =
+    {
+"111110100100000010100000110111001110101100000100101001011101100011101010010000001010010010001100101010100100010111110101110011011110101000010100111000001001110111101110010101001110000010001101101011110000000011100100110110011111100011001000001101100101001110001111001110100110010000111101110110110000100100011111001001110000011110110001010010101100001010100000111101110110001010000111110001110110110011001101001111000011101001010011100011000111010110000011"
+};
+
+char sample_ahs_onset_frame[] =
+    {
+"111101011000101001010000111001000111011110000000011110001110010011011111100000101101101001101110011111010000000001010010110001101101110100000010011110101100010001011101101010000111100011101100111101011010100011110010110001001111100011001000011010000000000000001010010010000000000001000000000000100000000011001000000000000000100000101000000000000000010010000101010010000000000010101100111110101000110110011001000000000100100011001000001010000100100000001100"
+};
+
+char sample_sid_first_inh_frame[] =
+    {
+"xBxBxBxBxBxBxBxBxBxBxBxBxBxBxBxBx1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0"
+};
+
+char sample_sid_update_inh_frame[] =
+    {
+"xBxBxBxBxBxBxBxBxBxBxBxBxBxBxBxBx0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1"
+};
+
+unsigned int string_to_ubit(ubit_t * ubits, char *string)
+{
+	unsigned int len;
+	unsigned int i;
+
+	len = strlen(string);
+
+	for (i = 0; i < len; i++) {
+		ubits[i] = string[i] & 1;
+	}
+
+	return len;
+}
+
+void test_gsm0503_detect_afs_dtx_frame(char *string)
+{
+	ubit_t ubits[512];
+	uint8_t dtx_frame_type;
+
+	string_to_ubit(ubits, string);
+	dtx_frame_type = gsm0503_detect_afs_dtx_frame(ubits);
+	printf(" ==> %u, %s\n", dtx_frame_type,
+	       gsm0503_amr_dtx_frame_name(dtx_frame_type));
+}
+
+void test_gsm0503_detect_ahs_dtx_frame(char *string)
+{
+	ubit_t ubits[512];
+	uint8_t dtx_frame_type;
+
+	string_to_ubit(ubits, string);
+	dtx_frame_type = gsm0503_detect_ahs_dtx_frame(ubits);
+	printf(" ==> %u, %s\n", dtx_frame_type,
+	       gsm0503_amr_dtx_frame_name(dtx_frame_type));
+}
+
+int main(int argc, char **argv)
+{
+	printf("FR AMR DTX FRAMES:\n");
+	test_gsm0503_detect_afs_dtx_frame(sample_afs_sid_frame);
+	test_gsm0503_detect_afs_dtx_frame(sample_afs_sid_update_frame);
+	test_gsm0503_detect_afs_dtx_frame(sample_afs_onset_frame);
+	printf("HR AMR DTX FRAMES:\n");
+	test_gsm0503_detect_ahs_dtx_frame(sample_ahs_sid_update_frame);
+	test_gsm0503_detect_ahs_dtx_frame(sample_ahs_sid_first_p1_frame);
+	test_gsm0503_detect_ahs_dtx_frame(sample_ahs_sid_first_p2_frame);
+	test_gsm0503_detect_ahs_dtx_frame(sample_ahs_onset_frame);
+	test_gsm0503_detect_ahs_dtx_frame(sample_sid_first_inh_frame);
+	test_gsm0503_detect_ahs_dtx_frame(sample_sid_update_inh_frame);
+
+	return EXIT_SUCCESS;
+}
diff --git a/tests/dtx/dtx_gsm0503_test.ok b/tests/dtx/dtx_gsm0503_test.ok
new file mode 100644
index 0000000..4544043
--- /dev/null
+++ b/tests/dtx/dtx_gsm0503_test.ok
@@ -0,0 +1,11 @@
+FR AMR DTX FRAMES:
+ ==> 0, AFS_SID_FIRST
+ ==> 1, AFS_SID_UPDATE
+ ==> 2, AFS_ONSET
+HR AMR DTX FRAMES:
+ ==> 3, AHS_SID_UPDATE
+ ==> 4, AHS_SID_FIRST_P1
+ ==> 5, AHS_SID_FIRST_P2
+ ==> 6, AHS_ONSET
+ ==> 7, AHS_SID_FIRST_INH
+ ==> 8, AHS_SID_UPDATE_INH
diff --git a/tests/testsuite.at b/tests/testsuite.at
index cb83ab9..bab5730 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -132,6 +132,12 @@
 AT_CHECK([$abs_top_builddir/tests/gsm0502/gsm0502_test], [0], [expout], [ignore])
 AT_CLEANUP
 
+AT_SETUP([dtx])
+AT_KEYWORDS([dtx])
+cat $abs_srcdir/dtx/dtx_gsm0503_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/dtx/dtx_gsm0503_test], [0], [expout], [ignore])
+AT_CLEANUP
+
 AT_SETUP([gsm0808])
 AT_KEYWORDS([gsm0808])
 cat $abs_srcdir/gsm0808/gsm0808_test.ok > expout

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

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I2bbdb39ea20461ca08b2e6f1a33532cb55cd5195
Gerrit-Change-Number: 17095
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200206/71230aae/attachment.htm>


More information about the gerrit-log mailing list