#pragma once #include #include "base.hpp" namespace frozenwasteland { namespace dsp { class Seeds { private: std::mt19937 _generator; Seeds(); unsigned int _next(); public: Seeds(const Seeds&) = delete; void operator=(const Seeds&) = delete; static Seeds& getInstance(); static unsigned int next(); }; struct NoiseGenerator : Generator { std::minstd_rand _generator; // one of the faster options. NoiseGenerator() : _generator(Seeds::next()) {} }; struct WhiteNoiseGenerator : NoiseGenerator { std::uniform_real_distribution _uniform; WhiteNoiseGenerator() : _uniform(-1.0, 1.0) {} virtual float _next() override { return _uniform(_generator); } }; template struct BasePinkNoiseGenerator : NoiseGenerator { static const int _n = 7; G _g; G _gs[_n]; uint32_t _count = _g.next(); virtual float _next() override { // See: http://www.firstpr.com.au/dsp/pink-noise/ float sum = _g.next(); for (int i = 0, bit = 1; i < _n; ++i, bit <<= 1) { if (_count & bit) { sum += _gs[i].next(); } else { sum += _gs[i].current(); } } ++_count; return sum / (float)(_n + 1); } }; struct PinkNoiseGenerator : BasePinkNoiseGenerator {}; struct RedNoiseGenerator : BasePinkNoiseGenerator {}; struct GaussianNoiseGenerator : NoiseGenerator { std::normal_distribution _normal; GaussianNoiseGenerator() : _normal(0, 1.0) {} virtual float _next() override { return _normal(_generator); } }; } // namespace dsp } // namespace frozenwasteland