FreeCalypso > hg > gsm-codec-lib
view libgsmfr2/full_dec.c @ 545:b07dba7b8a4f
doc/EFR-library-API: document RTP input wrapper
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 03 Oct 2024 09:26:04 +0000 |
parents | 3a617e4e9b27 |
children |
line wrap: on
line source
/* * This module implements the "full decoder" functionality of libgsmfr2: * first the Rx DTX handler, then the regular GSM 06.10 decoder. This full * decoder also implements the optional homing feature, resetting both * components upon receiving DHF. */ #include <stdint.h> #include <stdlib.h> #include <string.h> #include "tw_gsmfr.h" #include "typedef.h" #include "ed_state.h" #include "pp_state.h" struct gsmfr_fulldec_state { struct gsmfr_0610_state dec_0610; struct gsmfr_preproc_state rx_dtx; int is_homed; }; const unsigned gsmfr_fulldec_state_size = sizeof(struct gsmfr_fulldec_state); struct gsmfr_fulldec_state *gsmfr_fulldec_create(void) { struct gsmfr_fulldec_state *st; st = malloc(sizeof(struct gsmfr_fulldec_state)); if (st) gsmfr_fulldec_reset(st); return st; } void gsmfr_fulldec_reset(struct gsmfr_fulldec_state *st) { gsmfr_0610_reset(&st->dec_0610); gsmfr_preproc_reset(&st->rx_dtx); st->is_homed = 1; } static void emit_ehf_output(int16_t *pcm_out) { unsigned n; for (n = 0; n < 160; n++) pcm_out[n] = 0x0008; } void gsmfr_fulldec_good_frame(struct gsmfr_fulldec_state *st, const uint8_t *frame_in, int16_t *pcm_out) { uint8_t frame_mod[GSMFR_RTP_FRAME_LEN]; if (st->is_homed && !memcmp(frame_in, gsmfr_decoder_homing_frame, 12)) { emit_ehf_output(pcm_out); return; } memcpy(frame_mod, frame_in, GSMFR_RTP_FRAME_LEN); gsmfr_preproc_good_frame(&st->rx_dtx, frame_mod); gsmfr_0610_decode_frame(&st->dec_0610, frame_mod, pcm_out); if (!memcmp(frame_in, gsmfr_decoder_homing_frame, GSMFR_RTP_FRAME_LEN)) gsmfr_fulldec_reset(st); else st->is_homed = 0; } void gsmfr_fulldec_bfi(struct gsmfr_fulldec_state *st, int taf, int16_t *pcm_out) { uint8_t frame_mod[GSMFR_RTP_FRAME_LEN]; if (st->is_homed) { memset(pcm_out, 0, sizeof(int16_t) * 160); return; } gsmfr_preproc_bfi(&st->rx_dtx, taf, frame_mod); gsmfr_0610_decode_frame(&st->dec_0610, frame_mod, pcm_out); } void gsmfr_fulldec_bfi_bits(struct gsmfr_fulldec_state *st, const uint8_t *bad_frame, int taf, int16_t *pcm_out) { uint8_t frame_mod[GSMFR_RTP_FRAME_LEN]; if (st->is_homed) { memset(pcm_out, 0, sizeof(int16_t) * 160); return; } gsmfr_preproc_bfi_bits(&st->rx_dtx, bad_frame, taf, frame_mod); gsmfr_0610_decode_frame(&st->dec_0610, frame_mod, pcm_out); }