The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
4.6KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. Random::Random (const int64 seedValue) noexcept
  19. : seed (seedValue)
  20. {
  21. }
  22. Random::Random()
  23. : seed (1)
  24. {
  25. setSeedRandomly();
  26. }
  27. Random::~Random() noexcept
  28. {
  29. }
  30. void Random::setSeed (const int64 newSeed) noexcept
  31. {
  32. seed = newSeed;
  33. }
  34. void Random::combineSeed (const int64 seedValue) noexcept
  35. {
  36. seed ^= nextInt64() ^ seedValue;
  37. }
  38. void Random::setSeedRandomly()
  39. {
  40. static int64 globalSeed = 0;
  41. combineSeed (globalSeed ^ (int64) (pointer_sized_int) this);
  42. combineSeed (Time::getMillisecondCounter());
  43. combineSeed (Time::getHighResolutionTicks());
  44. combineSeed (Time::getHighResolutionTicksPerSecond());
  45. combineSeed (Time::currentTimeMillis());
  46. globalSeed ^= seed;
  47. }
  48. Random& Random::getSystemRandom() noexcept
  49. {
  50. static Random sysRand;
  51. return sysRand;
  52. }
  53. //==============================================================================
  54. int Random::nextInt() noexcept
  55. {
  56. seed = (seed * literal64bit (0x5deece66d) + 11) & literal64bit (0xffffffffffff);
  57. return (int) (seed >> 16);
  58. }
  59. int Random::nextInt (const int maxValue) noexcept
  60. {
  61. jassert (maxValue > 0);
  62. return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32);
  63. }
  64. int64 Random::nextInt64() noexcept
  65. {
  66. return (((int64) nextInt()) << 32) | (int64) (uint64) (uint32) nextInt();
  67. }
  68. bool Random::nextBool() noexcept
  69. {
  70. return (nextInt() & 0x40000000) != 0;
  71. }
  72. float Random::nextFloat() noexcept
  73. {
  74. return static_cast <uint32> (nextInt()) / (float) 0xffffffff;
  75. }
  76. double Random::nextDouble() noexcept
  77. {
  78. return static_cast <uint32> (nextInt()) / (double) 0xffffffff;
  79. }
  80. BigInteger Random::nextLargeNumber (const BigInteger& maximumValue)
  81. {
  82. BigInteger n;
  83. do
  84. {
  85. fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1);
  86. }
  87. while (n >= maximumValue);
  88. return n;
  89. }
  90. void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits)
  91. {
  92. arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space
  93. while ((startBit & 31) != 0 && numBits > 0)
  94. {
  95. arrayToChange.setBit (startBit++, nextBool());
  96. --numBits;
  97. }
  98. while (numBits >= 32)
  99. {
  100. arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt());
  101. startBit += 32;
  102. numBits -= 32;
  103. }
  104. while (--numBits >= 0)
  105. arrayToChange.setBit (startBit + numBits, nextBool());
  106. }
  107. //==============================================================================
  108. #if JUCE_UNIT_TESTS
  109. class RandomTests : public UnitTest
  110. {
  111. public:
  112. RandomTests() : UnitTest ("Random") {}
  113. void runTest()
  114. {
  115. beginTest ("Random");
  116. for (int j = 10; --j >= 0;)
  117. {
  118. Random r;
  119. r.setSeedRandomly();
  120. for (int i = 20; --i >= 0;)
  121. {
  122. expect (r.nextDouble() >= 0.0 && r.nextDouble() < 1.0);
  123. expect (r.nextFloat() >= 0.0f && r.nextFloat() < 1.0f);
  124. expect (r.nextInt (5) >= 0 && r.nextInt (5) < 5);
  125. expect (r.nextInt (1) == 0);
  126. int n = r.nextInt (50) + 1;
  127. expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
  128. n = r.nextInt (0x7ffffffe) + 1;
  129. expect (r.nextInt (n) >= 0 && r.nextInt (n) < n);
  130. }
  131. }
  132. }
  133. };
  134. static RandomTests randomTests;
  135. #endif