view libgsmfrp/bad_frame.c @ 133:b4b1c3a192c7

doc/Binary-file-format: document gsmrec-dump
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 11 Dec 2022 05:24:11 +0000
parents 2361a7d8c1eb
children f081a6850fb5
line wrap: on
line source

/*
 * In this module we implement our handling of BFI frame gaps.
 */

#include <stdint.h>
#include <string.h>
#include "gsm_fr_preproc.h"
#include "internal.h"

static int reduce_xmaxc(gsm_byte *frame)
{
	int mute_flag = 1;
	unsigned sub, xmaxc;

	for (sub = 0; sub < 4; sub++) {
		xmaxc = ((frame[sub*7+6] & 0x1F) << 1) | (frame[sub*7+7] >> 7);
		if (xmaxc > 4) {
			xmaxc -= 4;
			mute_flag = 0;
		} else
			xmaxc = 0;
		frame[sub*7+6] &= 0xE0;
		frame[sub*7+6] |= xmaxc >> 1;
		frame[sub*7+7] &= 0x7F;
		frame[sub*7+7] |= (xmaxc & 1) << 7;
	}
	return mute_flag;
}

static void random_grid_pos(struct gsmfr_preproc_state *st, gsm_byte *frame)
{
	unsigned sub, Mc;

	for (sub = 0; sub < 4; sub++) {
		Mc = gsmfr_preproc_prng(st, 2);
		frame[sub*7+6] &= 0x9F;
		frame[sub*7+6] |= Mc << 5;
	}
}

void gsmfr_preproc_bfi(struct gsmfr_preproc_state *st, int taf, gsm_byte *frame)
{
	int mute;

	switch (st->rx_state) {
	case NO_DATA:
		memcpy(frame, &gsmfr_preproc_silence_frame, sizeof(gsm_frame));
		return;
	case SPEECH:
		memcpy(frame, &st->speech_frame, sizeof(gsm_frame));
		st->rx_state = SPEECH_MUTING;
		return;
	case SPEECH_MUTING:
		mute = reduce_xmaxc(st->speech_frame);
		memcpy(frame, &st->speech_frame, sizeof(gsm_frame));
		random_grid_pos(st, frame);
		if (mute)
			st->rx_state = NO_DATA;
		return;
	case COMFORT_NOISE:
		gsmfr_preproc_gen_cn(st, frame);
		if (taf)
			st->rx_state = LOST_SID;
		return;
	case LOST_SID:
		gsmfr_preproc_gen_cn(st, frame);
		if (taf)
			st->rx_state = NO_DATA;
		return;
	}
}