ref: dec0729da7a1d518c468f91bf80aa8b671ba8670
parent: 1915e8269f81fb78c7289a56c5a85b4b88cf0a6c
author: robs <robs>
date: Sun Nov 23 14:36:07 EST 2008
PRNG clean-up
--- a/ChangeLog
+++ b/ChangeLog
@@ -39,7 +39,8 @@
Internal improvements:
- o
+ o Rationalise use of and make repeatable across different platforms
+ pseudo random number generators. (robs)
sox-14.2.0 2008-11-09
--- a/scripts/synth.sh
+++ b/scripts/synth.sh
@@ -29,7 +29,7 @@
o="overdrive 40 gain -8"
e="delay 0 .02 .04 .06 .08 .1 remix - $o fade 0"
s="$sox -q -n -p synth 0 0 0 80 87"
-l="$sox -q -n -p synth 0 0 0 80 0"
+l="$sox -q -n -p synth 0 0 0 80 0 0"
$play -m -v .8 \
"|$sox \
@@ -41,7 +41,7 @@
equalizer 7000 10 8 \
equalizer 5200 10 8 \
equalizer 3800 10 8 \
-equalizer 1500 10 8 pad 0 .21 remix 1 1 reverb 20 repeat 59" \
+equalizer 1500 10 8 pad 0 .21 remix 1 1 reverb 10 repeat 56" \
"|$sox \
\"|$sox -n -p trim 0 1.4\" \
\"|$s $G0 $e 2.6 .1 bend .5,200,.2\" \
@@ -63,15 +63,17 @@
\"|$l pl %10 $o trim 0 .5 bend .2,-300,.1\" \
\"|$l pl %5 $o trim 0 .5 bend .2,-200,.1\" \
\"|$l pl %0 $o fade 0 .55 .1 bend .2,-200,.1\" \
-\"|$l pl %12 $o trim 0 5.95\" \
+\"|$l pl %0 $o fade 0 2 .1\" \
+\"|$sox -n -p trim 0 3.95\" \
\"|$l pl %12 $o trim 0 .5 bend .2,-200,.1\" \
\"|$l pl %12 $o trim 0 .5 bend .2,-200,.1\" \
-\"|$l pl %12 $o trim 0 .5 bend .2,-200,.1\" \
-\"|$l pl %12 $o fade 0 .6 .1 bend .2,-200,.1\" \
-\"|$l pl %12 $o trim 0 1.95 bend .3,-100,1\" \
+\"|$l pl %12 $o fade 0 .8 .1 bend .2,-200,.1\" \
+\"|$l pl %12 $o trim 0 .3 bend .1,-200,.1\" \
+\"|$l pl %12 $o trim 0 1.95 bend .3,-50,1\" \
\"|$l pl %10 $o trim 0 2 bend .3,-50,1\" \
-\"|$l pl %9 $o trim 0 2 gain -3 \" \
-\"|$l pl %8 $o trim 0 2 gain -6 \" \
+\"|$l pl %9 $o trim 0 2 gain -3\" \
+\"|$l pl %8 $o fade h 0 1 .3\" \
+\"|$l pl %8 $o fade h 0 1 .1 gain 1.5\" \
\"|$l pl %2 pl %7 delay 0 .02 remix - $o trim 0 .25\" \
\"|$l pl %-5 $o trim 0 .25\" \
\"|$l pl %-5 $o trim 0 .25\" \
--- a/src/dither.c
+++ b/src/dither.c
@@ -25,10 +25,6 @@
#define PREC effp->out_signal.precision
-#define RAND_CONST 140359821
-static int32_t rand_ = ~RAND_CONST;
-#define RAND_ (rand_ = rand_ * RAND_CONST + 1)
-
typedef enum {Pdf_rectangular, Pdf_triangular, Pdf_gaussian} pdf_type_t;
static lsx_enum_item const pdf_types[] = {
LSX_ENUM_ITEM(Pdf_,rectangular)
@@ -190,7 +186,7 @@
int dummy = 0;
while (len--) {
- double d = *ibuf++ + p->am0 * RAND_ + p->am1 * RAND_;
+ double d = *ibuf++ + p->am0 * RANQD1 + p->am1 * RANQD1;
*obuf++ = SOX_ROUND_CLIP_COUNT(d, dummy);
}
return SOX_SUCCESS;
--- a/src/dither_fir.h
+++ b/src/dither_fir.h
@@ -7,7 +7,7 @@
int dummy = 0;
while (len--) {
- double r = p->am0 * RAND_ + p->am1 * RAND_;
+ double r = p->am0 * RANQD1 + p->am1 * RANQD1;
double error, d = *ibuf++;
int j = 0;
CONVOLVE
--- a/src/dither_iir.h
+++ b/src/dither_iir.h
@@ -8,7 +8,7 @@
int dummy = 0;
while (len--) {
- double r = p->am0 * RAND_ + p->am1 * RAND_;
+ double r = p->am0 * RANQD1 + p->am1 * RANQD1;
double error, d, output = 0;
int j = 0;
CONVOLVE
--- a/src/libsox.c
+++ b/src/libsox.c
@@ -48,6 +48,7 @@
sox_false,
8192,
0,
+ 0,
NULL, NULL, NULL};
void sox_output_message(FILE *file, const char *filename, const char *fmt, va_list ap)
--- a/src/sox.c
+++ b/src/sox.c
@@ -2485,13 +2485,9 @@
exit(0);
}
- if (sox_globals.repeatable)
- lsx_debug("Not reseeding PRNG; randomness is repeatable");
- else {
- time_t t;
-
- time(&t);
- srand((unsigned)t);
+ if (!sox_globals.repeatable) { /* Re-seed PRNG? */
+ sox_globals.ranqd1 = (int32_t)time(NULL);
+ srand((unsigned int)sox_globals.ranqd1); /* srand only for polyphase */
}
/* Save things that sox_sequence needs to be reinitialised for each segued
--- a/src/sox.h
+++ b/src/sox.h
@@ -179,7 +179,8 @@
* to perform file I/O. It can be useful to pass in similar sized
* data to get max performance.
*/
- size_t bufsiz, input_bufsiz;
+ size_t bufsiz, input_bufsiz;
+ int32_t ranqd1; /* Can be used to re-seed libSoX's PRNG */
/* private: */
char const * stdin_in_use_by;
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -18,6 +18,10 @@
#include "util.h"
#include <errno.h>
+
+#define RANQD1 ranqd1(sox_globals.ranqd1)
+#define DRANQD1 dranqd1(sox_globals.ranqd1)
+
typedef enum {SOX_SHORT, SOX_INT, SOX_FLOAT, SOX_DOUBLE} sox_data_t;
typedef enum {SOX_WAVE_SINE, SOX_WAVE_TRIANGLE} lsx_wave_t;
extern lsx_enum_item const lsx_wave_enum[];
--- a/src/synth.c
+++ b/src/synth.c
@@ -13,9 +13,6 @@
#include <string.h>
#include <ctype.h>
-#define RAND (2. * rand() * (1. / RAND_MAX) - 1)
-#define RAND_ ranqd1(r) * (1. / (65536. * 32768.)) /* [-1,1) */
-
typedef enum {
synth_sine,
synth_square,
@@ -405,7 +402,8 @@
chan->buffer = malloc(chan->buffer_len * sizeof(*chan->buffer));
chan->buffer[0] = 0;
for (j = 1; j < chan->buffer_len; dc += chan->buffer[j++])
- do chan->buffer[j] = chan->buffer[j - 1] + RAND_ * colour;
+ do chan->buffer[j] =
+ chan->buffer[j - 1] + (chan->p3 == 0? DRANQD1:dranqd1(r)) * colour;
while (fabs(chan->buffer[j]) > 1);
for (dc /= chan->buffer_len, j = 0; j < chan->buffer_len; ++j)
chan->buffer[j] = range_limit(chan->buffer[j] - dc, -1, 1) * a;
@@ -570,11 +568,11 @@
}
} else switch (chan->type) {
case synth_whitenoise:
- synth_out = RAND;
+ synth_out = DRANQD1;
break;
case synth_tpdfnoise:
- synth_out = .5 * (RAND + RAND);
+ synth_out = .5 * (DRANQD1 + DRANQD1);
break;
case synth_pinknoise:
@@ -582,7 +580,7 @@
break;
case synth_brownnoise:
- do synth_out = chan->last_out + RAND * (1. / 16);
+ do synth_out = chan->last_out + DRANQD1 * (1. / 16);
while (fabs(synth_out) > 1);
chan->last_out = synth_out;
break;
--- a/src/util.h
+++ b/src/util.h
@@ -92,7 +92,8 @@
#endif
/* Numerical Recipes in C, p. 284 */
-#define ranqd1(x) ((x) = 1664525L * (x) + 1013904223L)
+#define ranqd1(x) ((x) = 1664525L * (x) + 1013904223L) /* int32_t x */
+#define dranqd1(x) (ranqd1(x) * (1. / (65536. * 32768.))) /* [-1,1) */
#ifdef WORDS_BIGENDIAN
#define MACHINE_IS_BIGENDIAN 1
--- a/src/vorbis.c
+++ b/src/vorbis.c
@@ -305,7 +305,7 @@
vorbis_analysis_init(&ve->vd, &ve->vi);
vorbis_block_init(&ve->vd, &ve->vb);
- ogg_stream_init(&ve->os, rand()); /* Random serial number */
+ ogg_stream_init(&ve->os, INT_MAX & (int)RANQD1); /* Random serial number */
if (write_vorbis_header(ft, ve) == HEADER_ERROR) {
lsx_fail_errno(ft, SOX_EHDR,