diff amrconv/ietf-parse.c @ 214:934cf92a1c45

amrconv: new program amr-ietf-parse
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 20 Apr 2023 22:48:22 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/amrconv/ietf-parse.c	Thu Apr 20 22:48:22 2023 +0000
@@ -0,0 +1,83 @@
+/*
+ * This program reads an AMR recording in IETF RFC 4867 format and parses it
+ * into a human-readable form.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "amr_defs.h"
+
+extern char *amr_mode_names[16];
+extern const char amr_file_hdr[IETF_HDR_LEN];
+extern const uint8_t extra_bytes_per_ft[9];
+
+main(argc, argv)
+	char **argv;
+{
+	char *infname;
+	FILE *inf;
+	uint8_t frm_in[MAX_IF1_BYTES];
+	unsigned frame_no, mode, qbit, sti, sid_mode;
+	uint8_t ser_bits[MAX_SERIAL_SIZE];
+	uint16_t params[MAX_PRM_SIZE];
+	int rc;
+
+	if (argc != 2) {
+		fprintf(stderr, "usage: %s amr_file\n", argv[0]);
+		exit(1);
+	}
+	infname = argv[1];
+	inf = fopen(infname, "r");
+	if (!inf) {
+		perror(infname);
+		exit(1);
+	}
+	if (fread(frm_in, 1, IETF_HDR_LEN, inf) != IETF_HDR_LEN ||
+	    bcmp(frm_in, amr_file_hdr, IETF_HDR_LEN)) {
+		fprintf(stderr, "error: %s is not in IETF AMR format\n",
+			infname);
+		exit(1);
+	}
+	for (frame_no = 0; ; frame_no++) {
+		rc = getc(inf);
+		if (rc < 0)
+			break;
+		mode = (rc & 0x78) >> 3;
+		qbit = (rc & 4) >> 2;
+		printf("#%u: FT=%u (%s) Q=%u\n", frame_no, mode,
+			amr_mode_names[mode], qbit);
+		if (mode == MODE_NO_DATA)
+			continue;
+		if (mode > MRDTX) {
+			fprintf(stderr, "error in frame #%u: invalid FT=%u\n",
+				frame_no, mode);
+			exit(1);
+		}
+		rc = fread(frm_in, 1, extra_bytes_per_ft[mode], inf);
+		if (rc != extra_bytes_per_ft[mode]) {
+			fprintf(stderr,
+				"error: short read from %s on frame #%u\n",
+				infname, frame_no);
+			exit(1);
+		}
+		amr_if1_unpack(frm_in, ser_bits, mode);
+		reassemble_amr_params(ser_bits, params, mode);
+		dump_amr_params(params, mode);
+		if (mode == MRDTX) {
+			sti = (frm_in[4] & 0x10) >> 4;
+			sid_mode = 0;
+			if (frm_in[4] & 0x08)
+				sid_mode |= 1;
+			if (frm_in[4] & 0x04)
+				sid_mode |= 2;
+			if (frm_in[4] & 0x02)
+				sid_mode |= 4;
+			printf("  SID_%s Mode=%u\n", sti ? "UPDATE" : "FIRST",
+				sid_mode);
+		}
+	}
+	exit(0);
+}