view efrtest/etsi-dec.c @ 150:da17c7f02c6c

gsmefr-etsi-dec: add BE support
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 14 Dec 2022 22:04:39 +0000
parents 8ed838709897
children 9f354d2aea13
line wrap: on
line source

/*
 * gsmefr-etsi-dec is a test program for our EFR decoder: it reads ETSI's
 * .dec format as input and writes raw 16-bit PCM (same as ETSI's *.out)
 * as output, allowing our decoder to be tested with ETSI's official test
 * sequences.
 *
 * ETSI input and output files are read and written in LE byte order
 * by default, or in BE byte order if -b option is given.
 */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "../libgsmefr/gsm_efr.h"
#include "etsi.h"

static void
write_pcm_be(outf, pcm)
	FILE *outf;
	int16_t *pcm;
{
	uint8_t bytes[320], *dp;
	int16_t samp;
	unsigned n;

	dp = bytes;
	for (n = 0; n < 160; n++) {
		samp = pcm[n];
		*dp++ = (samp >> 8) & 0xFF;
		*dp++ = samp & 0xFF;
	}
	fwrite(bytes, 2, 160, outf);
}

static void
write_pcm_le(outf, pcm)
	FILE *outf;
	int16_t *pcm;
{
	uint8_t bytes[320], *dp;
	int16_t samp;
	unsigned n;

	dp = bytes;
	for (n = 0; n < 160; n++) {
		samp = pcm[n];
		*dp++ = samp & 0xFF;
		*dp++ = (samp >> 8) & 0xFF;
	}
	fwrite(bytes, 2, 160, outf);
}

main(argc, argv)
	char **argv;
{
	int big_endian;
	char *infname, *outfname;
	FILE *inf, *outf;
	struct EFR_decoder_state *state;
	unsigned frame_no;
	uint8_t input_bits[ETSI_DEC_NWORDS], frame[EFR_RTP_FRAME_LEN];
	int16_t pcm[160];
	int rc;

	if (argc == 3 && argv[1][0] != '-') {
		big_endian = 0;
		infname = argv[1];
		outfname = argv[2];
	} else if (argc == 4 && !strcmp(argv[1], "-b")) {
		big_endian = 1;
		infname = argv[2];
		outfname = argv[3];
	} else {
		fprintf(stderr, "usage: %s [-b] input.dec output.out\n",
			argv[0]);
		exit(1);
	}
	inf = fopen(infname, "r");
	if (!inf) {
		perror(infname);
		exit(1);
	}
	outf = fopen(outfname, "w");
	if (!outf) {
		perror(outfname);
		exit(1);
	}
	state = EFR_decoder_create();
	if (!state) {
		perror("EFR_decoder_create()");
		exit(1);
	}
	for (frame_no = 0; ; frame_no++) {
		rc = read_etsi_bits(inf, big_endian, input_bits,
				    ETSI_DEC_NWORDS, infname);
		if (!rc)
			break;
		if (input_bits[0] > 1) {
			fprintf(stderr, "error in %s frame #%u: BFI > 1\n",
				infname, frame_no);
			exit(1);
		}
		bits2frame(input_bits + 1, frame, infname, frame_no);
		if (input_bits[245] > 2) {
			fprintf(stderr, "error in %s frame #%u: SID > 2\n",
				infname, frame_no);
			exit(1);
		}
		if (input_bits[246] > 1) {
			fprintf(stderr, "error in %s frame #%u: TAF > 1\n",
				infname, frame_no);
			exit(1);
		}
		rc = EFR_sid_classify(frame);
		if (input_bits[245] != rc) {
			fprintf(stderr,
"warning: frame #%u has mismatching SID (file says %u, analysis yields %d)\n",
				frame_no, input_bits[245], rc);
		}
		EFR_decode_frame(state, frame, input_bits[0], input_bits[246],
				 pcm);
		if (big_endian)
			write_pcm_be(outf, pcm);
		else
			write_pcm_le(outf, pcm);
	}
	fclose(outf);
	exit(0);
}