view libgsmfrp/bad_frame.c @ 108:3b64f255689a

libgsmfrp: factor out PRNG into its own module, in preparation for using it as part of speech muting too
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 28 Nov 2022 04:00:18 +0000
parents b2255a5d0519
children 2361a7d8c1eb
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;
}

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));
		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;
	}
}