changeset 48:3e632126e099

efr-sid: generate efr-sid-test2.gsmx for OS#6538
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 11 Aug 2024 22:17:37 +0000
parents ee54b9748c09
children 2daadef1e70d
files .hgignore efr-sid/Makefile efr-sid/mk-sid-test2.c
diffstat 3 files changed, 164 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Wed Jul 24 05:39:51 2024 +0000
+++ b/.hgignore	Sun Aug 11 22:17:37 2024 +0000
@@ -26,6 +26,8 @@
 ^dmw/dmw-[au]law\.
 
 ^efr-sid/mk-sid-test$
+^efr-sid/mk-sid-test2$
+
 ^hr-sid/misorder$
 ^hr-sid/sidgen$
 
--- a/efr-sid/Makefile	Wed Jul 24 05:39:51 2024 +0000
+++ b/efr-sid/Makefile	Sun Aug 11 22:17:37 2024 +0000
@@ -1,16 +1,26 @@
 CC=	gcc
 CFLAGS=	-O2
-PROG=	mk-sid-test
+PROG1=	mk-sid-test
+PROG2=	mk-sid-test2
+PROGS=	${PROG1} ${PROG2}
 INPUT=	dtx01-frame71.cod
-OUTPUT=	efr-sid-test.gsmx
+OUT1=	efr-sid-test.gsmx
+OUT2=	efr-sid-test2.gsmx
+OUTPUTS=${OUT1} ${OUT2}
 
-all:	${PROG} ${OUTPUT}
+all:	${PROGS} ${OUTPUTS}
 
-${PROG}:	${PROG}.o etsi-bit-rd.o sidbits.o
+${PROG1}:	${PROG1}.o etsi-bit-rd.o sidbits.o
 	${CC} ${CFLAGS} -o $@ $^
 
-${OUTPUT}:	${PROG} ${INPUT}
-	./${PROG} ${INPUT} ${OUTPUT}
+${OUT1}:	${PROG1} ${INPUT}
+	./${PROG1} ${INPUT} $@
+
+${PROG2}:	${PROG2}.o etsi-bit-rd.o sidbits.o
+	${CC} ${CFLAGS} -o $@ $^
+
+${OUT2}:	${PROG2} ${INPUT}
+	./${PROG2} ${INPUT} $@
 
 clean:
-	rm -f ${PROG} *.o *.gsmx
+	rm -f ${PROGS} *.o *.gsmx
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/efr-sid/mk-sid-test2.c	Sun Aug 11 22:17:37 2024 +0000
@@ -0,0 +1,145 @@
+/*
+ * This program generates a set of EFR codec frames based on a single input
+ * frame (in ETSI cod format) that is expected to be a perfect SID.
+ * The output frame set is intended to serve as a unit test for the
+ * bit-counting SID classification function; it will contain different
+ * extents of bit clearing to produce valid SID, invalid SID and non-SID
+ * speech classifications.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <gsm_efr.h>
+#include "etsi.h"
+
+#define	TOTAL_BITS	244
+
+extern const uint8_t SID_codeword_bit_idx[95];
+
+static uint8_t input_frame[ETSI_ENC_NWORDS];
+static FILE *outf;
+
+static void
+read_input_file(filename)
+	char *filename;
+{
+	FILE *inf;
+
+	inf = fopen(filename, "r");
+	if (!inf) {
+		perror(filename);
+		exit(1);
+	}
+	read_etsi_bits(inf, 0, input_frame, ETSI_ENC_NWORDS, filename);
+	fclose(inf);
+}
+
+static void
+emit_out_frame(bits)
+	uint8_t *bits;
+{
+	uint8_t packed_frame[EFR_RTP_FRAME_LEN];
+
+	bits2frame(bits, packed_frame, "input", 0);
+	fwrite(packed_frame, 1, EFR_RTP_FRAME_LEN, outf);
+}
+
+static void
+emit_1bit_errors()
+{
+	uint8_t frame_bits[TOTAL_BITS];
+	unsigned n;
+
+	for (n = 0; n < 95; n++) {
+		bcopy(input_frame, frame_bits, TOTAL_BITS);
+		frame_bits[SID_codeword_bit_idx[n]] = 0;
+		emit_out_frame(frame_bits);
+	}
+}
+
+static void
+emit_2bit_errors()
+{
+	uint8_t frame_bits[TOTAL_BITS];
+
+	bcopy(input_frame, frame_bits, TOTAL_BITS);
+	frame_bits[SID_codeword_bit_idx[3]] = 0;
+	frame_bits[SID_codeword_bit_idx[14]] = 0;
+	emit_out_frame(frame_bits);
+	bcopy(input_frame, frame_bits, TOTAL_BITS);
+	frame_bits[SID_codeword_bit_idx[15]] = 0;
+	frame_bits[SID_codeword_bit_idx[92]] = 0;
+	emit_out_frame(frame_bits);
+	bcopy(input_frame, frame_bits, TOTAL_BITS);
+	frame_bits[SID_codeword_bit_idx[65]] = 0;
+	frame_bits[SID_codeword_bit_idx[35]] = 0;
+	emit_out_frame(frame_bits);
+	bcopy(input_frame, frame_bits, TOTAL_BITS);
+	frame_bits[SID_codeword_bit_idx[89]] = 0;
+	frame_bits[SID_codeword_bit_idx[79]] = 0;
+	emit_out_frame(frame_bits);
+	bcopy(input_frame, frame_bits, TOTAL_BITS);
+	frame_bits[SID_codeword_bit_idx[32]] = 0;
+	frame_bits[SID_codeword_bit_idx[38]] = 0;
+	emit_out_frame(frame_bits);
+	bcopy(input_frame, frame_bits, TOTAL_BITS);
+	frame_bits[SID_codeword_bit_idx[46]] = 0;
+	frame_bits[SID_codeword_bit_idx[26]] = 0;
+	emit_out_frame(frame_bits);
+}
+
+static void
+emit_15bit_errors()
+{
+	uint8_t frame_bits[TOTAL_BITS];
+	unsigned i, j;
+
+	for (i = 0; i < 6; i++) {
+		bcopy(input_frame, frame_bits, TOTAL_BITS);
+		for (j = 0; j < 15; j++)
+			frame_bits[SID_codeword_bit_idx[j * 6 + i]] = 0;
+		emit_out_frame(frame_bits);
+	}
+}
+
+static void
+emit_16bit_errors()
+{
+	uint8_t frame_bits[TOTAL_BITS];
+	unsigned i, j;
+
+	for (i = 0; i < 6; i++) {
+		bcopy(input_frame, frame_bits, TOTAL_BITS);
+		for (j = 0; j < 16; j++)
+			frame_bits[SID_codeword_bit_idx[j * 6 + i]] = 0;
+		emit_out_frame(frame_bits);
+	}
+}
+
+main(argc, argv)
+	char **argv;
+{
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s input.cod output.gsmx\n", argv[0]);
+		exit(1);
+	}
+	read_input_file(argv[1]);
+	outf = fopen(argv[2], "w");
+	if (!outf) {
+		perror(argv[2]);
+		exit(1);
+	}
+	/* emit the perfect, error-free SID first */
+	emit_out_frame(input_frame);
+	/* now different bit-error possibilities */
+	emit_1bit_errors();
+	emit_2bit_errors();
+	emit_15bit_errors();
+	emit_16bit_errors();
+	/* all done */
+	fclose(outf);
+	exit(0);
+}