comparison libgsmfr2/full_dec.c @ 279:4db5fc10fd1a

libgsmfr2: implement full decoder
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 14 Apr 2024 04:48:48 +0000
parents
children
comparison
equal deleted inserted replaced
278:c94d9a336e8f 279:4db5fc10fd1a
1 /*
2 * This module implements the "full decoder" functionality of libgsmfr2:
3 * first the Rx DTX handler, then the regular GSM 06.10 decoder. This full
4 * decoder also implements the optional homing feature, resetting both
5 * components upon receiving DHF.
6 */
7
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "tw_gsmfr.h"
12 #include "typedef.h"
13 #include "ed_state.h"
14 #include "pp_state.h"
15
16 struct gsmfr_fulldec_state {
17 struct gsmfr_0610_state dec_0610;
18 struct gsmfr_preproc_state rx_dtx;
19 int is_homed;
20 };
21
22 struct gsmfr_fulldec_state *gsmfr_fulldec_create(void)
23 {
24 struct gsmfr_fulldec_state *st;
25
26 st = malloc(sizeof(struct gsmfr_fulldec_state));
27 if (st)
28 gsmfr_fulldec_reset(st);
29 return st;
30 }
31
32 void gsmfr_fulldec_reset(struct gsmfr_fulldec_state *st)
33 {
34 gsmfr_0610_reset(&st->dec_0610);
35 gsmfr_preproc_reset(&st->rx_dtx);
36 st->is_homed = 1;
37 }
38
39 static void emit_ehf_output(int16_t *pcm_out)
40 {
41 unsigned n;
42
43 for (n = 0; n < 160; n++)
44 pcm_out[n] = 0x0008;
45 }
46
47 void gsmfr_fulldec_good_frame(struct gsmfr_fulldec_state *st,
48 const uint8_t *frame_in, int16_t *pcm_out)
49 {
50 uint8_t frame_mod[GSMFR_RTP_FRAME_LEN];
51
52 if (st->is_homed && !memcmp(frame_in, gsmfr_decoder_homing_frame, 12)) {
53 emit_ehf_output(pcm_out);
54 return;
55 }
56 memcpy(frame_mod, frame_in, GSMFR_RTP_FRAME_LEN);
57 gsmfr_preproc_good_frame(&st->rx_dtx, frame_mod);
58 gsmfr_0610_decode_frame(&st->dec_0610, frame_mod, pcm_out);
59 if (!memcmp(frame_in, gsmfr_decoder_homing_frame, GSMFR_RTP_FRAME_LEN))
60 gsmfr_fulldec_reset(st);
61 else
62 st->is_homed = 0;
63 }
64
65 void gsmfr_fulldec_bfi(struct gsmfr_fulldec_state *st, int taf,
66 int16_t *pcm_out)
67 {
68 uint8_t frame_mod[GSMFR_RTP_FRAME_LEN];
69
70 if (st->is_homed) {
71 memset(pcm_out, 0, sizeof(int16_t) * 160);
72 return;
73 }
74 gsmfr_preproc_bfi(&st->rx_dtx, taf, frame_mod);
75 gsmfr_0610_decode_frame(&st->dec_0610, frame_mod, pcm_out);
76 }