shithub: sox

Download patch

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,