FreeCalypso > hg > gsm-codec-lib
changeset 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 | 41f1ae68d253 |
children | 2361a7d8c1eb |
files | libgsmfrp/Makefile libgsmfrp/comfort_noise.c libgsmfrp/internal.h libgsmfrp/prng.c |
diffstat | 4 files changed, 60 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/libgsmfrp/Makefile Sun Nov 27 21:02:07 2022 +0000 +++ b/libgsmfrp/Makefile Mon Nov 28 04:00:18 2022 +0000 @@ -1,7 +1,7 @@ CC= gcc CFLAGS= -O2 -OBJS= bad_frame.o comfort_noise.o good_frame.o sidclass.o silence_frame.o \ - state.o +OBJS= bad_frame.o comfort_noise.o good_frame.o prng.o sidclass.o \ + silence_frame.o state.o LIB= libgsmfrp.a INSTALL_PREFIX= /usr/local
--- a/libgsmfrp/comfort_noise.c Sun Nov 27 21:02:07 2022 +0000 +++ b/libgsmfrp/comfort_noise.c Mon Nov 28 04:00:18 2022 +0000 @@ -17,53 +17,11 @@ static const uint8_t bc[4] = {0, 0, 0, 0}; static const uint8_t Nc[4] = {40, 120, 40, 120}; -/* pseudonoise() function is based on ETSI EFR code */ - -static uint16_t pseudonoise(struct gsmfr_preproc_state *st, uint16_t no_bits) -{ - uint16_t noise_bits, Sn, i; - - noise_bits = 0; - for (i = 0; i < no_bits; i++) - { - /* State n == 31 */ - if ((st->cn_random_lfsr & 0x00000001L) != 0) - { - Sn = 1; - } - else - { - Sn = 0; - } - - /* State n == 3 */ - if ((st->cn_random_lfsr & 0x10000000L) != 0) - { - Sn = Sn ^ 1; - } - else - { - Sn = Sn ^ 0; - } - - noise_bits = noise_bits << 1; - noise_bits = noise_bits | st->cn_random_lfsr & 1; - - st->cn_random_lfsr >>= 1; - if (Sn & 1) - { - st->cn_random_lfsr |= 0x40000000L; - } - } - - return noise_bits; -} - static uint8_t random_1to6(struct gsmfr_preproc_state *st) { uint8_t range8, range6; - range8 = pseudonoise(st, 3); + range8 = gsmfr_preproc_prng(st, 3); range6 = fold_table_8to6[(st->cn_random_6fold << 3) | range8]; st->cn_random_6fold++; if (st->cn_random_6fold >= 3) @@ -82,7 +40,7 @@ c = frame + 5; /* now do the 4 subframes, mostly PRNG output */ for (sub = 0; sub < 4; sub++) { - Mc = pseudonoise(st, 2); + Mc = gsmfr_preproc_prng(st, 2); for (pulse = 0; pulse < 13; pulse++) xmc[pulse] = random_1to6(st); /* packing code from libgsm */
--- a/libgsmfrp/internal.h Sun Nov 27 21:02:07 2022 +0000 +++ b/libgsmfrp/internal.h Mon Nov 28 04:00:18 2022 +0000 @@ -24,6 +24,8 @@ /* we use the same LFSR PRNG for CN as ETSI EFR implementation */ #define PN_INITIAL_SEED 0x70816958L /* Pseudo noise generator seed value */ -/* internal function */ +/* internal functions */ extern void gsmfr_preproc_gen_cn(struct gsmfr_preproc_state *state, gsm_byte *frame); +extern uint16_t gsmfr_preproc_prng(struct gsmfr_preproc_state *state, + uint16_t no_bits);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgsmfrp/prng.c Mon Nov 28 04:00:18 2022 +0000 @@ -0,0 +1,53 @@ +/* + * We use a pseudorandom sequence generator function in two places: + * when generating comfort noise (GSM 06.12 section 6.1), and when + * randomizing grid position parameters as part of speech muting + * during error handling (GSM 06.11 section 6). + * + * Our PRNG is a copy of the pseudonoise() function from ETSI EFR code, + * where it is used for similar purposes. + */ + +#include <stdint.h> +#include "gsm_fr_preproc.h" +#include "internal.h" + +uint16_t gsmfr_preproc_prng(struct gsmfr_preproc_state *st, uint16_t no_bits) +{ + uint16_t noise_bits, Sn, i; + + noise_bits = 0; + for (i = 0; i < no_bits; i++) + { + /* State n == 31 */ + if ((st->cn_random_lfsr & 0x00000001L) != 0) + { + Sn = 1; + } + else + { + Sn = 0; + } + + /* State n == 3 */ + if ((st->cn_random_lfsr & 0x10000000L) != 0) + { + Sn = Sn ^ 1; + } + else + { + Sn = Sn ^ 0; + } + + noise_bits = noise_bits << 1; + noise_bits = noise_bits | st->cn_random_lfsr & 1; + + st->cn_random_lfsr >>= 1; + if (Sn & 1) + { + st->cn_random_lfsr |= 0x40000000L; + } + } + + return noise_bits; +}