view efrtest/dlcap-dec.c @ 478:936a08cc73ce

doc/AMR-library-API: describe the decoder
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 19 May 2024 21:32:31 +0000
parents 5f23cb3f0f8d
children
line wrap: on
line source

/*
 * This program reads a TCH/EFS downlink capture produced with FreeCalypso tools
 * (fw version with TCH downlink sniffing feature and fc-shell tch record)
 * and feeds it to our libgsmefr decoder, making our best attempt to
 * replicate the processing steps that must be performed by the original DSP.
 *
 * The output format is "robe" (raw big-endian).
 */

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

main(argc, argv)
	char **argv;
{
	FILE *inf, *outf;
	struct EFR_decoder_state *state;
	char linebuf[128];
	int lineno, rc;
	uint16_t status_words[3];
	uint8_t tidsp_bytes[33], frame[EFR_RTP_FRAME_LEN];
	int16_t params[EFR_NUM_PARAMS], pcm[160];
	unsigned fn_mod_104;
	int bfi, taf, sid;

	if (argc != 3) {
		fprintf(stderr, "usage: %s infile outfile\n", argv[0]);
		exit(1);
	}
	inf = fopen(argv[1], "r");
	if (!inf) {
		perror(argv[1]);
		exit(1);
	}
	outf = fopen(argv[2], "w");
	if (!outf) {
		perror(argv[2]);
		exit(1);
	}
	state = EFR_decoder_create();
	if (!state) {
		perror("EFR_decoder_create()");
		exit(1);
	}
	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
		/* support both old and new formats */
		if (isxdigit(linebuf[0]) && isxdigit(linebuf[1]) &&
		    isxdigit(linebuf[2]) && isxdigit(linebuf[3])) {
			rc = parse_dlcap_common(linebuf, status_words,
						tidsp_bytes);
			if (rc < 0) {
invalid:			fprintf(stderr,
				"error: %s is not in the expected format\n",
					argv[1]);
				exit(1);
			}
			fn_mod_104 = 0;		/* won't have TAF */
		} else if (!strncmp(linebuf, "EFR ", 4)) {
			rc = parse_dlcap_common(linebuf + 4, status_words,
						tidsp_bytes);
			if (rc < 0)
				goto invalid;
			if (linebuf[85] != ' ')
				goto invalid;
			if (!isdigit(linebuf[86]))
				goto invalid;
			fn_mod_104 = strtoul(linebuf + 86, 0, 10);
		} else
			goto invalid;
		/* processing, hoping to replicate what the DSP does */
		efr_tidsp_to_std(tidsp_bytes, frame);
		EFR_frame2params(frame, params);
		bfi = (status_words[0] & 0x0204) != 0;
		sid = (status_words[0] & 0x0018) >> 3;
		taf = fn_mod_104 == 60;
		EFR_decode_params(state, params, bfi, sid, taf, pcm);
		write_pcm_to_robe(outf, pcm);
	}
	exit(0);
}