electro-music.com   Dedicated to experimental electro-acoustic
and electronic music
 
    Front Page  |  Articles  |  Radio
 |  Media  |  Forum  |  Wiki  |  Links  |  Store
Forum with support of Syndicator RSS
 FAQFAQ   CalendarCalendar   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   LinksLinks
 RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in  Chat RoomChat Room 
Live streaming at radio.electro-music.com

  host / artist show at your time
  EdisonRex Edison's Electronic Review
Please visit the chat
 Forum index » DIY Hardware and Software » ChucK programming language
Pink Noise
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [17 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
Author Message
Frostburn



Joined: Dec 12, 2007
Posts: 255
Location: Finland
Audio files: 9

PostPosted: Thu Jan 31, 2008 1:41 pm    Post subject: Pink Noise
Subject description: 1/f with ChucK
Reply with quote  Mark this post and the followings unread

Because Pink Noise is cool here's a patch:
Code:
//White noise => pinking_filter == Pink noise => dac;
Noise n => Gain in;
Gain out => dac;
PoleZero pz[16]; //The number controls the quality of the filter. Bigger ones bring out the lower frequencies.
for(0 => int i; i < pz.cap(); i++){
    1.0 => pz[i].b0;
    Math.pow(2.0,i + 1.0  -pz.cap())-1.0 => pz[i].a1;
    Math.pow(2.0,i +1.5  -pz.cap())-1.0 => pz[i].b1;
}
in => pz[0];
for(1 => int i; i < pz.cap(); i++) pz[i-1] => pz[i];
pz[pz.cap()-1] => out;

0.2 => out.gain;

//for(now + second => time later; now < later; 10::ms => now);
second => now;

I'm not sure if it's exactly pink. But the spectrum is a straight line when viewed in log-frequency.
It's not white. It's not brown. At least it's pinkish.
If you know a better way to make pink noise. Post away!

_________________
To boldly go where no man has bothered to go before.
Back to top
View user's profile Send private message
Inventor
Stream Operator


Joined: Oct 13, 2007
Posts: 5978
Location: San Antonio, Tx, USA
Audio files: 258

PostPosted: Thu Jan 31, 2008 2:07 pm    Post subject: Reply with quote  Mark this post and the followings unread

Well, got this from the Wikipedia entry on pink noise, for what its worth:

There are no simple mathematical models to create pink noise. It is usually generated by filtering white noise.
Back to top
View user's profile Send private message Send e-mail
Frostburn



Joined: Dec 12, 2007
Posts: 255
Location: Finland
Audio files: 9

PostPosted: Fri Feb 01, 2008 5:17 am    Post subject: Reply with quote  Mark this post and the followings unread

Another approach to a pinking filter:
This one doesn't cut off the lowest frequencies so it might be useful as a control signal. Because the "DC" component is not cut off the sound will clip at some point. Apply DC blocking as needed.
Code:
//Generating pink noise by integrating blue noise
//By: Pyry Pakkanen ( 2008 )
//Released under GNU GPL v3
//First the half derivate of white noise is taken (blue noise)
//then it's itegrated (browned) to get pink noise. (minus one halfth derivate of white noise)

//Don't ask me to prove this but I think that convolving a signal with the
//taylor series coefficients of (1-x)^n returns the n'th derivate of the signal

//Don't ask me to prove either that pink noise is actually the -0.5th derivate of white noise. :)


float coeff[16]; //Quality of the half derivate approximation
//Get the taylor series of sqrt(1 + x)
binomial_series(1.0,0.5,coeff);
//Reverse odd coefficients to get the series for sqrt(1 - x)
for(1 => int i; i < coeff.cap(); i + 2 => i) -coeff[i] => coeff[i];
//for(0 => int i; i < coeff.cap(); i++)<<<coeff[i]>>>;
Noise white_noise => Gain noise_in;
Gain noise_out;
convolve(noise_in,noise_out,coeff);
noise_out => OnePole browner => dac;
0.01 => browner.b0;
-1.0 => browner.a1;
10::second => now;


//Simple FIR filter
fun void convolve(Gain @ in, Gain @ out, float b[]){
    Delay d[b.cap()];
    for(0 => int i; i < b.cap(); i++){
        in => d[i] => out;
        i::samp => d[i].delay;
        b[i] => d[i].gain;
    }
}
//Generate the taylor series coefficients of (a+x)^n
fun void binomial_series(float a,float n,float coeff[]){
    Math.pow(a,n) => float c;
    for(0 => int i; i < coeff.cap(); i++){
        c => coeff[i];
        (n-i$float)/(i$float+1.0)/a *=> c;
    }
}

_________________
To boldly go where no man has bothered to go before.
Back to top
View user's profile Send private message
kijjaz



Joined: Sep 20, 2004
Posts: 765
Location: bangkok, thailand
Audio files: 4

PostPosted: Sat Mar 08, 2008 9:39 am    Post subject: Reply with quote  Mark this post and the followings unread

I'm not that good in this kind of physics-mathematics theory..
so here I come:

If it's hard to generate pink noise directly,
is it easier to come up with a physical model to simulate the behavior of a pink noise?
(that maybe later used as a filter or by any other kind of triggering methods)
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Frostburn



Joined: Dec 12, 2007
Posts: 255
Location: Finland
Audio files: 9

PostPosted: Sat Mar 08, 2008 11:01 am    Post subject: Reply with quote  Mark this post and the followings unread

kijjaz wrote:
If it's hard to generate pink noise directly,
is it easier to come up with a physical model to simulate the behavior of a pink noise?

The physical theory of pink noise suggests that it is produced by a great number of oscillators. Energy of an oscillator is inversely porportional to the square of it's "size" but if these oscillators are distributed naturally so that there are a lot of tiny ones compared to the big oscillators it turns out that the energy on a given frequency band is then only inversely porportional to the frequency of that band. And because there are so many of oscillators, no individual vibration can be heard from the cacophony => 1/f noise.

So the model would be tens of thousands of SinOscs arranged naturally by frequency and amplitude.
More accurate model would be a physical simulation that takes virtual sound producing balls and puts them in to big virtual bucket. Shake things around until equilibrium is reached and render the sound.

So in conclusion:
Code:
SinOsc oscillator[10000] > pink_filter_of_order_100;

The answer is no.

Sorry, simulating statistical physics with accurate physical models is often infeasible.
And if you drop the physical accuracy of the model it's better to think it only as a mathematical model.

_________________
To boldly go where no man has bothered to go before.
Back to top
View user's profile Send private message
Frostburn



Joined: Dec 12, 2007
Posts: 255
Location: Finland
Audio files: 9

PostPosted: Sat Mar 08, 2008 4:40 pm    Post subject: Reply with quote  Mark this post and the followings unread

Well that model of multiple oscillators got me thinking...
...IFFT can be seen as the big collection of sinusoid oscillators. The problem is that to get true pink noise out from an IFFT it's size needs to the same as the length of the resulting audio sample. So I take the same detour as I did in the previous post; First generate blue noise and then integrate it. This creates the pink random walk that is more gentle than the brownian motion you get from integrated white noise.
Code:
IFFT ifft => OnePole integrator => dac;
-1.0 => integrator.a1;
samp/second => integrator.b0;

256 => ifft.size;
Windowing.hamming(ifft.size()) => ifft.window;
0.25 => float hopSize;
2.0*hopSize => ifft.gain;
dur hop;
complex s[ifft.size()/2];

while(true){
        for(1.0 => float h; h < s.cap(); 1.0 +=> h){
                 ( %(  /*blue*/ Math.pow(h,0.5) /*blue*/    *10.0  ,pi*Std.randf() )$complex ) => s[h$int];
        }
        ifft.transform( s );
        hopSize*ifft.size()::samp => hop;
        hop => now;
}


If you remove the OnePole integrator and replace the /*blue*/ part with Math.pow(h,-0.5) you'll get DC blocked pink noise straight out of the IFFT.

_________________
To boldly go where no man has bothered to go before.
Back to top
View user's profile Send private message
kijjaz



Joined: Sep 20, 2004
Posts: 765
Location: bangkok, thailand
Audio files: 4

PostPosted: Sun Mar 09, 2008 6:04 am    Post subject: Reply with quote  Mark this post and the followings unread

Wow.. this is mathemagical!
I think about statistics and simulation now, ..
can we kinda ... generate pseudo-random numbers but with some characteristic in the movement of the data that would be close to Pink Noise?

I'm not a very math guy, just curious hahahha...
Thanks, Frostburn. this thread is inspiring.
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Frostburn



Joined: Dec 12, 2007
Posts: 255
Location: Finland
Audio files: 9

PostPosted: Sun Mar 09, 2008 6:52 am    Post subject: Reply with quote  Mark this post and the followings unread

kijjaz wrote:
can we kinda ... generate pseudo-random numbers but with some characteristic in the movement of the data that would be close to Pink Noise?


Well you can chuck the pink noise generating IFFT-OnePole patch in to a blackhole and just use integrator.last() to get random numbers with pink movement.
If you mean a random number generator that could be used like Std.randf() then the half derivating FIR filter that I posted can be turned in to a class that doesn't need to be ticked by a blackhole. All you need is a float array to hold concecutive (white) random numbers. A blue convolution table and one float to hold the previous value generated so that the blue noise can be integrated.
Another method involves adding together the output of many random number generators that run at different frequencies and are scaled accordingly.

_________________
To boldly go where no man has bothered to go before.
Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Sun Mar 09, 2008 10:58 am    Post subject: Reply with quote  Mark this post and the followings unread

Frostburn wrote:

Well you can chuck the pink noise generating IFFT-OnePole patch in to a blackhole and just use integrator.last() to get random numbers with pink movement.


Are you sure about this? Say that instead of that construction I'd use a saw wave's .last() yet poll it at random moment. There it's clear the distribution of the numbers will depend entirely on the timing of my calls, right? I'm not sure the method you propose here can be guaranteed to have any kind of distribution if you don't say anything about the timing of the calls.

Another option would be to use LiSa as a FIR filter by having her start a voice at every sample with the amplitude of Noise's last sample. Assuming we could get a impulse responce of a pinking filter that should create perfect pink noise though the price is obviously a rather high CPU cost.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Frostburn



Joined: Dec 12, 2007
Posts: 255
Location: Finland
Audio files: 9

PostPosted: Sun Mar 09, 2008 11:44 am    Post subject: Reply with quote  Mark this post and the followings unread

Kassen wrote:
Are you sure about this? Say that instead of that construction I'd use a saw wave's .last() yet poll it at random moment. There it's clear the distribution of the numbers will depend entirely on the timing of my calls, right? I'm not sure the method you propose here can be guaranteed to have any kind of distribution if you don't say anything about the timing of the calls.

You're right Kassen, I should have been more clear on how to use the ifft. Naturally if you don't use all the data you get from the ifft and use it in that order you won't get a pink distribution.
So the ifft doesn't make for a very flexible RNG because you have to buffer everything you're going to need later. And if you need a lot of pink random numbers at the beginning of your song you're at a loss.

_________________
To boldly go where no man has bothered to go before.
Back to top
View user's profile Send private message
Frostburn



Joined: Dec 12, 2007
Posts: 255
Location: Finland
Audio files: 9

PostPosted: Sun Mar 09, 2008 12:30 pm    Post subject: Reply with quote  Mark this post and the followings unread

Code:
class ColorRNG {
        16 => int order; //Quality of the fractional derivate approximation
        float coeff[]; //Binomial coefficients
        float buffer[]; //Buffer for the FIR filter that does the fractional derivation
       
        0.5 => float color; //0.0 = brown(red), 1.0 = white, defaults to pink = 0.5
       
        0.0 => float last; //The last number generated, needed for integration
        0.05 => float stepSize; //Integration step size
       
        //Generate the next random number
        fun float next(){
                0.0 => float val;
                for(0 => int i; i < order; i++){
                        buffer[i]*coeff[order-1-i] +=> val; //Convolve the FIR's impulse response with the buffer to get the fractional derivate
                        if( i < order-1)  buffer[i+1] => buffer[i];
                        else Std.randf() => buffer[i]; //add a new sample
                }
                return val*stepSize +=> last;
        }
       
        //Use this to change the color parameter
        fun float setColor(float value){
                value => color;
                update_fir();
        }
       
        //Remember to initialize the instance before using it
        fun void init(){ init(order); }
        fun void init(int _order){
                _order => order;
                new float[order] @=> coeff;
                new float[order] @=> buffer;
                for(0 => int i; i < buffer.cap(); i++) Std.randf() => buffer[i]; //Fill her up with noise
                update_fir();
        }
       
        //Generate the taylor series coefficients of (a+x)^n
        fun void binomial_series(float a,float n,float coeff[]){
            Math.pow(a,n) => float c;
            for(0 => int i; i < coeff.cap(); i++){
                c => coeff[i];
                (n-i$float)/(i$float+1.0)/a *=> c;
            }
        }
       
        fun void update_fir(){
                //Get the taylor series of Math.pow(1 + x,color)
                binomial_series(1.0,color,coeff);
                //Reverse odd coefficients to get the series for Math.pow(1 - x,color)
                for(1 => int i; i < coeff.cap(); i + 2 => i) -coeff[i] => coeff[i];
        }
}

ColorRNG randy;
randy.init(128); //Initialize and set the internal filter to have an order of 128
1.0 => randy.stepSize; //Spice things up a bit
0.5 => randy.setColor; //Pink

//Print out some random numbers with pink distribution
for(0 => int i; i < 10; i++) <<<randy.next()>>>; //Well ok you cannot actually tell from only 10 samples of noise.

_________________
To boldly go where no man has bothered to go before.
Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Sun Mar 09, 2008 3:30 pm    Post subject: Reply with quote  Mark this post and the followings unread

Another aspect is that with IFFT you would need to randomise the phase or the resulting values will be deterministic (like "pink" without "noise" :¬) ).

