BogaudioModules

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

commit 13581a5661220536052c013cd3cba150015b94bd
parent 69c0033c128595e60d5cd81206ce9d41ebec2183
Author: Matt Demanett <matt@demanett.net>
Date:   Thu, 22 Feb 2018 23:49:15 -0500

Additator: fix pops on modulate partial count; change partial count expected CV to 0-10v.

Diffstat:
Msrc/Additator.cpp | 12++++++++----
Msrc/Additator.hpp | 2+-
Msrc/dsp/oscillator.cpp | 28+++++++++++++++++++++++++---
Msrc/dsp/oscillator.hpp | 10+++++++++-
4 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/src/Additator.cpp b/src/Additator.cpp @@ -11,9 +11,12 @@ void Additator::onSampleRateChange() { _phase = PHASE_RESET; } -float Additator::cvValue(Input& cv) { +float Additator::cvValue(Input& cv, bool dc) { if (!cv.active) { - return 0.0f; + return dc ? 1.0f : 0.0f; + } + if (dc) { + return clamp(cv.value / 10.0f, 0.0f, 1.0f); } return clamp(cv.value / 5.0f, -1.0f, 1.0f); } @@ -51,7 +54,7 @@ void Additator::step() { } } - int partials = clamp((int)roundf(params[PARTIALS_PARAM].value + (maxPartials / 2.0f) * cvValue(inputs[PARTIALS_INPUT])), 0, maxPartials); + 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); @@ -63,6 +66,7 @@ void Additator::step() { _balance != balance || _filter != filter ) { + int envelopes = _partials != partials ? std::max(_partials, partials) : 0; _partials = partials; _amplitudeNormalization = amplitudeNormalization; _decay = decay; @@ -92,7 +96,7 @@ void Additator::step() { total /= _amplitudeNormalization; for (int i = 1, n = _oscillator.partialCount(); i <= n; ++i) { as[i] /= total; - _oscillator.setPartialAmplitude(i, as[i]); + _oscillator.setPartialAmplitude(i, as[i], i <= envelopes); } } diff --git a/src/Additator.hpp b/src/Additator.hpp @@ -87,7 +87,7 @@ struct Additator : Module { virtual void onReset() override; virtual void onSampleRateChange() override; - float cvValue(Input& cv); + float cvValue(Input& cv, bool dc = false); virtual void step() override; }; diff --git a/src/dsp/oscillator.cpp b/src/dsp/oscillator.cpp @@ -108,9 +108,21 @@ void SineBankOscillator::setPartialFrequencyRatio(int i, float frequencyRatio) { } } -void SineBankOscillator::setPartialAmplitude(int i, float amplitude) { +void SineBankOscillator::setPartialAmplitude(int i, float amplitude, bool envelope) { if (i <= (int)_partials.size()) { - _partials[i - 1].amplitude = amplitude; + Partial& p = _partials[i - 1]; + if (envelope) { + p.amplitudeTarget = amplitude; + p.amplitudeStepDelta = (amplitude - p.amplitude) / (float)_amplitudeEnvelopeSamples; + p.amplitudeSteps = _amplitudeEnvelopeSamples; + } + else if (p.amplitudeSteps > 0) { + p.amplitudeTarget = amplitude; + p.amplitudeStepDelta = (amplitude - p.amplitude) / (float)p.amplitudeSteps; + } + else { + p.amplitude = amplitude; + } } } @@ -122,6 +134,7 @@ void SineBankOscillator::syncToPhase(float phase) { void SineBankOscillator::_sampleRateChanged() { _maxPartialFrequency = _maxPartialFrequencySRRatio * _sampleRate; + _amplitudeEnvelopeSamples = _sampleRate * (_amplitudeEnvelopeMS / 1000.0f); for (Partial& p : _partials) { p.sine.setSampleRate(_sampleRate); } @@ -137,7 +150,16 @@ void SineBankOscillator::_frequencyChanged() { float SineBankOscillator::_next() { float next = 0.0; for (Partial& p : _partials) { - if (p.frequency < _maxPartialFrequency && (p.amplitude > 0.001 || p.amplitude < -0.001)) { + if (p.frequency < _maxPartialFrequency && (p.amplitude > 0.001 || p.amplitude < -0.001 || p.amplitudeSteps > 0)) { + if (p.amplitudeSteps > 0) { + if (p.amplitudeSteps == 1) { + p.amplitude = p.amplitudeTarget; + } + else { + p.amplitude += p.amplitudeStepDelta; + } + --p.amplitudeSteps; + } next += p.sine.next() * p.amplitude; } else { diff --git a/src/dsp/oscillator.hpp b/src/dsp/oscillator.hpp @@ -161,18 +161,26 @@ struct SineBankOscillator : OscillatorGenerator { float frequency; float frequencyRatio; float amplitude; + float amplitudeTarget; + float amplitudeStepDelta; + int amplitudeSteps; SineOscillator sine; Partial() : frequency(0.0) , frequencyRatio(0.0) , amplitude(0.0) + , amplitudeTarget(0.0) + , amplitudeStepDelta(0.0) + , amplitudeSteps(0) , sine(0.0, 0.0, 1.0) {} }; const float _maxPartialFrequencySRRatio = 0.48; float _maxPartialFrequency = 0.0; + const int _amplitudeEnvelopeMS = 10; + int _amplitudeEnvelopeSamples = 0; std::vector<Partial> _partials; SineBankOscillator( @@ -194,7 +202,7 @@ struct SineBankOscillator : OscillatorGenerator { // one-based indexes. void setPartial(int i, float frequencyRatio, float amplitude); void setPartialFrequencyRatio(int i, float frequencyRatio); - void setPartialAmplitude(int i, float amplitude); + void setPartialAmplitude(int i, float amplitude, bool envelope = false); void syncToPhase(float phase);