VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / modules / juce_core / maths / juce_Random.cpp
blobdf9b266526c4980038c027d27862fb4c6d9fdadb
1 /*
2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
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.
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.
20 ==============================================================================
23 namespace juce
26 Random::Random (int64 seedValue) noexcept : seed (seedValue)
30 Random::Random() : seed (1)
32 setSeedRandomly();
35 void Random::setSeed (const int64 newSeed) noexcept
37 if (this == &getSystemRandom())
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;
47 seed = newSeed;
50 void Random::combineSeed (const int64 seedValue) noexcept
52 seed ^= nextInt64() ^ seedValue;
55 void Random::setSeedRandomly()
57 static std::atomic<int64> globalSeed { 0 };
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;
67 Random& Random::getSystemRandom() noexcept
69 static Random sysRand;
70 return sysRand;
73 //==============================================================================
74 int Random::nextInt() noexcept
76 seed = (int64) (((((uint64) seed) * 0x5deece66dLL) + 11) & 0xffffffffffffLL);
78 return (int) (seed >> 16);
81 int Random::nextInt (const int maxValue) noexcept
83 jassert (maxValue > 0);
84 return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32);
87 int Random::nextInt (Range<int> range) noexcept
89 return range.getStart() + nextInt (range.getLength());
92 int64 Random::nextInt64() noexcept
94 return (int64) ((((uint64) (unsigned int) nextInt()) << 32) | (uint64) (unsigned int) nextInt());
97 bool Random::nextBool() noexcept
99 return (nextInt() & 0x40000000) != 0;
102 float Random::nextFloat() noexcept
104 auto result = static_cast<float> (static_cast<uint32> (nextInt()))
105 / (static_cast<float> (std::numeric_limits<uint32>::max()) + 1.0f);
106 return result == 1.0f ? 1.0f - std::numeric_limits<float>::epsilon() : result;
109 double Random::nextDouble() noexcept
111 return static_cast<uint32> (nextInt()) / (std::numeric_limits<uint32>::max() + 1.0);
114 BigInteger Random::nextLargeNumber (const BigInteger& maximumValue)
116 BigInteger n;
120 fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1);
122 while (n >= maximumValue);
124 return n;
127 void Random::fillBitsRandomly (void* const buffer, size_t bytes)
129 int* d = static_cast<int*> (buffer);
131 for (; bytes >= sizeof (int); bytes -= sizeof (int))
132 *d++ = nextInt();
134 if (bytes > 0)
136 const int lastBytes = nextInt();
137 memcpy (d, &lastBytes, bytes);
141 void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits)
143 arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space
145 while ((startBit & 31) != 0 && numBits > 0)
147 arrayToChange.setBit (startBit++, nextBool());
148 --numBits;
151 while (numBits >= 32)
153 arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt());
154 startBit += 32;
155 numBits -= 32;
158 while (--numBits >= 0)
159 arrayToChange.setBit (startBit + numBits, nextBool());
163 //==============================================================================
164 //==============================================================================
165 #if JUCE_UNIT_TESTS
167 class RandomTests : public UnitTest
169 public:
170 RandomTests()
171 : UnitTest ("Random", UnitTestCategories::maths)
174 void runTest() override
176 beginTest ("Random");
178 Random r = getRandom();
180 for (int i = 2000; --i >= 0;)
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);
187 int n = r.nextInt (50) + 1;
188 expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
190 n = r.nextInt (0x7ffffffe) + 1;
191 expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
196 static RandomTests randomTests;
198 #endif
200 } // namespace juce