annotate dev/s2u-regen.c @ 478:936a08cc73ce

doc/AMR-library-API: describe the decoder
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 19 May 2024 21:32:31 +0000
parents a5200ad12d58
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 /*
227
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
2 * This program generates a G.711 mu-law encoding table of the same form
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
3 * as the s2u[] table in the toast_ulaw.c module in libgsm/toast, i.e.,
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
4 * an encoding table that takes only the upper 13 bits of the linear PCM
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
5 * sample to be encoded, even though canonical mu-law encoding requires
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
6 * 14-bit input. The 13-bit table constructed by this program is computed
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
7 * as if the lsb of the "proper" 14-bit input is always zero, like it is
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
8 * expected to be when the linear PCM samples came from the output of a
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
9 * GSM speech decoder.
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
10 *
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
11 * The "engine" function that does the computation is based on ulaw_compress()
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
12 * from ITU-T G.191 STL.
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 */
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 #include <stdio.h>
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 #include <stdlib.h>
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 static unsigned
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
19 ulaw_compress(input)
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 unsigned input;
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 {
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
22 short i; /* aux.var. */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
23 short absno; /* absolute value of linear (input) sample */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
24 short segno; /* segment (Table 2/G711, column 1) */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
25 short low_nibble; /* low nibble of log companded sample */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
26 short high_nibble; /* high nibble of log companded sample */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
27 unsigned output;
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
29 /* -------------------------------------------------------------------- */
227
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
30 /* 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
31 /* Compute absolute value; adjust for easy processing */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
32 /* -------------------------------------------------------------------- */
227
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
33 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
34 ? (~input & 0x1FFF) + 33 /* negative samples */
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
35 : input + 33; /* NB: 33 is the difference value */
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
36 /* between the thresholds for */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
37 /* A-law and u-law. */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
38 if (absno > (0x1FFF)) /* limitation to "absno" < 8192 */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
39 absno = (0x1FFF);
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
41 /* Determination of sample's segment */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
42 i = absno >> 6;
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
43 segno = 1;
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
44 while (i != 0) {
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
45 segno++;
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
46 i >>= 1;
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
47 }
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
48
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
49 /* Mounting the high-nibble of the log-PCM sample */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
50 high_nibble = (0x0008) - segno;
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
52 /* Mounting the low-nibble of the log PCM sample */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
53 low_nibble = (absno >> segno) /* right shift of mantissa and */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
54 &(0x000F); /* masking away leading '1' */
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
55 low_nibble = (0x000F) - low_nibble;
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
57 /* 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
58 output = (high_nibble << 4) | low_nibble;
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
59
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
60 /* Add sign bit */
227
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
61 if (input < 0x2000)
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
62 output = output | (0x0080);
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
63
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
64 return output;
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 }
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 main(argc, argv)
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 char **argv;
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 {
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 unsigned input, output;
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
72 for (input = 0; input < 8192; input++) {
227
a5200ad12d58 dev/s2u-regen.c: new approach
Mychaela Falconia <falcon@freecalypso.org>
parents: 226
diff changeset
73 output = ulaw_compress(input << 1);
226
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
74 printf("%04o,", output);
84d22eb72196 dev: new program s2u-regen
Mychaela Falconia <falcon@freecalypso.org>
parents: 223
diff changeset
75 if ((input % 15) == 14 || input == 8191)
222
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 putchar('\n');
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 }
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 exit(0);
842136bbd0da dev: new program s2a-regen
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 }