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;
+}