annotate libgsmfrp/comfort_noise.c @ 183:452c1d5a6268

libgsmefr BFI w/o data: emit zero output after decoder reset In real-life usage, each EFR decoder session will most likely begin with lots of BFI frames before the first real frame arrives. However, because the spec-defined home state of the decoder is speech rather than CN, our regular logic for BFI w/o data would have to feed pseudorandom noise to the decoder (in the "fixed codebook excitation pulses" part), which is silly to do at the beginning of the decoder session right out of reset. Therefore, let's check reset_flag_old, and if we are still in the reset state, simply emit zero output.
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 03 Jan 2023 00:12:18 +0000
parents 3b64f255689a
children f081a6850fb5
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>
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)
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 | ((st->sid_xmaxc[sub] >> 1) & 0x1F);
286d5f097eb4 libgsmfrp: implement comfort noise generation
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 *c++ = ((st->sid_xmaxc[sub] & 0x1) << 7)
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 }