changeset 214:934cf92a1c45

amrconv: new program amr-ietf-parse
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 20 Apr 2023 22:48:22 +0000
parents 46a6e6b6841a
children 4c4649a5fec3
files .hgignore amrconv/Makefile amrconv/amr_bits.c amrconv/amr_defs.h amrconv/ietf-parse.c amrconv/ietf_common.c amrconv/if1_unpack.c
diffstat 7 files changed, 310 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Apr 20 02:36:14 2023 +0000
+++ b/.hgignore	Thu Apr 20 22:48:22 2023 +0000
@@ -3,6 +3,7 @@
 \.[oa]$
 
 ^amrconv/amr-cod-parse$
+^amrconv/amr-ietf-parse$
 ^amrconv/gsm-amr2efr$
 ^amrconv/gsm-efr2amr$
 
--- a/amrconv/Makefile	Thu Apr 20 02:36:14 2023 +0000
+++ b/amrconv/Makefile	Thu Apr 20 22:48:22 2023 +0000
@@ -1,6 +1,6 @@
 CC=	gcc
 CFLAGS=	-O2
-PROGS=	amr-cod-parse gsm-amr2efr gsm-efr2amr
+PROGS=	amr-cod-parse amr-ietf-parse gsm-amr2efr gsm-efr2amr
 LIBTEST=../libtest/libtest.a
 INSTBIN=/opt/freecalypso/bin
 
@@ -8,12 +8,17 @@
 EFR2AMR_OBJS=	amr122bits.o bitmanip.o efr2amr.o
 
 COD_PARSE_OBJS=	amr_common_tbl.o cod-parse.o cod-read.o param_asm.o param_dump.o
+IETF_PARSE_OBJS=amr122bits.o amr_bits.o amr_common_tbl.o bitmanip.o \
+		ietf-parse.o ietf_common.o if1_unpack.o param_asm.o param_dump.o
 
 all:	${PROGS}
 
 amr-cod-parse:	${COD_PARSE_OBJS}
 	${CC} ${CFLAGS} -o $@ ${COD_PARSE_OBJS}
 
