diff pcm-study/g711u-grep-gsmout.c @ 11:8b047c9bfe5f

g711u-grep-gsmout program written
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 15 May 2024 02:31:01 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pcm-study/g711u-grep-gsmout.c	Wed May 15 02:31:01 2024 +0000
@@ -0,0 +1,184 @@
+/*
+ * This programs reads a G.711 PCMU sample stream and 'grep's it for
+ * particular patterns that result from a GSM-FR or GSM-EFR decoder
+ * processing uplink test frames constructed in vband-misc repository,
+ * ul-test subdirectory.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+static const uint8_t match_frame_fr[160] = {
+0xFF,0x0F,0x0E,0x1B,0x8D,0x8A,0x9C,0x23,0x1D,0x38,0x1C,0x1B,0x26,0x8A,0x80,0x92,
+0x11,0x06,0x1E,0xA3,0x9B,0xBF,0x9B,0x91,0x9C,0x11,0x06,0x1C,0x98,0x87,0x8D,0xAF,
+0x1D,0x16,0x13,0x1F,0xBE,0x8D,0x88,0x99,0x1D,0x07,0x05,0x12,0xAC,0x8B,0x87,0x95,
+0x25,0x09,0x06,0x14,0xAA,0x8B,0x88,0x97,0x25,0x0A,0x09,0x1A,0xA4,0x8C,0x8A,0x99,
+0x28,0x0C,0x09,0x1B,0xA5,0x8C,0x8B,0x9D,0x23,0x0C,0x0A,0x19,0xA4,0x8C,0x8A,0x9D,
+0x1E,0x0A,0x0A,0x1C,0xA2,0x8C,0x8B,0x9B,0x25,0x0C,0x0A,0x19,0xA7,0x8C,0x8B,0x9B,
+0x26,0x0D,0x0B,0x1A,0xAA,0x8D,0x8A,0x99,0x2A,0x0D,0x0B,0x1A,0xAB,0x8E,0x8C,0x99,
+0x2F,0x0F,0x0B,0x19,0xAE,0x8E,0x8C,0x99,0x34,0x0F,0x0D,0x1A,0xB2,0x91,0x8D,0x99,
+0x3B,0x12,0x0D,0x19,0xBA,0x92,0x8E,0x9B,0x38,0x14,0x0F,0x1B,0xBB,0x94,0x8E,0x9A,
+0x3B,0x13,0x0E,0x1B,0xBA,0x95,0x90,0x9B,0x3F,0x16,0x0F,0x1B,0xBB,0x94,0x8F,0x9C,
+};
+
+static const uint8_t match_frame_efr_classic[160] = {
+0x6F,0x64,0x63,0x6B,0xE8,0xDA,0xDC,0xEF,0x60,0x5A,0x5D,0x6F,0xE2,0xD8,0xD9,0xEC,
+0x5F,0x58,0x5E,0x7E,0xE2,0xDF,0xE2,0xF0,0x63,0x58,0x59,0x67,0xE0,0xD4,0xD7,0xEC,
+0x5E,0x56,0x5A,0x6D,0xE1,0xD6,0xD7,0xEA,0x4D,0x37,0x2F,0x3A,0xC2,0xA7,0xA3,0xB5,
+0x2F,0x1C,0x1A,0x2D,0xA9,0x96,0x96,0xAE,0x22,0x12,0x14,0x31,0x9E,0x8F,0x94,0xB6,
+0x1B,0x0D,0x0F,0x2C,0x9B,0x8C,0x8E,0xAB,0x17,0x09,0x0C,0x28,0x97,0x88,0x8A,0xA7,
+0x15,0x07,0x0A,0x29,0x95,0x88,0x8B,0xAA,0x15,0x08,0x0B,0x2A,0x96,0x88,0x8B,0xAA,
+0x15,0x09,0x0C,0x2A,0x97,0x89,0x8C,0xAA,0x17,0x0A,0x0D,0x2B,0x98,0x8A,0x8D,0xAB,
+0x18,0x0A,0x0D,0x2A,0x99,0x8A,0x8D,0xAA,0x18,0x0A,0x0D,0x29,0x99,0x8A,0x8D,0xA9,
+0x19,0x0A,0x0D,0x29,0x99,0x8A,0x8D,0xA9,0x19,0x0A,0x0D,0x29,0x99,0x8A,0x8D,0xA9,
+0x19,0x0A,0x0D,0x28,0x99,0x8A,0x8C,0xA8,0x19,0x0A,0x0D,0x27,0x9A,0x8B,0x8D,0xA7,
+};
+
+static const uint8_t match_frame_amrefr_dec[160] = {
+0x6F,0x66,0x66,0x6E,0xE5,0xDA,0xDD,0xF2,0x5F,0x5A,0x5E,0x76,0xE0,0xD8,0xDA,0xEF,
+0x5E,0x59,0x5F,0xFC,0xE1,0xDF,0xE5,0xF5,0x61,0x59,0x5B,0x6B,0xDE,0xD4,0xD9,0xEF,
+0x5D,0x56,0x5B,0x71,0xDF,0xD6,0xD8,0xEE,0x4D,0x38,0x31,0x3E,0xBD,0xA7,0xA5,0xB9,
+0x2D,0x1C,0x1C,0x35,0xA5,0x96,0x98,0xB4,0x1F,0x12,0x17,0x3D,0x9C,0x90,0x96,0xC1,
+0x1A,0x0E,0x12,0x38,0x98,0x8C,0x8F,0xB4,0x16,0x0A,0x0D,0x32,0x94,0x88,0x8C,0xAE,
+0x13,0x08,0x0C,0x35,0x92,0x88,0x8C,0xB3,0x13,0x08,0x0D,0x35,0x93,0x88,0x8D,0xB3,
+0x13,0x09,0x0D,0x34,0x94,0x89,0x8D,0xB3,0x15,0x0A,0x0E,0x35,0x96,0x8B,0x8E,0xB5,
+0x16,0x0B,0x0E,0x32,0x97,0x8B,0x8E,0xB3,0x16,0x0A,0x0E,0x32,0x96,0x8A,0x8E,0xB1,
+0x16,0x0B,0x0E,0x31,0x96,0x8B,0x8E,0xB1,0x16,0x0B,0x0E,0x31,0x97,0x8B,0x8E,0xB1,
+0x16,0x0A,0x0E,0x30,0x97,0x8A,0x8E,0xAF,0x17,0x0B,0x0E,0x2F,0x97,0x8B,0x8E,0xAE,
+};
+
+enum state {
+	STATE_GROUND = 0,
+	STATE_FE,
+	STATE_EFR_PRELIM,
+	STATE_EFR_CLASSIC,
+	STATE_EFR_AMR,
+	STATE_FR,
+};
+
+static enum state state;
+static unsigned fe_byte_count, match_pos;
+
+static void
+report_match(name, offset)
+	char *name;
+	unsigned offset;
+{
+	offset -= 319;
+	printf("Matched output of %s decoder\n", name);
+	printf("File offset: %u (0x%x), offset % 160 = %u\n", offset, offset,
+		offset % 160);
+}
+
+static void
+process_sample(samp, offset)
+	unsigned samp, offset;
+{
+	if (samp == 0xFE) {
+		if (state != STATE_FE) {
+			state = STATE_FE;
+			fe_byte_count = 1;
+		} else if (fe_byte_count < 160)
+			fe_byte_count++;
+		return;
+	}
+	switch (state) {
+	case STATE_GROUND:
+		return;
+	case STATE_FE:
+		if (fe_byte_count < 160) {
+			state = STATE_GROUND;
+			return;
+		}
+		switch (samp) {
+		case 0x6F:
+			state = STATE_EFR_PRELIM;
+			return;
+		case 0xFF:
+			state = STATE_FR;
+			match_pos = 1;
+			return;
+		default:
+			state = STATE_GROUND;
+		}
+		return;
+	case STATE_EFR_PRELIM:
+		switch (samp) {
+		case 0x64:
+			state = STATE_EFR_CLASSIC;
+			match_pos = 2;
+			return;
+		case 0x66:
+			state = STATE_EFR_AMR;
+			match_pos = 2;
+			return;
+		default:
+			state = STATE_GROUND;
+		}
+		return;
+	case STATE_EFR_CLASSIC:
+		if (samp == match_frame_efr_classic[match_pos])
+			match_pos++;
+		else {
+			state = STATE_GROUND;
+			return;
+		}
+		if (match_pos < 160)
+			return;
+		report_match("classic EFR", offset);
+		state = STATE_GROUND;
+		return;
+	case STATE_EFR_AMR:
+		if (samp == match_frame_amrefr_dec[match_pos])
+			match_pos++;
+		else {
+			state = STATE_GROUND;
+			return;
+		}
+		if (match_pos < 160)
+			return;
+		report_match("AMR-EFR", offset);
+		state = STATE_GROUND;
+		return;
+	case STATE_FR:
+		if (samp == match_frame_fr[match_pos])
+			match_pos++;
+		else {
+			state = STATE_GROUND;
+			return;
+		}
+		if (match_pos < 160)
+			return;
+		report_match("GSM-FR", offset);
+		state = STATE_GROUND;
+		return;
+	default:
+		state = STATE_GROUND;
+	}
+}
+
+main(argc, argv)
+	char **argv;
+{
+	FILE *inf;
+	unsigned offset;
+	int c;
+
+	if (argc != 2) {
+		fprintf(stderr, "usage: %s pcmu-bin-file\n", argv[0]);
+		exit(1);
+	}
+	inf = fopen(argv[1], "r");
+	if (!inf) {
+		perror(argv[1]);
+		exit(1);
+	}
+	for (offset = 0; ; offset++) {
+		c = getc(inf);
+		if (c < 0)
+			break;
+		process_sample(c, offset);
+	}
+	exit(0);
+}