annotate libgsmhr1/rtp_in.c @ 581:e2d5cad04cbf

libgsmhr1 RxFE: store CN R0+LPC separately from speech In the original GSM 06.06 code the ECU for speech mode is entirely separate from the CN generator, maintaining separate state. (The main intertie between them is the speech vs CN state variable, distinguishing between speech and CN BFIs, in addition to the CN-specific function of distinguishing between initial and update SIDs.) In the present RxFE implementation I initially thought that we could use the same saved_frame buffer for both ECU and CN, overwriting just the first 4 params (R0 and LPC) when a valid SID comes in. However, I now realize it was a bad idea: the original code has a corner case (long sequence of speech-mode BFIs to put the ECU in state 6, then SID and CN-mode BFIs, then a good speech frame) that would be broken by that buffer reuse approach. We could eliminate this corner case by resetting the ECU state when passing through a CN insertion period, but doing so would needlessly increase the behavioral diffs between GSM 06.06 and our version. Solution: use a separate CN-specific buffer for CN R0+LPC parameters, and match the behavior of GSM 06.06 code in this regard.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 13 Feb 2025 10:02:45 +0000
parents cc3a831712a4
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
492
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * The function implemented in this module takes whatever HRv1 payload format
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * came in from RTP (can be RFC 5993 with or without TW-TS-002 extensions,
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 * can be bare TS 101 318, can be zero-length or missing payload) and turns it
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 * into canonical TW-TS-002 format, be it for storage or for immediate
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 * further processing.
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 */
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <stdint.h>
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <string.h>
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include "tw_gsmhr.h"
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 int gsmhr_rtp_in_preen(const uint8_t *rtp_in, unsigned rtp_in_len,
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 uint8_t *canon_pl)
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 {
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 int ft;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 switch (rtp_in_len) {
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 case 0:
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 /* BFI-no-data, but not an invalid RTP input per se */
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 canon_pl[0] = 0x70;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 return 0;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 case 1:
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 /*
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 * This length is valid only if the payload is in
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 * RFC 5993 or TW-TS-002 format with FT=1 or FT=7.
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 */
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 if (rtp_in[0] & 0x80)
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 goto bad_rtp_input;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 ft = rtp_in[0] >> 4;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 if (ft == 1 || ft == 7) {
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 canon_pl[0] = rtp_in[0];
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 return 0;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 } else
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 goto bad_rtp_input;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 case GSMHR_FRAME_LEN_RPF:
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 /*
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 * The length is that of a TS 101 318 payload.
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 * No further checks can be done: every possible
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 * bit pattern is a valid payload in this format.
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 * But we do need to check for a perfect SID
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 * (the only kind of SID this format allows)
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 * and mark it accordingly in the output.
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 */
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 canon_pl[0] = gsmhr_ts101318_is_perfect_sid(rtp_in) << 4;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 memcpy(canon_pl + 1, rtp_in, GSMHR_FRAME_LEN_RPF);
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 return 0;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 case GSMHR_FRAME_LEN_5993:
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 /*
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 * This length is valid only if the payload is in
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 * RFC 5993 or TW-TS-002 format with FT=0, FT=2 or FT=6.
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 */
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 if (rtp_in[0] & 0x80)
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 goto bad_rtp_input;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 ft = rtp_in[0] >> 4;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 if (ft == 0 || ft == 2 || ft == 6) {
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 memcpy(canon_pl, rtp_in, GSMHR_FRAME_LEN_5993);
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 return 0;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 } else
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 goto bad_rtp_input;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 default:
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 bad_rtp_input:
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 /*
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 * Treat it like BFI-no-data, and tell the caller
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 * that we received an invalid RTP payload.
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 */
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 canon_pl[0] = 0x70;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 return -1;
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 }
cc3a831712a4 libgsmhr1: implement arbitrary RTP input
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 }