andrewm@0: #ifndef _PinkNoise_H andrewm@0: #define _PinkNoise_H andrewm@0: andrewm@0: // Technique by Larry "RidgeRat" Trammell 3/2006 andrewm@0: // http://home.earthlink.net/~ltrammell/tech/pinkalg.htm andrewm@0: // implementation and optimization by David Lowenfels andrewm@0: andrewm@0: #include andrewm@0: #include andrewm@0: #include andrewm@0: andrewm@0: #define PINK_NOISE_NUM_STAGES 3 andrewm@0: andrewm@0: class PinkNoise { andrewm@0: public: andrewm@0: PinkNoise() { andrewm@0: srand ( time(NULL) ); // initialize random generator andrewm@0: clear(); andrewm@0: } andrewm@0: andrewm@0: void clear() { andrewm@0: for( size_t i=0; i< PINK_NOISE_NUM_STAGES; i++ ) andrewm@0: state[ i ] = 0.0; andrewm@0: } andrewm@0: andrewm@0: float tick() { andrewm@0: static const float RMI2 = 2.0 / float(RAND_MAX); // + 1.0; // change for range [0,1) andrewm@0: static const float offset = A[0] + A[1] + A[2]; andrewm@0: andrewm@0: // unrolled loop andrewm@0: float temp = float( rand() ); andrewm@0: state[0] = P[0] * (state[0] - temp) + temp; andrewm@0: temp = float( rand() ); andrewm@0: state[1] = P[1] * (state[1] - temp) + temp; andrewm@0: temp = float( rand() ); andrewm@0: state[2] = P[2] * (state[2] - temp) + temp; andrewm@0: return ( A[0]*state[0] + A[1]*state[1] + A[2]*state[2] )*RMI2 - offset; andrewm@0: } andrewm@0: andrewm@0: protected: andrewm@0: float state[ PINK_NOISE_NUM_STAGES ]; andrewm@0: static const float A[ PINK_NOISE_NUM_STAGES ]; andrewm@0: static const float P[ PINK_NOISE_NUM_STAGES ]; andrewm@0: }; andrewm@0: andrewm@0: //const float PinkNoise::A[] = { 0.02109238, 0.07113478, 0.68873558 }; // rescaled by (1+P)/(1-P) andrewm@0: //const float PinkNoise::P[] = { 0.3190, 0.7756, 0.9613 }; andrewm@0: andrewm@0: #endif