BogaudioModules

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

commit 99c3cd2e9132674bad67796ddd1433e62b40ecf4
parent 13581a5661220536052c013cd3cba150015b94bd
Author: Matt Demanett <matt@demanett.net>
Date:   Fri, 23 Feb 2018 00:10:14 -0500

Additator: only calculate paramter changes each N steps; saves lots of CPU.

Diffstat:
Msrc/Additator.cpp | 160+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/Additator.hpp | 2++
2 files changed, 85 insertions(+), 77 deletions(-)

diff --git a/src/Additator.cpp b/src/Additator.cpp @@ -3,11 +3,13 @@ void Additator::onReset() { _syncTrigger.reset(); + _steps = 0; _phase = PHASE_RESET; } void Additator::onSampleRateChange() { _oscillator.setSampleRate(engineGetSampleRate()); + _steps = 0; _phase = PHASE_RESET; } @@ -27,93 +29,97 @@ void Additator::step() { if (!outputs[AUDIO_OUTPUT].active) { return; } - - float width = clamp(params[WIDTH_PARAM].value + (maxWidth / 2.0f) * cvValue(inputs[WIDTH_INPUT]), 0.0f, maxWidth); - float oddSkew = clamp(params[ODD_SKEW_PARAM].value + cvValue(inputs[ODD_SKEW_INPUT]), -maxSkew, maxSkew); - float evenSkew = clamp(params[EVEN_SKEW_PARAM].value + cvValue(inputs[EVEN_SKEW_INPUT]), -maxSkew, maxSkew); - if ( - _width != width || - _oddSkew != oddSkew || - _evenSkew != evenSkew - ) { - _width = width; - _oddSkew = oddSkew; - _evenSkew = evenSkew; - - float multiple = 1.0f; - _oscillator.setPartialFrequencyRatio(1, multiple); - for (int i = 2, n = _oscillator.partialCount(); i <= n; ++i) { - float ii = i; - if (i % 2 == 0) { - ii += _evenSkew; - } - else { - ii += _oddSkew; + ++_steps; + if (_steps >= modulationSteps) { + _steps = 0; + + float width = clamp(params[WIDTH_PARAM].value + (maxWidth / 2.0f) * cvValue(inputs[WIDTH_INPUT]), 0.0f, maxWidth); + float oddSkew = clamp(params[ODD_SKEW_PARAM].value + cvValue(inputs[ODD_SKEW_INPUT]), -maxSkew, maxSkew); + float evenSkew = clamp(params[EVEN_SKEW_PARAM].value + cvValue(inputs[EVEN_SKEW_INPUT]), -maxSkew, maxSkew); + if ( + _width != width || + _oddSkew != oddSkew || + _evenSkew != evenSkew + ) { + _width = width; + _oddSkew = oddSkew; + _evenSkew = evenSkew; + + float multiple = 1.0f; + _oscillator.setPartialFrequencyRatio(1, multiple); + for (int i = 2, n = _oscillator.partialCount(); i <= n; ++i) { + float ii = i; + if (i % 2 == 0) { + ii += _evenSkew; + } + else { + ii += _oddSkew; + } + _oscillator.setPartialFrequencyRatio(i, powf(ii, _width)); } - _oscillator.setPartialFrequencyRatio(i, powf(ii, _width)); } - } - int partials = clamp((int)roundf(params[PARTIALS_PARAM].value * cvValue(inputs[PARTIALS_INPUT], true)), 0, maxPartials); - float amplitudeNormalization = clamp(params[GAIN_PARAM].value + ((maxAmplitudeNormalization - minAmplitudeNormalization) / 2.0f) * cvValue(inputs[GAIN_INPUT]), minAmplitudeNormalization, maxAmplitudeNormalization); - float decay = clamp(params[DECAY_PARAM].value + ((maxDecay - minDecay) / 2.0f) * cvValue(inputs[DECAY_INPUT]), minDecay, maxDecay); - float balance = clamp(params[BALANCE_PARAM].value + cvValue(inputs[BALANCE_INPUT]), -1.0f, 1.0f); - float filter = clamp(params[FILTER_PARAM].value + cvValue(inputs[FILTER_INPUT]), minFilter, maxFilter); - if ( - _partials != partials || - _amplitudeNormalization != amplitudeNormalization || - _decay != decay || - _balance != balance || - _filter != filter - ) { - int envelopes = _partials != partials ? std::max(_partials, partials) : 0; - _partials = partials; - _amplitudeNormalization = amplitudeNormalization; - _decay = decay; - _balance = balance; - _filter = filter; - - float as[maxPartials + 1]; - float total = as[1] = 1.0f; - filter = log10f(_filter) + 1.0f; - for (int i = 2, n = _oscillator.partialCount(); i <= n; ++i) { - as[i] = 0.0f; - if (i <= _partials) { - as[i] = powf(i, -_decay) * powf(_filter, i); - if (i % 2 == 0) { - if (_balance > 0.0f) { - as[i] *= 1.0f - _balance; + int partials = clamp((int)roundf(params[PARTIALS_PARAM].value * cvValue(inputs[PARTIALS_INPUT], true)), 0, maxPartials); + float amplitudeNormalization = clamp(params[GAIN_PARAM].value + ((maxAmplitudeNormalization - minAmplitudeNormalization) / 2.0f) * cvValue(inputs[GAIN_INPUT]), minAmplitudeNormalization, maxAmplitudeNormalization); + float decay = clamp(params[DECAY_PARAM].value + ((maxDecay - minDecay) / 2.0f) * cvValue(inputs[DECAY_INPUT]), minDecay, maxDecay); + float balance = clamp(params[BALANCE_PARAM].value + cvValue(inputs[BALANCE_INPUT]), -1.0f, 1.0f); + float filter = clamp(params[FILTER_PARAM].value + cvValue(inputs[FILTER_INPUT]), minFilter, maxFilter); + if ( + _partials != partials || + _amplitudeNormalization != amplitudeNormalization || + _decay != decay || + _balance != balance || + _filter != filter + ) { + int envelopes = _partials != partials ? std::max(_partials, partials) : 0; + _partials = partials; + _amplitudeNormalization = amplitudeNormalization; + _decay = decay; + _balance = balance; + _filter = filter; + + float as[maxPartials + 1]; + float total = as[1] = 1.0f; + filter = log10f(_filter) + 1.0f; + for (int i = 2, n = _oscillator.partialCount(); i <= n; ++i) { + as[i] = 0.0f; + if (i <= _partials) { + as[i] = powf(i, -_decay) * powf(_filter, i); + if (i % 2 == 0) { + if (_balance > 0.0f) { + as[i] *= 1.0f - _balance; + } } - } - else { - if (_balance < 0.0f) { - as[i] *= 1.0f + _balance; + else { + if (_balance < 0.0f) { + as[i] *= 1.0f + _balance; + } } + total += as[i]; } - total += as[i]; + } + total /= _amplitudeNormalization; + for (int i = 1, n = _oscillator.partialCount(); i <= n; ++i) { + as[i] /= total; + _oscillator.setPartialAmplitude(i, as[i], i <= envelopes); } } - total /= _amplitudeNormalization; - for (int i = 1, n = _oscillator.partialCount(); i <= n; ++i) { - as[i] /= total; - _oscillator.setPartialAmplitude(i, as[i], i <= envelopes); - } - } - float frequency = params[FREQUENCY_PARAM].value; - if (inputs[PITCH_INPUT].active) { - frequency += inputs[PITCH_INPUT].value; - } - frequency = clamp(cvToFrequency(frequency), 50.0f, 10000.0f); - _oscillator.setFrequency(frequency); + float frequency = params[FREQUENCY_PARAM].value; + if (inputs[PITCH_INPUT].active) { + frequency += inputs[PITCH_INPUT].value; + } + frequency = clamp(cvToFrequency(frequency), 50.0f, 10000.0f); + _oscillator.setFrequency(frequency); - if (_syncTrigger.process(inputs[SYNC_INPUT].value)) { - _oscillator.syncToPhase(_phase == PHASE_SINE ? 0.0f : M_PI / 2.0f); - } - Phase phase = ((int)params[PHASE_PARAM].value) == 2 ? PHASE_COSINE : PHASE_SINE; - if (_phase != phase) { - _phase = phase; - _oscillator.syncToPhase(_phase == PHASE_SINE ? 0.0f : M_PI / 2.0f); + if (_syncTrigger.process(inputs[SYNC_INPUT].value)) { + _oscillator.syncToPhase(_phase == PHASE_SINE ? 0.0f : M_PI / 2.0f); + } + Phase phase = ((int)params[PHASE_PARAM].value) == 2 ? PHASE_COSINE : PHASE_SINE; + if (_phase != phase) { + _phase = phase; + _oscillator.syncToPhase(_phase == PHASE_SINE ? 0.0f : M_PI / 2.0f); + } } outputs[AUDIO_OUTPUT].value = _oscillator.next() * 5.0; diff --git a/src/Additator.hpp b/src/Additator.hpp @@ -56,6 +56,7 @@ struct Additator : Module { PHASE_COSINE }; + const int modulationSteps = 100; const int maxPartials = 100; const float maxWidth = 2.0f; const float maxSkew = 0.99f; @@ -66,6 +67,7 @@ struct Additator : Module { const float minFilter = 0.1; const float maxFilter = 1.9; + int _steps = 0; int _partials = 0; float _width = 0.0f; float _oddSkew = 0.0f;