FreeCalypso > hg > gsm-codec-lib
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; + } +}