FreeCalypso > hg > gsm-codec-lib
annotate libgsmfr2/full_dec.c @ 536:a3300483ae74
doc/FR1-library-API: document return value from gsmfr_tfo_xfrm_*
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 21 Sep 2024 20:48:58 +0000 |
parents | 3a617e4e9b27 |
children |
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 } |