I think, BTW, that "pink" is a property of noise in therms of frequency. If you you are more interested in a series of random numbers the stochastic distribution they have will probably be more relevant. There's a good article in the Csound book on creating series of random numbers with various kinds of distributions. I could look it up for you later if you have specific interests?

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Frostburn



Joined: Dec 12, 2007
Posts: 255
Location: Finland
Audio files: 9

PostPosted: Mon Mar 10, 2008 12:18 am    Post subject: Reply with quote  Mark this post and the followings unread

Kassen wrote:
Another aspect is that with IFFT you would need to randomise the phase or the resulting values will be deterministic (like "pink" without "noise" :¬) ).

Yes the phase randomization is a must but it'll still be deterministic because all random number generators in home computers are pseudo random, they're just seeded with a value from the system clock or something so that you don't always get the same sequence.
You'd need one of those fancy quantum random number generators to get truly random sequences.
Or you could just plug some electronic device to the microphone port and record the noise it produces, it usually has a pink distribution.

EDIT:
Kassen wrote:
I think, BTW, that "pink" is a property of noise in therms of frequency. If you you are more interested in a series of random numbers the stochastic distribution they have will probably be more relevant. There's a good article in the Csound book on creating series of random numbers with various kinds of distributions. I could look it up for you later if you have specific interests?


