Mozzi  version v2.0
sound synthesis library for Arduino
mozzi_rand.h
1 /*
2  * mozzi_rand.h
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2012-2024 Tim Barrass and the Mozzi Team
7  *
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
9  *
10  */
11 
12 #ifndef MOZZI_RAND_H_
13 #define MOZZI_RAND_H_
14 
15 #include <Arduino.h>
16 #include "internal/mozzi_rand_p.h"
17 
18 /** @defgroup random Fast random number generator functions
19 
20 These replace Arduino random() which is so slow it will stop your audio. They can even be used to generate audio noise.
21 */
22 
23 /** @ingroup random
24 Random number generator. A faster replacement for Arduino's random function,
25 which is too slow to use with Mozzi.
26 Based on Marsaglia, George. (2003). Xorshift RNGs. http://www.jstatsoft.org/v08/i14/xorshift.pdf
27 @return a random 32 bit integer.
28 @todo check timing of xorshift96(), rand() and other PRNG candidates.
29  */
30 inline uint32_t xorshift96() { return MozziPrivate::MozziRandPrivate::xorshift96(); };
31 
32 /** @ingroup random
33 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used
34 in Mozzi's rand() function. This can be useful if you want random sequences to
35 be different on each run of a sketch, by seeding with fairly random input, such
36 as analogRead() on an unconnected pin (as explained in the Arduino documentation
37 for randomSeed(). randSeed is the same as xorshift96Seed(), but easier to
38 remember.
39 @param seed a number to use as a seed.
40 */
41 inline void randSeed(uint32_t seed) { MozziPrivate::randSeed(seed); };
42 
43 /** @ingroup random
44 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used
45 in Mozzi's rand() function. This can be useful if you want random sequences to
46 be different on each run of a sketch, by seeding with a fairly random input.
47 randSeed() called without a parameter uses noise from reading the Arduino's
48 internal temperature as the seed, a technique discussed at
49 http://arduino.cc/forum/index.php/topic,38091.0.html, borrowing code put there
50 by Rob Tillaart.
51 
52 @note Intialization of the random seed is done differently on different MCUs,
53  but is nowhere near perfect for most (and for some it is not even implemented at all).
54  Many implementations (e.g. on AVR, STM32) simply rely on reading a (hopefully noisy)
55  internal temperature sensor.
56  You will often get better results by calling analogRead() - @em not mozziAnalogRead(0), in this case! -
57  on one or two floating (non-connected) analog pins.
58 */
59 inline void randSeed() { MozziPrivate::MozziRandPrivate::autoSeed(); };
60 
61 /** @ingroup random
62 Initialises Mozzi's (pseudo)random number generator xorshift96() with a chosen seed number.
63 @param seed a number to use as a seed.
64 // TODO: duplicate deprecate / remove
65 */
66 inline void xorshiftSeed(uint32_t seed) { randSeed(seed); };
67 
68 /** @ingroup random
69 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
70 @param minval the minimum signed byte value of the range to be chosen from. Minval will be the minimum value possibly returned by the function.
71 @param maxval the maximum signed byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
72 @return a random signed byte between minval and maxval-1 inclusive.
73 */
75 {
76  return (int8_t) ((((int) (lowByte(xorshift96()))) * (maxval-minval))>>8) + minval;
77 }
78 
79 /** @ingroup random
80 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
81 @param maxval the maximum signed byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
82 @return a random signed byte between 0 and maxval-1 inclusive.
83 */
84 inline int8_t rand(int8_t maxval)
85 {
86  return (int8_t) ((((int) (lowByte(xorshift96()))) * maxval)>>8);
87 }
88 
89 /** @ingroup random
90 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
91 @param minval the minimum unsigned byte value of the range to be chosen from. Minval will be the minimum value possibly returned by the function.
92 @param maxval the maximum unsigned byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
93 @return a random unsigned byte between minval and maxval-1 inclusive.
94 */
96 {
97  return (uint8_t) ((((unsigned int) (lowByte(xorshift96()))) * (maxval-minval))>>8) + minval;
98 }
99 
100 /** @ingroup random
101 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
102 @param maxval the maximum unsigned byte value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
103 @return a random unsigned byte between 0 and maxval-1 inclusive.
104 */
105 inline uint8_t rand(uint8_t maxval)
106 {
107  return (uint8_t) ((((unsigned int) (lowByte(xorshift96()))) * maxval)>>8);
108 }
109 
110 /** @ingroup random
111 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
112 @param minval the minimum signed int value of the range to be chosen from. Minval will be the minimum value possibly returned by the function.
113 @param maxval the maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
114 @return a random int between minval and maxval-1 inclusive.
115 
116 @note The returned value is always in the 16 bit range, even on platforms where int is wider. If you need 32 bits, call xorshift96(), directly.
117 */
118 inline int rand(int minval, int maxval)
119 {
120  return (int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval);
121 }
122 
123 /** @ingroup random
124 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
125 @param maxval the maximum signed int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
126 @return a random int between 0 and maxval-1 inclusive.
127 
128 @note The returned value is always in the 16 bit range, even on platforms where int is wider. If you need 32 bits, call xorshift96(), directly.
129 */
130 inline int rand(int maxval)
131 {
132  return (int) (((xorshift96() & 0xFFFF) * maxval)>>16);
133 }
134 
135 /** @ingroup random
136 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
137 @param minval the minimum unsigned int value of the range to be chosen from. Minval will be the minimum value possibly returned by the function.
138 @param maxval the maximum unsigned int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
139 @return a random unsigned int between minval and maxval-1 inclusive.
140 */
141 inline unsigned int rand(unsigned int minval, unsigned int maxval)
142 {
143  return (unsigned int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval);
144 }
145 
146 /** @ingroup random
147 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
148 @param maxval the maximum unsigned int value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
149 @return a random unsigned int between 0 and maxval-1 inclusive.
150 
151 @note The returned value is always in the 16 bit range, even on platforms where int is wider. If you need 32 bits, call xorshift96(), directly.
152 */
153 inline unsigned int rand(unsigned int maxval)
154 {
155  return (unsigned int) (((xorshift96() & 0xFFFF) * maxval)>>16);
156 }
157 
158 /** @ingroup random
159 Generates a random number in the range for midi notes.
160 @return a random value between 0 and 127 inclusive
161 */
162 inline uint8_t randMidiNote()
163 {
164  return lowByte(xorshift96())>>1;
165 }
166 
167 #endif /* MOZZI_RAND_H_ */