+amr-ietf-parse:	${IETF_PARSE_OBJS}
+	${CC} ${CFLAGS} -o $@ ${IETF_PARSE_OBJS}
+
 gsm-amr2efr:	${AMR2EFR_OBJS}
 	${CC} ${CFLAGS} -o $@ ${AMR2EFR_OBJS}
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/amrconv/amr_bits.c	Thu Apr 20 22:48:22 2023 +0000
@@ -0,0 +1,126 @@
+/*
+ * This C module is a complement to amr122bits.c, for programs that
+ * need to work with all AMR modes and not just MR122.
+ */
+
+#include <stdint.h>
+
+const uint8_t amr_475_bit_order[95] = {
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+   10, 11, 12, 13, 14, 15, 23, 24, 25, 26,
+   27, 28, 48, 49, 61, 62, 82, 83, 47, 46,
+   45, 44, 81, 80, 79, 78, 17, 18, 20, 22,
+   77, 76, 75, 74, 29, 30, 43, 42, 41, 40,
+   38, 39, 16, 19, 21, 50, 51, 59, 60, 63,
+   64, 72, 73, 84, 85, 93, 94, 32, 33, 35,
+   36, 53, 54, 56, 57, 66, 67, 69, 70, 87,
+   88, 90, 91, 34, 55, 68, 89, 37, 58, 71,
+   92, 31, 52, 65, 86
+};
+
+const uint8_t amr_515_bit_order[103] = {
+    7,  6,  5,   4,   3,   2,  1,  0, 15, 14,
+   13, 12, 11,  10,   9,   8, 23, 24, 25, 26,
+   27, 46, 65,  84,  45,  44, 43, 64, 63, 62,
+   83, 82, 81, 102, 101, 100, 42, 61, 80, 99,
+   28, 47, 66,  85,  18,  41, 60, 79, 98, 29,
+   48, 67, 17,  20,  22,  40, 59, 78, 97, 21,
+   30, 49, 68,  86,  19,  16, 87, 39, 38, 58,
+   57, 77, 35,  54,  73,  92, 76, 96, 95, 36,
+   55, 74, 93,  32,  51,  33, 52, 70, 71, 89,
+   90, 31, 50,  69,  88,  37, 56, 75, 94, 34,
+   53, 72, 91							
+};
+
+const uint8_t amr_59_bit_order[118] = {
+    0,   1,   4,   5,   3,   6,   7,   2,  13,  15,
+    8,   9,  11,  12,  14,  10,  16,  28,  74,  29,
+   75,  27,  73,  26,  72,  30,  76,  51,  97,  50,
+   71,  96, 117,  31,  77,  52,  98,  49,  70,  95,
+  116,  53,  99,  32,  78,  33,  79,  48,  69,  94,
+  115,  47,  68,  93, 114,  46,  67,  92, 113,  19,
+   21,  23,  22,  18,  17,  20,  24, 111,  43,  89,
+  110,  64,  65,  44,  90,  25,  45,  66,  91, 112,
+   54, 100,  40,  61,  86, 107,  39,  60,  85, 106,
+   36,  57,  82, 103,  35,  56,  81, 102,  34,  55,
+   80, 101,  42,  63,  88, 109,  41,  62,  87, 108,
+   38,  59,  84, 105,  37,  58,  83, 104
+};
+
+const uint8_t amr_67_bit_order[134] = {
+    0,   1,   4,   3,   5,   6,  13,   7,   2,   8,
+    9,  11,  15,  12,  14,  10,  28,  82,  29,  83,
+   27,  81,  26,  80,  30,  84,  16,  55, 109,  56,
+  110,  31,  85,  57, 111,  48,  73, 102, 127,  32,
+   86,  51,  76, 105, 130,  52,  77, 106, 131,  58,
+  112,  33,  87,  19,  23,  53,  78, 107, 132,  21,
+   22,  18,  17,  20,  24,  25,  50,  75, 104, 129,
+   47,  72, 101, 126,  54,  79, 108, 133,  46,  71,
+  100, 125, 128, 103,  74,  49,  45,  70,  99, 124,
+   42,  67,  96, 121,  39,  64,  93, 118,  38,  63,
+   92, 117,  35,  60,  89, 114,  34,  59,  88, 113,
+   44,  69,  98, 123,  43,  68,  97, 122,  41,  66,
+   95, 120,  40,  65,  94, 119,  37,  62,  91, 116,
+   36,  61,  90, 115						
+};
+
+const uint8_t amr_74_bit_order[148] = {
+    0,   1,	  2,   3,   4,   5,   6,   7,   8,   9,
+   10,  11,	 12,  13,  14,  15,  16,  26,  87,  27,
+   88,  28,	 89,  29,  90,  30,  91,  51,  80, 112,
+  141,  52,  81, 113, 142,  54,  83, 115, 144,  55,
+   84, 116, 145,  58, 119,  59, 120,  21,  22,  23,
+   17,  18,	 19,  31,  60,  92, 121,  56,  85, 117,
+  146,  20,	 24,  25,  50,  79, 111, 140,  57,  86,
+  118, 147,	 49,  78, 110, 139,  48,  77,  53,  82,
+  114, 143, 109, 138,  47,  76, 108, 137,  32,  33,
+   61,  62,	 93,  94, 122, 123,  41,  42,  43,  44,
+   45,  46,	 70,  71,  72,  73,  74,  75, 102, 103,
+  104, 105, 106, 107, 131, 132, 133, 134, 135, 136,
+   34,  63,	 95, 124,  35,  64,  96, 125,  36,  65,
+   97, 126,	 37,  66,  98, 127,	 38,  67,  99, 128,
+   39,  68, 100, 129,  40,  69, 101, 130
+};
+
+const uint8_t amr_795_bit_order[159] = {
+    8,   7,   6,   5,   4,   3,   2,  14,  16,   9,
+   10,  12,  13,  15,  11,  17,  20,  22,  24,  23,
+   19,  18,  21,  56,  88, 122, 154,  57,  89, 123,
+  155,  58,  90, 124, 156,  52,  84, 118, 150,  53,
+   85, 119, 151,  27,  93,  28,  94,  29,  95,  30,
+   96,  31,  97,  61, 127,  62, 128,  63, 129,  59,
+   91, 125, 157,  32,  98,  64, 130,   1,   0,  25,
+   26,  33,  99,  34, 100,  65, 131,  66, 132,  54,
+   86, 120, 152,  60,  92, 126, 158,  55,  87, 121,
+  153, 117, 116, 115,  46,  78, 112, 144,  43,  75,
+  109, 141,  40,  72, 106, 138,  36,  68, 102, 134,
+  114, 149, 148, 147, 146,  83,  82,  81,  80,  51,
+   50,  49,  48,  47,  45,  44,  42,  39,  35,  79,
+   77,  76,  74,  71,  67, 113, 111, 110, 108, 105,
+  101, 145, 143, 142, 140, 137, 133,  41,  73, 107,
+  139,  37,  69, 103, 135,  38,  70, 104, 136
+};
+
+const uint8_t amr_102_bit_order[204] = {
+    7,   6,   5,   4,   3,   2,   1,   0,  16,  15,
+   14,  13,  12,  11,  10,   9,   8,  26,  27,  28,
+   29,  30,  31, 115, 116, 117, 118, 119, 120,  72,
+   73, 161, 162,  65,  68,  69, 108, 111, 112, 154,
+  157, 158, 197, 200, 201,  32,  33, 121, 122,  74,
+   75, 163, 164,  66, 109, 155, 198,  19,  23,  21,
+   22,  18,  17,  20,  24,  25,  37,  36,  35,  34,
+   80,  79,  78,  77, 126, 125, 124, 123, 169, 168,
+  167, 166,  70,  67,  71, 113, 110, 114, 159, 156,
+  160, 202, 199, 203,  76, 165,  81,  82,  92,  91,
+   93,  83,  95,  85,  84,  94, 101, 102,  96, 104,
+   86, 103,  87,  97, 127, 128, 138, 137, 139, 129,
+  141, 131, 130, 140, 147, 148, 142, 150, 132, 149,
+  133, 143, 170, 171, 181, 180, 182, 172, 184, 174,
+  173, 183, 190, 191, 185, 193, 175, 192, 176, 186,
+   38,  39,  49,  48,  50,  40,  52,  42,  41,  51,
+   58,  59,  53,  61,  43,  60,  44,  54, 194, 179,
+  189, 196, 177, 195, 178, 187, 188, 151, 136, 146,
+  153, 134, 152, 135, 144, 145, 105,  90, 100, 107,
+   88, 106,  89,  98,  99,  62,  47,  57,  64,  45,
+   63,  46,  55,  56					
+};
--- a/amrconv/amr_defs.h	Thu Apr 20 02:36:14 2023 +0000
+++ b/amrconv/amr_defs.h	Thu Apr 20 22:48:22 2023 +0000
@@ -5,6 +5,8 @@
 
 #define	MAX_PRM_SIZE		57	/* max. num. of params      */
 #define	MAX_SERIAL_SIZE		244	/* max. num. of serial bits */
