changeset 101:d86f866489e9

gsm-amr2efr utility written
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 27 Nov 2022 05:15:39 +0000
parents d5bab777865a
children dd88f9312170
files .hgignore miscutil/Makefile miscutil/amr122bits.c miscutil/amr2efr.c miscutil/bitmanip.c
diffstat 5 files changed, 129 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sat Nov 26 22:07:55 2022 +0000
+++ b/.hgignore	Sun Nov 27 05:15:39 2022 +0000
@@ -20,6 +20,7 @@
 ^frtest/gsmfr-max-out$
 ^frtest/gsmfr-preproc$
 
+^miscutil/gsm-amr2efr$
 ^miscutil/gsmrec-dump$
 
 ^pcap/rtp-gsmfr-extr$
--- a/miscutil/Makefile	Sat Nov 26 22:07:55 2022 +0000
+++ b/miscutil/Makefile	Sun Nov 27 05:15:39 2022 +0000
@@ -1,12 +1,17 @@
 CC=	gcc
 CFLAGS=	-O2
-PROGS=	gsmrec-dump
+PROGS=	gsm-amr2efr gsmrec-dump
 LIBEFR=	../libgsmefr/libgsmefr.a
 LIBTEST=../libtest/libtest.a
 INSTBIN=/opt/freecalypso/bin
 
+AMR2EFR_OBJS=	amr122bits.o bitmanip.o amr2efr.o
+
 all:	${PROGS}
 
+gsm-amr2efr:	${AMR2EFR_OBJS}
+	${CC} ${CFLAGS} -o $@ ${AMR2EFR_OBJS}
+
 gsmrec-dump:	gsmrec-dump.o ${LIBTEST} ${LIBEFR}
 	${CC} ${CFLAGS} -o $@ gsmrec-dump.o ${LIBTEST} ${LIBEFR} -lgsm
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscutil/amr122bits.c	Sun Nov 27 05:15:39 2022 +0000
@@ -0,0 +1,36 @@
+/*
+ * This C module provides the bit reordering table to be used for conversion
+ * between EFR in ETSI TS 101 318 representation and AMR 12k2 in RFC 4867
+ * or AMR IF1 representation, which is the table mapping from AMR IF1 bit
+ * order for 12k2 mode to the "natural" bit order of codec parameters.
+ */
+
+#include <stdint.h>
+
+const uint8_t amr_122_bit_order[244] = {
+    0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
+   10,  11,  12,  13,  14,  23,  15,  16,  17,  18,
+   19,  20,  21,  22,  24,  25,  26,  27,  28,  38,
+  141,  39, 142,  40, 143,  41, 144,  42, 145,  43,
+  146,  44, 147,  45, 148,  46, 149,  47,  97, 150,
+  200,  48,  98, 151, 201,  49,  99, 152, 202,  86,
+  136, 189, 239,  87, 137, 190, 240,  88, 138, 191,
+  241,  91, 194,  92, 195,  93, 196,  94, 197,  95,
+  198,  29,  30,  31,  32,  33,  34,  35,  50, 100,
+  153, 203,  89, 139, 192, 242,  51, 101, 154, 204,
+   55, 105, 158, 208,  90, 140, 193, 243,  59, 109,
+  162, 212,  63, 113, 166, 216,  67, 117, 170, 220,
+   36,  37,  54,  53,  52,  58,  57,  56,  62,  61,
+   60,  66,  65,  64,  70,  69,  68, 104, 103, 102,
+  108, 107, 106, 112, 111, 110, 116, 115, 114, 120,
+  119, 118, 157, 156, 155, 161, 160, 159, 165, 164,
+  163, 169, 168, 167, 173, 172, 171, 207, 206, 205,
+  211, 210, 209, 215, 214, 213, 219, 218, 217, 223,
+  222, 221,  73,  72,  71,  76,  75,  74,  79,  78,
+   77,  82,  81,  80,  85,  84,  83, 123, 122, 121,
+  126, 125, 124, 129, 128, 127, 132, 131, 130, 135,
+  134, 133, 176, 175, 174, 179, 178, 177, 182, 181,
+  180, 185, 184, 183, 188, 187, 186, 226, 225, 224,
+  229, 228, 227, 232, 231, 230, 235, 234, 233, 238,
+  237, 236,  96, 199						
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscutil/amr2efr.c	Sun Nov 27 05:15:39 2022 +0000
@@ -0,0 +1,62 @@
+/*
+ * Our gsm-amr2efr utility reads in a speech recording in .amr format
+ * (the mode must be MR122 for every frame, no DTX) and converts it into
+ * our ad hoc .gsmx format for EFR.  The conversion is a bit reshuffling
+ * only, no transcoding takes place.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+extern const uint8_t amr_122_bit_order[244];
+
+main(argc, argv)
+	char **argv;
+{
+	FILE *inf, *outf;
+	int hdrb;
+	uint8_t frm_in[31], frm_out[31];
+	unsigned bit_a, bit_n;
+
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s input.amr output.gsmx\n", argv[0]);
+		exit(1);
+	}
+	inf = fopen(argv[1], "r");
+	if (!inf) {
+		perror(argv[1]);
+		exit(1);
+	}
+	outf = fopen(argv[2], "w");
+	if (!outf) {
+		perror(argv[2]);
+		exit(1);
+	}
+	for (;;) {
+		hdrb = getc(inf);
+		if (hdrb < 0)
+			break;
+		if ((hdrb & 0x78) != 0x38) {
+			fprintf(stderr, "error: unexpected content in %s\n",
+				argv[1]);
+			exit(1);
+		}
+		if (fread(frm_in, 1, 31, inf) != 31) {
+			fprintf(stderr, "error: short read from %s\n", argv[1]);
+			exit(1);
+		}
+		bzero(frm_out, 31);
+		frm_out[0] = 0xC0;
+		for (bit_a = 0; bit_a < 244; bit_a++) {
+			bit_n = amr_122_bit_order[bit_a];
+			msb_set_bit(frm_out, 4 + bit_n,
+				    msb_get_bit(frm_in, bit_a));
+		}
+		fwrite(frm_out, 1, 31, outf);
+	}
+	fclose(outf);
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscutil/bitmanip.c	Sun Nov 27 05:15:39 2022 +0000
@@ -0,0 +1,24 @@
+/*
+ * This module provides two utility functions that serve as building blocks
+ * for frame bit reordering operations.
+ */
+
+#include <stdint.h>
+
+msb_get_bit(buf, bn)
+	uint8_t *buf;
+{
+	int pos_byte = bn >> 3;
+	int pos_bit  = 7 - (bn & 7);
+
+	return (buf[pos_byte] >> pos_bit) & 1;
+}
+
+msb_set_bit(buf, bn, bit)
+	uint8_t *buf;
+{
+	int pos_byte = bn >> 3;
+	int pos_bit  = 7 - (bn & 7);
+
+	buf[pos_byte] |= (bit << pos_bit);
+}