annotate libgsmfr2/full_dec.c @ 553:ebcf414b7d99 default tip

doc/TFO-transform: describe details for FRv1, both modes
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 07 Oct 2024 08:24:24 +0000
parents 3a617e4e9b27
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
279
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * This module implements the "full decoder" functionality of libgsmfr2:
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * first the Rx DTX handler, then the regular GSM 06.10 decoder. This full
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 * decoder also implements the optional homing feature, resetting both
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 * components upon receiving DHF.
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 */
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 #include <stdint.h>
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <stdlib.h>
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <string.h>
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include "tw_gsmfr.h"
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include "typedef.h"
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include "ed_state.h"
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include "pp_state.h"
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 struct gsmfr_fulldec_state {
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 struct gsmfr_0610_state dec_0610;
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 struct gsmfr_preproc_state rx_dtx;
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 int is_homed;
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 };
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21
533
3a617e4e9b27 libgsmfr2: add const words with struct sizes
Mychaela Falconia <falcon@freecalypso.org>
parents: 527
diff changeset
22 const unsigned gsmfr_fulldec_state_size = sizeof(struct gsmfr_fulldec_state);
3a617e4e9b27 libgsmfr2: add const words with struct sizes
Mychaela Falconia <falcon@freecalypso.org>
parents: 527
diff changeset
23
279
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 struct gsmfr_fulldec_state *gsmfr_fulldec_create(void)
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 {
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 struct gsmfr_fulldec_state *st;
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 st = malloc(sizeof(struct gsmfr_fulldec_state));
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 if (st)
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 gsmfr_fulldec_reset(st);
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 return st;
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 }
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 void gsmfr_fulldec_reset(struct gsmfr_fulldec_state *st)
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 {
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 gsmfr_0610_reset(&st->dec_0610);
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 gsmfr_preproc_reset(&st->rx_dtx);
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 st->is_homed = 1;
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 }
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 static void emit_ehf_output(int16_t *pcm_out)
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 {
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 unsigned n;
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 for (n = 0; n < 160; n++)
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 pcm_out[n] = 0x0008;
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 }
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 void gsmfr_fulldec_good_frame(struct gsmfr_fulldec_state *st,
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 const uint8_t *frame_in, int16_t *pcm_out)
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 {
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 uint8_t frame_mod[GSMFR_RTP_FRAME_LEN];
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 if (st->is_homed && !memcmp(frame_in, gsmfr_decoder_homing_frame, 12)) {
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 emit_ehf_output(pcm_out);
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 return;
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 }
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 memcpy(frame_mod, frame_in, GSMFR_RTP_FRAME_LEN);
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 gsmfr_preproc_good_frame(&st->rx_dtx, frame_mod);
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 gsmfr_0610_decode_frame(&st->dec_0610, frame_mod, pcm_out);
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 if (!memcmp(frame_in, gsmfr_decoder_homing_frame, GSMFR_RTP_FRAME_LEN))
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 gsmfr_fulldec_reset(st);
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 else
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 st->is_homed = 0;
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 }
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 void gsmfr_fulldec_bfi(struct gsmfr_fulldec_state *st, int taf,
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 int16_t *pcm_out)
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 {
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 uint8_t frame_mod[GSMFR_RTP_FRAME_LEN];
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 if (st->is_homed) {
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 memset(pcm_out, 0, sizeof(int16_t) * 160);
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 return;
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 }
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 gsmfr_preproc_bfi(&st->rx_dtx, taf, frame_mod);
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 gsmfr_0610_decode_frame(&st->dec_0610, frame_mod, pcm_out);
4db5fc10fd1a libgsmfr2: implement full decoder
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 }
527
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
79
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
80 void gsmfr_fulldec_bfi_bits(struct gsmfr_fulldec_state *st,
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
81 const uint8_t *bad_frame, int taf, int16_t *pcm_out)
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
82 {
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
83 uint8_t frame_mod[GSMFR_RTP_FRAME_LEN];
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
84
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
85 if (st->is_homed) {
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
86 memset(pcm_out, 0, sizeof(int16_t) * 160);
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
87 return;
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
88 }
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
89 gsmfr_preproc_bfi_bits(&st->rx_dtx, bad_frame, taf, frame_mod);
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
90 gsmfr_0610_decode_frame(&st->dec_0610, frame_mod, pcm_out);
f3246d109e2d libgsmfr2: add gsmfr_fulldec_bfi_bits()
Mychaela Falconia <falcon@freecalypso.org>
parents: 279
diff changeset
91 }