changeset 247:56d3fbacd115

dev: new program xmaxc-tables
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 12 May 2023 02:04:42 +0000
parents a55fcc8b6daf
children 6ac547f0b903
files .hgignore dev/Makefile dev/xmaxc-tables.c
diffstat 3 files changed, 104 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue May 09 22:49:07 2023 +0000
+++ b/.hgignore	Fri May 12 02:04:42 2023 +0000
@@ -28,6 +28,8 @@
 ^dev/s2u-regen-plus4\.out$
 ^dev/u2s-regen$
 ^dev/u2s-regen\.out$
+^dev/xmaxc-tables$
+^dev/xmaxc-tables\.out$
 
 ^efrtest/gsmefr-cod-parse$
 ^efrtest/gsmefr-cod2gsmx$
--- a/dev/Makefile	Tue May 09 22:49:07 2023 +0000
+++ b/dev/Makefile	Fri May 12 02:04:42 2023 +0000
@@ -1,10 +1,10 @@
 CC=	gcc
 CFLAGS=	-O2
 PROGS=	a2s-regen efr-bit-packing efr-sid-insert efr-tidsp gsm0611-silence-fr \
-	mk-256bytes s2a-regen s2u-regen s2u-regen-plus4 u2s-regen
+	mk-256bytes s2a-regen s2u-regen s2u-regen-plus4 u2s-regen xmaxc-tables
 DATAOUT=a2s-regen.out efr-bit-packing.out efr-sid-insert.out efr-tidsp.out \
 	gsm0611-silence-fr.out s2a-regen.out s2u-regen.out s2u-regen-plus4.out \
-	u2s-regen.out
+	u2s-regen.out xmaxc-tables.out
 
 all:	${PROGS} ${DATAOUT}
 
@@ -65,5 +65,11 @@
 u2s-regen.out:	u2s-regen
 	./u2s-regen > $@
 
+xmaxc-tables:	xmaxc-tables.c
+	${CC} ${CFLAGS} -o $@ $@.c
+
+xmaxc-tables.out:	xmaxc-tables
+	./xmaxc-tables > $@
+
 clean:
 	rm -f *.o *.out ${PROGS}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dev/xmaxc-tables.c	Fri May 12 02:04:42 2023 +0000
@@ -0,0 +1,94 @@
+/*
+ * For libgsmfrp: if we are going to initiate comfort noise generation
+ * upon receiving an invalid SID, and if we are going to harvest the
+ * needed LARc and Xmaxc parameters from the last speech frame, we'll
+ * need a way to compute a single mean Xmaxc from the 4 subframe Xmaxc
+ * parameters of that last speech frame.
+ *
+ * This program generates Xmaxc dequantization and requantization tables
+ * that are specifically optimized for performing this mean manipulation.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+static uint16_t dequant_table[64];
+static uint8_t requant_table[1024];
+
+static void
+compute_dequant()
+{
+	unsigned xmaxc, dequant, step;
+
+	dequant = 0;
+	step = 1;
+	for (xmaxc = 0; xmaxc < 64; xmaxc++) {
+		dequant_table[xmaxc] = dequant;
+		dequant += step;
+		if ((xmaxc & 7) == 7 && xmaxc != 7)
+			step <<= 1;
+	}
+}
+
+static void
+compute_requant()
+{
+	unsigned x, c;
+
+	for (x = 0; x < 1024; x++) {
+		for (c = 0; c < 63; c++) {
+			if (x < dequant_table[c+1])
+				break;
+		}
+		requant_table[x] = c;
+	}
+}
+
+static void
+print_dequant()
+{
+	unsigned c, r;
+
+	puts("const uint16_t dequant_table[64] = {");
+	for (c = 0; c < 64; c++) {
+		r = c & 7;
+		if (!r)
+			putchar('\t');
+		printf("%3u,", dequant_table[c]);
+		if (r == 7)
+			putchar('\n');
+		else
+			putchar(' ');
+	}
+	fputs("};\n\n", stdout);
+}
+
+static void
+print_requant()
+{
+	unsigned x, r;
+
+	puts("const uint8_t requant_table[1024] = {");
+	for (x = 0; x < 1024; x++) {
+		r = x & 15;
+		if (!r)
+			putchar('\t');
+		printf("%2u,", requant_table[x]);
+		if (r == 15)
+			putchar('\n');
+		else
+			putchar(' ');
+	}
+	fputs("};\n", stdout);
+}
+
+main(argc, argv)
+	char **argv;
+{
+	compute_dequant();
+	compute_requant();
+	print_dequant();
+	print_requant();
+	exit(0);
+}