| Mozzi version v1.1.0 sound synthesis library for Arduino |

mozzi_rand.cpp
1 #include "mozzi_rand.h"
2
3 #include "hardware_defines.h"
4
5 #if IS_STM32()
6 //#include <STM32ADC.h>
7 extern STM32ADC adc;
8 #elif IS_ESP8266()
9 #include <esp8266_peri.h>
10 #endif
11
12 // moved these out of xorshift96() so xorshift96() can be reseeded manually
13 static unsigned long x=132456789, y=362436069, z=521288629;
14 // static unsigned long x= analogRead(A0)+123456789;
15 // static unsigned long y= analogRead(A1)+362436069;
16 // static unsigned long z= analogRead(A2)+521288629;
17
18 /** @ingroup random
19 Random number generator. A faster replacement for Arduino's random function,
20 which is too slow to use with Mozzi.
21 Based on Marsaglia, George. (2003). Xorshift RNGs. http://www.jstatsoft.org/v08/i14/xorshift.pdf
22 @return a random 32 bit integer.
23 @todo check timing of xorshift96(), rand() and other PRNG candidates.
24 */
25
26 unsigned long xorshift96()
27 { //period 2^96-1
28 // static unsigned long x=123456789, y=362436069, z=521288629;
29 unsigned long t;
30
31 x ^= x << 16;
32 x ^= x >> 5;
33 x ^= x << 1;
34
35 t = x;
36 x = y;
37 y = z;
38 z = t ^ x ^ y;
39
40 return z;
41 }
42
43
44 /** @ingroup random
45 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used
46 in Mozzi's rand() function. This can be useful if you want random sequences to
47 be different on each run of a sketch, by seeding with fairly random input, such
48 as analogRead() on an unconnected pin (as explained in the Arduino documentation
49 for randomSeed(). randSeed is the same as xorshift96Seed(), but easier to
50 remember.
51 @param seed a number to use as a seed.
52 */
53 void randSeed(long seed)
54 {
55 x=seed;
56 }
57
58
59 #if defined (__AVR_ATmega644P__)
60
61 // a less fancy version for gizduino (__AVR_ATmega644P__) which doesn't know INTERNAL
62 static long longRandom()
63 {
64 return ((long)analogRead(0)+63)*(analogRead(1)+97); // added offsets in case analogRead is 0
65 }
66
67 #elif defined (__AVR_ATmega2560__)
68 /*
69 longRandom(), used as a seed generator, comes from:
70 http://arduino.cc/forum/index.php/topic,38091.0.html
71 // AUTHOR: Rob Tillaart
72 // PURPOSE: Simple Random functions based upon unreliable internal temp sensor
73 // VERSION: 0.1
74 // DATE: 2011-05-01
75 //
76 // Released to the public domain, use at own risk
77 //
78 */
79 static long longRandom()
80 {
81 //analogReference(INTERNAL2V56);
82 unsigned long rv = 0;
83 for (uint8_t i=0; i< 32; i++) rv |= ((analogRead(8)+2294) & 1L) << i; // added 2294 in case analogRead is 0
84 return rv;
85 }
86
87 #elif IS_AVR()
88
89 static long longRandom()
90 {
91 //analogReference(INTERNAL);
92 unsigned long rv = 0;
93 for (uint8_t i=0; i< 32; i++) rv |= ((analogRead(8)+1171) & 1L) << i; // added 1171 in case analogRead is 0
94 return rv;
95 }
96
97
98 #endif
99
100
101 /** @ingroup random
102 Initialises Mozzi's (pseudo)random number generator xorshift96(), which is used
103 in Mozzi's rand() function. This can be useful if you want random sequences to
104 be different on each run of a sketch, by seeding with a fairly random input.
105 randSeed() called without a parameter uses noise from reading the Arduino's
106 internal temperature as the seed, a technique discussed at
107 http://arduino.cc/forum/index.php/topic,38091.0.html, borrowing code put there
108 by Rob Tillaart.
109 @note It's not perfect, as discussed in the forum thread.
110 It might only work with some processors: (from the thread)
111 "...ATmega328P in DIP, possibly others but the duemilanove and uno will do it at least."
112 So far, gizduino's __AVR_ATmega644P__ chip doesn't like it, so we use (long)analogRead(0)*analogRead(1) for that instead.
113 It works to some degree on STM32 chips, but the produced seed is not very random at all. Again, using an appropriate
114 analogRead() (preferably on one or two floating input pins) is much more effective.
115 @todo add Teensy 3 code
116 */
117 void randSeed() {
118 #if IS_AVR()
119 ADCSRA &= ~ (1 << ADIE); // adc Disable Interrupt, re-enable at end
120 // this attempt at remembering analog_reference stops it working
121 // maybe needs a delay after changing analog reference in longRandom (Arduino reference suggests this)
122 // because the analog reads return 0
123 //uint8_t analog_reference_orig = ADMUX&192; // analog_reference is high 2 bits of ADMUX, store this because longRandom sets it to internal
124 x=longRandom();
125 y=longRandom();
126 z=longRandom();
127 //analogReference(analog_reference_orig); // change back to original
128 ADCSRA |= (1 << ADIE); // adc re-Enable Interrupt
129 #elif IS_STM32()
130 // Unfortunately the internal temp sensor on STM32s does _not_ appear to create a lot of noise.
131 // Ironically, the calls to calibrate help induce some random noise. You're still fairly likely to produce two equal
132 // random seeds in two subsequent runs, however.
133 adc.enableInternalReading();
134 float dummy = adc.readTemp();
135 int* dummy_int = (int*) &dummy;
136 x=*dummy_int;
137 adc.calibrate();
138 dummy = adc.readTemp();
139 y=*dummy_int;
140 adc.calibrate();
141 dummy = adc.readTemp();
142 z=*dummy_int;
143 #elif IS_ESP8266()
144 x = RANDOM_REG32;
145 y = random (0xFFFFFFFF) ^ RANDOM_REG32;
146 z = random (0xFFFFFFFF) ^ RANDOM_REG32;
147 #else
148 #warning Automatic random seeding not implemented on this platform
149 #endif
150 }
151
152
153
154 /** @ingroup random
155 Initialises Mozzi's (pseudo)random number generator xorshift96() with a chosen seed number.
156 @param seed a number to use as a seed.
157 */
158 void xorshiftSeed(long seed)
159 {
160 x=seed;
161 }
162
163
164
165 /** @ingroup random
166 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
167 @param minval the minimum signed uint8_t value of the range to be chosen from. Minval will be the minimum value possibly returned by the function.
168 @param maxval the maximum signed uint8_t value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
169 @return a random int8_t between minval and maxval-1 inclusive.
170 */
171 int8_t rand(int8_t minval, int8_t maxval)
172 {
173 return (int8_t) ((((int) (lowByte(xorshift96()))) * (maxval-minval))>>8) + minval;
174 }
175
176
177 /** @ingroup random
178 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
179 @param minval the minimum unsigned uint8_t value of the range to be chosen from. Minval will be the minimum value possibly returned by the function.
180 @param maxval the maximum unsigned uint8_t value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
181 @return a random uint8_t between minval and maxval-1 inclusive.
182 */
183 uint8_t rand(uint8_t minval, uint8_t maxval)
184 {
185 return (uint8_t) ((((unsigned int) (lowByte(xorshift96()))) * (maxval-minval))>>8) + minval;
186 }
187
188
189 /** @ingroup random
190 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
191 @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.
192 @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.
193 @return a random int between minval and maxval-1 inclusive.
194 */
195 int rand( int minval, int maxval)
196 {
197 return (int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval);
198 }
199
200
201 /** @ingroup random
202 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
203 @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.
204 @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.
205 @return a random unsigned int between minval and maxval-1 inclusive.
206 */
207 unsigned int rand(unsigned int minval, unsigned int maxval)
208 {
209 return (unsigned int) ((((xorshift96() & 0xFFFF) * (maxval-minval))>>16) + minval);
210 }
211
212
213 /** @ingroup random
214 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
215 @param maxval the maximum signed uint8_t value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
216 @return a random int8_t between 0 and maxval-1 inclusive.
217 */
218 int8_t rand(int8_t maxval)
219 {
220 return (int8_t) ((((int) (lowByte(xorshift96()))) * maxval)>>8);
221 }
222
223
224 /** @ingroup random
225 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
226 @param maxval the maximum unsigned uint8_t value of the range to be chosen from. Maxval-1 will be the largest value possibly returned by the function.
227 @return a random uint8_t between 0 and maxval-1 inclusive.
228 */
229 uint8_t rand(uint8_t maxval)
230 {
231 return (uint8_t) ((((unsigned int) (lowByte(xorshift96()))) * maxval)>>8);
232 }
233
234
235 /** @ingroup random
236 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
237 @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.
238 @return a random int between 0 and maxval-1 inclusive.
239 */
240 int rand(int maxval)
241 {
242 return (int) (((xorshift96() & 0xFFFF) * maxval)>>16);
243 }
244
245
246 /** @ingroup random
247 Ranged random number generator, faster than Arduino's built-in random function, which is too slow for generating at audio rate with Mozzi.
248 @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.
249 @return a random unsigned int between 0 and maxval-1 inclusive.
250 */
251 unsigned int rand(unsigned int maxval)
252 {
253 return (unsigned int) (((xorshift96() & 0xFFFF) * maxval)>>16);
254 }
255
256
257 /** @ingroup random
258 Generates a random number in the range for midi notes.
259 @return a random value between 0 and 127 inclusive
260 */
261 uint8_t randMidiNote()
262 {
263 return lowByte(xorshift96())>>1;
264 }
xorshiftSeed
void xorshiftSeed(long seed)
Initialises Mozzi&#39;s (pseudo)random number generator xorshift96() with a chosen seed number...
Definition: mozzi_rand.cpp:158
randSeed
void randSeed()
Initialises Mozzi&#39;s (pseudo)random number generator xorshift96(), which is used in Mozzi&#39;s rand() fun...
Definition: mozzi_rand.cpp:117
randSeed
void randSeed(long seed)
Initialises Mozzi&#39;s (pseudo)random number generator xorshift96(), which is used in Mozzi&#39;s rand() fun...
Definition: mozzi_rand.cpp:53
rand
int rand(int maxval)
Ranged random number generator, faster than Arduino&#39;s built-in random function, which is too slow for...
Definition: mozzi_rand.cpp:240
IS_STM32
#define IS_STM32()
Definition: hardware_defines.h:18
rand
unsigned int rand(unsigned int minval, unsigned int maxval)
Ranged random number generator, faster than Arduino&#39;s built-in random function, which is too slow for...
Definition: mozzi_rand.cpp:207
IS_AVR
#define IS_AVR()
Definition: hardware_defines.h:15
xorshift96
unsigned long xorshift96()
Random number generator.
Definition: mozzi_rand.cpp:26
randMidiNote
uint8_t randMidiNote()
Generates a random number in the range for midi notes.
Definition: mozzi_rand.cpp:261
rand
unsigned int rand(unsigned int maxval)
Ranged random number generator, faster than Arduino&#39;s built-in random function, which is too slow for...
Definition: mozzi_rand.cpp:251
rand
int rand(int minval, int maxval)
Ranged random number generator, faster than Arduino&#39;s built-in random function, which is too slow for...
Definition: mozzi_rand.cpp:195
IS_ESP8266
#define IS_ESP8266()
Definition: hardware_defines.h:19