annotate libgsmfr2/comfort_noise.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 573afa985df6
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * In this module we implement comfort noise generation per GSM 06.12
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * or 3GPP TS 46.012.
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 */
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 #include <stdint.h>
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 #include <string.h>
256
a33edf624061 libgsmfr2: start with API definition and port of libgsmfrp code
Mychaela Falconia <falcon@freecalypso.org>
parents: 242
diff changeset
8 #include "tw_gsmfr.h"
262
573afa985df6 libgsmfr2: split pp_state.h from pp_internal.h
Mychaela Falconia <falcon@freecalypso.org>
parents: 256
diff changeset
9 #include "pp_state.h"
256
a33edf624061 libgsmfr2: start with API definition and port of libgsmfrp code
Mychaela Falconia <falcon@freecalypso.org>
parents: 242
diff changeset
10 #include "pp_internal.h"
4
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 static const uint8_t fold_table_8to6[24] = {
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 1, 2, 3, 4, 5, 6, 1, 2,
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 1, 2, 3, 4, 5, 6, 3, 4,
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 1, 2, 3, 4, 5, 6, 5, 6,
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 };
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 static const uint8_t bc[4] = {0, 0, 0, 0};
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 static const uint8_t Nc[4] = {40, 120, 40, 120};
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 static uint8_t random_1to6(struct gsmfr_preproc_state *st)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 {
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 uint8_t range8, range6;
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24
108
3b64f255689a libgsmfrp: factor out PRNG into its own module,
Mychaela Falconia <falcon@freecalypso.org>
parents: 4
diff changeset
25 range8 = gsmfr_preproc_prng(st, 3);
4
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 range6 = fold_table_8to6[(st->cn_random_6fold << 3) | range8];
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 st->cn_random_6fold++;
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 if (st->cn_random_6fold >= 3)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 st->cn_random_6fold = 0;
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 return range6;
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 }
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32
256
a33edf624061 libgsmfr2: start with API definition and port of libgsmfrp code
Mychaela Falconia <falcon@freecalypso.org>
parents: 242
diff changeset
33 void gsmfr_preproc_gen_cn(struct gsmfr_preproc_state *st, uint8_t *frame)
4
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 {
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 unsigned sub, pulse;
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 uint8_t Mc, xmc[13];
256
a33edf624061 libgsmfr2: start with API definition and port of libgsmfrp code
Mychaela Falconia <falcon@freecalypso.org>
parents: 242
diff changeset
37 uint8_t *c;
4
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 /* global bytes (magic and LARc) are fixed */
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 memcpy(frame, st->sid_prefix, 5);
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 c = frame + 5;
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 /* now do the 4 subframes, mostly PRNG output */
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 for (sub = 0; sub < 4; sub++) {
108
3b64f255689a libgsmfrp: factor out PRNG into its own module,
Mychaela Falconia <falcon@freecalypso.org>
parents: 4
diff changeset
44 Mc = gsmfr_preproc_prng(st, 2);
4
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 for (pulse = 0; pulse < 13; pulse++)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 xmc[pulse] = random_1to6(st);
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 /* packing code from libgsm */
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 *c++ = ((Nc[sub] & 0x7F) << 1)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 | ((bc[sub] >> 1) & 0x1);
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 *c++ = ((bc[sub] & 0x1) << 7)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 | ((Mc & 0x3) << 5)
242
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
52 | ((st->sid_xmaxc >> 1) & 0x1F);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
53 *c++ = ((st->sid_xmaxc & 0x1) << 7)
4
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 | ((xmc[0] & 0x7) << 4)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 | ((xmc[1] & 0x7) << 1)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 | ((xmc[2] >> 2) & 0x1);
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 *c++ = ((xmc[2] & 0x3) << 6)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 | ((xmc[3] & 0x7) << 3)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 | (xmc[4] & 0x7);
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 *c++ = ((xmc[5] & 0x7) << 5)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 | ((xmc[6] & 0x7) << 2)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 | ((xmc[7] >> 1) & 0x3);
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 *c++ = ((xmc[7] & 0x1) << 7)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 | ((xmc[8] & 0x7) << 4)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 | ((xmc[9] & 0x7) << 1)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 | ((xmc[10] >> 2) & 0x1);
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 *c++ = ((xmc[10] & 0x3) << 6)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 | ((xmc[11] & 0x7) << 3)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 | (xmc[12] & 0x7);
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 }
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 }
242
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
72
256
a33edf624061 libgsmfr2: start with API definition and port of libgsmfrp code
Mychaela Falconia <falcon@freecalypso.org>
parents: 242
diff changeset
73 void gsmfr_preproc_sid2cn(struct gsmfr_preproc_state *st, uint8_t *frame)
242
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
74 {
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
75 unsigned sub, pulse;
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
76 uint8_t Mc, xmc[13];
256
a33edf624061 libgsmfr2: start with API definition and port of libgsmfrp code
Mychaela Falconia <falcon@freecalypso.org>
parents: 242
diff changeset
77 uint8_t *c;
242
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
78
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
79 /* save LARc and Xmaxc from the last subframe for subsequent CN gen */
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
80 memcpy(st->sid_prefix, frame, 5);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
81 st->sid_xmaxc = ((frame[27] & 0x1F) << 1) | (frame[28] >> 7);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
82 /* ... and turn *this* frame into very first CN output */
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
83 c = frame + 5;
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
84 for (sub = 0; sub < 4; sub++) {
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
85 Mc = gsmfr_preproc_prng(st, 2);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
86 for (pulse = 0; pulse < 13; pulse++)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
87 xmc[pulse] = random_1to6(st);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
88 /* keep each of Xmaxc and replace the rest with CN */
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
89 *c++ = ((Nc[sub] & 0x7F) << 1)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
90 | ((bc[sub] >> 1) & 0x1);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
91 *c &= 0x1F;
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
92 *c++ |= ((bc[sub] & 0x1) << 7)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
93 | ((Mc & 0x3) << 5);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
94 *c &= 0x80;
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
95 *c++ |= ((xmc[0] & 0x7) << 4)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
96 | ((xmc[1] & 0x7) << 1)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
97 | ((xmc[2] >> 2) & 0x1);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
98 *c++ = ((xmc[2] & 0x3) << 6)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
99 | ((xmc[3] & 0x7) << 3)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
100 | (xmc[4] & 0x7);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
101 *c++ = ((xmc[5] & 0x7) << 5)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
102 | ((xmc[6] & 0x7) << 2)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
103 | ((xmc[7] >> 1) & 0x3);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
104 *c++ = ((xmc[7] & 0x1) << 7)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
105 | ((xmc[8] & 0x7) << 4)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
106 | ((xmc[9] & 0x7) << 1)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
107 | ((xmc[10] >> 2) & 0x1);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
108 *c++ = ((xmc[10] & 0x3) << 6)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
109 | ((xmc[11] & 0x7) << 3)
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
110 | (xmc[12] & 0x7);
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
111 }
f081a6850fb5 libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
112 }