annotate efrtest/dlcap-dec.c @ 242:f081a6850fb5

libgsmfrp: new refined implementation The previous implementation exhibited the following defects, which are now fixed: 1) The last received valid SID was cached forever for the purpose of handling future invalid SIDs - we could have received some valid SID ages ago, then lots of speech or NO_DATA, and if we then get an invalid SID, we would resurrect the last valid SID from ancient history - a bad design. In our new design, we handle invalid SID based on the current state, much like BFI. 2) GSM 06.11 spec says clearly that after the second lost SID (received BFI=1 && TAF=1 in CN state) we need to gradually decrease the output level, rather than jump directly to emitting silence frames - we previously failed to implement such logic. 3) Per GSM 06.12 section 5.2, Xmaxc should be the same in all 4 subframes in a SID frame. What should we do if we receive an otherwise valid SID frame with different Xmaxc? Our previous approach would replicate this Xmaxc oddity in every subsequent generated CN frame, which is rather bad. In our new design, the very first CN frame (which can be seen as a transformation of the SID frame itself) retains the original 4 distinct Xmaxc, but all subsequent CN frames are based on the Xmaxc from the last subframe of the most recent SID.
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 09 May 2023 05:16:31 +0000
parents 5f23cb3f0f8d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
140
5efc377326da gsmefr-dlcap-gsmx: EFR counterpart to gsmfr-cvt-dlcap
Mychaela Falconia <falcon@freecalypso.org>
parents: 139
diff changeset
2 * This program reads a TCH/EFS downlink capture produced with FreeCalypso tools
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * (fw version with TCH downlink sniffing feature and fc-shell tch record)
164
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
4 * and feeds it to our libgsmefr decoder, making our best attempt to
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
5 * replicate the processing steps that must be performed by the original DSP.
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
6 *
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
7 * The output format is "robe" (raw big-endian).
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 */
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <ctype.h>
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <stdio.h>
139
be57e06bed84 factor out common part of gsmfr-cvt-dlcap, in prep for EFR
Mychaela Falconia <falcon@freecalypso.org>
parents: 137
diff changeset
12 #include <stdint.h>
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include <stdlib.h>
137
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
14 #include <string.h>
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
15 #include <strings.h>
164
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
16 #include "../libgsmefr/gsm_efr.h"
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 main(argc, argv)
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 char **argv;
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 {
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 FILE *inf, *outf;
164
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
22 struct EFR_decoder_state *state;
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 char linebuf[128];
137
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
24 int lineno, rc;
139
be57e06bed84 factor out common part of gsmfr-cvt-dlcap, in prep for EFR
Mychaela Falconia <falcon@freecalypso.org>
parents: 137
diff changeset
25 uint16_t status_words[3];
164
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
26 uint8_t tidsp_bytes[33], frame[EFR_RTP_FRAME_LEN];
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
27 int16_t params[EFR_NUM_PARAMS], pcm[160];
137
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
28 unsigned fn_mod_104;
164
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
29 int bfi, taf, sid;
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 if (argc != 3) {
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 fprintf(stderr, "usage: %s infile outfile\n", argv[0]);
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 exit(1);
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 }
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 inf = fopen(argv[1], "r");
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 if (!inf) {
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 perror(argv[1]);
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 exit(1);
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 }
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 outf = fopen(argv[2], "w");
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 if (!outf) {
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 perror(argv[2]);
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 exit(1);
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 }
164
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
45 state = EFR_decoder_create();
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
46 if (!state) {
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
47 perror("EFR_decoder_create()");
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
48 exit(1);
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
49 }
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
137
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
51 /* support both old and new formats */
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
52 if (isxdigit(linebuf[0]) && isxdigit(linebuf[1]) &&
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
53 isxdigit(linebuf[2]) && isxdigit(linebuf[3])) {
139
be57e06bed84 factor out common part of gsmfr-cvt-dlcap, in prep for EFR
Mychaela Falconia <falcon@freecalypso.org>
parents: 137
diff changeset
54 rc = parse_dlcap_common(linebuf, status_words,
137
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
55 tidsp_bytes);
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
56 if (rc < 0) {
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 invalid: fprintf(stderr,
137
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
58 "error: %s is not in the expected format\n",
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
59 argv[1]);
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 exit(1);
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 }
137
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
62 fn_mod_104 = 0; /* won't have TAF */
140
5efc377326da gsmefr-dlcap-gsmx: EFR counterpart to gsmfr-cvt-dlcap
Mychaela Falconia <falcon@freecalypso.org>
parents: 139
diff changeset
63 } else if (!strncmp(linebuf, "EFR ", 4)) {
5efc377326da gsmefr-dlcap-gsmx: EFR counterpart to gsmfr-cvt-dlcap
Mychaela Falconia <falcon@freecalypso.org>
parents: 139
diff changeset
64 rc = parse_dlcap_common(linebuf + 4, status_words,
137
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
65 tidsp_bytes);
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
66 if (rc < 0)
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
67 goto invalid;
140
5efc377326da gsmefr-dlcap-gsmx: EFR counterpart to gsmfr-cvt-dlcap
Mychaela Falconia <falcon@freecalypso.org>
parents: 139
diff changeset
68 if (linebuf[85] != ' ')
137
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
69 goto invalid;
140
5efc377326da gsmefr-dlcap-gsmx: EFR counterpart to gsmfr-cvt-dlcap
Mychaela Falconia <falcon@freecalypso.org>
parents: 139
diff changeset
70 if (!isdigit(linebuf[86]))
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 goto invalid;
140
5efc377326da gsmefr-dlcap-gsmx: EFR counterpart to gsmfr-cvt-dlcap
Mychaela Falconia <falcon@freecalypso.org>
parents: 139
diff changeset
72 fn_mod_104 = strtoul(linebuf + 86, 0, 10);
137
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
73 } else
b7ea278390eb gsmfr-cvt-dlcap: support new FC TCH DL recording format
Mychaela Falconia <falcon@freecalypso.org>
parents: 19
diff changeset
74 goto invalid;
164
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
75 /* processing, hoping to replicate what the DSP does */
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
76 efr_tidsp_to_std(tidsp_bytes, frame);
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
77 EFR_frame2params(frame, params);
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
78 bfi = (status_words[0] & 0x0204) != 0;
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
79 sid = (status_words[0] & 0x0018) >> 3;
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
80 taf = fn_mod_104 == 60;
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
81 EFR_decode_params(state, params, bfi, sid, taf, pcm);
5f23cb3f0f8d gsmefr-dlcap-dec program written
Mychaela Falconia <falcon@freecalypso.org>
parents: 163
diff changeset
82 write_pcm_to_robe(outf, pcm);
19
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 }
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 exit(0);
7960744ba19c frtest: gsmfr-cvt-dlcap program based on fc-tch2fr
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 }