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)\"
}
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);
+}
\ No newline at end of file
/* 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, ...);
+++ /dev/null
-/*
- 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);
-}
+++ /dev/null
-/*
- 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);
#include "alac.h"
#include "apple_alac.h"
-#include "mt64.h"
// parameters from the source
static unsigned char *aesiv;
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;
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;
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)
else
s = INT64_MIN;
}
- */
+
s>>=(64-output_precision);
return s;
}
#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))) {