VCV Rack API v2
Loading...
Searching...
No Matches
random.hpp
Go to the documentation of this file.
1#pragma once
2#include <common.hpp>
3#include <random>
4#include <vector>
5
6
7namespace rack {
9namespace random {
10
11
27 uint64_t state[2] = {};
28
29 void seed(uint64_t s0, uint64_t s1) {
30 state[0] = s0;
31 state[1] = s1;
32 // A bad seed will give a bad first result, so shift the state
33 operator()();
34 }
35
36 bool isSeeded() {
37 return state[0] || state[1];
38 }
39
40 static uint64_t rotl(uint64_t x, int k) {
41 return (x << k) | (x >> (64 - k));
42 }
43
44 uint64_t operator()() {
45 uint64_t s0 = state[0];
46 uint64_t s1 = state[1];
47 uint64_t result = s0 + s1;
48
49 s1 ^= s0;
50 state[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14);
51 state[1] = rotl(s1, 36);
52
53 return result;
54 }
55 constexpr uint64_t min() const {
56 return 0;
57 }
58 constexpr uint64_t max() const {
59 return UINT64_MAX;
60 }
61};
62
63
64// Simple global API
65
66void init();
67
72
73template <typename T>
74T get() {
75 // Call operator()() and cast by default
76 return local()();
77}
78
79template <>
80inline uint32_t get() {
81 // Take top 32 bits which has better randomness properties.
82 return get<uint64_t>() >> 32;
83}
84
85template <>
86inline uint16_t get() {
87 return get<uint64_t>() >> 48;
88}
89
90template <>
91inline uint8_t get() {
92 return get<uint64_t>() >> 56;
93}
94
95template <>
96inline bool get() {
97 return get<uint64_t>() >> 63;
98}
99
100template <>
101inline float get() {
102 // The multiplier is 2f7fffff in hex. This gives maximum precision of uint32_t -> float conversion and its image is [0, 1).
103 return get<uint32_t>() * 2.32830629e-10f;
104}
105
106template <>
107inline double get() {
108 return get<uint64_t>() * 5.421010862427522e-20;
109}
110
111
113inline uint64_t u64() {return get<uint64_t>();}
115inline uint32_t u32() {return get<uint32_t>();}
117inline float uniform() {return get<float>();}
118
120inline float normal() {
121 // Box-Muller transform
122 float radius = std::sqrt(-2.f * std::log(1.f - get<float>()));
123 float theta = 2.f * M_PI * get<float>();
124 return radius * std::sin(theta);
125
126 // // Central Limit Theorem
127 // const int n = 8;
128 // float sum = 0.0;
129 // for (int i = 0; i < n; i++) {
130 // sum += get<float>();
131 // }
132 // return (sum - n / 2.f) / std::sqrt(n / 12.f);
133}
134
136inline void buffer(uint8_t* out, size_t len) {
137 Xoroshiro128Plus& rng = local();
138 for (size_t i = 0; i < len; i += 4) {
139 uint64_t r = rng();
140 out[i] = r;
141 if (i + 1 < len)
142 out[i + 1] = r >> 8;
143 if (i + 2 < len)
144 out[i + 2] = r >> 16;
145 if (i + 3 < len)
146 out[i + 3] = r >> 24;
147 }
148}
149
151inline std::vector<uint8_t> vector(size_t len) {
152 std::vector<uint8_t> v(len);
153 buffer(v.data(), len);
154 return v;
155}
156
157
158} // namespace random
159} // namespace rack
float normal()
Returns a normal random number with mean 0 and standard deviation 1.
Definition random.hpp:120
void buffer(uint8_t *out, size_t len)
Fills an array with random bytes.
Definition random.hpp:136
Xoroshiro128Plus & local()
Returns the generator.
uint64_t u64()
Returns a uniform random uint64_t from 0 to UINT64_MAX.
Definition random.hpp:113
float uniform()
Returns a uniform random float in the interval [0.0, 1.0)
Definition random.hpp:117
std::vector< uint8_t > vector(size_t len)
Creates a vector of random bytes.
Definition random.hpp:151
T get()
Definition random.hpp:74
uint32_t u32()
Returns a uniform random uint32_t from 0 to UINT32_MAX.
Definition random.hpp:115
Root namespace for the Rack API.
Definition AudioDisplay.hpp:9
xoroshiro128+.
Definition random.hpp:26
constexpr uint64_t max() const
Definition random.hpp:58
constexpr uint64_t min() const
Definition random.hpp:55
void seed(uint64_t s0, uint64_t s1)
Definition random.hpp:29
static uint64_t rotl(uint64_t x, int k)
Definition random.hpp:40
uint64_t operator()()
Definition random.hpp:44
bool isSeeded()
Definition random.hpp:36
uint64_t state[2]
Definition random.hpp:27