A reader (you know who you are!) proposed an interesting project that will involve measuring audio passbands and suggested using white noise to show the entire shape on a spectrum analyzer. He pointed me at the NOISE 1B Noise Generator based on a PIC microcontroller, which led to trying out the same idea on an Arduino.
The first pass used the low bit from the Arduino runtime’s built-in random() function:

Well, that’s a tad pokey for audio: 54 μs/bit = 18.5 kHz. Turns out they use an algorithm based on multiplication and division to produce nice-looking numbers, but doing that to 32 bit quantities takes quite a while on an 8 bit microcontroller teleported from the mid 1990s.
The general idea is to send a bit from the end of a linear feedback shift register to an output to produce a randomly switching binary signal. Because successive values involve only shifts and XORs, it should trundle along at a pretty good clip and, indeed, it does:

I used the Galois optimization, rather than a traditional LFSR, because I only need one random bit and don’t care about the actual sequence of values. In round numbers, it spits out bits an order of magnitude faster at 6 μs/bit = 160 kHz.
For lack of anything smarter, I picked the first set of coefficients from the list of 32 bit maximal-length values at https://users.ece.cmu.edu/~koopman/lfsr/index.html:
0x80000057.
The spectrum looks pretty good, particularly if you’re only interested in the audio range way over on the left side:

It’s down 3 dB at 76 kHz, about half the 160 kHz bit flipping pace.
If you were fussy, you’d turn off the 1 ms timer interrupt to remove a slight jitter in the output.
It’s built with an old Arduino Pro Mini wired up to a counterfeit FTDI USB converter. Maybe this is the best thing I can do with it: put it in a box with a few audio filters for various noise colors and be done with it.
It occurs to me I could fire it into the 60 kHz preamp’s snout to measure the response over a fairly broad range while I’m waiting for better RF reception across the continent.
The Arduino source code as a GitHub Gist:
| // Quick test for random bit generation timing | |
| // Ed Nisley KE4ZNU – 2017-10-25 | |
| // Observe output bit on an oscilloscope | |
| // LFSR info https://en.wikipedia.org/wiki/Linear-feedback_shift_register | |
| // This code uses the Galois implementation | |
| // Coefficients from https://users.ece.cmu.edu/~koopman/lfsr/index.html | |
| #define PIN_RND 13 | |
| #include <Entropy.h> | |
| uint32_t Rnd; | |
| byte LowBit; | |
| void setup() { | |
| Serial.begin(57600); | |
| Serial.println("Random bit timing"); | |
| Serial.println("Ed Nisley KE4ZNU – 2017-10-25"); | |
| Entropy.initialize(); | |
| pinMode(PIN_RND,OUTPUT); | |
| uint32_t Seed = Entropy.random(); | |
| Serial.print("Seed: "); | |
| Serial.println(Seed,HEX); | |
| randomSeed(Seed); | |
| do { | |
| Rnd = random(); | |
| } while (!Rnd); // get nonzero initial value | |
| } | |
| void loop() { | |
| // digitalWrite(PIN_RND,Rnd & 1); // about 55 us/bit | |
| // Rnd = random(); | |
| LowBit = Rnd & 1; | |
| digitalWrite(PIN_RND,LowBit); // about 6 us/bit | |
| Rnd >>= 1; | |
| Rnd ^= LowBit ? 0x80000057ul : 0ul; | |
| } |