OpenWareLaboratory
NoiseGenerator.h
Go to the documentation of this file.
1 #ifndef NOISE_GENERATOR_HPP
2 #define NOISE_GENERATOR_HPP
3 
4 #include <stdint.h>
5 #include "basicmaths.h"
6 #include "SignalGenerator.h"
7 
9  public:
10  /* returns white noise in the range -1 to 1 */
11  virtual float generate(){
12 #if 0 // #ifdef ARM_CORTEX
13  // todo: fixme
14  union {
15  float f;
16  uint32_t i;
17  } x;
18  x.i = arm_rand32();
19  // brutally converting u32 to float by zeroing some
20  // exponent bits in IEEE single precision float
21  // x.i &= 0xbfffffff; // mask top exponent bit to get exponent values from 2^-1 to 2^-126 (-1 to 1)
22  x.i &= 0x9fffffff; // mask top two exponent bits to get exponent values from 2^-2 to 2^-126 (-0.5 to 0.5)
23  // mantissa holds a value from 1.0 to 1.999...
24  // https://en.wikipedia.org/wiki/Single-precision_floating-point_format
25  return x.f;
26 #else
27  return randf()*2 - 1;
28 #endif
29  }
32  return new WhiteNoiseGenerator();
33  }
34  static void destroy(WhiteNoiseGenerator* osc){
35  delete osc;
36  }
37 };
38 
39 #ifdef ARM_CORTEX
40 #define CTZ(x) (__builtin_ctz(x))
41 #else
42 int inline CTZ(int num){
43  int i=0;
44  while (((num>>i)&1)==0 && i<sizeof(int)) i++;
45  return i;
46 }
47 #endif
48 
50 private:
51  enum {
52  NumPinkBins = 16,
53  NumPinkBins1 = NumPinkBins-1
54  };
55 public:
57  m_count = 1;
58  m_pink = 0;
59  for (int i=0; i<NumPinkBins; i++)
60  {
61  m_pinkStore[i] = 0.0f;
62  }
63  };
64 
65  /* returns pink noise random number in the range -0.5 to 0.5 */
66  float generate(){
67  float prevr;
68  float r;
69  unsigned long k = CTZ(m_count);
70  k = k & NumPinkBins1;
71  // get previous value of this octave
72  prevr = m_pinkStore[k];
73  while (true){
75  // store new value
76  m_pinkStore[k] = r;
77  r -= prevr;
78  // update total
79  m_pink += r;
80  if (m_pink <-4.0f || m_pink > 4.0f)
81  m_pink -= r;
82  else
83  break;
84  }
85  // update counter
86  m_count++;
87  return (WhiteNoiseGenerator::generate() + m_pink)*0.125f;
88  }
91  return new PinkNoiseGenerator();
92  }
93  static void destroy(PinkNoiseGenerator* osc){
94  delete osc;
95  }
96 private:
97  unsigned long m_count;
98  float m_pink;
99  float m_pinkStore[NumPinkBins];
100 };
101 
106 private:
107  float m_brown;
108 public:
110  m_brown = 0.0f;
111  }
112  // returns brown noise random number in the range -0.5 to 0.5
113  float generate() {
114  while (true){
115  float r = WhiteNoiseGenerator::generate();
116  m_brown += r;
117  if (m_brown<-8.0f || m_brown>8.0f)
118  m_brown -= r;
119  else
120  break;
121  }
122  return m_brown*0.0625f;
123  }
126  return new BrownNoiseGenerator();
127  }
128  static void destroy(BrownNoiseGenerator* osc){
129  delete osc;
130  }
131 };
132 
134 private:
135  FloatArray noise; // whitenoise
136  int phase;
137 public:
138  GaussianNoiseGenerator(FloatArray ns) : noise(ns), phase(0) {}
139  static void destroy(GaussianNoiseGenerator* gn){
140  FloatArray::destroy(gn->noise);
141  delete gn;
142  }
143  static GaussianNoiseGenerator* create(int size){
145  // generate white gaussian noise:
146  // from http://www.musicdsp.org/showone.php?id=168
147  /* Setup constants */
148  const static int q = 15;
149  const static float c1 = (1 << q) - 1;
150  const static float c2 = ((int)(c1 / 3)) + 1;
151  const static float c3 = 1.f / c1;
152  float max = 0;
153 
154  /* random number in range 0 - 1 not including 1 */
155  float random = 0.f;
156  for(int i = 0; i < gn->noise.getSize(); i++){
157  random = ((float)rand() / (float)RAND_MAX);
158  gn->noise[i] = (2.f * ((random * c2) + (random * c2) + (random * c2)) - 3.f * (c2 - 1.f)) * c3;
159  if(fabs(gn->noise[i]) > max)
160  max = fabs(gn->noise[i]);
161  }
162  for (int i = 0; i < gn->noise.getSize(); i++){
163  //normalize the gain of our noise
164  gn->noise[i] = gn->noise[i] / max;
165  }
166 
167  return gn;
168  }
169 
170  float generate(){
171  float sample = noise[phase];
172  phase = randf()*noise.getSize();
173  return sample;
174  }
176 };
177 
178 
179 #if 0 // ARM_CORTEX
180 class TrueNoiseGenerator : public SignalGenerator {
181 public:
182  TrueNoiseGenerator() {
183  RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG,ENABLE);
184  RNG_Cmd(ENABLE);
185  }
186  float generate(){
187  while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET);
188  uint32_t data = RNG_GetRandomNumber();
189  return data/float(UINT32_MAX);
190  }
191 };
192 #endif
193 
194 #endif /* NOISE_GENERATOR_HPP */
int CTZ(int num)
float randf()
generate a random number between 0 and 1
Definition: basicmaths.c:74
uint32_t arm_rand32()
Generate an unsigned 32bit pseudo-random number using xorshifter algorithm.
Definition: basicmaths.c:67
#define max(a, b)
Definition: basicmaths.h:41
Generator that produces Brownian noise (aka red noise)
float generate()
Produce the next consecutive sample.
static BrownNoiseGenerator * create()
static void destroy(BrownNoiseGenerator *osc)
This class contains useful methods for manipulating arrays of floats.
Definition: FloatArray.h:12
static void destroy(FloatArray array)
Destroys a FloatArray created with the create() method.
Definition: FloatArray.cpp:472
static FloatArray create(int size)
Creates a new FloatArray.
Definition: FloatArray.cpp:466
static GaussianNoiseGenerator * create(int size)
static void destroy(GaussianNoiseGenerator *gn)
float generate()
Produce the next consecutive sample.
GaussianNoiseGenerator(FloatArray ns)
static void destroy(PinkNoiseGenerator *osc)
static PinkNoiseGenerator * create()
float generate()
Produce the next consecutive sample.
Base class for signal generators such as Oscillators.
virtual float generate()
Produce the next consecutive sample.
size_t getSize() const
Definition: SimpleArray.h:31
static void destroy(WhiteNoiseGenerator *osc)
static WhiteNoiseGenerator * create()
virtual float generate()
Produce the next consecutive sample.