2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 //----------------------------------------------------------------------------//
22 // Ran088: L'Ecuyer's 1996 three-component Tausworthe generator "taus88"
23 //----------------------------------------------------------------------------//
25 // Returns an integer random number uniformly distributed within [0,4294967295]
27 // The period length is approximately 2^88 (which is 3*10^26).
28 // This generator is very fast and passes all standard statistical tests.
31 // (1) P. L'Ecuyer, Maximally equidistributed combined Tausworthe generators,
32 // Mathematics of Computation, 65, 203-213 (1996), see Figure 4.
33 // (2) recommended in:
34 // P. L'Ecuyer, Random number generation, chapter 4 of the
35 // Handbook on Simulation, Ed. Jerry Banks, Wiley, 1997.
37 //----------------------------------------------------------------------------//
39 //----------------------------------------------------------------------------//
40 // I chose this random number generator for the following reasons:
42 // easier and faster to seed than other high quality rng's such as Mersenne Twister.
43 // the internal state is only 12 bytes.
44 // the period is long enough for music/audio.
45 // possible to code in altivec in future if needed.
47 //----------------------------------------------------------------------------//
52 #include "SC_Endian.h"
54 #include "SC_BoundsMacros.h"
60 void init(uint32 seed
);
64 int32
irand(int32 scale
);
65 int32
irand2(int32 scale
);
66 int32
ilinrand(int32 scale
);
67 int32
ibilinrand(int32 scale
);
75 double drand2(double scale
);
76 double linrand(double scale
);
77 double bilinrand(double scale
);
78 double exprandrng(double lo
, double hi
);
79 double exprand(double scale
);
80 double biexprand(double scale
);
81 double sum3rand(double scale
);
83 uint32 s1
, s2
, s3
; // random generator state
86 inline void RGen::init(uint32 seed
)
88 // humans tend to use small seeds - mess up the bits
89 seed
= (uint32
)Hash((int)seed
);
91 // initialize seeds using the given seed value taking care of
92 // the requirements. The constants below are arbitrary otherwise
93 s1
= 1243598713U ^ seed
; if (s1
< 2) s1
= 1243598713U;
94 s2
= 3093459404U ^ seed
; if (s2
< 8) s2
= 3093459404U;
95 s3
= 1821928721U ^ seed
; if (s3
< 16) s3
= 1821928721U;
98 inline uint32
trand( uint32
& s1
, uint32
& s2
, uint32
& s3
)
100 // This function is provided for speed in inner loops where the
101 // state variables are loaded into registers.
102 // Thus updating the instance variables can
103 // be postponed until the end of the loop.
104 s1
= ((s1
& (uint32
)-2) << 12) ^ (((s1
<< 13) ^ s1
) >> 19);
105 s2
= ((s2
& (uint32
)-8) << 4) ^ (((s2
<< 2) ^ s2
) >> 25);
106 s3
= ((s3
& (uint32
)-16) << 17) ^ (((s3
<< 3) ^ s3
) >> 11);
110 inline uint32
RGen::trand()
112 // generate a random 32 bit number
113 return ::trand(s1
, s2
, s3
);
116 inline double RGen::drand()
118 // return a double from 0.0 to 0.999...
119 #if BYTE_ORDER == BIG_ENDIAN
120 union { struct { uint32 hi
, lo
; } i
; double f
; } du
;
122 union { struct { uint32 lo
, hi
; } i
; double f
; } du
;
124 du
.i
.hi
= 0x41300000;
126 return du
.f
- 1048576.;
129 inline float RGen::frand()
131 // return a float from 0.0 to 0.999...
132 union { uint32 i
; float f
; } u
; // union for floating point conversion of result
133 u
.i
= 0x3F800000 | (trand() >> 9);
137 inline float RGen::frand0()
139 // return a float from +1.0 to +1.999...
140 union { uint32 i
; float f
; } u
; // union for floating point conversion of result
141 u
.i
= 0x3F800000 | (trand() >> 9);
145 inline float RGen::frand2()
147 // return a float from -1.0 to +0.999...
148 union { uint32 i
; float f
; } u
; // union for floating point conversion of result
149 u
.i
= 0x40000000 | (trand() >> 9);
153 inline float RGen::frand8()
155 // return a float from -0.125 to +0.124999...
156 union { uint32 i
; float f
; } u
; // union for floating point conversion of result
157 u
.i
= 0x3E800000 | (trand() >> 9);
161 inline float RGen::fcoin()
163 // only return one of the two values -1.0 or +1.0
164 union { uint32 i
; float f
; } u
; // union for floating point conversion of result
165 u
.i
= 0x3F800000 | (0x80000000 & trand());
169 inline int32
RGen::irand(int32 scale
)
171 // return an int from 0 to scale - 1
172 return (int32
)floor(scale
* drand());
175 inline int32
RGen::irand2(int32 scale
)
177 // return a int from -scale to +scale
178 return (int32
)floor((2. * scale
+ 1.) * drand() - scale
);
181 inline int32
RGen::ilinrand(int32 scale
)
183 int32 a
= irand(scale
);
184 int32 b
= irand(scale
);
188 inline double RGen::linrand(double scale
)
192 return sc_min(a
,b
) * scale
;
195 inline int32
RGen::ibilinrand(int32 scale
)
197 int32 a
= irand(scale
);
198 int32 b
= irand(scale
);
202 inline double RGen::bilinrand(double scale
)
206 return (a
- b
) * scale
;
209 inline double RGen::exprandrng(double lo
, double hi
)
211 return lo
* exp(log(hi
/ lo
) * drand());
214 inline double RGen::exprand(double scale
)
217 while ((z
= drand()) == 0.0) {}
218 return -log(z
) * scale
;
221 inline double RGen::biexprand(double scale
)
224 while ((z
= drand2(1.)) == 0.0 || z
== -1.0) {}
225 if (z
> 0.0) z
= log(z
);
230 inline double RGen::sum3rand(double scale
)
232 // larry polansky's poor man's gaussian generator
233 return (drand() + drand() + drand() - 1.5) * 0.666666667 * scale
;
236 inline double drand( uint32
& s1
, uint32
& s2
, uint32
& s3
)
238 union { struct { uint32 hi
, lo
; } i
; double f
; } u
;
240 u
.i
.lo
= trand(s1
,s2
,s3
);
241 return u
.f
- 1048576.;
244 inline float frand( uint32
& s1
, uint32
& s2
, uint32
& s3
)
246 // return a float from 0.0 to 0.999...
247 union { uint32 i
; float f
; } u
;
248 u
.i
= 0x3F800000 | (trand(s1
,s2
,s3
) >> 9);
252 inline float frand0( uint32
& s1
, uint32
& s2
, uint32
& s3
)
254 // return a float from +1.0 to +1.999...
255 union { uint32 i
; float f
; } u
;
256 u
.i
= 0x3F800000 | (trand(s1
,s2
,s3
) >> 9);
260 inline float frand2( uint32
& s1
, uint32
& s2
, uint32
& s3
)
262 // return a float from -1.0 to +0.999...
263 union { uint32 i
; float f
; } u
;
264 u
.i
= 0x40000000 | (trand(s1
,s2
,s3
) >> 9);
268 inline float frand8( uint32
& s1
, uint32
& s2
, uint32
& s3
)
270 // return a float from -0.125 to +0.124999...
271 union { uint32 i
; float f
; } u
;
272 u
.i
= 0x3E800000 | (trand(s1
,s2
,s3
) >> 9);
276 inline float fcoin( uint32
& s1
, uint32
& s2
, uint32
& s3
)
278 // only return one of the two values -1.0 or +1.0
279 union { uint32 i
; float f
; } u
;
280 u
.i
= 0x3F800000 | (0x80000000 & trand(s1
,s2
,s3
));