A cheap LSFR gives a simple white noise output:
//--------------------------------------------------------------------------------
// Fast pseudo random number generator from
// http://en.wikipedia.org/wiki/Linear_feedback_shift_register
//--------------------------------------------------------------------------------
uint16_t g_rand = 0xACE1u;
void nextRand()
{
g_rand = (g_rand >> 1) ^ (-(g_rand & 1u) & 0xB400u);
}
I want the effect of filter sweeping this but being a little 8 bit chip, proper DSP is out of my league. Instead I do a cheap low pass filter by averaging the last sample with the current one, then the previous one to that with its previous etc. To get more variation I average every other one and then fill the gaps, generates a sort of noise drop off curve:
#define FILTER_NOISE(idx1, idx2) g_noise[idx1] = (g_noise[idx1] >> 1) + (g_noise[idx2] >> 1);
#define AVG_NOISE(idx1, idx2, idx3) g_noise[idx1] = (g_noise[idx2] >> 1) + (g_noise[idx3] >> 1);
uint8_t g_noise[16];
void updateNoise()
{
nextRand();
g_noise[0] = (uint8_t)g_rand; // ** Initial white noise value
FILTER_NOISE(2, 0) // Average every other sample to
FILTER_NOISE(4, 2) // get more muffled low pass white
FILTER_NOISE(6, 4) // noise.
FILTER_NOISE(8, 6)
FILTER_NOISE(10, 8)
FILTER_NOISE(12, 10) // Last couple of sample are filtering
FILTER_NOISE(13, 12) // each sample.
FILTER_NOISE(14, 13)
FILTER_NOISE(15, 14)
AVG_NOISE(1, 0, 2) // Averate between gaps in filtered
AVG_NOISE(3, 2, 4) // samples.
AVG_NOISE(5, 4, 6)
AVG_NOISE(7, 6, 8)
AVG_NOISE(9, 8, 10)
AVG_NOISE(11, 10, 12)
}
Messy code, but still faster than my awful assembly code version… beaten by GCC’s optimiser once again. Here’s what it sounds like sweeping over this with a pot:
[audio:https://www.alexallmont.com/wp-content/uploads/2012/04/noise-capture.mp3|titles=noise capture]