From: Mike Brady Date: Wed, 7 Sep 2016 08:05:43 +0000 (+0100) Subject: Add a fancy 64-bit pseudo random number generator -- thanks to its developers X-Git-Tag: 3.0.d18~49 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4e4edf9909067e041a483389346c403e70221472;p=thirdparty%2Fshairport-sync.git Add a fancy 64-bit pseudo random number generator -- thanks to its developers --- diff --git a/Makefile.am b/Makefile.am index ff677f80..332f3255 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS = man bin_PROGRAMS = shairport-sync -shairport_sync_SOURCES = shairport.c rtsp.c mdns.c mdns_external.c common.c rtp.c player.c alac.c audio.c +shairport_sync_SOURCES = shairport.c rtsp.c mdns.c mdns_external.c common.c rtp.c player.c alac.c audio.c mt19937-64.c AM_CFLAGS = -Wno-multichar -DSYSCONFDIR=\"$(sysconfdir)\" AM_CPPFLAGS = -Wno-multichar -DSYSCONFDIR=\"$(sysconfdir)\" diff --git a/mt19937-64.c b/mt19937-64.c new file mode 100644 index 00000000..5c742422 --- /dev/null +++ b/mt19937-64.c @@ -0,0 +1,168 @@ +/* + A C-program for MT19937-64 (2014/2/23 version). + Coded by Takuji Nishimura and Makoto Matsumoto. + + This is a 64-bit version of Mersenne Twister pseudorandom number + generator. + + Before using, initialize the state by using init_genrand64(seed) + or init_by_array64(init_key, key_length). + + Copyright (C) 2004, 2014, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + References: + T. Nishimura, ``Tables of 64-bit Mersenne Twisters'' + ACM Transactions on Modeling and + Computer Simulation 10. (2000) 348--357. + M. Matsumoto and T. Nishimura, + ``Mersenne Twister: a 623-dimensionally equidistributed + uniform pseudorandom number generator'' + ACM Transactions on Modeling and + Computer Simulation 8. (Jan. 1998) 3--30. + + Any feedback is very welcome. + http://www.math.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove spaces) +*/ + + +#include +#include "mt64.h" + +#define NN 312 +#define MM 156 +#define MATRIX_A UINT64_C(0xB5026F5AA96619E9) +#define UM UINT64_C(0xFFFFFFFF80000000) /* Most significant 33 bits */ +#define LM UINT64_C(0x7FFFFFFF) /* Least significant 31 bits */ + + +/* The array for the state vector */ +static uint64_t mt[NN]; +/* mti==NN+1 means mt[NN] is not initialized */ +static int mti=NN+1; + +/* initializes mt[NN] with a seed */ +void init_genrand64(uint64_t seed) +{ + mt[0] = seed; + for (mti=1; mti> 62)) + mti); +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +void init_by_array64(uint64_t init_key[], + uint64_t key_length) +{ + unsigned int i, j; + uint64_t k; + init_genrand64(UINT64_C(19650218)); + i=1; j=0; + k = (NN>key_length ? NN : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 62)) * UINT64_C(3935559000370003845))) + + init_key[j] + j; /* non linear */ + i++; j++; + if (i>=NN) { mt[0] = mt[NN-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=NN-1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 62)) * UINT64_C(2862933555777941757))) + - i; /* non linear */ + i++; + if (i>=NN) { mt[0] = mt[NN-1]; i=1; } + } + + mt[0] = UINT64_C(1) << 63; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0, 2^64-1]-interval */ +uint64_t genrand64_int64(void) +{ + int i; + uint64_t x; + static uint64_t mag01[2]={UINT64_C(0), MATRIX_A}; + + if (mti >= NN) { /* generate NN words at one time */ + + /* if init_genrand64() has not been called, */ + /* a default initial seed is used */ + if (mti == NN+1) + init_genrand64(UINT64_C(5489)); + + for (i=0;i>1) ^ mag01[(int)(x&UINT64_C(1))]; + } + for (;i>1) ^ mag01[(int)(x&UINT64_C(1))]; + } + x = (mt[NN-1]&UM)|(mt[0]&LM); + mt[NN-1] = mt[MM-1] ^ (x>>1) ^ mag01[(int)(x&UINT64_C(1))]; + + mti = 0; + } + + x = mt[mti++]; + + x ^= (x >> 29) & UINT64_C(0x5555555555555555); + x ^= (x << 17) & UINT64_C(0x71D67FFFEDA60000); + x ^= (x << 37) & UINT64_C(0xFFF7EEE000000000); + x ^= (x >> 43); + + return x; +} + +/* generates a random number on [0, 2^63-1]-interval */ +int64_t genrand64_int63(void) +{ + return (int64_t)(genrand64_int64() >> 1); +} + +/* generates a random number on [0,1]-real-interval */ +double genrand64_real1(void) +{ + return (genrand64_int64() >> 11) * (1.0/9007199254740991.0); +} + +/* generates a random number on [0,1)-real-interval */ +double genrand64_real2(void) +{ + return (genrand64_int64() >> 11) * (1.0/9007199254740992.0); +} + +/* generates a random number on (0,1)-real-interval */ +double genrand64_real3(void) +{ + return ((genrand64_int64() >> 12) + 0.5) * (1.0/4503599627370496.0); +} diff --git a/mt64.h b/mt64.h new file mode 100644 index 00000000..5d0a4152 --- /dev/null +++ b/mt64.h @@ -0,0 +1,81 @@ +/* + A C-program for MT19937-64 (2014/2/23 version). + Coded by Takuji Nishimura and Makoto Matsumoto. + + This is a 64-bit version of Mersenne Twister pseudorandom number + generator. + + Before using, initialize the state by using init_genrand64(seed) + or init_by_array64(init_key, key_length). + + Copyright (C) 2004, 2014, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + References: + T. Nishimura, ``Tables of 64-bit Mersenne Twisters'' + ACM Transactions on Modeling and + Computer Simulation 10. (2000) 348--357. + M. Matsumoto and T. Nishimura, + ``Mersenne Twister: a 623-dimensionally equidistributed + uniform pseudorandom number generator'' + ACM Transactions on Modeling and + Computer Simulation 8. (Jan. 1998) 3--30. + + Any feedback is very welcome. + http://www.math.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove spaces) +*/ + +#include + +/* initializes mt[NN] with a seed */ +void init_genrand64(uint64_t seed); + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +void init_by_array64(uint64_t init_key[], + uint64_t key_length); + +/* generates a random number on [0, 2^64-1]-interval */ +uint64_t genrand64_int64(void); + + +/* generates a random number on [0, 2^63-1]-interval */ +int64_t genrand64_int63(void); + +/* generates a random number on [0,1]-real-interval */ +double genrand64_real1(void); + +/* generates a random number on [0,1)-real-interval */ +double genrand64_real2(void); + +/* generates a random number on (0,1)-real-interval */ +double genrand64_real3(void); diff --git a/player.c b/player.c index 3aafa459..9299ab55 100644 --- a/player.c +++ b/player.c @@ -68,6 +68,7 @@ #include "alac.h" #include "apple_alac.h" +#include "mt64.h" // parameters from the source static unsigned char *aesiv; @@ -583,13 +584,12 @@ int32_t rand_in_range(int32_t exclusive_range_limit) { } int64_t rand_in_range_64(int64_t exclusive_range_limit) { - static uint64_t lcg_prev = 12345; - // returns a pseudo random integer in the range 0 to (exclusive_range_limit-1) inclusive - int64_t sp = lcg_prev; - int64_t rl = exclusive_range_limit; - lcg_prev = lcg_prev * 69069 + 3; // crappy psrg - sp = sp*rl; // 64 bit calculation. INtersting part if above the 32 rightmost bits; - return sp; + // this is a call to a 64-bit pseudo-random number generator + // from the archive downloaded http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/mt19937-64stdint.tgz + // from http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt64.html + + + return genrand64_int63() % exclusive_range_limit; } static inline int32_t dithered_vol_32(int32_t sample, int output_precision) { diff --git a/shairport.c b/shairport.c index 1b746922..050338d8 100644 --- a/shairport.c +++ b/shairport.c @@ -54,6 +54,7 @@ #include "rtsp.h" #include "rtp.h" #include "mdns.h" +#include "mt64.h" // 64-bit prng #include #include @@ -778,6 +779,14 @@ int main(int argc, char **argv) { #ifdef HAVE_APPLE_ALAC config.decoders_supported += 1<= 2 && ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0))) {