changeset 29:d21c68b8f16c

gsmfr-hand-test: yet another debug aid
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 21 Nov 2022 03:09:39 +0000
parents a8fd4ff6b013
children 2272ba6f6879
files .hgignore frtest/Makefile frtest/hand-test.c
diffstat 3 files changed, 185 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Mon Nov 21 01:02:07 2022 +0000
+++ b/.hgignore	Mon Nov 21 03:09:39 2022 +0000
@@ -8,6 +8,7 @@
 ^frtest/gsmfr-cvt-dlcap$
 ^frtest/gsmfr-decode$
 ^frtest/gsmfr-encode$
+^frtest/gsmfr-hand-test$
 ^frtest/gsmfr-max-out$
 ^frtest/gsmfr-preproc$
 
--- a/frtest/Makefile	Mon Nov 21 01:02:07 2022 +0000
+++ b/frtest/Makefile	Mon Nov 21 03:09:39 2022 +0000
@@ -1,6 +1,7 @@
 CC=	gcc
 CFLAGS=	-O2
-PROGS=	gsmfr-cvt-dlcap gsmfr-decode gsmfr-encode gsmfr-max-out gsmfr-preproc
+PROGS=	gsmfr-cvt-dlcap gsmfr-decode gsmfr-encode gsmfr-hand-test gsmfr-max-out\
+	gsmfr-preproc
 LIBPP=	../libgsmfrp/libgsmfrp.a
 LIBTEST=../libtest/libtest.a
 LIBDEC=	${LIBTEST} ${LIBPP}
@@ -19,6 +20,9 @@
 gsmfr-encode:	encode.o ${LIBTEST}
 	${CC} ${CFLAGS} -o $@ encode.o ${LIBTEST} -lgsm
 
+gsmfr-hand-test:	hand-test.o
+	${CC} ${CFLAGS} -o $@ hand-test.o -lgsm
+
 gsmfr-max-out:	max-out.o ${LIBDEC}
 	${CC} ${CFLAGS} -o $@ max-out.o ${LIBDEC} -lgsm
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/frtest/hand-test.c	Mon Nov 21 03:09:39 2022 +0000
@@ -0,0 +1,179 @@
+/*
+ * This program is a debug aid that allows a developer to hand-craft input
+ * to the GSM 06.10 decoder (libgsm) and see what output magnitude it results
+ * in, in the style of gsmfr-max-out.  This program reads input from an
+ * ASCII text file in the same format as gsmrec-dump, performs gsm_implode()
+ * and gsm_decode() operations and reports maximum output magnitude for
+ * each processed frame.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <gsm.h>
+
+static char *infname;
+static FILE *inf;
+static char linebuf[256];
+static int lineno;
+
+static
+get_line()
+{
+	if (!fgets(linebuf, sizeof linebuf, inf))
+		return 0;
+	lineno++;
+	if (!index(linebuf, '\n')) {
+		fprintf(stderr, "%s line %d: too long or missing newline\n",
+			infname, lineno);
+		exit(1);
+	}
+	return 1;
+}
+
+static
+read_lar_params(params)
+	gsm_signal *params;
+{
+	char *cp;
+	unsigned n;
+
+	for (;;) {
+		if (!get_line())
+			return 0;
+		for (cp = linebuf; isspace(*cp); cp++)
+			;
+		if (*cp)
+			break;
+	}
+	if (*cp == '#') {
+		cp++;
+		if (!isdigit(*cp)) {
+inv_syntax:		fprintf(stderr,
+				"%s line %d: invalid syntax (expected LAR)\n",
+				infname, lineno);
+			exit(1);
+		}
+		while (isdigit(*cp))
+			cp++;
+		if (*cp++ != ':')
+			goto inv_syntax;
+		while (isspace(*cp))
+			cp++;
+	}
+	if (cp[0] != 'F' || cp[1] != 'R' || !isspace(cp[2]))
+		goto inv_syntax;
+	cp += 3;
+	for (n = 0; n < 8; n++) {
+		while (isspace(*cp))
+			cp++;
+		if (!isdigit(*cp))
+			goto inv_syntax;
+		params[n] = strtoul(cp, &cp, 10);
+		if (!isspace(*cp))
+			goto inv_syntax;
+	}
+	fputs(linebuf, stdout);
+	return 1;
+}
+
+static void
+read_subframe_params(params)
+	gsm_signal *params;
+{
+	char *cp;
+	unsigned n;
+
+	for (;;) {
+		if (!get_line()) {
+			fprintf(stderr,
+				"%s bad: EOF in the middle of a frame\n",
+				infname);
+			exit(1);
+		}
+		for (cp = linebuf; isspace(*cp); cp++)
+			;
+		if (*cp)
+			break;
+	}
+	for (n = 0; n < 17; n++) {
+		while (isspace(*cp))
+			cp++;
+		if (!isdigit(*cp)) {
+inv_syntax:		fprintf(stderr,
+			"%s line %d: invalid syntax (expected subframe)\n",
+				infname, lineno);
+			exit(1);
+		}
+		params[n] = strtoul(cp, &cp, 10);
+		if (!isspace(*cp))
+			goto inv_syntax;
+	}
+	fputs(linebuf, stdout);
+}
+
+static
+read_frame(params)
+	gsm_signal *params;
+{
+	int rc;
+	unsigned n, idx;
+
+	rc = read_lar_params(params);
+	if (!rc)
+		return 0;
+	idx = 8;
+	for (n = 0; n < 4; n++) {
+		read_subframe_params(params + idx);
+		idx += 17;
+	}
+	return 1;
+}
+
+main(argc, argv)
+	char **argv;
+{
+	gsm dec_state;
+	gsm_signal params[76];
+	uint8_t frame[33];
+	int16_t pcm[160];
+	int rc, i;
+	unsigned samp_abs, samp_max;
+
+	if (argc != 2) {
+		fprintf(stderr, "usage: %s input-file\n", argv[0]);
+		exit(1);
+	}
+	infname = argv[1];
+	inf = fopen(infname, "r");
+	if (!inf) {
+		perror(infname);
+		exit(1);
+	}
+	dec_state = gsm_create();
+	if (!dec_state) {
+		fprintf(stderr, "gsm_create() failed!\n");
+		exit(1);
+	}
+	for (;;) {
+		rc = read_frame(params);
+		if (!rc)
+			break;
+		gsm_implode(dec_state, params, frame);
+		gsm_decode(dec_state, frame, pcm);
+		samp_max = 0;
+		for (i = 0; i < 160; i++) {
+			if (pcm[i] >= 0)
+				samp_abs = pcm[i];
+			else
+				samp_abs = -pcm[i];
+			if (samp_abs > samp_max)
+				samp_max = samp_abs;
+		}
+		printf("  MAX=%u\n", samp_max);
+	}
+	exit(0);
+}