+#define	MAX_IF1_BYTES		31	/* max bytes in AMR IF1 packing */
+#define	IETF_HDR_LEN		6	/* .amr file header bytes */
 
 enum TXFrameType {
 	TX_SPEECH_GOOD = 0,
@@ -30,6 +32,8 @@
 	MRDTX
 };
 
+#define	MODE_NO_DATA		15
+
 /* number of speech bits for all modes */
 #define	AMR_NBITS_475		95
 #define	AMR_NBITS_515		103
--- /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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/amrconv/ietf_common.c	Thu Apr 20 22:48:22 2023 +0000
@@ -0,0 +1,11 @@
+/*
+ * This C module holds some common data items for IETF RFC 4867
+ * AMR file format.
+ */
+
+#include <stdint.h>
+#include "amr_defs.h"
+
+const char amr_file_hdr[IETF_HDR_LEN] = "#!AMR\n";
+
+const uint8_t extra_bytes_per_ft[9] = {12, 13, 15, 17, 19, 20, 26, 31, 5};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/amrconv/if1_unpack.c	Thu Apr 20 22:48:22 2023 +0000
@@ -0,0 +1,79 @@
+/*
+ * In this module we implement our function for unpacking bits from AMR IF1
+ * and reshuffling them into the codec's natural bit order.
+ */
+
+#include <stdint.h>
+#include "amr_defs.h"
+
+extern const uint8_t amr_475_bit_order[95];
+extern const uint8_t amr_515_bit_order[103];
+extern const uint8_t amr_59_bit_order[118];
+extern const uint8_t amr_67_bit_order[134];
+extern const uint8_t amr_74_bit_order[148];
+extern const uint8_t amr_795_bit_order[159];
+extern const uint8_t amr_102_bit_order[204];
+extern const uint8_t amr_122_bit_order[244];
+
+static void
+unpack_bits(if1_bytes, codec_bits, nbits, table)
+	uint8_t *if1_bytes, *codec_bits;
+	unsigned nbits;
+	const uint8_t *table;
+{
+	unsigned n, nb;
+
+	for (n = 0; n < nbits; n++) {
+		if (table)
+			nb = table[n];
+		else
+			nb = n;
+		codec_bits[nb] = msb_get_bit(if1_bytes, n);
+	}
+}
+
+amr_if1_unpack(if1_bytes, codec_bits, mode)
+	uint8_t *if1_bytes, *codec_bits;
+	unsigned mode;
+{
+	switch (mode) {
+	case MR475:
+		unpack_bits(if1_bytes, codec_bits, AMR_NBITS_475,
+				amr_475_bit_order);
+		return(0);
+	case MR515:
+		unpack_bits(if1_bytes, codec_bits, AMR_NBITS_515,
+				amr_515_bit_order);
+		return(0);
+	case MR59:
+		unpack_bits(if1_bytes, codec_bits, AMR_NBITS_59,
+				amr_59_bit_order);
+		return(0);
+	case MR67:
+		unpack_bits(if1_bytes, codec_bits, AMR_NBITS_67,
+				amr_67_bit_order);
+		return(0);
+	case MR74:
+		unpack_bits(if1_bytes, codec_bits, AMR_NBITS_74,
+				amr_74_bit_order);
+		return(0);
+	case MR795:
+		unpack_bits(if1_bytes, codec_bits, AMR_NBITS_795,
+				amr_795_bit_order);
+		return(0);
+	case MR102:
+		unpack_bits(if1_bytes, codec_bits, AMR_NBITS_102,
+				amr_102_bit_order);
+		return(0);
+	case MR122:            
+		unpack_bits(if1_bytes, codec_bits, AMR_NBITS_122,
+				amr_122_bit_order);
+		return(0);
+	case MRDTX:
+		unpack_bits(if1_bytes, codec_bits, AMR_NBITS_SID,
+				(const uint8_t *) 0);
+		return(0);
+	default:
+		return(-1);
+	}
+}