FreeCalypso > hg > gsm-codec-lib
comparison libgsmfrp/comfort_noise.c @ 108:3b64f255689a
libgsmfrp: factor out PRNG into its own module,
in preparation for using it as part of speech muting too
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 28 Nov 2022 04:00:18 +0000 |
parents | 286d5f097eb4 |
children | f081a6850fb5 |
comparison
equal
deleted
inserted
replaced
107:41f1ae68d253 | 108:3b64f255689a |
---|---|
15 }; | 15 }; |
16 | 16 |
17 static const uint8_t bc[4] = {0, 0, 0, 0}; | 17 static const uint8_t bc[4] = {0, 0, 0, 0}; |
18 static const uint8_t Nc[4] = {40, 120, 40, 120}; | 18 static const uint8_t Nc[4] = {40, 120, 40, 120}; |
19 | 19 |
20 /* pseudonoise() function is based on ETSI EFR code */ | |
21 | |
22 static uint16_t pseudonoise(struct gsmfr_preproc_state *st, uint16_t no_bits) | |
23 { | |
24 uint16_t noise_bits, Sn, i; | |
25 | |
26 noise_bits = 0; | |
27 for (i = 0; i < no_bits; i++) | |
28 { | |
29 /* State n == 31 */ | |
30 if ((st->cn_random_lfsr & 0x00000001L) != 0) | |
31 { | |
32 Sn = 1; | |
33 } | |
34 else | |
35 { | |
36 Sn = 0; | |
37 } | |
38 | |
39 /* State n == 3 */ | |
40 if ((st->cn_random_lfsr & 0x10000000L) != 0) | |
41 { | |
42 Sn = Sn ^ 1; | |
43 } | |
44 else | |
45 { | |
46 Sn = Sn ^ 0; | |
47 } | |
48 | |
49 noise_bits = noise_bits << 1; | |
50 noise_bits = noise_bits | st->cn_random_lfsr & 1; | |
51 | |
52 st->cn_random_lfsr >>= 1; | |
53 if (Sn & 1) | |
54 { | |
55 st->cn_random_lfsr |= 0x40000000L; | |
56 } | |
57 } | |
58 | |
59 return noise_bits; | |
60 } | |
61 | |
62 static uint8_t random_1to6(struct gsmfr_preproc_state *st) | 20 static uint8_t random_1to6(struct gsmfr_preproc_state *st) |
63 { | 21 { |
64 uint8_t range8, range6; | 22 uint8_t range8, range6; |
65 | 23 |
66 range8 = pseudonoise(st, 3); | 24 range8 = gsmfr_preproc_prng(st, 3); |
67 range6 = fold_table_8to6[(st->cn_random_6fold << 3) | range8]; | 25 range6 = fold_table_8to6[(st->cn_random_6fold << 3) | range8]; |
68 st->cn_random_6fold++; | 26 st->cn_random_6fold++; |
69 if (st->cn_random_6fold >= 3) | 27 if (st->cn_random_6fold >= 3) |
70 st->cn_random_6fold = 0; | 28 st->cn_random_6fold = 0; |
71 return range6; | 29 return range6; |
80 /* global bytes (magic and LARc) are fixed */ | 38 /* global bytes (magic and LARc) are fixed */ |
81 memcpy(frame, st->sid_prefix, 5); | 39 memcpy(frame, st->sid_prefix, 5); |
82 c = frame + 5; | 40 c = frame + 5; |
83 /* now do the 4 subframes, mostly PRNG output */ | 41 /* now do the 4 subframes, mostly PRNG output */ |
84 for (sub = 0; sub < 4; sub++) { | 42 for (sub = 0; sub < 4; sub++) { |
85 Mc = pseudonoise(st, 2); | 43 Mc = gsmfr_preproc_prng(st, 2); |
86 for (pulse = 0; pulse < 13; pulse++) | 44 for (pulse = 0; pulse < 13; pulse++) |
87 xmc[pulse] = random_1to6(st); | 45 xmc[pulse] = random_1to6(st); |
88 /* packing code from libgsm */ | 46 /* packing code from libgsm */ |
89 *c++ = ((Nc[sub] & 0x7F) << 1) | 47 *c++ = ((Nc[sub] & 0x7F) << 1) |
90 | ((bc[sub] >> 1) & 0x1); | 48 | ((bc[sub] >> 1) & 0x1); |