FreeCalypso > hg > gsm-codec-lib
annotate libgsmfrp/comfort_noise.c @ 266:8821ffaa93a5
libgsmfr2: integrate decoder main function from libgsm
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 14 Apr 2024 00:36:16 +0000 |
parents | f081a6850fb5 |
children |
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> |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
8 #include "gsm_fr_preproc.h" |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
9 #include "internal.h" |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
10 |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
11 static const uint8_t fold_table_8to6[24] = { |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
12 1, 2, 3, 4, 5, 6, 1, 2, |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
13 1, 2, 3, 4, 5, 6, 3, 4, |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
14 1, 2, 3, 4, 5, 6, 5, 6, |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
15 }; |
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 static const uint8_t bc[4] = {0, 0, 0, 0}; |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
18 static const uint8_t Nc[4] = {40, 120, 40, 120}; |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
19 |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
20 static uint8_t random_1to6(struct gsmfr_preproc_state *st) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
21 { |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
22 uint8_t range8, range6; |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
23 |
108
3b64f255689a
libgsmfrp: factor out PRNG into its own module,
Mychaela Falconia <falcon@freecalypso.org>
parents:
4
diff
changeset
|
24 range8 = gsmfr_preproc_prng(st, 3); |
4
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
25 range6 = fold_table_8to6[(st->cn_random_6fold << 3) | range8]; |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
26 st->cn_random_6fold++; |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
27 if (st->cn_random_6fold >= 3) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
28 st->cn_random_6fold = 0; |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
29 return range6; |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
30 } |
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 void gsmfr_preproc_gen_cn(struct gsmfr_preproc_state *st, gsm_byte *frame) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
33 { |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
34 unsigned sub, pulse; |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
35 uint8_t Mc, xmc[13]; |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
36 gsm_byte *c; |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
37 |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
38 /* global bytes (magic and LARc) are fixed */ |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
39 memcpy(frame, st->sid_prefix, 5); |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
40 c = frame + 5; |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
41 /* now do the 4 subframes, mostly PRNG output */ |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
42 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
|
43 Mc = gsmfr_preproc_prng(st, 2); |
4
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
44 for (pulse = 0; pulse < 13; pulse++) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
45 xmc[pulse] = random_1to6(st); |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
46 /* packing code from libgsm */ |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
47 *c++ = ((Nc[sub] & 0x7F) << 1) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
48 | ((bc[sub] >> 1) & 0x1); |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
49 *c++ = ((bc[sub] & 0x1) << 7) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
50 | ((Mc & 0x3) << 5) |
242
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
51 | ((st->sid_xmaxc >> 1) & 0x1F); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
52 *c++ = ((st->sid_xmaxc & 0x1) << 7) |
4
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
53 | ((xmc[0] & 0x7) << 4) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
54 | ((xmc[1] & 0x7) << 1) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
55 | ((xmc[2] >> 2) & 0x1); |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
56 *c++ = ((xmc[2] & 0x3) << 6) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
57 | ((xmc[3] & 0x7) << 3) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
58 | (xmc[4] & 0x7); |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
59 *c++ = ((xmc[5] & 0x7) << 5) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
60 | ((xmc[6] & 0x7) << 2) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
61 | ((xmc[7] >> 1) & 0x3); |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
62 *c++ = ((xmc[7] & 0x1) << 7) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
63 | ((xmc[8] & 0x7) << 4) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
64 | ((xmc[9] & 0x7) << 1) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
65 | ((xmc[10] >> 2) & 0x1); |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
66 *c++ = ((xmc[10] & 0x3) << 6) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
67 | ((xmc[11] & 0x7) << 3) |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
68 | (xmc[12] & 0x7); |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
69 } |
286d5f097eb4
libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
70 } |
242
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
71 |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
72 void gsmfr_preproc_sid2cn(struct gsmfr_preproc_state *st, gsm_byte *frame) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
73 { |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
74 unsigned sub, pulse; |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
75 uint8_t Mc, xmc[13]; |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
76 gsm_byte *c; |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
77 |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
78 /* 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
|
79 memcpy(st->sid_prefix, frame, 5); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
80 st->sid_xmaxc = ((frame[27] & 0x1F) << 1) | (frame[28] >> 7); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
81 /* ... and turn *this* frame into very first CN output */ |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
82 c = frame + 5; |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
83 for (sub = 0; sub < 4; sub++) { |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
84 Mc = gsmfr_preproc_prng(st, 2); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
85 for (pulse = 0; pulse < 13; pulse++) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
86 xmc[pulse] = random_1to6(st); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
87 /* keep each of Xmaxc and replace the rest with CN */ |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
88 *c++ = ((Nc[sub] & 0x7F) << 1) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
89 | ((bc[sub] >> 1) & 0x1); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
90 *c &= 0x1F; |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
91 *c++ |= ((bc[sub] & 0x1) << 7) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
92 | ((Mc & 0x3) << 5); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
93 *c &= 0x80; |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
94 *c++ |= ((xmc[0] & 0x7) << 4) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
95 | ((xmc[1] & 0x7) << 1) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
96 | ((xmc[2] >> 2) & 0x1); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
97 *c++ = ((xmc[2] & 0x3) << 6) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
98 | ((xmc[3] & 0x7) << 3) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
99 | (xmc[4] & 0x7); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
100 *c++ = ((xmc[5] & 0x7) << 5) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
101 | ((xmc[6] & 0x7) << 2) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
102 | ((xmc[7] >> 1) & 0x3); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
103 *c++ = ((xmc[7] & 0x1) << 7) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
104 | ((xmc[8] & 0x7) << 4) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
105 | ((xmc[9] & 0x7) << 1) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
106 | ((xmc[10] >> 2) & 0x1); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
107 *c++ = ((xmc[10] & 0x3) << 6) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
108 | ((xmc[11] & 0x7) << 3) |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
109 | (xmc[12] & 0x7); |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
110 } |
f081a6850fb5
libgsmfrp: new refined implementation
Mychaela Falconia <falcon@freecalypso.org>
parents:
108
diff
changeset
|
111 } |