OpenShot Audio Library | OpenShotAudio 0.4.0

Loading...
Searching...
No Matches
juce_Random.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23 namespace juce
24{
25
26 Random::Random (int64 seedValue) noexcept : seed (seedValue)
27{
28}
29
30 Random::Random() : seed (1)
31{
32 setSeedRandomly();
33}
34
35 void Random::setSeed (const int64 newSeed) noexcept
36{
37 if (this == &getSystemRandom())
38 {
39 // Resetting the system Random risks messing up
40 // JUCE's internal state. If you need a predictable
41 // stream of random numbers you should use a local
42 // Random object.
43 jassertfalse;
44 return;
45 }
46
47 seed = newSeed;
48}
49
50 void Random::combineSeed (const int64 seedValue) noexcept
51{
52 seed ^= nextInt64() ^ seedValue;
53}
54
55 void Random::setSeedRandomly()
56{
57 static std::atomic<int64> globalSeed { 0 };
58
59 combineSeed (globalSeed ^ (int64) (pointer_sized_int) this);
60 combineSeed (Time::getMillisecondCounter());
61 combineSeed (Time::getHighResolutionTicks());
62 combineSeed (Time::getHighResolutionTicksPerSecond());
63 combineSeed (Time::currentTimeMillis());
64 globalSeed ^= seed;
65}
66
67 Random& Random::getSystemRandom() noexcept
68{
69 static Random sysRand;
70 return sysRand;
71}
72
73//==============================================================================
74 int Random::nextInt() noexcept
75{
76 seed = (int64) (((((uint64) seed) * 0x5deece66dLL) + 11) & 0xffffffffffffLL);
77
78 return (int) (seed >> 16);
79}
80
81 int Random::nextInt (const int maxValue) noexcept
82{
83 jassert (maxValue > 0);
84 return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32);
85}
86
87 int Random::nextInt (Range<int> range) noexcept
88{
89 return range.getStart() + nextInt (range.getLength());
90}
91
92int64 Random::nextInt64() noexcept
93{
94 return (int64) ((((uint64) (unsigned int) nextInt()) << 32) | (uint64) (unsigned int) nextInt());
95}
96
97 bool Random::nextBool() noexcept
98{
99 return (nextInt() & 0x40000000) != 0;
100}
101
102 float Random::nextFloat() noexcept
103{
104 auto result = static_cast<float> (static_cast<uint32> (nextInt()))
105 / (static_cast<float> (std::numeric_limits<uint32>::max()) + 1.0f);
106 return jmin (result, 1.0f - std::numeric_limits<float>::epsilon());
107}
108
109 double Random::nextDouble() noexcept
110{
111 return static_cast<uint32> (nextInt()) / (std::numeric_limits<uint32>::max() + 1.0);
112}
113
114 BigInteger Random::nextLargeNumber (const BigInteger& maximumValue)
115{
116 BigInteger n;
117
118 do
119 {
120 fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1);
121 }
122 while (n >= maximumValue);
123
124 return n;
125}
126
127 void Random::fillBitsRandomly (void* const buffer, size_t bytes)
128{
129 int* d = static_cast<int*> (buffer);
130
131 for (; bytes >= sizeof (int); bytes -= sizeof (int))
132 *d++ = nextInt();
133
134 if (bytes > 0)
135 {
136 const int lastBytes = nextInt();
137 memcpy (d, &lastBytes, bytes);
138 }
139}
140
141 void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits)
142{
143 arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space
144
145 while ((startBit & 31) != 0 && numBits > 0)
146 {
147 arrayToChange.setBit (startBit++, nextBool());
148 --numBits;
149 }
150
151 while (numBits >= 32)
152 {
153 arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt());
154 startBit += 32;
155 numBits -= 32;
156 }
157
158 while (--numBits >= 0)
159 arrayToChange.setBit (startBit + numBits, nextBool());
160}
161
162
163//==============================================================================
164//==============================================================================
165#if JUCE_UNIT_TESTS
166
167 class RandomTests final : public UnitTest
168{
169 public:
170 RandomTests()
171 : UnitTest ("Random", UnitTestCategories::maths)
172 {}
173
174 void runTest() override
175 {
176 beginTest ("Random");
177
178 Random r = getRandom();
179
180 for (int i = 2000; --i >= 0;)
181 {
182 expect (r.nextDouble() >= 0.0 && r.nextDouble() < 1.0);
183 expect (r.nextFloat() >= 0.0f && r.nextFloat() < 1.0f);
184 expect (r.nextInt (5) >= 0 && r.nextInt (5) < 5);
185 expect (r.nextInt (1) == 0);
186
187 int n = r.nextInt (50) + 1;
188 expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
189
190 n = r.nextInt (0x7ffffffe) + 1;
191 expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
192 }
193 }
194};
195
196 static RandomTests randomTests;
197
198#endif
199
200} // namespace juce
juce::BigInteger
Definition juce_BigInteger.h:39
juce::BigInteger::getHighestBit
int getHighestBit() const noexcept
Definition juce_BigInteger.cpp:391
juce::BigInteger::setBitRangeAsInt
BigInteger & setBitRangeAsInt(int startBit, int numBits, uint32 valueToSet)
Definition juce_BigInteger.cpp:263
juce::BigInteger::setBit
BigInteger & setBit(int bitNumber)
Definition juce_BigInteger.cpp:294
juce::Random
Definition juce_Random.h:35
juce::Random::nextFloat
float nextFloat() noexcept
Definition juce_Random.cpp:102
juce::Random::Random
Random()
Definition juce_Random.cpp:30
juce::Random::fillBitsRandomly
void fillBitsRandomly(void *bufferToFill, size_t sizeInBytes)
Definition juce_Random.cpp:127
juce::Random::nextBool
bool nextBool() noexcept
Definition juce_Random.cpp:97
juce::Random::setSeedRandomly
void setSeedRandomly()
Definition juce_Random.cpp:55
juce::Random::combineSeed
void combineSeed(int64 seedValue) noexcept
Definition juce_Random.cpp:50
juce::Random::nextInt
int nextInt() noexcept
Definition juce_Random.cpp:74
juce::Random::nextInt64
int64 nextInt64() noexcept
Definition juce_Random.cpp:92
juce::Random::setSeed
void setSeed(int64 newSeed) noexcept
Definition juce_Random.cpp:35
juce::Random::nextDouble
double nextDouble() noexcept
Definition juce_Random.cpp:109
juce::Random::nextLargeNumber
BigInteger nextLargeNumber(const BigInteger &maximumValue)
Definition juce_Random.cpp:114
juce::Random::getSystemRandom
static Random & getSystemRandom() noexcept
Definition juce_Random.cpp:67
juce::Range
Definition juce_Range.h:40
juce::Time::getHighResolutionTicks
static int64 getHighResolutionTicks() noexcept
juce::Time::currentTimeMillis
static int64 currentTimeMillis() noexcept
Definition juce_Time.cpp:220
juce::Time::getHighResolutionTicksPerSecond
static int64 getHighResolutionTicksPerSecond() noexcept
juce::Time::getMillisecondCounter
static uint32 getMillisecondCounter() noexcept
Definition juce_Time.cpp:241
juce::UnitTest
Definition juce_UnitTest.h:70