BogaudioModules

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

commit 6286ed9e1a5dea07608f3add8c9e32366caae2ac
parent 157290f8189a510d0e4974224995fe15a3a067c0
Author: Matt Demanett <matt@demanett.net>
Date:   Sun, 17 Jun 2018 22:51:10 -0400

Test and recalibrate slew limters.

Diffstat:
Msrc/Additator.cpp | 14+++++++-------
Msrc/FMOp.cpp | 8++++----
Msrc/FMOp.hpp | 1-
Msrc/Mix4.cpp | 2+-
Msrc/Mix8.cpp | 4++--
Msrc/Pan.cpp | 5+++--
Msrc/VCA.cpp | 4++--
Msrc/VCAmp.cpp | 3++-
Msrc/VCO.cpp | 2+-
Msrc/VCO.hpp | 1-
Msrc/XCO.cpp | 30+++++++++++++-----------------
Msrc/XCO.hpp | 5-----
Msrc/XFade.cpp | 2+-
Msrc/dsp/signal.cpp | 3++-
Msrc/dsp/signal.hpp | 7+++----
Msrc/mixer.cpp | 12+++++++-----
Msrc/mixer.hpp | 6++++--
17 files changed, 52 insertions(+), 57 deletions(-)

diff --git a/src/Additator.cpp b/src/Additator.cpp @@ -13,13 +13,13 @@ void Additator::onSampleRateChange() { _maxFrequency = 0.475f * sampleRate; _steps = modulationSteps; _phase = PHASE_RESET; - _widthSL.setParams(sampleRate, slewLimitTime);; - _oddSkewSL.setParams(sampleRate, slewLimitTime);; - _evenSkewSL.setParams(sampleRate, slewLimitTime);; - _amplitudeNormalizationSL.setParams(sampleRate, slewLimitTime);; - _decaySL.setParams(sampleRate, slewLimitTime);; - _balanceSL.setParams(sampleRate, slewLimitTime);; - _filterSL.setParams(sampleRate, slewLimitTime);; + _widthSL.setParams(sampleRate, slewLimitTime, maxWidth); + _oddSkewSL.setParams(sampleRate, slewLimitTime, 2.0f * maxSkew); + _evenSkewSL.setParams(sampleRate, slewLimitTime, 2.0f * maxSkew); + _amplitudeNormalizationSL.setParams(sampleRate, slewLimitTime, maxAmplitudeNormalization - minAmplitudeNormalization); + _decaySL.setParams(sampleRate, slewLimitTime, maxDecay - minDecay); + _balanceSL.setParams(sampleRate, slewLimitTime, 2.0f); + _filterSL.setParams(sampleRate, slewLimitTime, maxFilter - minFilter); } float Additator::cvValue(Input& cv, bool dc) { diff --git a/src/FMOp.cpp b/src/FMOp.cpp @@ -17,10 +17,10 @@ void FMOp::onSampleRateChange() { _phasor.setSampleRate(sampleRate); _decimator.setParams(sampleRate, oversample); _maxFrequency = 0.475f * sampleRate; - _feedbackSL.setParams(sampleRate, slewLimitTime); - _depthSL.setParams(sampleRate, slewLimitTime); - _levelSL.setParams(sampleRate, slewLimitTime); - _sustainSL.setParams(sampleRate, slewLimitTime / 10.0f); + _feedbackSL.setParams(sampleRate, 5.0f, 1.0f); + _depthSL.setParams(sampleRate, 5.0f, 1.0f); + _levelSL.setParams(sampleRate, 10.0f, 1.0f); + _sustainSL.setParams(sampleRate, 1.0f, 1.0f); } json_t* FMOp::toJson() { diff --git a/src/FMOp.hpp b/src/FMOp.hpp @@ -55,7 +55,6 @@ struct FMOp : Module { const float amplitude = 5.0f; const int modulationSteps = 100; static constexpr int oversample = 8; - const float slewLimitTime = 1.0f; const float oversampleMixIncrement = 0.01f; int _steps = 0; float _feedback = 0.0f; diff --git a/src/Mix4.cpp b/src/Mix4.cpp @@ -7,7 +7,7 @@ void Mix4::onSampleRateChange() { _channel2.setSampleRate(sr); _channel3.setSampleRate(sr); _channel4.setSampleRate(sr); - _slewLimiter.setParams(sr, MixerChannel::slewTimeMS); + _slewLimiter.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels); _rms.setSampleRate(sr); } diff --git a/src/Mix8.cpp b/src/Mix8.cpp @@ -11,8 +11,8 @@ void Mix8::onSampleRateChange() { _channel6.setSampleRate(sr); _channel7.setSampleRate(sr); _channel8.setSampleRate(sr); - _slewLimiter.setParams(sr, MixerChannel::slewTimeMS); - _rms.setSampleRate(sr); + _slewLimiter.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels); +_rms.setSampleRate(sr); } void Mix8::step() { diff --git a/src/Pan.cpp b/src/Pan.cpp @@ -1,9 +1,10 @@ #include "Pan.hpp" +#include "mixer.hpp" void Pan::onSampleRateChange() { - _slew1.setParams(engineGetSampleRate(), 100.0f); - _slew2.setParams(engineGetSampleRate(), 100.0f); + _slew1.setParams(engineGetSampleRate(), MixerChannel::panSlewTimeMS, 2.0f); + _slew2.setParams(engineGetSampleRate(), MixerChannel::panSlewTimeMS, 2.0f); } void Pan::step() { diff --git a/src/VCA.cpp b/src/VCA.cpp @@ -3,8 +3,8 @@ void VCA::onSampleRateChange() { float sampleRate = engineGetSampleRate(); - _levelSL1.setParams(sampleRate, 100.0f); - _levelSL2.setParams(sampleRate, 100.0f); + _levelSL1.setParams(sampleRate, 5.0f, 1.0f); + _levelSL2.setParams(sampleRate, 5.0f, 1.0f); } void VCA::step() { diff --git a/src/VCAmp.cpp b/src/VCAmp.cpp @@ -1,9 +1,10 @@ #include "VCAmp.hpp" +#include "mixer.hpp" void VCAmp::onSampleRateChange() { float sampleRate = engineGetSampleRate(); - _levelSL.setParams(sampleRate, 10.0f); + _levelSL.setParams(sampleRate, MixerChannel::levelSlewTimeMS, maxDecibels - minDecibels); _rms.setSampleRate(sampleRate); } diff --git a/src/VCO.cpp b/src/VCO.cpp @@ -140,7 +140,7 @@ void VCO::setSampleRate(float sampleRate) { _squareDecimator.setParams(sampleRate, oversample); _sawDecimator.setParams(sampleRate, oversample); _triangleDecimator.setParams(sampleRate, oversample); - _squarePulseWidthSL.setParams(sampleRate, slewLimitTime / 10.0f); + _squarePulseWidthSL.setParams(sampleRate, 0.1f, 2.0f); } void VCO::setFrequency(float frequency) { diff --git a/src/VCO.hpp b/src/VCO.hpp @@ -46,7 +46,6 @@ struct VCO : Module { const int modulationSteps = 100; const float amplitude = 5.0f; static constexpr int oversample = 8; - const float slewLimitTime = 1.0f; int _modulationStep = 0; float _oversampleThreshold = 0.0f; float _frequency = 0.0f; diff --git a/src/XCO.cpp b/src/XCO.cpp @@ -73,10 +73,10 @@ void XCO::step() { _fmDepth *= clamp(inputs[FM_DEPTH_INPUT].value / 10.0f, 0.0f, 1.0f); } - _squarePhaseOffset = _squarePhaseOffsetSL.next(phaseOffset(params[SQUARE_PHASE_PARAM], inputs[SQUARE_PHASE_INPUT])); - _sawPhaseOffset = _sawPhaseOffsetSL.next(phaseOffset(params[SAW_PHASE_PARAM], inputs[SAW_PHASE_INPUT])); - _trianglePhaseOffset = _trianglePhaseOffsetSL.next(phaseOffset(params[TRIANGLE_PHASE_PARAM], inputs[TRIANGLE_PHASE_INPUT])); - _sinePhaseOffset = _sinePhaseOffsetSL.next(phaseOffset(params[SINE_PHASE_PARAM], inputs[SINE_PHASE_INPUT])); + _squarePhaseOffset = phaseOffset(params[SQUARE_PHASE_PARAM], inputs[SQUARE_PHASE_INPUT]); + _sawPhaseOffset = phaseOffset(params[SAW_PHASE_PARAM], inputs[SAW_PHASE_INPUT]); + _trianglePhaseOffset = phaseOffset(params[TRIANGLE_PHASE_PARAM], inputs[TRIANGLE_PHASE_INPUT]); + _sinePhaseOffset = phaseOffset(params[SINE_PHASE_PARAM], inputs[SINE_PHASE_INPUT]); _squareMix = level(params[SQUARE_MIX_PARAM], inputs[SQUARE_MIX_INPUT]); _sawMix = level(params[SAW_MIX_PARAM], inputs[SAW_MIX_INPUT]); @@ -234,19 +234,15 @@ void XCO::setSampleRate(float sampleRate) { _triangleDecimator.setParams(sampleRate, oversample); _sineDecimator.setParams(sampleRate, oversample); - _fmDepthSL.setParams(sampleRate, slewLimitTime); - _squarePulseWidthSL.setParams(sampleRate, slewLimitTime / 10.0f); - _sawSaturationSL.setParams(sampleRate, slewLimitTime / 10.0f); - _triangleSampleWidthSL.setParams(sampleRate, slewLimitTime / 10.0f); - _sineFeedbackSL.setParams(sampleRate, slewLimitTime / 10.0f); - _squarePhaseOffsetSL.setParams(sampleRate, slewLimitTime / 2.0f); - _sawPhaseOffsetSL.setParams(sampleRate, slewLimitTime / 2.0f); - _trianglePhaseOffsetSL.setParams(sampleRate, slewLimitTime / 2.0f); - _sinePhaseOffsetSL.setParams(sampleRate, slewLimitTime / 2.0f); - _squareMixSL.setParams(sampleRate, slewLimitTime); - _sawMixSL.setParams(sampleRate, slewLimitTime); - _triangleMixSL.setParams(sampleRate, slewLimitTime); - _sineMixSL.setParams(sampleRate, slewLimitTime); + _fmDepthSL.setParams(sampleRate, 5.0f, 1.0f); + _squarePulseWidthSL.setParams(sampleRate, 0.1f, 2.0f); + _sawSaturationSL.setParams(sampleRate, 1.0f, 1.0f); + _triangleSampleWidthSL.setParams(sampleRate, 0.1f, 1.0f); + _sineFeedbackSL.setParams(sampleRate, 0.1f, 1.0f); + _squareMixSL.setParams(sampleRate, 5.0f, 1.0f); + _sawMixSL.setParams(sampleRate, 5.0f, 1.0f); + _triangleMixSL.setParams(sampleRate, 5.0f, 1.0f); + _sineMixSL.setParams(sampleRate, 5.0f, 1.0f); } void XCO::setFrequency(float frequency) { diff --git a/src/XCO.hpp b/src/XCO.hpp @@ -70,7 +70,6 @@ struct XCO : Module { const int modulationSteps = 100; const float amplitude = 5.0f; static constexpr int oversample = 8; - const float slewLimitTime = 1.0f; const float sineOversampleMixIncrement = 0.01f; int _modulationStep = 0; float _oversampleThreshold = 0.0f; @@ -113,10 +112,6 @@ struct XCO : Module { SlewLimiter _sawSaturationSL; SlewLimiter _triangleSampleWidthSL; SlewLimiter _sineFeedbackSL; - SlewLimiter _squarePhaseOffsetSL; - SlewLimiter _sawPhaseOffsetSL; - SlewLimiter _trianglePhaseOffsetSL; - SlewLimiter _sinePhaseOffsetSL; SlewLimiter _squareMixSL; SlewLimiter _sawMixSL; SlewLimiter _triangleMixSL; diff --git a/src/XFade.cpp b/src/XFade.cpp @@ -2,7 +2,7 @@ #include "XFade.hpp" void XFade::onSampleRateChange() { - _mixSL.setParams(engineGetSampleRate(), 100.0f); + _mixSL.setParams(engineGetSampleRate(), 10.0f, 2.0f); } void XFade::step() { diff --git a/src/dsp/signal.cpp b/src/dsp/signal.cpp @@ -177,9 +177,10 @@ void PositiveZeroCrossing::reset() { } -void SlewLimiter::setParams(float sampleRate, float milliseconds) { +void SlewLimiter::setParams(float sampleRate, float milliseconds, float range) { assert(sampleRate > 0.0f); assert(milliseconds >= 0.0f); + assert(range > 0.0f); _delta = range / ((milliseconds / 1000.0f) * sampleRate); } diff --git a/src/dsp/signal.hpp b/src/dsp/signal.hpp @@ -116,15 +116,14 @@ struct PositiveZeroCrossing { }; struct SlewLimiter { - const float range = 10.0f; float _delta; float _last = 0.0f; - SlewLimiter(float sampleRate = 1000.0f, float milliseconds = 1.0f) { - setParams(sampleRate, milliseconds); + SlewLimiter(float sampleRate = 1000.0f, float milliseconds = 1.0f, float range = 10.0f) { + setParams(sampleRate, milliseconds, range); } - void setParams(float sampleRate, float milliseconds = 1.0f); + void setParams(float sampleRate, float milliseconds = 1.0f, float range = 10.0f); float next(float sample); }; diff --git a/src/mixer.cpp b/src/mixer.cpp @@ -3,10 +3,12 @@ const float MixerChannel::maxDecibels = 6.0f; const float MixerChannel::minDecibels = Amplifier::minDecibels; -const float MixerChannel::slewTimeMS = 10.0f; +const float MixerChannel::levelSlewTimeMS = 5.0f; +const float MixerChannel::panSlewTimeMS = 10.0f; void MixerChannel::setSampleRate(float sampleRate) { - _slewLimiter.setParams(sampleRate, slewTimeMS); + _levelSL.setParams(sampleRate, levelSlewTimeMS, maxDecibels - minDecibels); + _panSL.setParams(sampleRate, panSlewTimeMS, 2.0f); _rms.setSampleRate(sampleRate); } @@ -17,7 +19,7 @@ void MixerChannel::next(bool stereo) { } if (_muteParam.value > 0.5f) { - _amplifier.setLevel(_slewLimiter.next(minDecibels)); + _amplifier.setLevel(_levelSL.next(minDecibels)); } else { float level = clamp(_levelParam.value, 0.0f, 1.0f); @@ -26,7 +28,7 @@ void MixerChannel::next(bool stereo) { } level *= maxDecibels - minDecibels; level += minDecibels; - _amplifier.setLevel(_slewLimiter.next(level)); + _amplifier.setLevel(_levelSL.next(level)); } out = _amplifier.next(_inInput.value); @@ -36,7 +38,7 @@ void MixerChannel::next(bool stereo) { if (_panInput.active) { pan *= clamp(_panInput.value / 5.0f, -1.0f, 1.0f); } - _panner.setPan(pan); + _panner.setPan(_panSL.next(pan)); _panner.next(out, left, right); } } diff --git a/src/mixer.hpp b/src/mixer.hpp @@ -10,11 +10,13 @@ namespace bogaudio { struct MixerChannel { static const float maxDecibels; static const float minDecibels; - static const float slewTimeMS; + static const float levelSlewTimeMS; + static const float panSlewTimeMS; Amplifier _amplifier; Panner _panner; - SlewLimiter _slewLimiter; + SlewLimiter _levelSL; + SlewLimiter _panSL; RootMeanSquare _rms; Param& _levelParam;