annotate dev/s2u-regen-plus4.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 67d60915fbbe
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
228
67d60915fbbe dev: new program s2u-regen-plus4
Mychaela Falconia <falcon@freecalypso.org>
parents: 227
diff changeset
2 * This program is a companion to s2u-regen.c: it computes a mu-law encoding
67d60915fbbe dev: new program s2u-regen-plus4
Mychaela Falconia <falcon@freecalypso.org>
parents: 227
diff changeset
3 * table with 13-bit input just like s2u-regen, but computes it as if the
67d60915fbbe dev: new program s2u-regen-plus4
Mychaela Falconia <falcon@freecalypso.org>
parents: 227
diff changeset
4 * lsb following the 13-bit part is always 1 rather than always 0. The
67d60915fbbe dev: new program s2u-regen-plus4
Mychaela Falconia <falcon@freecalypso.org>
parents: 227
diff changeset
5 * purpose of this program is to illustrate the effect of that lsb on the
67d60915fbbe dev: new program s2u-regen-plus4
Mychaela Falconia <falcon@freecalypso.org>
parents: 227
diff changeset
6 * mu-law output.
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 */
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <stdio.h>
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <stdlib.h>
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 static unsigned
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
13 ulaw_compress(input)
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 unsigned input;
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 {
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
16 short i; /* aux.var. */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
17 short absno; /* absolute value of linear (input) sample */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
18 short segno; /* segment (Table 2/G711, column 1) */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
19 short low_nibble; /* low nibble of log companded sample */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
20 short high_nibble; /* high nibble of log companded sample */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
21 unsigned output;
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
23 /* -------------------------------------------------------------------- */
227
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
24 /* Input is 14-bit right-justified in this version */
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
25 /* Compute absolute value; adjust for easy processing */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
26 /* -------------------------------------------------------------------- */
227
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
27 absno = input >= 0x2000 /* compute 1's complement in case of */
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
28 ? (~input & 0x1FFF) + 33 /* negative samples */
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
29 : input + 33; /* NB: 33 is the difference value */
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
30 /* between the thresholds for */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
31 /* A-law and u-law. */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
32 if (absno > (0x1FFF)) /* limitation to "absno" < 8192 */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
33 absno = (0x1FFF);
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
35 /* Determination of sample's segment */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
36 i = absno >> 6;
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
37 segno = 1;
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
38 while (i != 0) {
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
39 segno++;
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
40 i >>= 1;
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
41 }
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
42
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
43 /* Mounting the high-nibble of the log-PCM sample */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
44 high_nibble = (0x0008) - segno;
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
46 /* Mounting the low-nibble of the log PCM sample */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
47 low_nibble = (absno >> segno) /* right shift of mantissa and */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
48 &(0x000F); /* masking away leading '1' */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
49 low_nibble = (0x000F) - low_nibble;
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
51 /* Joining the high-nibble and the low-nibble of the log PCM sample */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
52 output = (high_nibble << 4) | low_nibble;
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
53
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
54 /* Add sign bit */
227
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
55 if (input < 0x2000)
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
56 output = output | (0x0080);
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
57
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
58 return output;
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 }
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 main(argc, argv)
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 char **argv;
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 {
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 unsigned input, output;
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
66 for (input = 0; input < 8192; input++) {
228
67d60915fbbe dev: new program s2u-regen-plus4
Mychaela Falconia <falcon@freecalypso.org>
parents: 227
diff changeset
67 output = ulaw_compress((input << 1) + 1);
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
68 printf("%04o,", output);
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
69 if ((input % 15) == 14 || input == 8191)
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 putchar('\n');
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 }
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 exit(0);
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 }