CSL  6.0
Noise.cpp
Go to the documentation of this file.
1 //
2 // Noise.cpp
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5 
6 #include "Noise.h"
7 #include <time.h>
8 
9 using namespace csl;
10 
11 ///
12 /// Abstract Noise class
13 ///
14 
15 /// Constructors call UnitGenerator & Scalable constructors
16 /// Noise defaults to expansion copy policy (i.e. distinct noise per channel)
17 /// if no seed is specified, current clock time is used
18 
20  UnitGenerator(),
21  Scalable(1.f, 0.f),
22  //mCopyPolicy(kExpand),
23  mSeed(time(NULL)),
24  mDivisor(1.0f / (float) 0x7fffffff) {
26 }
27 
28 Noise::Noise(double ampl, double offset) :
29  UnitGenerator(),
30  Scalable((float)ampl, (float)offset),
31  //mCopyPolicy(kExpand),
32  mSeed(time(NULL)),
33  mDivisor(1.0f / (float) 0x7fffffff) {
35 }
36 
37 Noise::Noise(int seed, double ampl, double offset) :
38  UnitGenerator(),
39  Scalable((float)ampl, (float)offset),
40  //mCopyPolicy(kExpand),
41  mSeed(seed),
42  mDivisor(1.0f / (float) 0x7fffffff) {
44 }
45 
46 void Noise::dump() {
47  logMsg("a Noise generator");
50 }
51 
52 ///
53 /// White noise -- equal power per frequency
54 ///
55 
56 void WhiteNoise::nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException) {
57  sample* out = outputBuffer.buffer(outBufNum); // get ptr to output channel
58  unsigned numFrames = outputBuffer.mNumFrames; // get buffer length
59 
60  DECLARE_SCALABLE_CONTROLS; // declare the scale/offset buffers and values
62 #ifdef CSL_DEBUG
63  logMsg("WhiteNoise nextBuffer");
64 #endif
65  for (unsigned i = 0; i < numFrames; i++) { // sample loop
66  // call generate_random_number and do the division myself
67  *out++ = ((((float) generateRandomNumber()) * mDivisor) * scaleValue) + offsetValue;
68  UPDATE_SCALABLE_CONTROLS; // update the dynamic scale/offset
69  }
70 }
71 
72 /// Most of this code was taken from an public domain C implementation written by Phil Burk.
73 /// The code and the webpage explaining it is at
74 /// http://www.firstpr.com.au/dsp/pink-noise/phil_burk_19990905mPatestmPink.c
75 /// and
76 /// http://www.firstpr.com.au/dsp/pink-noise/
77 
80  initialize(32);
81 }
82 
83 PinkNoise::PinkNoise(double ampl, double offset) : Noise(ampl, offset) {
85  initialize(32);
86 }
87 
88 PinkNoise::PinkNoise(int seed, double ampl, double offset) : Noise(seed, ampl, offset) {
90  initialize(32);
91 }
92 
93 /// Setup PinkNoise structure for N rows of generators.
94 void PinkNoise::initialize(int numRows) {
95  int i;
96  int pmax;
97  mPinkIndex = 0;
98  mPinkIndexMask = (1<<numRows) - 1;
99  // Calculate maximum possible signed random value. Extra 1 for white noise always added.
100  pmax = (numRows + 1) * (1<<(PINK_RANDOM_BITS-1));
101  mPinkScalar = 1.0f / pmax;
102  // Initialize rows.
103  for (i=0; i<numRows; i++ ) mPinkRows[i] = 0;
104  mPinkRunningSum = 0;
105 }
106 
107 // Generate Pink noise values between -1.0 and +1.0
109  int newRandom;
110  int sum;
111  sample output;
112  // Increment and mask index.
114  // If index is zero, don't update any random values.
115  if (mPinkIndex != 0 ) {
116  // Determine how many trailing zeros in PinkIndex.
117  // This algorithm will hang if n==0 so test first.
118  int numZeros = 0;
119  int n = mPinkIndex;
120  while((n & 1) == 0 ) {
121  n = n >> 1;
122  numZeros++;
123  }
124  // Replace the indexed ROWS random value.
125  // Subtract and add back to RunningSum instead of adding all the random values together. Only one changes each time.
126  mPinkRunningSum -= mPinkRows[numZeros];
127  newRandom = ((int)generateRandomNumber()) >> PINK_RANDOM_SHIFT;
128  mPinkRunningSum += newRandom;
129  mPinkRows[numZeros] = newRandom;
130  }
131  // Add extra white noise value.
132  newRandom = ((int)generateRandomNumber()) >> PINK_RANDOM_SHIFT;
133  sum = mPinkRunningSum + newRandom;
134  // Scale to range of -1.0 to 0.9999.
135  output = mPinkScalar * sum;
136 //#define PINK_MEASURE
137 #ifdef PINK_MEASURE
138  // Check Min/Max
139  static float pinkMax = 0, pinkMin = 0;
140  if (output > pinkMax ) pinkMax = output;
141  else if (output < pinkMin ) pinkMin = output;
142 // printf("max: %g\t min: %g", pinkMax, pinkMin);
143 #endif
144  return output;
145 }
146 
147 void PinkNoise::nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException) {
148  SampleBuffer out = outputBuffer.buffer(outBufNum);
149  unsigned numFrames = outputBuffer.mNumFrames;
150 
151  DECLARE_SCALABLE_CONTROLS; // declare the scale/offset buffers and values as above
152 #ifdef CSL_DEBUG
153  logMsg("SineAsScaled nextBuffer");
154 #endif
156  for (unsigned i = 0; i < numFrames; i++ ) {
157  *out++ = (nextPink() * scaleValue) + offsetValue; // get a sample
159  }
160 }
161 
sample * SampleBuffer
1-channel buffer data type, vector of (sample)
Definition: CSL_Types.h:194
#define UPDATE_SCALABLE_CONTROLS
Definition: CSL_Core.h:444
void logMsg(const char *format,...)
These are the public logging messages.
Definition: CGestalt.cpp:292
sample nextPink()
returns the next pink noise sample
Definition: Noise.cpp:108
int mPinkIndex
Incremented each sample.
Definition: Noise.h:82
call monoNextBuffer multiple times
Definition: CSL_Core.h:212
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
int generateRandomNumber()
returns the next pseudo-random number
Definition: Noise.h:92
void initialize(int numRows)
set up PinkNoise for N rows of generators
Definition: Noise.cpp:94
Abstract Noise class - inherits from UnitGenerator & Scalable, and provides constructors and basic ps...
Definition: Noise.h:21
PinkNoise()
Constructors.
Definition: Noise.cpp:78
virtual void dump()
pretty-print the receiver
Definition: CSL_Core.cpp:693
int mPinkRunningSum
Used to optimize summing of generators.
Definition: Noise.h:81
Noise()
Constructors.
Definition: Noise.cpp:19
Scalable – mix-in class with scale and offset control inputs (may be constants or generators)...
Definition: CSL_Core.h:403
int mPinkIndexMask
Index wrapped by ANDing with this mask.
Definition: Noise.h:83
int mPinkRows[PINK_MAX_RANDOM_ROWS]
Pink noise generator rows.
Definition: Noise.h:80
float mPinkScalar
Used to scale within range of -1.0 to +1.0.
Definition: Noise.h:84
float sample
(could be changed to int, or double)
Definition: CSL_Types.h:191
#define PINK_RANDOM_SHIFT
Definition: Noise.h:13
void setCopyPolicy(BufferCopyPolicy ch)
get/set the receiver's buffer copy policy
Definition: CSL_Core.h:256
#define LOAD_SCALABLE_CONTROLS
Load the scale/offset-related values at the start.
Definition: CSL_Core.h:436
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
Definition: CSL_Core.h:106
forward declaration
Definition: CSL_Core.h:241
void dump()
Tell me more about what is happening.
Definition: Noise.cpp:46
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
Destructor.
Definition: Noise.cpp:56
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
Destructor.
Definition: Noise.cpp:147
virtual void dump()
pretty-print the receiver's input/controls map
Definition: CSL_Core.cpp:926
Base class of CSL exceptions (written upper-case). Has a string message.
#define PINK_RANDOM_BITS
Definition: Noise.h:12
#define DECLARE_SCALABLE_CONTROLS
Macros for all the Scalable UnitGenerators (note that these don't end with ";")
Definition: CSL_Core.h:429