summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2017-11-11 22:47:47 +0100
committerRobin Gareus <robin@gareus.org>2017-11-12 00:22:34 +0100
commit93e32af9f40064a2adf194e91c2398db90876aea (patch)
tree257d1a48e30507bbca49a83af1c90a6a36bfdd25
parent52aa9bf84806307f1df4a7b05aea3d93fb8abc58 (diff)
Add a noise generator (Lua DSP)
-rw-r--r--libs/ardour/ardour/dsp_filter.h28
-rw-r--r--libs/ardour/dsp_filter.cc82
-rw-r--r--libs/ardour/luabindings.cc11
3 files changed, 121 insertions, 0 deletions
diff --git a/libs/ardour/ardour/dsp_filter.h b/libs/ardour/ardour/dsp_filter.h
index f54eeac302..f3100efac5 100644
--- a/libs/ardour/ardour/dsp_filter.h
+++ b/libs/ardour/ardour/dsp_filter.h
@@ -310,5 +310,33 @@ namespace ARDOUR { namespace DSP {
fftwf_plan _fftplan;
};
+ class LIBARDOUR_API Generator {
+ public:
+ Generator ();
+
+ enum Type {
+ UniformWhiteNoise,
+ GaussianWhiteNoise,
+ PinkNoise,
+ };
+
+ void run (float *data, const uint32_t n_samples);
+ void set_type (Type t);
+
+ private:
+ uint32_t randi ();
+ float randf () { return (randi () / 1073741824.f) - 1.f; }
+ float grandf ();
+
+ Type _type;
+ uint32_t _rseed;
+ /* pink-noise */
+ float _b0, _b1, _b2, _b3, _b4, _b5, _b6;
+ /* gaussian white */
+ bool _pass;
+ float _rn;
+
+ };
+
} } /* namespace */
#endif
diff --git a/libs/ardour/dsp_filter.cc b/libs/ardour/dsp_filter.cc
index cff1128aa1..5e2cff6799 100644
--- a/libs/ardour/dsp_filter.cc
+++ b/libs/ardour/dsp_filter.cc
@@ -425,3 +425,85 @@ FFTSpectrum::power_at_bin (const uint32_t b, const float norm) const {
const float a = _fft_power[b] * norm;
return a > 1e-12 ? 10.0 * fast_log10 (a) : -INFINITY;
}
+
+Generator::Generator ()
+ : _type (UniformWhiteNoise)
+ , _rseed (1)
+{
+ set_type (UniformWhiteNoise);
+}
+
+void
+Generator::set_type (Generator::Type t) {
+ _type = t;
+ _b0 = _b1 = _b2 = _b3 = _b4 = _b5 = _b6 = 0;
+ _pass = false;
+ _rn = 0;
+}
+
+void
+Generator::run (float *data, const uint32_t n_samples)
+{
+ switch (_type) {
+ default:
+ case UniformWhiteNoise:
+ for (uint32_t i = 0; i < n_samples; ++i) {
+ data[i] = randf();
+ }
+ break;
+ case GaussianWhiteNoise:
+ for (uint32_t i = 0 ; i < n_samples; ++i) {
+ data[i] = 0.7079f * grandf();
+ }
+ break;
+ case PinkNoise:
+ for (uint32_t i = 0 ; i < n_samples; ++i) {
+ const float white = .39572f * randf ();
+ _b0 = .99886f * _b0 + white * .0555179f;
+ _b1 = .99332f * _b1 + white * .0750759f;
+ _b2 = .96900f * _b2 + white * .1538520f;
+ _b3 = .86650f * _b3 + white * .3104856f;
+ _b4 = .55000f * _b4 + white * .5329522f;
+ _b5 = -.7616f * _b5 - white * .0168980f;
+ data[i] = _b0 + _b1 + _b2 + _b3 + _b4 + _b5 + _b6 + white * 0.5362f;
+ _b6 = white * 0.115926f;
+ }
+ break;
+ }
+}
+
+inline uint32_t
+Generator::randi ()
+{
+ // 31bit Park-Miller-Carta Pseudo-Random Number Generator
+ uint32_t hi, lo;
+ lo = 16807 * (_rseed & 0xffff);
+ hi = 16807 * (_rseed >> 16);
+ lo += (hi & 0x7fff) << 16;
+ lo += hi >> 15;
+ lo = (lo & 0x7fffffff) + (lo >> 31);
+ return (_rseed = lo);
+}
+
+inline float
+Generator::grandf ()
+{
+ float x1, x2, r;
+
+ if (_pass) {
+ _pass = false;
+ return _rn;
+ }
+
+ do {
+ x1 = randf ();
+ x2 = randf ();
+ r = x1 * x1 + x2 * x2;
+ } while ((r >= 1.0f) || (r < 1e-22f));
+
+ r = sqrtf (-2.f * logf (r) / r);
+
+ _pass = true;
+ _rn = r * x2;
+ return r * x1;
+}
diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc
index 80101cd571..00e5b98884 100644
--- a/libs/ardour/luabindings.cc
+++ b/libs/ardour/luabindings.cc
@@ -2353,6 +2353,11 @@ LuaBindings::common (lua_State* L)
.addFunction ("power_at_bin", &DSP::FFTSpectrum::power_at_bin)
.addFunction ("freq_at_bin", &DSP::FFTSpectrum::freq_at_bin)
.endClass ()
+ .beginClass <DSP::Generator> ("Generator")
+ .addVoidConstructor ()
+ .addFunction ("run", &DSP::Generator::run)
+ .addFunction ("set_type", &DSP::Generator::set_type)
+ .endClass ()
/* DSP enums */
.beginNamespace ("BiquadType")
@@ -2367,6 +2372,12 @@ LuaBindings::common (lua_State* L)
.addConst ("HighShelf", ARDOUR::DSP::Biquad::HighShelf)
.endNamespace ()
+ .beginNamespace ("NoiseType")
+ .addConst ("UniformWhiteNoise", ARDOUR::DSP::Generator::UniformWhiteNoise)
+ .addConst ("GaussianWhiteNoise", ARDOUR::DSP::Generator::GaussianWhiteNoise)
+ .addConst ("PinkNoise", ARDOUR::DSP::Generator::PinkNoise)
+ .endNamespace ()
+
.beginClass <DSP::DspShm> ("DspShm")
.addConstructor<void (*) (size_t)> ()
.addFunction ("allocate", &DSP::DspShm::allocate)