BogaudioModules

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

commit bfc86042f14425e4c501129f915d2894365c571f
parent d8086cd8d9e1d527b4c3e9ee7b89c87af026fcd6
Author: Matt Demanett <matt@demanett.net>
Date:   Mon, 10 Jun 2019 00:15:24 -0400

v1: set custom param value displays where needed.

Diffstat:
Msrc/AD.hpp | 4++--
Msrc/ADSR.hpp | 6+++---
Msrc/Additator.hpp | 8++++----
Msrc/Analyzer.hpp | 2+-
Msrc/Clpr.hpp | 6+++---
Msrc/Cmp.hpp | 2+-
Msrc/DADSRH.hpp | 10+++++-----
Msrc/DADSRHPlus.hpp | 10+++++-----
Msrc/DGate.hpp | 4++--
Msrc/EightFO.cpp | 3++-
Msrc/EightFO.hpp | 3+--
Msrc/FMOp.hpp | 50+++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/LFO.cpp | 3++-
Msrc/LFO.hpp | 3+--
Msrc/LLFO.cpp | 2+-
Msrc/LLFO.hpp | 3+--
Msrc/Nsgt.hpp | 2+-
Msrc/Pressor.hpp | 6+++---
Msrc/Shaper.hpp | 8++++----
Msrc/ShaperPlus.hpp | 8++++----
Msrc/Slew.hpp | 8++++----
Msrc/VCA.cpp | 2+-
Msrc/VCA.hpp | 15++++++++++++---
Msrc/VCM.cpp | 2+-
Msrc/VCM.hpp | 21+++++++++++++++------
Msrc/VCO.cpp | 2+-
Msrc/VCO.hpp | 13+++++++++++--
Msrc/XCO.cpp | 2+-
Msrc/XCO.hpp | 13+++++++++++--
Msrc/bogaudio.hpp | 1+
Msrc/lfo_base.cpp | 24+++++++++++++++---------
Msrc/lfo_base.hpp | 11++++++++++-
32 files changed, 174 insertions(+), 83 deletions(-)