You're right. The color of the noise has to do with scale, both time and spatial scale. Or to put it in another way, frequency and the weight of those frequencies.
To preserve the color of the sequence you need to use the random values in the specific order they were generated.
I used the term "distribution" in the wrong place in my code comments. It has to do with how the individual values relate to each other without respect to generation order.
A random sequence can have pretty much any distribution and still be white in the spectrum. I'm not sure if it's generally true but I think that distribution and color are pretty much independant properties of random sequences.

_________________
To boldly go where no man has bothered to go before.
Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Mon Mar 10, 2008 5:01 pm    Post subject: Reply with quote  Mark this post and the followings unread

Frostburn wrote:
I'm not sure if it's generally true but I think that distribution and color are pretty much independant properties of random sequences.


I was just wondering about that as well. Wouldn't like to have to deliver proof on this as that's well out of my range :¬)

I do suspect you can say that for two successive samples the delta will tend to be higher in white then in pink noise but beyond that.... Hard stuff.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
wppk



Joined: Jan 25, 2008
Posts: 31
Location: Los Angeles

PostPosted: Wed Mar 12, 2008 1:29 pm    Post subject: Make use of that Pink noise. Reply with quote  Mark this post and the followings unread

Here's a simple Binaural Beat generator to throw under your Pink Noise.
Entrain your Brain. Very Happy

