SubSub page: Creating noise and random patterns in software
design started 2015
Introduction:
Pseudo Random BitSequences (PRBS) can be made by hardware using shift registers and exor feedback. They generate a long chain of
all possible word values (except 0) and repeats after all values have been generated.
If the chain is long enough (few seconds or more) it will sound as noise.
You can also make a shift register with feedback in software, example using only 1 line of code:
// 16 bit PRBS with shift register and XOR on Bit 16,15,13,4 makes noise, state is defined as integer:
state=(state<<1 | (((state>>15)&1) ^((state>>14)&1) ^ ((state>>12)&1) ^ ((state>>3)&1) ));
Note: this code is much faster than the "random" command in Arduino language
Next step is to map variable "state" to a value that you send to the DAC.
If you take one bit (irrelevant which one) you get white noise. For example, take bit 7: DAC= state && 128.
Although the DAC is now only 0 or 128 (like tossing a coin), at a clockfrequency above audio the result sounds and measures like white noise in the audio band.
If you combine more bits you create an average and this results in a lowpassfilter. For example, combine bit 1+2+3+4+5+6: DAC= state && 127.
If you run this code at 20kHz the pattern repeats after 3.2 seconds.
here is a Noise sound example As used in MonoVoks and MonoLadder synths
You can also make the pattern short by resetting it, it will start to sound like a tone, the frequency is the repetition period.
This allows for a complex spectrum waveform. If you now change the startpoint of the pattern
(the value in the register, the seed) on a regular base, for example every second, you get a stepwise change in spectrum.
Here is an audio example, starting with noise played at a few different keys (speed) but from 18s up the lengh is gradually diminished up to the point you hear a tone
After that at 30s the tone is played on a few keys. As a bonus, from 44s up a software BR filter is modulating the pattern.
here is a Noise changing into Pattern sound example
In the whole example, an LFO is stepping the pattern and also ramping the analog filter down at a 1Hz speed.
These patterns are used as an oscillator wavemode in MonoVoks, MonoLadder and MonoStat synths.
How to make colored noise like pink and red noise? (this is what is done in the PRBSynth)
If you toss a coin at a certain rate (Freq F >audio) it results in white noise for audio (flat spectrum).
Now also toss a second coin nr2 at a lower rate like F/3, coin nr3 at F/9 and coin nr 4 at F/27 (4 coins is enough in practice).
If you add these results you will get something that has a spectrum increasing at lower frequencies.
Tweaking the amounts in which you sum the coins you can go from pink to red noise.
Also changing the spacing F-F/3-F/9-F/27 allows you to change the spectrum.
A trick is now added to save processing time. In the above scenario, at some moments the microprocessor would need to throw 4 coins at the same time.
This takes up too much computing time. I implemented the following scheme to have only one coin being calculated each round:
First check if coin4 (F/27) has to be thrown, if so do that and skip the rest.
If not coin4 then check coin3 (F/9), if so do that and skip the rest.
If not coin3 then check coin2 (F/3), if so do that and skip the rest.
If not coin2 then throw coin1 (F).
The gaps by not throwing the skipped coins are not audible to me, presumably because there is still always a certain coin being thrown at a rate >audio.
In practice I could run a pink noise generating code up to 50kHz this way on a Arduino ProMini 16MHz. Bonus: the fact that coins 2-3-4 run at lower frequencies masks the otherwise audible repeating pattern of coin1.
With a "switch case" structure you could switch between noise colors by using different versions.
code example for red noise:(repeated at frequency F)
s2cnt++; // counter for coin2
s3cnt++; // counter for coin3
s4cnt++; // counter for coin4
if (s4cnt>26){
state4=(state4<<1 | (((state4>>15)&1) ^((state4>>14)&1) ^ ((state4>>12)&1) ^ ((state4>>3)&1) ));//throw coin4
s4cnt=0;
}
else if (s3cnt>8){
state3=(state3<<1 | (((state3>>15)&1) ^((state3>>14)&1) ^ ((state3>>12)&1) ^ ((state3>>3)&1) ));//throw coin3
s3cnt=0;
}
else if (s2cnt>2){
state2=(state2<<1 | (((state2>>15)&1) ^((state2>>14)&1) ^ ((state2>>12)&1) ^ ((state2>>3)&1) ));//throw coin2
s2cnt=0;
}
else{
state1=(state1<<1 | (((state1>>15)&1) ^((state1>>14)&1) ^ ((state1>>12)&1) ^ ((state1>>3)&1) ));//throw coin1
}
DAC=(state1 & 16)+(state2>>11)+(state3>>11)+(state4>>11);//add the coins to get 7 bit value red noise