view trau-decode/extr-fr.c @ 12:154586f0f423

trau-files: decode to playable WAV
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 24 May 2024 20:05:15 +0000
parents 0565aaa84b17
children
line wrap: on
line source

/*
 * This module implements the FR decoding part of trau-extr.
 */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <tw_gsmfr.h>

/* this corresponds to the bit-lengths of the individual codec
 * parameters as indicated in Table 1.1 of TS 46.010 */
static const uint8_t gsm_fr_map[GSMFR_NUM_PARAMS] = {
	6, 6, 5, 5, 4, 4, 3, 3,
	7, 2, 2, 6, 3, 3, 3, 3,
	3, 3, 3, 3, 3, 3, 3, 3,
	3, 7, 2, 2, 6, 3, 3, 3,
	3, 3, 3, 3, 3, 3, 3, 3,
	3, 3, 7, 2, 2, 6, 3, 3,
	3, 3, 3, 3, 3, 3, 3, 3,
	3, 3, 3, 7, 2, 2, 6, 3,
	3, 3, 3, 3, 3, 3, 3, 3,
	3, 3, 3, 3
};

static unsigned
get_le(bits, nbits)
	uint8_t *bits;
	unsigned nbits;
{
	unsigned accum, mask;
	unsigned n;

	accum = 0;
	mask = 1;
	for (n = 0; n < nbits; n++) {
		if (*bits)
			accum |= mask;
		bits++;
		mask <<= 1;
	}
	return accum;
}

static void
dbits_to_params(d_bits, params)
	uint8_t *d_bits;
	int16_t *params;
{
	unsigned np, len;
	uint8_t *ip;
	int16_t *op;

	ip = d_bits;
	op = params;
	for (np = 0; np < GSMFR_NUM_PARAMS; np++) {
		len = gsm_fr_map[np];
		*op++ = get_le(ip, len);
		ip += len;
	}
}

void
convert_fr_frame(d_bits, outf)
	uint8_t *d_bits;
	FILE *outf;
{
	int16_t params[GSMFR_NUM_PARAMS];
	uint8_t rtp_pack[GSMFR_RTP_FRAME_LEN];

	dbits_to_params(d_bits, params);
	gsmfr_pack_from_array(params, rtp_pack);
	fwrite(rtp_pack, 1, GSMFR_RTP_FRAME_LEN, outf);
}