diff libgsmfrp/bad_frame.c @ 6:b2255a5d0519

libgsmfrp: implement BFI handling
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 19 Nov 2022 21:18:53 +0000
parents
children 2361a7d8c1eb
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgsmfrp/bad_frame.c	Sat Nov 19 21:18:53 2022 +0000
@@ -0,0 +1,59 @@
+/*
+ * 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;
+	}
+}