diff frtest/hand-test.c @ 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
children
line wrap: on
line diff
--- /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);
+}