Fast Whitenoise Generator

notes
This is Whitenoise... :o)
code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
float g_fScale = 2.0f / 0xffffffff;
int g_x1 = 0x67452301;
int g_x2 = 0xefcdab89;

void whitenoise(
  float* _fpDstBuffer, // Pointer to buffer
  unsigned int _uiBufferSize, // Size of buffer
  float _fLevel ) // Noiselevel (0.0 ... 1.0)
{
  _fLevel *= g_fScale;

  while( _uiBufferSize-- )
  {
    g_x1 ^= g_x2;
    *_fpDstBuffer++ = g_x2 * _fLevel;
    g_x2 += g_x1;
  }
}

Comments

Works well! Kinda fast! The spectrum looks completely flat in an FFT analyzer.
As I said! :-)
Take care
I'm now waiting for pink and brown. :-)
To get pink noise, you can apply a 3dB/Oct filter, for example the pink noise filter in the Filters section.

To get brown noise, apply an one pole LP filter to get a 6dB/oct slope.

Peter
Yeah, I know how to do it with a filter. I was just looking to see if this guy had anything else clever up his sleeve.

I'm currently using this great stuff:

vellocet.com/dsp/noise/VRand.html
I compiled it, but I get some grainyness that a unisgned long LC algorithm does not give me...  am I the only one?

pa
Did you do everything right? It works here.
I've noticed that my code is similar to a so called "feedback shift register" as used in the Commodore C64 Soundchip 6581 called SID for noise generation.

Links:
en.wikipedia.org/wiki/Linear_feedback_shift_register
en.wikipedia.org/wiki/MOS_Technology_SID
www.cc65.org/mailarchive/2003-06/3156.html
SID noise! cool.
  • Date: 2021-06-25 11:43:00
  • By: TaleTN
I still seem to run into this noise generator from time to time, so I thought I'd provide some extra info here:

The seed provided above will result in a sequence with a period of 3/4 * 2^29, and with 268876131 unique output values in the [-2147483635, 2147483642] range. This is probably more than enough to generate white noise at any reasonable sample rate, but you can easily increase/max out the period and range, simply by using different seed values.

If you instead use g_x1 = 0x70f4f854 and g_x2 = 0xe1e9f0a7, then this will result in a sequence with a period of 3/4 * 2^32, with 1896933636 unique output values in the [-2147483647, 2147483647] range. This is probably the best you can do with a word size of 32 bits. Also note that only the highest bit will actually have the max period, lower bits will have increasingly shorter periods (just like with a Linear Congruential Generator).