Code:
fun void beatgen( float base, float beat, float gain, int minutes){
   
 beat/2 => float half;
 base + half => float freq1;
 base - half => float freq2;
 SinOsc s1 => dac.left;
 SinOsc s2 => dac.right;
 freq1 => s1.freq;
 freq2 => s2.freq; 
 
 minutes::minute => now;
 
}
Back to top
View user's profile Send private message
Frostburn



Joined: Dec 12, 2007
Posts: 255
Location: Finland
Audio files: 9

PostPosted: Wed Mar 12, 2008 1:38 pm    Post subject: Reply with quote  Mark this post and the followings unread

Ahh the good old binaural beats. Smile
I used to play with them couple of years ago, fun things.
Hmm... I just figured out how to do free (enharmonic) additive synthesis with IFFT. Maybe it could be used to enhance the entrainment... well at least get the same effect with more expressive instruments than just sine beeps.

EDIT: And the verdict is: It works!
Replacing sinewave partials with binaural beating sinewave partials creates a perceivable binaural beat while keeping the waveform intact on both channels.
It even works through melodies with a sawtooth wave. Time to go all binaural on the brain.

_________________
To boldly go where no man has bothered to go before.
Back to top
View user's profile Send private message
Frostburn



Joined: Dec 12, 2007
Posts: 255
Location: Finland
Audio files: 9

