Remove mersenne generator -- too slow, try another one
This commit is contained in:
+1
-1
@@ -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 mt19937-64.c
|
||||
shairport_sync_SOURCES = shairport.c rtsp.c mdns.c mdns_external.c common.c rtp.c player.c alac.c audio.c
|
||||
|
||||
AM_CFLAGS = -Wno-multichar -DSYSCONFDIR=\"$(sysconfdir)\"
|
||||
AM_CPPFLAGS = -Wno-multichar -DSYSCONFDIR=\"$(sysconfdir)\"
|
||||
|
||||
@@ -575,3 +575,40 @@ char *str_replace ( const char *string, const char *substr, const char *replacem
|
||||
}
|
||||
return newstr;
|
||||
}
|
||||
|
||||
/* from http://burtleburtle.net/bob/rand/smallprng.html */
|
||||
|
||||
typedef uint64_t u8;
|
||||
typedef struct ranctx { uint64_t a; uint64_t b; uint64_t c; uint64_t d; } ranctx;
|
||||
|
||||
static struct ranctx rx;
|
||||
|
||||
#define rot(x,k) (((x)<<(k))|((x)>>(64-(k))))
|
||||
inline uint64_t ranval( ranctx *x ) {
|
||||
uint64_t e = x->a - rot(x->b, 7);
|
||||
x->a = x->b ^ rot(x->c, 13);
|
||||
x->b = x->c + rot(x->d, 37);
|
||||
x->c = x->d + e;
|
||||
x->d = e + x->a;
|
||||
return x->d;
|
||||
}
|
||||
|
||||
void raninit( ranctx *x, uint64_t seed ) {
|
||||
uint64_t i;
|
||||
x->a = 0xf1ea5eed, x->b = x->c = x->d = seed;
|
||||
for (i=0; i<20; ++i) {
|
||||
(void)ranval(x);
|
||||
}
|
||||
}
|
||||
|
||||
void r64init(uint64_t seed) {
|
||||
raninit(&rx,seed);
|
||||
}
|
||||
|
||||
inline uint64_t r64u() {
|
||||
return(ranval(&rx));
|
||||
}
|
||||
|
||||
inline int64_t r64i() {
|
||||
return(ranval(&rx)>>1);
|
||||
}
|
||||
@@ -145,6 +145,14 @@ ssize_t non_blocking_write(int fd, const void *buf, size_t count); // used in a
|
||||
/* from http://coding.debuntu.org/c-implementing-str_replace-replace-all-occurrences-substring#comment-722 */
|
||||
char *str_replace ( const char *string, const char *substr, const char *replacement );
|
||||
|
||||
|
||||
// based on http://burtleburtle.net/bob/rand/smallprng.html
|
||||
|
||||
void r64init(uint64_t seed);
|
||||
inline uint64_t r64u();
|
||||
inline int64_t r64i();
|
||||
|
||||
|
||||
int debuglev;
|
||||
void die(char *format, ...);
|
||||
void warn(char *format, ...);
|
||||
|
||||
-168
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
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 <stdio.h>
|
||||
#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<NN; mti++)
|
||||
mt[mti] = (UINT64_C(6364136223846793005) * (mt[mti-1] ^ (mt[mti-1] >> 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<NN-MM;i++) {
|
||||
x = (mt[i]&UM)|(mt[i+1]&LM);
|
||||
mt[i] = mt[i+MM] ^ (x>>1) ^ mag01[(int)(x&UINT64_C(1))];
|
||||
}
|
||||
for (;i<NN-1;i++) {
|
||||
x = (mt[i]&UM)|(mt[i+1]&LM);
|
||||
mt[i] = mt[i+(MM-NN)] ^ (x>>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);
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
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 <inttypes.h>
|
||||
|
||||
/* 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);
|
||||
@@ -68,7 +68,6 @@
|
||||
#include "alac.h"
|
||||
|
||||
#include "apple_alac.h"
|
||||
#include "mt64.h"
|
||||
|
||||
// parameters from the source
|
||||
static unsigned char *aesiv;
|
||||
@@ -85,6 +84,7 @@ static int input_bytes_per_frame = 4;
|
||||
static int output_bytes_per_frame;
|
||||
static int output_sample_ratio;
|
||||
static int output_sample_rate;
|
||||
static int64_t previous_random_number = 0;
|
||||
|
||||
|
||||
// The maximum frame size change there can be is +/- 1;
|
||||
@@ -583,15 +583,6 @@ int32_t rand_in_range(int32_t exclusive_range_limit) {
|
||||
return sp >> 32;
|
||||
}
|
||||
|
||||
int64_t rand_in_range_64(int64_t exclusive_range_limit) {
|
||||
// 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) {
|
||||
if ((fix_volume==0x1000) && (output_precision==32)) {
|
||||
return sample;
|
||||
@@ -599,10 +590,15 @@ static inline int32_t dithered_vol_32(int32_t sample, int output_precision) {
|
||||
int64_t s = sample; // 64 bit signed
|
||||
int64_t v = fix_volume & 0x1FFFF; // 17 bit unsigned made a 33 bit unsigned
|
||||
v<<=16;
|
||||
s = s*v; // 32 bit multiplication
|
||||
/*
|
||||
// here, do the dithering
|
||||
int64_t tpdf = rand_in_range_64((1<<(64-output_precision))+1) - rand_in_range_64((1<<(64-output_precision))+1);
|
||||
s = s*v; // 32 bit multiplication -- we need to dither it down to its target resolution
|
||||
|
||||
int64_t r = r64i();
|
||||
int64_t mask = 1<<(64+1-output_precision);
|
||||
//mask -=1;
|
||||
int64_t tpdf = (r&mask); //-(previous_random_number&((1<<(64+1-output_precision))-1));
|
||||
debug(1,"output precision is %d, m is %llx, r is %llx, tpdf is %llx",output_precision,mask,r,tpdf);
|
||||
previous_random_number=r;
|
||||
|
||||
// Check there's no clipping -- if there is,
|
||||
if (tpdf>=0) {
|
||||
if (INT64_MAX-tpdf>=s)
|
||||
@@ -615,7 +611,7 @@ static inline int32_t dithered_vol_32(int32_t sample, int output_precision) {
|
||||
else
|
||||
s = INT64_MIN;
|
||||
}
|
||||
*/
|
||||
|
||||
s>>=(64-output_precision);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -778,6 +778,10 @@ int main(int argc, char **argv) {
|
||||
#ifdef HAVE_APPLE_ALAC
|
||||
config.decoders_supported += 1<<decoder_apple_alac;
|
||||
#endif
|
||||
|
||||
// initialise random number generator
|
||||
|
||||
r64init(0);
|
||||
|
||||
/* Check if we are called with -V or --version parameter */
|
||||
if (argc >= 2 && ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0))) {
|
||||
|
||||
Reference in New Issue
Block a user