annotate frtest/decode-r.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 14b627682458
children cfa3006a66da
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
153
14b627682458 gsmfr-decode-r utility put together
Mychaela Falconia <falcon@freecalypso.org>
parents: 16
diff changeset
2 * gsmfr-decode-r is like gsmfr-decode, but writes the decoded PCM
14b627682458 gsmfr-decode-r utility put together
Mychaela Falconia <falcon@freecalypso.org>
parents: 16
diff changeset
3 * output in our "robe" format instead of WAV.
12
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 */
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 #include <stdio.h>
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 #include <stdint.h>
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 #include <stdlib.h>
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <gsm.h>
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include "../libgsmfrp/gsm_fr_preproc.h"
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include "../libtest/binreader.h"
153
14b627682458 gsmfr-decode-r utility put together
Mychaela Falconia <falcon@freecalypso.org>
parents: 16
diff changeset
12 #include "../libtest/robewrite.h"
12
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 main(argc, argv)
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 char **argv;
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 {
153
14b627682458 gsmfr-decode-r utility put together
Mychaela Falconia <falcon@freecalypso.org>
parents: 16
diff changeset
17 FILE *binf, *outf;
12
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 gsm dec_state;
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 struct gsmfr_preproc_state *pp_state;
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 uint8_t frame[BINFILE_MAX_FRAME];
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 int16_t pcm[160];
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 int rc, bfi, taf;
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 if (argc != 3) {
153
14b627682458 gsmfr-decode-r utility put together
Mychaela Falconia <falcon@freecalypso.org>
parents: 16
diff changeset
25 fprintf(stderr, "usage: %s input.gsm output.robe\n", argv[0]);
12
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 exit(1);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 }
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 binf = fopen(argv[1], "r");
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 if (!binf) {
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 perror(argv[1]);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 exit(1);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 }
153
14b627682458 gsmfr-decode-r utility put together
Mychaela Falconia <falcon@freecalypso.org>
parents: 16
diff changeset
33 outf = fopen(argv[2], "w");
14b627682458 gsmfr-decode-r utility put together
Mychaela Falconia <falcon@freecalypso.org>
parents: 16
diff changeset
34 if (!outf) {
12
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 perror(argv[2]);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 exit(1);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 }
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 dec_state = gsm_create();
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 if (!dec_state) {
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 fprintf(stderr, "gsm_create() failed!\n");
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 exit(1);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 }
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 pp_state = gsmfr_preproc_create();
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 if (!pp_state) {
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 fprintf(stderr, "gsmfr_preproc_create() failed!\n");
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 exit(1);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 }
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 for (;;) {
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 rc = binfile_read_frame(binf, frame);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 if (rc < 0) {
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 fprintf(stderr, "error: garbage in %s\n", argv[1]);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 exit(1);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 }
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 if (!rc)
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 break;
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 if (frame[0] == 0xBF) {
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 bfi = 1;
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 taf = frame[1] & 1;
16
b9a842775f40 gsmfr-decode: trivial bug
Mychaela Falconia <falcon@freecalypso.org>
parents: 12
diff changeset
59 } else if ((frame[0] & 0xF0) == 0xD0)
12
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 bfi = 0;
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 else {
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 fprintf(stderr, "error: %s is not in FR codec format\n",
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 argv[1]);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 exit(1);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 }
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 if (bfi)
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 gsmfr_preproc_bfi(pp_state, taf, frame);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 else
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 gsmfr_preproc_good_frame(pp_state, frame);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 gsm_decode(dec_state, frame, pcm);
153
14b627682458 gsmfr-decode-r utility put together
Mychaela Falconia <falcon@freecalypso.org>
parents: 16
diff changeset
71 write_pcm_to_robe(outf, pcm);
12
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 }
153
14b627682458 gsmfr-decode-r utility put together
Mychaela Falconia <falcon@freecalypso.org>
parents: 16
diff changeset
73 fclose(outf);
12
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 exit(0);
f88817a233fb gsmfr-decode test program written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 }