1 /* pinknoise.h
2 
3    pink noise generating class using the Voss-McCartney algorithm, as
4    described at www.firstpr.com.au/dsp/pink-noise/
5 
6    (c) 2002 Nathaniel Virgo
7 
8    Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
9    2000-2002 Richard W.E. Furse. The author may be contacted at
10    richard@muse.demon.co.uk.
11 
12    This library is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public Licence as
14    published by the Free Software Foundation; either version 2 of the
15    Licence, or (at your option) any later version.
16 
17    This library is distributed in the hope that it will be useful, but
18    WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    General Public License for more details.
21 
22    You should have received a copy of the GNU General Public License
23    along with this library; if not, write to the Free Software
24    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25    02111-1307, USA. */
26 
27 #ifndef _PINKNOISE_H
28 #define _PINKNOISE_H
29 
30 #include <stdlib.h>
31 
32 typedef unsigned int CounterType;
33 typedef float DataValue;
34 
35 const int n_generators = 8*sizeof(CounterType);
36 
37 class PinkNoise {
38  private:
39 
40     CounterType counter;
41     DataValue * generators;
42     DataValue last_value;
43 
44  public:
45 
PinkNoise()46     PinkNoise() {
47 	generators = new DataValue[n_generators];
48 	reset();
49     }
50 
~PinkNoise()51     ~PinkNoise() {delete [] generators;};
52 
reset()53     void reset() {
54 	counter = 0;
55 	last_value = 0;
56 	for (int i=0; i<n_generators; ++i) {
57 	    generators[i] = 2*(rand()/DataValue(RAND_MAX))-1;
58 	    last_value += generators[i];
59 	}
60     }
61 
getUnscaledValue()62     inline DataValue getUnscaledValue() {
63 	if (counter != 0) {
64 	    // set index to number of trailing zeros in counter.
65 	    // hangs if counter==0, hence the slightly inefficient
66 	    // test above.
67 	    CounterType n = counter;
68 	    int index = 0;
69 	    while ( (n & 1) == 0 ) {
70 		n >>= 1;
71 		index++;
72 		// this loop means that the plugins cannot be labelled as
73 		// capable of hard real-time performance.
74 	    }
75 
76 	    last_value -= generators[index];
77 	    generators[index] = 2*(rand()/DataValue(RAND_MAX))-1;
78 	    last_value += generators[index];
79 	}
80 
81 	counter++;
82 
83 	return last_value;
84     }
85 
getValue()86     inline DataValue getValue() {
87 	return getUnscaledValue()/n_generators;
88     }
89 
getLastValue()90     inline DataValue getLastValue() {
91 	return last_value/n_generators;
92     }
93 
getValue2()94     inline DataValue getValue2() {
95 	// adding some white noise gets rid of some nulls in the frequency spectrum
96 	// but makes the signal spikier, so possibly not so good for control signals.
97 	return (getUnscaledValue() + rand()/DataValue(RAND_MAX*0.5)-1)/(n_generators+1);
98     }
99 
100 };
101 
102 #endif
103 
104 
105 
106 
107 
108 
109 
110 
111 
112