view amrdiff/amrdiff.c @ 6:b55451463161

amrdiff: recognize DHF transform
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 03 Apr 2024 20:15:37 +0000
parents a03c87a2abc6
children
line wrap: on
line source

/*
 * This program reads two ETSI/3GPP test sequence files, one from
 * the AMR set of 3GPP TS 26.074 and the other from the "EFR2" set of
 * amr122_efr.zip, and performs a diff between them.
 */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "etsi.h"
#include "amr_defs.h"

const uint8_t amr122_dhf_bits[244] = {
0,0,0,0,1,0,0,0,0,1,0,1,0,1,0,0,1,1,0,1,1,0,1,1,1,0,0,1,0,1,1,0,1,0,1,0,1,0,1,0,
1,0,1,0,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,1,0,1,1,0,0,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,0,
1,0,0,0,0,0,1,1,0,1,1,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,
0,0,0,1,0,1,0,1,1,0,0,0,0,1,0,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,1,1,1,0,1,1,0,
1,0,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,
0,0,0,0
};

const uint8_t efr_dhf_bits[244] = {
0,0,0,0,1,0,0,0,0,1,0,1,1,1,1,0,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,1,1,1,1,1,0,1,0,
1,0,1,0,1,1,0,1,0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,0,1,0,0,0,0,1,1,0,0,0,
0,1,1,0,0,0,0,0,0,1,1,1,1,0,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,
1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,
1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,
};

main(argc, argv)
	char **argv;
{
	char *amr_filename, *efr_filename;
	int amr_be, efr_be;
	FILE *inf_amr, *inf_efr;
	unsigned frame_no;
	uint8_t amr_bits[COD_FORMAT_NWORDS], efr_bits[ETSI_ENC_NWORDS];
	int rc_amr, rc_efr, amr_sp, efr_sp;

	if (argc != 5) {
usage:		fprintf(stderr,
			"usage: %s amr-cod-file be|le efr-cod-file be|le\n",
			argv[0]);
		exit(1);
	}
	amr_filename = argv[1];
	if (!strcmp(argv[2], "be"))
		amr_be = 1;
	else if (!strcmp(argv[2], "le"))
		amr_be = 0;
	else
		goto usage;
	efr_filename = argv[3];
	if (!strcmp(argv[4], "be"))
		efr_be = 1;
	else if (!strcmp(argv[4], "le"))
		efr_be = 0;
	else
		goto usage;
	inf_amr = fopen(amr_filename, "r");
	if (!inf_amr) {
		perror(amr_filename);
		exit(1);
	}
	inf_efr = fopen(efr_filename, "r");
	if (!inf_efr) {
		perror(efr_filename);
		exit(1);
	}
	for (frame_no = 0; ; frame_no++) {
		rc_amr = read_etsi_bits(inf_amr, amr_be, amr_bits,
					COD_FORMAT_NWORDS, amr_filename);
		rc_efr = read_etsi_bits(inf_efr, efr_be, efr_bits,
					ETSI_ENC_NWORDS, efr_filename);
		if (!rc_amr && !rc_efr)
			break;
		if (!rc_amr) {
			printf("EFR file %s is longer than AMR file %s\n",
				efr_filename, amr_filename);
			exit(0);
		}
		if (!rc_efr) {
			printf("AMR file %s is longer than EFR file %s\n",
				amr_filename, efr_filename);
			exit(0);
		}
		/* grok AMR frame type */
		switch (amr_bits[0]) {
		case TX_SPEECH_GOOD:
			if (amr_bits[245] != MR122) {
				fprintf(stderr,
					"error: %s frame #%u is not MR122\n",
					amr_filename, frame_no);
				exit(1);
			}
			amr_sp = 1;
			break;
		case TX_SID_FIRST:
		case TX_SID_UPDATE:
		case TX_NO_DATA:
			amr_sp = 0;
			break;
		default:
			fprintf(stderr,
				"error: %s frame #%u has unknown type %u\n",
				amr_filename, frame_no, amr_bits[0]);
			exit(1);
		}
		efr_sp = efr_bits[245];
		if (!amr_sp && !efr_sp)
			continue;
		if (!amr_sp || !efr_sp) {
			printf("frame #%u: AMR SP %d != EFR SP %d\n", frame_no,
				amr_sp, efr_sp);
			continue;
		}
		if (!bcmp(amr_bits+1, efr_bits, 244))
			continue;
		if (!bcmp(amr_bits+1, amr122_dhf_bits, 244) &&
		    !bcmp(efr_bits, efr_dhf_bits, 244))
			printf("frame #%u: DHF transform\n", frame_no);
		else
			printf("frame #%u: bits differ\n", frame_no);
	}
	exit(0);
}