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:http://www.alexallmont.com/wp-content/uploads/2012/04/noise-capture.mp3|titles=noise capture]