From 1e279d3cb80822e772dd7cf285601c835b5e73c4 Mon Sep 17 00:00:00 2001 From: Yury Popov Date: Tue, 15 Nov 2022 09:58:29 +0300 Subject: [PATCH] Add PRNG and use it instead of rand() --- src/libespeak-ng/common.c | 13 +++++++++++++ src/libespeak-ng/common.h | 3 +++ src/libespeak-ng/klatt.c | 7 ++----- src/libespeak-ng/speech.c | 3 +++ src/libespeak-ng/wavegen.c | 3 ++- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/libespeak-ng/common.c b/src/libespeak-ng/common.c index f44cf5e3..8b2bb872 100644 --- a/src/libespeak-ng/common.c +++ b/src/libespeak-ng/common.c @@ -326,4 +326,17 @@ int towlower2(unsigned int c, Translator *translator) return ucd_tolower(c); } +static uint32_t espeak_rand_state = 0; + +long espeak_rand(long min, long max) { + // Ref: https://github.com/bminor/glibc/blob/glibc-2.36/stdlib/random_r.c#L364 + espeak_rand_state = (((uint64_t)espeak_rand_state * 1103515245) + 12345) % 0x7fffffff; + long res = (long)espeak_rand_state; + return (res % (max-min+1))-min; +} + +void espeak_srand(long seed) { + espeak_rand_state = (uint32_t)(seed); + (void)espeak_rand(0, 1); // Dummy flush a generator +} diff --git a/src/libespeak-ng/common.h b/src/libespeak-ng/common.h index 76fff8bf..ecec0d0e 100644 --- a/src/libespeak-ng/common.h +++ b/src/libespeak-ng/common.h @@ -26,6 +26,9 @@ extern ESPEAK_NG_API int GetFileLength(const char *filename); extern ESPEAK_NG_API void strncpy0(char *to, const char *from, int size); +void espeak_srand(long seed); +long espeak_rand(long min, long max); + int IsAlpha(unsigned int c); int IsBracket(int c); int IsDigit(unsigned int c); diff --git a/src/libespeak-ng/klatt.c b/src/libespeak-ng/klatt.c index 55d294f7..954553c0 100644 --- a/src/libespeak-ng/klatt.c +++ b/src/libespeak-ng/klatt.c @@ -35,6 +35,7 @@ #include #include "klatt.h" +#include "common.h" // for espeak_rand #include "synthesize.h" // for frame_t, WGEN_DATA, STEPSIZE, N_KLATTP, echo... #include "voice.h" // for voice_t, N_PEAKS #ifdef INCLUDE_SPEECHPLAYER @@ -46,11 +47,7 @@ extern unsigned char *out_end; static int nsamples; static int sample_count; -#ifdef _MSC_VER -#define getrandom(min, max) ((rand()%(int)(((max)+1)-(min)))+(min)) -#else -#define getrandom(min, max) ((rand()%(long)(((max)+1)-(min)))+(min)) -#endif +#define getrandom(min, max) espeak_rand((min), (max)) // function prototypes for functions private to this file diff --git a/src/libespeak-ng/speech.c b/src/libespeak-ng/speech.c index ed704623..6d05512b 100644 --- a/src/libespeak-ng/speech.c +++ b/src/libespeak-ng/speech.c @@ -404,6 +404,9 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_Initialize(espeak_ng_ERROR_CONTEXT *con option_phonemes = 0; option_phoneme_events = 0; + // Seed random generator + espeak_srand(time(NULL)); + return ENS_OK; } diff --git a/src/libespeak-ng/wavegen.c b/src/libespeak-ng/wavegen.c index cc9d9dd4..5762c988 100644 --- a/src/libespeak-ng/wavegen.c +++ b/src/libespeak-ng/wavegen.c @@ -33,6 +33,7 @@ #include #include "wavegen.h" +#include "common.h" // for espeak_rand #include "synthesize.h" // for WGEN_DATA, RESONATOR, frame_t #include "mbrola.h" // for MbrolaFill, MbrolaReset, mbrola... @@ -668,7 +669,7 @@ static int ApplyBreath(void) int ix; // use two random numbers, for alternate formants - noise = (rand() & 0x3fff) - 0x2000; + noise = espeak_rand(-0x2000, 0x1fff); for (ix = 1; ix < N_PEAKS; ix++) { int amp;