FreeCalypso > hg > gsm-codec-lib
changeset 6:b2255a5d0519
libgsmfrp: implement BFI handling
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 19 Nov 2022 21:18:53 +0000 |
parents | 4812e00bc100 |
children | 634df6435e16 |
files | libgsmfrp/Makefile libgsmfrp/bad_frame.c |
diffstat | 2 files changed, 61 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/libgsmfrp/Makefile Sat Nov 19 20:46:13 2022 +0000 +++ b/libgsmfrp/Makefile Sat Nov 19 21:18:53 2022 +0000 @@ -1,6 +1,7 @@ CC= gcc CFLAGS= -O2 -OBJS= comfort_noise.o good_frame.o sidclass.o silence_frame.o state.o +OBJS= bad_frame.o comfort_noise.o good_frame.o sidclass.o silence_frame.o \ + state.o LIB= libgsmfrp.a all: ${LIB}
--- /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; + } +}