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