BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

commit 0b32da3a357f36d4a54edeb78aee3137f6c3a785
parent 95ff1b7aa05fce8c167c2af9a6fcd1b2fc6f8acf
Author: Matt Demanett <matt@fundera.com>
Date:   Fri,  1 Dec 2017 15:46:11 -0500

Fix up Noise module and make it available.

Diffstat:
Mres/Noise-src.svg | 0
Mres/Noise.svg | 0
Msrc/BogaudioModules.cpp | 2+-
Msrc/Noise.cpp | 30+++++++++++++++++++++++++++---
Msrc/dsp/base.hpp | 12+++++++++++-
Msrc/dsp/noise.hpp | 54++++++++++++++++++++++++++----------------------------
6 files changed, 65 insertions(+), 33 deletions(-)

diff --git a/res/Noise-src.svg b/res/Noise-src.svg Binary files differ. diff --git a/res/Noise.svg b/res/Noise.svg Binary files differ. diff --git a/src/BogaudioModules.cpp b/src/BogaudioModules.cpp @@ -18,5 +18,5 @@ void init(rack::Plugin *p) { p->addModel(createModel<OffsetWidget>("Bogaudio", "Bogaudio-Offset", "Offset", ATTENUATOR_TAG, UTILITY_TAG)); p->addModel(createModel<SampleHoldWidget>("Bogaudio", "Bogaudio-SampleHold", "S&H", SAMPLE_AND_HOLD_TAG, DUAL_TAG, UTILITY_TAG)); p->addModel(createModel<ManualWidget>("Bogaudio", "Bogaudio-Manual", "Manual", UTILITY_TAG)); - // p->addModel(createModel<NoiseWidget>("Bogaudio", "Bogaudio-Noise", "Noise", NOISE_TAG, UTILITY_TAG)); + p->addModel(createModel<NoiseWidget>("Bogaudio", "Bogaudio-Noise", "Noise", NOISE_TAG, UTILITY_TAG)); } diff --git a/src/Noise.cpp b/src/Noise.cpp @@ -8,13 +8,16 @@ struct Noise : Module { }; enum InputsIds { + ABS_INPUT, NUM_INPUTS }; enum OutputsIds { WHITE_OUTPUT, PINK_OUTPUT, + RED_OUTPUT, GAUSS_OUTPUT, + ABS_OUTPUT, NUM_OUTPUTS }; @@ -24,6 +27,7 @@ struct Noise : Module { bogaudio::dsp::WhiteNoiseGenerator _white; bogaudio::dsp::PinkNoiseGenerator _pink; + bogaudio::dsp::RedNoiseGenerator _red; bogaudio::dsp::GaussianNoiseGenerator _gauss; Noise() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} @@ -38,9 +42,21 @@ void Noise::step() { if (outputs[PINK_OUTPUT].active) { outputs[PINK_OUTPUT].value = _pink.next() * 10.0; } + if (outputs[RED_OUTPUT].active) { + outputs[RED_OUTPUT].value = _red.next() * 10.0; + } if (outputs[GAUSS_OUTPUT].active) { outputs[GAUSS_OUTPUT].value = _gauss.next(); } + + float in = 0.0; + if (inputs[ABS_INPUT].active) { + in = inputs[ABS_INPUT].value; + if (in < 0.0) { + in = -in; + } + } + outputs[ABS_OUTPUT].value = in; } @@ -60,12 +76,20 @@ NoiseWidget::NoiseWidget() { addChild(createScrew<ScrewSilver>(Vec(box.size.x - 15, 365))); // generated by svg_widgets.rb - auto whiteOutputPosition = Vec(10.5, 34.0); - auto pinkOutputPosition = Vec(10.5, 75.0); - auto gaussOutputPosition = Vec(10.5, 144.0); + auto absInputPosition = Vec(10.5, 243.0); + + auto whiteOutputPosition = Vec(10.5, 31.0); + auto pinkOutputPosition = Vec(10.5, 72.0); + auto redOutputPosition = Vec(10.5, 113.0); + auto gaussOutputPosition = Vec(10.5, 154.0); + auto absOutputPosition = Vec(10.5, 281.0); // end generated by svg_widgets.rb + addInput(createInput<PJ301MPort>(absInputPosition, module, Noise::ABS_INPUT)); + addOutput(createOutput<PJ301MPort>(whiteOutputPosition, module, Noise::WHITE_OUTPUT)); addOutput(createOutput<PJ301MPort>(pinkOutputPosition, module, Noise::PINK_OUTPUT)); + addOutput(createOutput<PJ301MPort>(redOutputPosition, module, Noise::RED_OUTPUT)); addOutput(createOutput<PJ301MPort>(gaussOutputPosition, module, Noise::GAUSS_OUTPUT)); + addOutput(createOutput<PJ301MPort>(absOutputPosition, module, Noise::ABS_OUTPUT)); } diff --git a/src/dsp/base.hpp b/src/dsp/base.hpp @@ -3,10 +3,20 @@ namespace bogaudio { namespace dsp { struct Generator { + float _current = 0.0; + Generator() {} virtual ~Generator() {} - virtual float next() = 0; + float current() { + return _current; + } + + float next() { + return _current = _next(); + } + + virtual float _next() = 0; }; } // namespace dsp diff --git a/src/dsp/noise.hpp b/src/dsp/noise.hpp @@ -2,53 +2,51 @@ namespace bogaudio { namespace dsp { -struct NoiseGenerator : Generator { - NoiseGenerator() {} -}; +struct NoiseGenerator : Generator {}; struct WhiteNoiseGenerator : NoiseGenerator { - WhiteNoiseGenerator() {} - - virtual float next() { - return rack::randomf(); + const uint32_t _mask = -1; + const float _randMax = powf(2.0, 31) - 1; + int _last = 0; // rack::randomu32(); + + virtual float _next() { + // don't use this for cryptography. + _last = ((_last * 1103515245) + 12345) & _mask; + return _last / _randMax; } }; -struct PinkNoiseGenerator : NoiseGenerator { +template<typename G> +struct BasePinkNoiseGenerator : NoiseGenerator { static const int _n = 7; - uint64_t _g; - uint64_t _gs[_n]; - uint32_t _count; - uint64_t _sum; - - PinkNoiseGenerator() { - _sum = _g = rack::randomu64(); - for (int i = 0; i < _n; ++i) { - _sum += _gs[i] = rack::randomu64(); - } - _count = rack::randomu32(); - } + G _g; + G _gs[_n]; + uint32_t _count = rack::randomu32(); - virtual float next() { + virtual float _next() { // See: http://www.firstpr.com.au/dsp/pink-noise/ - _sum -= _g; - _sum += _g = rack::randomu64(); + float sum = _g.next(); for (int i = 0, bit = 1; i < _n; ++i, bit <<= 1) { if (_count & bit) { - _sum -= _gs[i]; - _sum += _gs[i] = rack::randomu64(); - break; + sum += _gs[i].next(); + } + else { + sum += _gs[i].current(); } } ++_count; - return (_sum >> (64 - 24)) / powf(2, 24); + return sum / (float)(_n + 1); } }; +struct PinkNoiseGenerator : BasePinkNoiseGenerator<WhiteNoiseGenerator> {}; + +struct RedNoiseGenerator : BasePinkNoiseGenerator<PinkNoiseGenerator> {}; + struct GaussianNoiseGenerator : NoiseGenerator { GaussianNoiseGenerator() {} - virtual float next() { + virtual float _next() { return rack::randomNormal(); } };