view efr-sid/mk-sid-test2.c @ 49:2daadef1e70d

efr-sid OS#6538: more sensible 15-bit and 16-bit errors
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 12 Aug 2024 02:37:21 +0000
parents 3e632126e099
children 0db059f4632d
line wrap: on
line source

/*
 * 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 < 11; 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 < 20; i++) {
		bcopy(input_frame, frame_bits, TOTAL_BITS);
		for (j = 0; j < 16; j++)
			frame_bits[SID_codeword_bit_idx[j * 5 + 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);
}