PostPosted: Sun Mar 16, 2008 1:42 am    Post subject: Reply with quote  Mark this post and the followings unread

Why use pink noise only as a background for binaural sinewaves when you can make the noise itself do the beating.

The following piece of code sounds quite nauseating because it messes with the sense of sound localisation.
I take no responsibility for any damages it may cause.
Use at your own risk!

Code:
//Binaural beating pink noise
//Use at your own risk. The author takes no responsibility of it's effects.

//----Choose your beating frequency-----
16.0 => float binauralBeat;
//--------------------------------------

IFFT ifft[2];
ifft[0] => dac.left;
ifft[1] => dac.right;

256 => ifft[0].size => ifft[1].size;
4 => int overlap;
Windowing.triangle(2*ifft[0].size()/overlap) => ifft[0].window => ifft[1].window;
complex s[2][ifft[0].size()/2];
dur hop;

polar tmp;
0.0 => float binauralPhase;
while(true){
        for(1.0 => float h; h < s[0].cap(); 1.0 +=> h){
                 %(  Math.pow(h,-0.5)  ,pi*Std.randf() ) => tmp; //This is the pink part
                 ( tmp * %(0.05,-binauralPhase)  )$complex => s[0][h$int]; //Shift the left channel-
                 ( tmp * %(0.05,binauralPhase)  )$complex => s[1][h$int]; //-and the right channel in phase. (also scale them by 0.05)
        }
        ifft[0].transform( s[0] );
        ifft[1].transform( s[1] );
        (ifft[0].size()/overlap)::samp => hop;
        binauralBeat*pi*hop/second +=> binauralPhase; //Accumulate the phase shift
        hop => now;
}

_________________
To boldly go where no man has bothered to go before.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [17 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
 Forum index » DIY Hardware and Software » ChucK programming language
Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum
e-m mkii

Please support our site. If you click through and buy from
our affiliate partners, we earn a small commission.


Forum with support of Syndicator RSS
Powered by phpBB © 2001, 2005 phpBB Group
Copyright © 2003 through 2009 by electro-music.com - Conditions Of Use