diff --git a/src/AD.hpp b/src/AD.hpp @@ -53,8 +53,8 @@ struct AD : Module { AD() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - configParam(ATTACK_PARAM, 0.0f, 1.0f, 0.12f, "attack"); - configParam(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "decay"); + configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.141421f, "Attack", "s"); + configParam<EnvelopeSegmentParamQuantity>(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "Decay", "s"); configParam(LOOP_PARAM, 0.0f, 1.0f, 0.0f, "Loop"); configParam(LINEAR_PARAM, 0.0f, 1.0f, 0.0f, "Linear"); diff --git a/src/ADSR.hpp b/src/ADSR.hpp @@ -44,10 +44,10 @@ struct ADSR : Module { ADSR() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - configParam(ATTACK_PARAM, 0.0f, 1.0f, 0.12f, "attack"); - configParam(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "decay"); + configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.141421f, "Attack", "s"); + configParam<EnvelopeSegmentParamQuantity>(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "Decay", "s"); configParam(SUSTAIN_PARAM, 0.0f, 1.0f, 1.0f, "Sustain", "%", 0.0f, 100.0f); - configParam(RELEASE_PARAM, 0.0f, 1.0f, 0.31623f, "release"); + configParam<EnvelopeSegmentParamQuantity>(RELEASE_PARAM, 0.0f, 1.0f, 0.31623f, "Release", "s"); configParam(LINEAR_PARAM, 0.0f, 1.0f, 0.0f, "Linear"); onReset(); diff --git a/src/Additator.hpp b/src/Additator.hpp @@ -96,16 +96,16 @@ struct Additator : Module { : _oscillator(1000.0f, 100.0f, maxPartials) { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - configParam(FREQUENCY_PARAM, -3.0f, 6.0f, 0.0f, "Frequency", " Hz", 2.0f, referenceFrequency); + configParam<FrequencyParamQuantity>(FREQUENCY_PARAM, -3.0f, 6.0f, 0.0f, "Frequency", " Hz"); configParam(PARTIALS_PARAM, 1.0f, Additator::maxPartials, Additator::maxPartials / 5.0f, "Partials"); configParam(FINE_PARAM, -1.0f, 1.0f, 0.0f, "Fine tune", " cents", 0.0f, 100.0f); configParam(WIDTH_PARAM, 0.0f, maxWidth, maxWidth / 2.0f, "Width", "%", 0.0f, 2.0f * (1.0f / maxWidth) * 100.0f, -100.0f); configParam(ODD_SKEW_PARAM, -maxSkew, maxSkew, 0.0f, "Odd skew", "%", 0.0f, (1.0f / maxSkew) * 100.0f); configParam(EVEN_SKEW_PARAM, -maxSkew, maxSkew, 0.0f, "Even skew", "%", 0.0f, (1.0f / maxSkew) * 100.0f); - configParam(GAIN_PARAM, minAmplitudeNormalization, maxAmplitudeNormalization, (maxAmplitudeNormalization - minAmplitudeNormalization) / 2.0 + minAmplitudeNormalization, "gain"); - configParam(DECAY_PARAM, minDecay, maxDecay, (maxDecay - minDecay) / 2.0 + minDecay, "decay"); + configParam(GAIN_PARAM, minAmplitudeNormalization, maxAmplitudeNormalization, (maxAmplitudeNormalization - minAmplitudeNormalization) / 2.0 + minAmplitudeNormalization, "Gain"); + configParam(DECAY_PARAM, minDecay, maxDecay, (maxDecay - minDecay) / 2.0 + minDecay, "Decay"); configParam(BALANCE_PARAM, -1.0f, 1.0f, 0.0f, "Balance", "%", 0.0f, 100.0f); - configParam(FILTER_PARAM, minFilter, maxFilter, (maxFilter - minFilter) / 2.0 + minFilter, "filter"); + configParam(FILTER_PARAM, minFilter, maxFilter, (maxFilter - minFilter) / 2.0 + minFilter, "Filter"); configParam(PHASE_PARAM, 1.0f, 2.0f, 1.0f, "Phase"); onReset(); diff --git a/src/Analyzer.hpp b/src/Analyzer.hpp @@ -49,7 +49,7 @@ struct Analyzer : AnalyzerBase { int _modulationStep = 0; Analyzer() : AnalyzerBase(4, NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { - configParam(RANGE2_PARAM, -1.0f, 1.0f, 0.0f, "range"); + configParam(RANGE2_PARAM, -1.0f, 1.0f, 0.0f, "Range"); configParam(SMOOTH_PARAM, 0.0f, 1.0f, 0.5f, "Smoothing", " ms", 0.0f, 500.0f); configParam(QUALITY_PARAM, 1.0f, 3.0f, 1.0f, "Analysis quality"); configParam(WINDOW_PARAM, 1.0f, 3.0f, 1.0f, "Analysis window type"); diff --git a/src/Clpr.hpp b/src/Clpr.hpp @@ -48,9 +48,9 @@ struct Clpr : Module { Clpr() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - configParam(THRESHOLD_PARAM, 0.0f, 1.0f, 0.8f, "threshold"); - configParam(OUTPUT_GAIN_PARAM, 0.0f, 1.0f, 0.0f, "output_gain"); - configParam(KNEE_PARAM, 0.0f, 1.0f, 0.0f, "knee"); + configParam(THRESHOLD_PARAM, 0.0f, 1.0f, 0.8f, "Threshold", " dB", 0.0f, 30.0f, -24.0f); + configParam(OUTPUT_GAIN_PARAM, 0.0f, 1.0f, 0.0f, "Output gain", " dB", 0.0f, 24.0f); + configParam(KNEE_PARAM, 0.0f, 1.0f, 0.0f, "Knee"); onReset(); } diff --git a/src/Cmp.hpp b/src/Cmp.hpp @@ -53,7 +53,7 @@ struct Cmp : Module { configParam(A_PARAM, -1.0f, 1.0f, 0.0f, "A", "V", 0.0f, 10.0f); configParam(B_PARAM, -1.0f, 1.0f, 0.0f, "B", "V", 0.0f, 10.0f); configParam(WINDOW_PARAM, 0.0f, 1.0f, 0.5f, "Window", "V", 0.0f, 10.0f); - configParam(LAG_PARAM, 0.0f, 1.0f, 0.1f, "lag"); + configParam<ScaledSquaringParamQuantity<1>>(LAG_PARAM, 0.0f, 1.0f, 0.1f, "Lag", "s"); configParam(OUTPUT_PARAM, 0.0f, 1.0f, 0.0f, "Output"); onReset(); diff --git a/src/DADSRH.hpp b/src/DADSRH.hpp @@ -115,12 +115,12 @@ struct DADSRH : TriggerOnLoadModule { _triggerOnLoad, _shouldTriggerOnLoad ) { - configParam(DELAY_PARAM, 0.0f, 1.0f, 0.0f, "delay"); - configParam(ATTACK_PARAM, 0.0f, 1.0f, 0.12f, "attack"); - configParam(DECAY_PARAM, 0.0f, 1.0f, 0.32f, "decay"); + configParam<EnvelopeSegmentParamQuantity>(DELAY_PARAM, 0.0f, 1.0f, 0.0f, "Delay", "s"); + configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.14142f, "Attack", "s"); + configParam<EnvelopeSegmentParamQuantity>(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "Decay", "s"); configParam(SUSTAIN_PARAM, 0.0f, 1.0f, 0.5f, "Sustain", "%", 0.0f, 100.0f); - configParam(RELEASE_PARAM, 0.0f, 1.0f, 0.32f, "release"); - configParam(HOLD_PARAM, 0.0f, 1.0f, 0.45f, "hold"); + configParam<EnvelopeSegmentParamQuantity>(RELEASE_PARAM, 0.0f, 1.0f, 0.31623f, "Release", "s"); + configParam<EnvelopeSegmentParamQuantity>(HOLD_PARAM, 0.0f, 1.0f, 0.44721f, "Hold", "s"); configParam(ATTACK_SHAPE_PARAM, 1.0f, 3.0f, 1.0f, "Attack shape"); configParam(DECAY_SHAPE_PARAM, 1.0f, 3.0f, 1.0f, "Decay shape"); configParam(RELEASE_SHAPE_PARAM, 1.0f, 3.0f, 1.0f, "Release shape"); diff --git a/src/DADSRHPlus.hpp b/src/DADSRHPlus.hpp @@ -126,12 +126,12 @@ struct DADSRHPlus : TriggerOnLoadModule { _triggerOnLoad, _shouldTriggerOnLoad ) { - configParam(DELAY_PARAM, 0.0f, 1.0f, 0.0f, "delay"); - configParam(ATTACK_PARAM, 0.0f, 1.0f, 0.12f, "attack"); - configParam(DECAY_PARAM, 0.0f, 1.0f, 0.32f, "decay"); + configParam<EnvelopeSegmentParamQuantity>(DELAY_PARAM, 0.0f, 1.0f, 0.0f, "Delay", "s"); + configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.14142f, "Attack", "s"); + configParam<EnvelopeSegmentParamQuantity>(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "Decay", "s"); configParam(SUSTAIN_PARAM, 0.0f, 1.0f, 0.5f, "Sustain", "%", 0.0f, 100.0f); - configParam(RELEASE_PARAM, 0.0f, 1.0f, 0.32f, "release"); - configParam(HOLD_PARAM, 0.0f, 1.0f, 0.45f, "hold"); + configParam<EnvelopeSegmentParamQuantity>(RELEASE_PARAM, 0.0f, 1.0f, 0.31623f, "Release", "s"); + configParam<EnvelopeSegmentParamQuantity>(HOLD_PARAM, 0.0f, 1.0f, 0.44721f, "Hold", "s"); configParam(ATTACK_SHAPE_PARAM, 1.0f, 3.0f, 1.0f, "Attack shape"); configParam(DECAY_SHAPE_PARAM, 1.0f, 3.0f, 1.0f, "Decay shape"); configParam(RELEASE_SHAPE_PARAM, 1.0f, 3.0f, 1.0f, "Release shape"); diff --git a/src/DGate.hpp b/src/DGate.hpp @@ -45,8 +45,8 @@ struct DGate : TriggerOnLoadModule { float _stageProgress; DGate() : TriggerOnLoadModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { - configParam(DELAY_PARAM, 0.0f, 1.0f, 0.0f, "delay"); - configParam(GATE_PARAM, 0.0f, 1.0f, 0.32f, "gate"); + configParam<EnvelopeSegmentParamQuantity>(DELAY_PARAM, 0.0f, 1.0f, 0.0f, "Delay", "s"); + configParam<EnvelopeSegmentParamQuantity>(GATE_PARAM, 0.0f, 1.0f, 0.31623f, "Gate", "s"); configParam(LOOP_PARAM, 0.0f, 1.0f, 1.0f, "Loop"); configParam(TRIGGER_PARAM, 0.0f, 1.0f, 0.0f, "Trigger"); diff --git a/src/EightFO.cpp b/src/EightFO.cpp @@ -24,6 +24,7 @@ void EightFO::onSampleRateChange() { void EightFO::process(const ProcessArgs& args) { lights[SLOW_LIGHT].value = _slowMode = params[SLOW_PARAM].getValue() > 0.5f; + if (!( outputs[PHASE7_OUTPUT].isConnected() || outputs[PHASE6_OUTPUT].isConnected() || @@ -41,7 +42,7 @@ void EightFO::process(const ProcessArgs& args) { if (_modulationStep >= modulationSteps) { _modulationStep = 0; - setFrequency(_slowMode, params[FREQUENCY_PARAM], inputs[PITCH_INPUT], _phasor); + setFrequency(params[FREQUENCY_PARAM], inputs[PITCH_INPUT], _phasor); _wave = (Wave)params[WAVE_PARAM].getValue(); if (_wave == SQUARE_WAVE) { diff --git a/src/EightFO.hpp b/src/EightFO.hpp @@ -76,7 +76,6 @@ struct EightFO : LFOBase { int _modulationStep = 0; Wave _wave = NO_WAVE; - bool _slowMode = false; int _sampleSteps = 1; int _sampleStep = 0; float _offset = 0.0f; @@ -117,7 +116,7 @@ struct EightFO : LFOBase { bool _phase0Active = false; EightFO() : LFOBase(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { - configParam(FREQUENCY_PARAM, -8.0, 5.0, 0.0, "frequency"); + configParam<LFOFrequencyParamQuantity>(FREQUENCY_PARAM, -8.0, 5.0, 0.0, "Frequency", " Hz"); configParam(WAVE_PARAM, 1.0, 5.0, 3.0, "Waveform"); configParam(SLOW_PARAM, 0.0, 1.0, 0.0, "Slow"); configParam(SAMPLE_PWM_PARAM, -1.0, 1.0, 0.0, "Width", "%", 0.0f, 100.0f); diff --git a/src/FMOp.hpp b/src/FMOp.hpp @@ -12,6 +12,9 @@ extern Model* modelFMOp; namespace bogaudio { +struct FMOpRatioParamQuantity; +struct FMOpLevelParamQuantity; + struct FMOp : Module { enum ParamsIds { RATIO_PARAM, @@ -84,15 +87,15 @@ struct FMOp : Module { : _envelope(true) { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - configParam(RATIO_PARAM, -1.0f, 1.0f, 0.0f, "Frequency ratio"); + configParam<FMOpRatioParamQuantity>(RATIO_PARAM, -1.0f, 1.0f, 0.0f, "Frequency ratio"); configParam(FINE_PARAM, -1.0f, 1.0f, 0.0f, "Fine tune", " cents", 0.0f, 100.0f); - configParam(ATTACK_PARAM, 0.0f, 1.0f, 0.12f, "attack"); - configParam(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "decay"); + configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.141421f, "Attack", "s"); + configParam<EnvelopeSegmentParamQuantity>(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "Decay", "s"); configParam(SUSTAIN_PARAM, 0.0f, 1.0f, 1.0f, "Sustain", "%", 0.0f, 100.0f); - configParam(RELEASE_PARAM, 0.0f, 1.0f, 0.31623f, "release"); + configParam<EnvelopeSegmentParamQuantity>(RELEASE_PARAM, 0.0f, 1.0f, 0.31623f, "Release", "s"); configParam(DEPTH_PARAM, 0.0f, 1.0f, 0.0f, "FM depth", "%", 0.0f, 100.0f); configParam(FEEDBACK_PARAM, 0.0f, 1.0f, 0.0f, "Feedback", "%", 0.0f, 100.0f); - configParam(LEVEL_PARAM, 0.0f, 1.0f, 1.0f, "level"); // FIXME: , " dB", 0.0f, -Amplifier::minDecibels, Amplifier::minDecibels); + configParam<FMOpLevelParamQuantity>(LEVEL_PARAM, 0.0f, 1.0f, 1.0f, "Level"); configParam(ENV_TO_LEVEL_PARAM, 0.0f, 1.0f, 0.0f, "Level follows envelope"); configParam(ENV_TO_FEEDBACK_PARAM, 0.0f, 1.0f, 0.0f, "Feedback follows envelope"); configParam(ENV_TO_DEPTH_PARAM, 0.0f, 1.0f, 0.0f, "FM depth follows envelope"); @@ -108,4 +111,41 @@ struct FMOp : Module { void process(const ProcessArgs& args) override; }; +struct FMOpRatioParamQuantity : ParamQuantity { + float getDisplayValue() override { + float v = getValue(); + if (!module) { + return v; + } + + if (v < 0.0f) { + return std::max(1.0f + v, 0.01f); + } + v *= 9.0f; + v += 1.0f; + return v; + } + + void setDisplayValue(float v) override { + if (!module) { + return; + } + + if (v < 1.0f) { + v = v - 1.0f; + } + else { + v -= 1.0f; + v /= 9.0f; + } + setValue(v); + } +}; + +struct FMOpLevelParamQuantity : AmpliferParamQuantity { + bool isLinear() override { + return static_cast<FMOp*>(module)->_linearLevel; + } +}; + } // namespace bogaudio diff --git a/src/LFO.cpp b/src/LFO.cpp @@ -15,6 +15,7 @@ void LFO::onSampleRateChange() { void LFO::process(const ProcessArgs& args) { lights[SLOW_LIGHT].value = _slowMode = params[SLOW_PARAM].getValue() > 0.5f; + if (!( outputs[SINE_OUTPUT].isConnected() || outputs[TRIANGLE_OUTPUT].isConnected() || @@ -29,7 +30,7 @@ void LFO::process(const ProcessArgs& args) { if (_modulationStep >= modulationSteps) { _modulationStep = 0; - setFrequency(_slowMode, params[FREQUENCY_PARAM], inputs[PITCH_INPUT], _phasor); + setFrequency(params[FREQUENCY_PARAM], inputs[PITCH_INPUT], _phasor); float pw = params[PW_PARAM].getValue(); if (inputs[PW_INPUT].isConnected()) { diff --git a/src/LFO.hpp b/src/LFO.hpp @@ -48,7 +48,6 @@ struct LFO : LFOBase { const float amplitude = 5.0f; int _modulationStep = 0; - bool _slowMode = false; int _sampleSteps = 1; int _sampleStep = 0; float _offset = 0.0f; @@ -74,7 +73,7 @@ struct LFO : LFOBase { bool _squareActive = false; LFO() : LFOBase(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { - configParam(FREQUENCY_PARAM, -8.0f, 5.0f, 0.0f, "frequency"); + configParam<LFOFrequencyParamQuantity>(FREQUENCY_PARAM, -5.0f, 8.0f, 0.0f, "Frequency", " Hz"); configParam(SLOW_PARAM, 0.0f, 1.0f, 0.0f, "Slow"); configParam(SAMPLE_PARAM, 0.0f, 1.0f, 0.0f, "Output sampling", "%", 0.0f, 100.0f); configParam(PW_PARAM, -1.0f, 1.0f, 0.0f, "Pulse width", "%", 0.0f, 100.0f*0.5f*(1.0f - 2.0f * _square.minPulseWidth), 50.0f); diff --git a/src/LLFO.cpp b/src/LLFO.cpp @@ -29,7 +29,7 @@ void LLFO::process(const ProcessArgs& args) { if (_modulationStep >= modulationSteps) { _modulationStep = 0; - setFrequency(_slowMode, params[FREQUENCY_PARAM], inputs[PITCH_INPUT], _phasor); + setFrequency(params[FREQUENCY_PARAM], inputs[PITCH_INPUT], _phasor); _invert = false; switch (wave) { diff --git a/src/LLFO.hpp b/src/LLFO.hpp @@ -54,7 +54,6 @@ struct LLFO : LFOBase { const float amplitude = 5.0f; int _modulationStep = 0; - bool _slowMode = false; float _offset = 0.0f; float _scale = 0.0f; PositiveZeroCrossing _resetTrigger; @@ -73,7 +72,7 @@ struct LLFO : LFOBase { , _invert(false) , _oscillator(&_sine) { - configParam(FREQUENCY_PARAM, -8.0f, 5.0f, 0.0f, "frequency"); + configParam<LFOFrequencyParamQuantity>(FREQUENCY_PARAM, -8.0f, 5.0f, 0.0f, "Frequency", " Hz"); configParam(WAVE_PARAM, 0.0f, 5.0f, 0.0f, "Waveform"); configParam(SLOW_PARAM, 0.0f, 1.0f, 0.0f, "Slow mode"); configParam(OFFSET_PARAM, -1.0f, 1.0f, 0.0f, "Offset", "V", 0.0f, 5.0f); diff --git a/src/Nsgt.hpp b/src/Nsgt.hpp @@ -53,7 +53,7 @@ struct Nsgt : Module { Nsgt() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); configParam(THRESHOLD_PARAM, 0.0f, 1.0f, 0.8f, "Threshold", " dB", 0.0f, 30.0f, -24.0f); - configParam(RATIO_PARAM, 0.0f, 1.0f, 0.552f, "ratio"); + configParam<DynamicsRatioParamQuantity>(RATIO_PARAM, 0.0f, 1.0f, 0.55159f, "Ratio"); configParam(KNEE_PARAM, 0.0f, 1.0f, 1.0f, "Knee"); onReset(); diff --git a/src/Pressor.hpp b/src/Pressor.hpp @@ -77,9 +77,9 @@ struct Pressor : Module { { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); configParam(THRESHOLD_PARAM, 0.0f, 1.0f, 0.8f, "Threshold", " dB", 0.0f, 30.0f, -24.0f); - configParam(RATIO_PARAM, 0.0f, 1.0f, 0.552f, "ratio"); - configParam(ATTACK_PARAM, 0.0f, 1.0f, 0.316f, "attack"); - configParam(RELEASE_PARAM, 0.0f, 1.0f, 0.316f, "release"); + configParam<DynamicsRatioParamQuantity>(RATIO_PARAM, 0.0f, 1.0f, 0.55159f, "Ratio"); + configParam<ScaledSquaringParamQuantity<500>>(ATTACK_PARAM, 0.0f, 1.0f, 0.31623f, "Attack", "ms"); + configParam<ScaledSquaringParamQuantity<2>>(RELEASE_PARAM, 0.0f, 1.0f, 0.31623f, "Release", "s"); configParam(OUTPUT_GAIN_PARAM, 0.0f, 1.0f, 0.0f, "Output gain", " dB", 0.0f, 24.0f); configParam(INPUT_GAIN_PARAM, -1.0f, 1.0f, 0.0f, "Input gain", " dB", 0.0f, 12.0f); configParam(DETECTOR_MIX_PARAM, -1.0f, 1.0f, 0.0f, "Detector mix", "%", 0.0f, 100.0f); diff --git a/src/Shaper.hpp b/src/Shaper.hpp @@ -89,10 +89,10 @@ struct Shaper : TriggerOnLoadModule { _shouldTriggerOnLoad ) { - configParam(ATTACK_PARAM, 0.0f, 1.0f, 0.12f, "attack"); - configParam(ON_PARAM, 0.0f, 1.0f, 0.32f, "on"); - configParam(DECAY_PARAM, 0.0f, 1.0f, 0.32f, "decay"); - configParam(OFF_PARAM, 0.0f, 1.0f, 0.07f, "off"); + configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.14142f, "Attack", "s"); + configParam<EnvelopeSegmentParamQuantity>(ON_PARAM, 0.0f, 1.0f, 0.31623f, "On", "s"); + configParam<EnvelopeSegmentParamQuantity>(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "Decay", "s"); + configParam<EnvelopeSegmentParamQuantity>(OFF_PARAM, 0.0f, 1.0f, 0.07071f, "Off", "s"); configParam(ENV_PARAM, 0.0f, 1.0f, 1.0f, "Env", "%", 0.0f, 100.0f); configParam(SIGNAL_PARAM, 0.0f, 1.0f, 0.1f, "Signal", "x", 10.0f); configParam(TRIGGER_PARAM, 0.0f, 1.0f, 0.0f, "Trigger"); diff --git a/src/ShaperPlus.hpp b/src/ShaperPlus.hpp @@ -96,10 +96,10 @@ struct ShaperPlus : TriggerOnLoadModule { _shouldTriggerOnLoad ) { - configParam(ATTACK_PARAM, 0.0f, 1.0f, 0.12f, "attack"); - configParam(ON_PARAM, 0.0f, 1.0f, 0.32f, "on"); - configParam(DECAY_PARAM, 0.0f, 1.0f, 0.32f, "decay"); - configParam(OFF_PARAM, 0.0f, 1.0f, 0.07f, "off"); + configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.14142f, "Attack", "s"); + configParam<EnvelopeSegmentParamQuantity>(ON_PARAM, 0.0f, 1.0f, 0.31623f, "On", "s"); + configParam<EnvelopeSegmentParamQuantity>(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "Decay", "s"); + configParam<EnvelopeSegmentParamQuantity>(OFF_PARAM, 0.0f, 1.0f, 0.07071f, "Off", "s"); configParam(ENV_PARAM, 0.0f, 1.0f, 1.0f, "Env", "%", 0.0f, 100.0f); configParam(SIGNAL_PARAM, 0.0f, 1.0f, 0.1f, "Signal", "x", 10.0f); configParam(TRIGGER_PARAM, 0.0f, 1.0f, 0.0f, "Trigger"); diff --git a/src/Slew.hpp b/src/Slew.hpp @@ -43,10 +43,10 @@ struct Slew : Module { Slew() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - configParam(RISE_PARAM, 0.0f, 1.0f, 0.316f, "rise"); - configParam(RISE_SHAPE_PARAM, -1.0f, 1.0f, 0.0f, "rise_shape"); - configParam(FALL_PARAM, 0.0f, 1.0f, 0.316f, "fall"); - configParam(FALL_SHAPE_PARAM, -1.0f, 1.0f, 0.0f, "fall_shape"); + configParam<EnvelopeSegmentParamQuantity>(RISE_PARAM, 0.0f, 1.0f, 0.31623f, "Rise", "s"); + configParam(RISE_SHAPE_PARAM, -1.0f, 1.0f, 0.0f, "Rise shape"); + configParam<EnvelopeSegmentParamQuantity>(FALL_PARAM, 0.0f, 1.0f, 0.31623f, "Fall", "s"); + configParam(FALL_SHAPE_PARAM, -1.0f, 1.0f, 0.0f, "Fall shape"); onReset(); } diff --git a/src/VCA.cpp b/src/VCA.cpp @@ -8,7 +8,7 @@ void VCA::onSampleRateChange() { } void VCA::process(const ProcessArgs& args) { - bool linear = params[LINEAR_PARAM].getValue() > 0.5f; + bool linear = isLinear(); lights[LINEAR_LIGHT].value = linear; channelStep(inputs[IN1_INPUT], outputs[OUT1_OUTPUT], params[LEVEL1_PARAM], inputs[CV1_INPUT], _amplifier1, _levelSL1, linear); channelStep(inputs[IN2_INPUT], outputs[OUT2_OUTPUT], params[LEVEL2_PARAM], inputs[CV2_INPUT], _amplifier2, _levelSL2, linear); diff --git a/src/VCA.hpp b/src/VCA.hpp @@ -9,6 +9,8 @@ extern Model* modelVCA; namespace bogaudio { +struct VCALevelParamQuantity; + struct VCA : Module { enum ParamsIds { LEVEL1_PARAM, @@ -43,16 +45,23 @@ struct VCA : Module { VCA() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - configParam(LEVEL1_PARAM, 0.0f, 1.0f, 0.8f, "level1"); - configParam(LEVEL2_PARAM, 0.0f, 1.0f, 0.8f, "level2"); - configParam(LINEAR_PARAM, 0.0f, 1.0f, 0.0f, "linear"); + configParam<VCALevelParamQuantity>(LEVEL1_PARAM, 0.0f, 1.0f, 0.8f, "Level 1"); + configParam<VCALevelParamQuantity>(LEVEL2_PARAM, 0.0f, 1.0f, 0.8f, "Level 2"); + configParam(LINEAR_PARAM, 0.0f, 1.0f, 0.0f, "Linear"); onSampleRateChange(); } + inline bool isLinear() { return params[LINEAR_PARAM].getValue() > 0.5f; } void onSampleRateChange() override; void process(const ProcessArgs& args) override; void channelStep(Input& input, Output& output, Param& knob, Input& cv, Amplifier& amplifier, bogaudio::dsp::SlewLimiter& levelSL, bool linear); }; +struct VCALevelParamQuantity : AmpliferParamQuantity { + bool isLinear() override { + return static_cast<VCA*>(module)->isLinear(); + } +}; + } // namespace bogaudio diff --git a/src/VCM.cpp b/src/VCM.cpp @@ -2,7 +2,7 @@ #include "VCM.hpp" void VCM::process(const ProcessArgs& args) { - bool linear = params[LINEAR_PARAM].getValue() > 0.5f; + bool linear = isLinear(); lights[LINEAR_LIGHT].value = linear; if (outputs[MIX_OUTPUT].isConnected()) { float out = channelStep(inputs[IN1_INPUT], params[LEVEL1_PARAM], inputs[CV1_INPUT], _amplifier1, linear); diff --git a/src/VCM.hpp b/src/VCM.hpp @@ -10,6 +10,8 @@ extern Model* modelVCM; namespace bogaudio { +struct VCMLevelParamQuantity; + struct VCM : DisableOutputLimitModule { enum ParamsIds { LEVEL1_PARAM, @@ -50,17 +52,24 @@ struct VCM : DisableOutputLimitModule { Amplifier _amplifier4; VCM() : DisableOutputLimitModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { - configParam(LEVEL1_PARAM, 0.0f, 1.0f, 0.8f, "level1"); - configParam(LEVEL2_PARAM, 0.0f, 1.0f, 0.8f, "level2"); - configParam(LEVEL3_PARAM, 0.0f, 1.0f, 0.8f, "level3"); - configParam(LEVEL4_PARAM, 0.0f, 1.0f, 0.8f, "level4"); - configParam(MIX_PARAM, 0.0f, 1.0f, 0.8f, "mix"); - configParam(LINEAR_PARAM, 0.0f, 1.0f, 0.0f, "linear"); + configParam<VCMLevelParamQuantity>(LEVEL1_PARAM, 0.0f, 1.0f, 0.8f, "Level 1"); + configParam<VCMLevelParamQuantity>(LEVEL2_PARAM, 0.0f, 1.0f, 0.8f, "Level 2"); + configParam<VCMLevelParamQuantity>(LEVEL3_PARAM, 0.0f, 1.0f, 0.8f, "Level 3"); + configParam<VCMLevelParamQuantity>(LEVEL4_PARAM, 0.0f, 1.0f, 0.8f, "Level 4"); + configParam<VCMLevelParamQuantity>(MIX_PARAM, 0.0f, 1.0f, 0.8f, "Mix level"); + configParam(LINEAR_PARAM, 0.0f, 1.0f, 0.0f, "Linear"); onReset(); } + inline bool isLinear() { return params[LINEAR_PARAM].getValue() > 0.5f; } void process(const ProcessArgs& args) override; float channelStep(Input& input, Param& knob, Input& cv, Amplifier& amplifier, bool linear); }; +struct VCMLevelParamQuantity : AmpliferParamQuantity { + bool isLinear() override { + return static_cast<VCM*>(module)->isLinear(); + } +}; + } // namespace bogaudio diff --git a/src/VCO.cpp b/src/VCO.cpp @@ -35,7 +35,7 @@ void VCO::process(const ProcessArgs& args) { _baseVOct += clamp(inputs[PITCH_INPUT].getVoltage(), -5.0f, 5.0f); } if (_slowMode) { - _baseVOct -= 7.0f; + _baseVOct += _slowModeOffset; } _baseHz = cvToFrequency(_baseVOct); diff --git a/src/VCO.hpp b/src/VCO.hpp @@ -3,7 +3,6 @@ #include "bogaudio.hpp" #include "dsp/filter.hpp" #include "dsp/oscillator.hpp" -#include "dsp/pitch.hpp" #include "dsp/signal.hpp" using namespace bogaudio::dsp; @@ -12,6 +11,8 @@ extern Model* modelVCO; namespace bogaudio { +struct VCOFrequencyParamQuantity; + struct VCO : Module { enum ParamsIds { FREQUENCY_PARAM, @@ -47,6 +48,7 @@ struct VCO : Module { const int modulationSteps = 100; const float amplitude = 5.0f; static constexpr int oversample = 8; + const float _slowModeOffset = -7.0f; int _modulationStep = 0; float _oversampleThreshold = 0.0f; float _frequency = 0.0f; @@ -72,7 +74,7 @@ struct VCO : Module { VCO() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - configParam(FREQUENCY_PARAM, -3.0f, 6.0f, 0.0f, "Frequency", " Hz", 2.0f, referenceFrequency); + configParam<VCOFrequencyParamQuantity>(FREQUENCY_PARAM, -3.0f, 6.0f, 0.0f, "Frequency", " Hz"); configParam(FINE_PARAM, -1.0f, 1.0f, 0.0f, "Fine tune", " cents", 0.0f, 100.0f); configParam(SLOW_PARAM, 0.0f, 1.0f, 0.0f, "Slow mode"); configParam(PW_PARAM, -1.0f, 1.0f, 0.0f, "Pulse width", "%", 0.0f, 100.0f*0.5f*(1.0f - 2.0f * _square.minPulseWidth), 50.0f); @@ -92,4 +94,11 @@ struct VCO : Module { void setFrequency(float frequency); }; +struct VCOFrequencyParamQuantity : FrequencyParamQuantity { + float offset() override { + VCO* vco = static_cast<VCO*>(module); + return vco->_slowMode ? vco->_slowModeOffset : 0.0f; + } +}; + } // namespace bogaudio diff --git a/src/XCO.cpp b/src/XCO.cpp @@ -36,7 +36,7 @@ void XCO::process(const ProcessArgs& args) { _baseVOct += clamp(inputs[PITCH_INPUT].getVoltage(), -5.0f, 5.0f); } if (_slowMode) { - _baseVOct -= 7.0f; + _baseVOct += _slowModeOffset; } _baseHz = cvToFrequency(_baseVOct); diff --git a/src/XCO.hpp b/src/XCO.hpp @@ -3,7 +3,6 @@ #include "bogaudio.hpp" #include "dsp/filter.hpp" #include "dsp/oscillator.hpp" -#include "dsp/pitch.hpp" #include "dsp/signal.hpp" using namespace bogaudio::dsp; @@ -12,6 +11,8 @@ extern Model* modelXCO; namespace bogaudio { +struct XCOFrequencyParamQuantity; + struct XCO : Module { enum ParamsIds { FREQUENCY_PARAM, @@ -71,6 +72,7 @@ struct XCO : Module { const int modulationSteps = 100; const float amplitude = 5.0f; static constexpr int oversample = 8; + const float _slowModeOffset = -7.0f; const float sineOversampleMixIncrement = 0.01f; int _modulationStep = 0; float _oversampleThreshold = 0.0f; @@ -120,7 +122,7 @@ struct XCO : Module { XCO() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - configParam(FREQUENCY_PARAM, -3.0f, 6.0f, 0.0f, "Frequency", " Hz", 2.0f, referenceFrequency); + configParam<XCOFrequencyParamQuantity>(FREQUENCY_PARAM, -3.0f, 6.0f, 0.0f, "Frequency", " Hz"); configParam(FINE_PARAM, -1.0f, 1.0f, 0.0f, "Fine tune", " cents", 0.0f, 100.0f); configParam(SLOW_PARAM, 0.0f, 1.0f, 0.0f, "Slow mode"); configParam(FM_DEPTH_PARAM, 0.0f, 1.0f, 0.0f, "FM depth", "%", 0.0f, 100.0f); @@ -153,4 +155,11 @@ struct XCO : Module { void setFrequency(float frequency); }; +struct XCOFrequencyParamQuantity : FrequencyParamQuantity { + float offset() override { + XCO* xco = static_cast<XCO*>(module); + return xco->_slowMode ? xco->_slowModeOffset : 0.0f; + } +}; + } // namespace bogaudio diff --git a/src/bogaudio.hpp b/src/bogaudio.hpp @@ -9,6 +9,7 @@ #include "rack.hpp" +#include "param_quantities.hpp" #include "rack_overrides.hpp" #include "trigger_on_load.hpp" #include "widgets.hpp" diff --git a/src/lfo_base.cpp b/src/lfo_base.cpp @@ -46,20 +46,26 @@ void LFOBase::setPitchMode(PitchMode mode) { } } -void LFOBase::setFrequency(bool slow, Param& frequency, Input& pitch, Phasor& phasor) { - float f = frequency.value; - if (pitch.isConnected()) { - f += pitch.getVoltage(); - } - if (slow) { - f -= 8.0f; +float LFOBase::getPitchOffset() { + float offset = 0.0f; + if (_slowMode) { + offset -= 8.0f; } else { - f -= 4.0f; + offset -= 4.0f; } if (isCompliantPitchMode()) { - f -= 3.0f; + offset -= 3.0f; + } + return offset; +} + +void LFOBase::setFrequency(Param& frequency, Input& pitch, Phasor& phasor) { + float f = frequency.value; + if (pitch.isConnected()) { + f += pitch.getVoltage(); } + f += getPitchOffset(); f = cvToFrequency(f); if (f > 2000.0f) { diff --git a/src/lfo_base.hpp b/src/lfo_base.hpp @@ -21,6 +21,7 @@ struct LFOBase : Module { }; PitchMode _pitchMode = UNKNOWN_PITCH_MODE; + bool _slowMode = false; PitchModeListener* _pitchModeListener = NULL; LFOBase(int np, int ni, int no, int nl) { @@ -32,7 +33,15 @@ struct LFOBase : Module { bool isCompliantPitchMode() { return _pitchMode != CLASSIC_PITCH_MODE; } void setPitchMode(PitchMode mode); void setPitchModeListener(PitchModeListener* listener) { _pitchModeListener = listener; } - void setFrequency(bool slow, Param& frequency, Input& pitch, Phasor& phasor); + float getPitchOffset(); + void setFrequency(Param& frequency, Input& pitch, Phasor& phasor); +}; + +struct LFOFrequencyParamQuantity : FrequencyParamQuantity { + float offset() override { + LFOBase* lfo = static_cast<LFOBase*>(module); + return lfo->getPitchOffset(); + } }; struct PitchModeMenuItem : MenuItem {