annotate efrtest/etsi-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 da17c7f02c6c
children 9f354d2aea13
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * gsmefr-etsi-dec is a test program for our EFR decoder: it reads ETSI's
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * .dec format as input and writes raw 16-bit PCM (same as ETSI's *.out)
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 * as output, allowing our decoder to be tested with ETSI's official test
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 * sequences.
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 *
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
7 * ETSI input and output files are read and written in LE byte order
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
8 * by default, or in BE byte order if -b option is given.
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 */
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <stdio.h>
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <stdint.h>
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include <stdlib.h>
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include <string.h>
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 #include <strings.h>
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 #include "../libgsmefr/gsm_efr.h"
145
8ed838709897 efrtest: ETSI bit reading factored out of gsmefr-etsi-dec
Mychaela Falconia <falcon@freecalypso.org>
parents: 97
diff changeset
17 #include "etsi.h"
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 static void
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
20 write_pcm_be(outf, pcm)
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
21 FILE *outf;
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
22 int16_t *pcm;
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
23 {
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
24 uint8_t bytes[320], *dp;
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
25 int16_t samp;
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
26 unsigned n;
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
27
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
28 dp = bytes;
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
29 for (n = 0; n < 160; n++) {
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
30 samp = pcm[n];
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
31 *dp++ = (samp >> 8) & 0xFF;
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
32 *dp++ = samp & 0xFF;
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
33 }
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
34 fwrite(bytes, 2, 160, outf);
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
35 }
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
36
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
37 static void
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 write_pcm_le(outf, pcm)
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 FILE *outf;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 int16_t *pcm;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 {
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 uint8_t bytes[320], *dp;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 int16_t samp;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 unsigned n;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 dp = bytes;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 for (n = 0; n < 160; n++) {
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 samp = pcm[n];
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 *dp++ = samp & 0xFF;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 *dp++ = (samp >> 8) & 0xFF;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 }
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 fwrite(bytes, 2, 160, outf);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 }
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 main(argc, argv)
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 char **argv;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 {
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
58 int big_endian;
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
59 char *infname, *outfname;
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 FILE *inf, *outf;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 struct EFR_decoder_state *state;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 unsigned frame_no;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 uint8_t input_bits[ETSI_DEC_NWORDS], frame[EFR_RTP_FRAME_LEN];
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 int16_t pcm[160];
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 int rc;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
67 if (argc == 3 && argv[1][0] != '-') {
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
68 big_endian = 0;
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
69 infname = argv[1];
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
70 outfname = argv[2];
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
71 } else if (argc == 4 && !strcmp(argv[1], "-b")) {
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
72 big_endian = 1;
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
73 infname = argv[2];
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
74 outfname = argv[3];
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
75 } else {
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
76 fprintf(stderr, "usage: %s [-b] input.dec output.out\n",
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
77 argv[0]);
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 exit(1);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 }
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
80 inf = fopen(infname, "r");
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 if (!inf) {
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
82 perror(infname);
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 exit(1);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 }
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
85 outf = fopen(outfname, "w");
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 if (!outf) {
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
87 perror(outfname);
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 exit(1);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 }
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 state = EFR_decoder_create();
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 if (!state) {
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 perror("EFR_decoder_create()");
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 exit(1);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 }
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 for (frame_no = 0; ; frame_no++) {
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
96 rc = read_etsi_bits(inf, big_endian, input_bits,
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
97 ETSI_DEC_NWORDS, infname);
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 if (!rc)
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 break;
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 if (input_bits[0] > 1) {
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 fprintf(stderr, "error in %s frame #%u: BFI > 1\n",
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
102 infname, frame_no);
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 exit(1);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 }
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
105 bits2frame(input_bits + 1, frame, infname, frame_no);
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 if (input_bits[245] > 2) {
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 fprintf(stderr, "error in %s frame #%u: SID > 2\n",
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
108 infname, frame_no);
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 exit(1);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
110 }
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 if (input_bits[246] > 1) {
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 fprintf(stderr, "error in %s frame #%u: TAF > 1\n",
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
113 infname, frame_no);
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 exit(1);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115 }
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 rc = EFR_sid_classify(frame);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 if (input_bits[245] != rc) {
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
118 fprintf(stderr,
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
119 "warning: frame #%u has mismatching SID (file says %u, analysis yields %d)\n",
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
120 frame_no, input_bits[245], rc);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
121 }
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
122 EFR_decode_frame(state, frame, input_bits[0], input_bits[246],
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
123 pcm);
150
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
124 if (big_endian)
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
125 write_pcm_be(outf, pcm);
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
126 else
da17c7f02c6c gsmefr-etsi-dec: add BE support
Mychaela Falconia <falcon@freecalypso.org>
parents: 145
diff changeset
127 write_pcm_le(outf, pcm);
96
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
128 }
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
129 fclose(outf);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
130 exit(0);
9cf1355bc071 gsmefr-etsi-dec test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
131 }