Creating colored Noise

dsp

#1

Hi everyone,

So im trying to create a simple brownian or red noise for a synth. This is how i create white noise:

float r = rand()/(float)RAND_MAX;
output=r*2-1;
return(output);

Now to create a simple brownian noise i thought i could use the last value of the white noise, add it with the new value and then take its average. Like this:

float r1 = rand()/(float)RAND_MAX;
float newOutput = r1*2 -1;
output = (oldOutput + newOutput) * 0.5;
oldOutput = newOutput;
return(output);

So when i print this, i do get smoother transitions between the output numbers. This however has no effect on the audio, which still sounds like completely random white noise. Could someone explain this to me?

Thanks so much, its probably very obvious but im a bit stuck on it


#2

Maybe you try: oldOutput = output instead of oldOutput = newOutput;?

But this will not attantuate the frequencies a lot and it will also sound different on different sample rates. You maybe try a filter or some more complex algorithm to create other colors.


#3

IIRC, Brownian noise/motion is defined as the integral of a white noise signal . However, this is likely too heavy to calculate in real-time.

I learned to generate red noise by adding a random value to the previous sample where the value to add is in a reduced range (such as -0.1 to +0.1). By changing the range of the value to add you can get a filtering effect where a wider range is closer to white noise and a smaller range has reduced higher frequencies. I’m not sure if there’s a ‘correct’ range to use for ‘proper’ red noise - possibly just down to experimentation?

If you use this method, you have to be sure to clamp your values from -1 to +1 !


#4

Brown noise is generated by integrating a white noise signal - basically keep summing white noise values, and this is the output value. Your next problem will be that this sum will follow a random walk away from 0, and will be unbounded. To avoid the walk, just pull it towards 0 (by multiplying by a number slightly off 1). Apply a bound if you want to avoid it overflowing some range.

Something like this:

    float get_brown_noise_sample()
    {
        auto white = get_white_noise_sample();

        previous_noise_value_ += white;

        if (previous_noise_value_ > 32.0f || previous_noise_value_ < -32.0f)
        {
            previous_noise_value_ -= white;
        }

        previous_noise_value_ = previous_noise_value_ * 0.998f;

        return previous_noise_value_ / 32.0f;
    }

I think you can build a filter to do this too. Pink noise is more of a challenge, and there’s a nice technique of considering it the sum of white noise generators updating at different rates, each consecutive one being a power of 2 slower than the previous. Looking at my example of this, 12 white noise generators works well.


#6

Thanks, this makes the difference just big enough to be audible. So i do know that it works


#7

Thanks so much, this already works really well. It doesnt really matter for me, if there is a ‘correct’ range :slight_smile:


#8

Thanks. I dont completely understand where you get the values 32 and -32 from?