BogaudioModules

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

commit 46bcbf6f0c30bd129aef16e77ffb164c7b592565
parent 18f1ab9da5fa91c182b319dc9ef5d25f185fc55c
Author: Matt Demanett <matt@demanett.net>
Date:   Mon,  8 Jan 2018 22:53:43 -0500

More consistent names for some source files.

Diffstat:
MMakefile | 2+-
Msrc/Analyzer.cpp | 2+-
Dsrc/BogaudioModules.cpp | 31-------------------------------
Msrc/DADSRH.cpp | 2+-
Dsrc/DADSRHCore.cpp | 264-------------------------------------------------------------------------------
Dsrc/DADSRHCore.hpp | 182-------------------------------------------------------------------------------
Msrc/DADSRHPlus.cpp | 2+-
Msrc/DGate.cpp | 2+-
Msrc/Manual.cpp | 2+-
Msrc/Noise.cpp | 2+-
Msrc/Offset.cpp | 2+-
Msrc/Reftone.cpp | 2+-
Msrc/SampleHold.cpp | 2+-
Msrc/Shaper.cpp | 2+-
Dsrc/ShaperCore.cpp | 134-------------------------------------------------------------------------------
Dsrc/ShaperCore.hpp | 138-------------------------------------------------------------------------------
Msrc/ShaperPlus.cpp | 2+-
Msrc/Switch.cpp | 2+-
Msrc/VCA.cpp | 2+-
Asrc/bogaudio.cpp | 31+++++++++++++++++++++++++++++++
Rsrc/BogaudioModules.hpp -> src/bogaudio.hpp | 0
Asrc/dadsrh_core.cpp | 264+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/dadsrh_core.hpp | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/shaper_core.cpp | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/shaper_core.hpp | 138+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
25 files changed, 763 insertions(+), 763 deletions(-)

diff --git a/Makefile b/Makefile @@ -23,7 +23,7 @@ benchmark_clean: clean: benchmark_clean distprep: - rm -f build/src/BogaudioModules.cpp* + rm -f build/src/bogaudio.cpp* SLUG=Bogaudio dist: distprep diff --git a/src/Analyzer.cpp b/src/Analyzer.cpp @@ -1,5 +1,5 @@ -#include "BogaudioModules.hpp" +#include "bogaudio.hpp" #include "dsp/dsp.hpp" using namespace bogaudio::dsp; diff --git a/src/BogaudioModules.cpp b/src/BogaudioModules.cpp @@ -1,31 +0,0 @@ -#include "BogaudioModules.hpp" - -Plugin *plugin; - -void init(rack::Plugin *p) { - plugin = p; - p->slug = "Bogaudio"; -#if defined(VERSION) - p->version = TOSTRING(VERSION); - p->website = "https://github.com/bogaudio/BogaudioModules"; - p->manual = "https://github.com/bogaudio/BogaudioModules/blob/master/README.md"; -#elif defined(REQUIRE_VERSION) -#error define VERSION=0.N.M to make dist -#endif - - p->addModel(createModel<ShaperWidget>("Bogaudio", "Bogaudio-Shaper", "Shaper", ENVELOPE_GENERATOR_TAG, AMPLIFIER_TAG)); - p->addModel(createModel<ShaperPlusWidget>("Bogaudio", "Bogaudio-ShaperPlus", "Shaper+", ENVELOPE_GENERATOR_TAG, AMPLIFIER_TAG)); - p->addModel(createModel<DADSRHWidget>("Bogaudio", "Bogaudio-DADSRH", "DADSR(H)", ENVELOPE_GENERATOR_TAG)); - p->addModel(createModel<DADSRHPlusWidget>("Bogaudio", "Bogaudio-DADSRHPlus", "DADSR(H)+", ENVELOPE_GENERATOR_TAG)); - - p->addModel(createModel<AnalyzerWidget>("Bogaudio", "Bogaudio-Analyzer", "Analyzer", VISUAL_TAG)); - - p->addModel(createModel<DGateWidget>("Bogaudio", "Bogaudio-DGate", "DGate", 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<OffsetWidget>("Bogaudio", "Bogaudio-Offset", "Offset", ATTENUATOR_TAG, UTILITY_TAG)); - p->addModel(createModel<ReftoneWidget>("Bogaudio", "Bogaudio-Reftone", "Reftone", TUNER_TAG, UTILITY_TAG)); - p->addModel(createModel<SampleHoldWidget>("Bogaudio", "Bogaudio-SampleHold", "S&H", SAMPLE_AND_HOLD_TAG, DUAL_TAG, UTILITY_TAG)); - p->addModel(createModel<SwitchWidget>("Bogaudio", "Bogaudio-Switch", "Switch", SWITCH_TAG, UTILITY_TAG)); - p->addModel(createModel<VCAWidget>("Bogaudio", "Bogaudio-VCA", "VCA", AMPLIFIER_TAG, DUAL_TAG, UTILITY_TAG)); -} diff --git a/src/DADSRH.cpp b/src/DADSRH.cpp @@ -1,5 +1,5 @@ -#include "DADSRHCore.hpp" +#include "dadsrh_core.hpp" struct DADSRH : TriggerOnLoadModule { enum ParamsIds { diff --git a/src/DADSRHCore.cpp b/src/DADSRHCore.cpp @@ -1,264 +0,0 @@ - -#include "DADSRHCore.hpp" - -void DADSRHCore::reset() { - _trigger.reset(); - _triggerOuptutPulseGen.process(10.0); - _stage = STOPPED_STAGE; - _releaseLevel = _holdProgress = _stageProgress = _envelope = 0.0; -} - -void DADSRHCore::step() { - const int SHAPE1 = 1; - const int SHAPE2 = 2; - const int SHAPE3 = 3; - const float shapeExponent = 2.0; - const float shapeInverseExponent = 0.5; - - bool slow = _speedParam.value <= 0.5; - if ( - _trigger.process(_triggerParam.value + _triggerInput.value) || - (_firstStep && _triggerOnLoad && _shouldTriggerOnLoad && _loopParam.value < 0.5 && _modeParam.value < 0.5) - ) { - if (_stage == STOPPED_STAGE || _retriggerParam.value <= 0.5) { - _stage = DELAY_STAGE; - _holdProgress = _stageProgress = _envelope = 0.0; - } - else { - switch (_stage) { - case STOPPED_STAGE: - case ATTACK_STAGE: { - break; - } - - case DELAY_STAGE: { - _stage = ATTACK_STAGE; - _stageProgress = _envelope = 0.0; - - // we're skipping the delay; subtract the full delay time from hold time so that env has the same shape as if we'd waited out the delay. - float delayTime = knobTime(_delayParam, _delayInput, slow, true); - float holdTime = knobTime(_holdParam, _holdInput, slow); - _holdProgress = fminf(1.0, delayTime / holdTime); - break; - } - - case DECAY_STAGE: - case SUSTAIN_STAGE: - case RELEASE_STAGE: { - _stage = ATTACK_STAGE; - switch ((int)_attackShapeParam.value) { - case SHAPE2: { - _stageProgress = _envelope; - break; - } - case SHAPE3: { - _stageProgress = pow(_envelope, shapeInverseExponent); - break; - } - default: { - _stageProgress = pow(_envelope, shapeExponent); - break; - } - } - - // reset hold to what it would have been at this point in the attack the first time through. - float delayTime = knobTime(_delayParam, _delayInput, slow, true); - float attackTime = knobTime(_attackParam, _attackInput, slow); - float holdTime = knobTime(_holdParam, _holdInput, slow); - _holdProgress = fminf(1.0, (delayTime + _stageProgress * attackTime) / holdTime); - break; - } - } - } - } - else { - switch (_stage) { - case STOPPED_STAGE: - case RELEASE_STAGE: { - break; - } - - case DELAY_STAGE: - case ATTACK_STAGE: - case DECAY_STAGE: - case SUSTAIN_STAGE: { - bool gateMode = _modeParam.value > 0.5; - bool holdComplete = _holdProgress >= 1.0; - if (!holdComplete) { - // run the hold accumulation even if we're not in hold mode, in case we switch mid-cycle. - _holdProgress += stepAmount(_holdParam, _holdInput, slow); - holdComplete = _holdProgress >= 1.0; - } - - if (gateMode ? !_trigger.isHigh() : holdComplete) { - _stage = RELEASE_STAGE; - _stageProgress = 0.0; - _releaseLevel = _envelope; - } - break; - } - } - } - - bool complete = false; - switch (_stage) { - case STOPPED_STAGE: { - break; - } - - case DELAY_STAGE: { - _stageProgress += stepAmount(_delayParam, _delayInput, slow, true); - if (_stageProgress >= 1.0) { - _stage = ATTACK_STAGE; - _stageProgress = 0.0; - } - break; - } - - case ATTACK_STAGE: { - _stageProgress += stepAmount(_attackParam, _attackInput, slow); - switch ((int)_attackShapeParam.value) { - case SHAPE2: { - _envelope = _stageProgress; - break; - } - case SHAPE3: { - _envelope = pow(_stageProgress, shapeExponent); - break; - } - default: { - _envelope = pow(_stageProgress, shapeInverseExponent); - break; - } - } - if (_envelope >= 1.0) { - _stage = DECAY_STAGE; - _stageProgress = 0.0; - } - break; - } - - case DECAY_STAGE: { - float sustainLevel = knobAmount(_sustainParam, _sustainInput); - _stageProgress += stepAmount(_decayParam, _decayInput, slow); - switch ((int)_decayShapeParam.value) { - case SHAPE2: { - _envelope = 1.0 - _stageProgress; - break; - } - case SHAPE3: { - _envelope = _stageProgress >= 1.0 ? 0.0 : pow(1.0 - _stageProgress, shapeInverseExponent); - break; - } - default: { - _envelope = _stageProgress >= 1.0 ? 0.0 : pow(1.0 - _stageProgress, shapeExponent); - break; - } - } - _envelope *= 1.0 - sustainLevel; - _envelope += sustainLevel; - if (_envelope <= sustainLevel) { - _stage = SUSTAIN_STAGE; - } - break; - } - - case SUSTAIN_STAGE: { - _envelope = knobAmount(_sustainParam, _sustainInput); - break; - } - - case RELEASE_STAGE: { - _stageProgress += stepAmount(_releaseParam, _releaseInput, slow); - switch ((int)_releaseShapeParam.value) { - case SHAPE2: { - _envelope = 1.0 - _stageProgress; - break; - } - case SHAPE3: { - _envelope = _stageProgress >= 1.0 ? 0.0 : pow(1.0 - _stageProgress, shapeInverseExponent); - break; - } - default: { - _envelope = _stageProgress >= 1.0 ? 0.0 : pow(1.0 - _stageProgress, shapeExponent); - break; - } - } - _envelope *= _releaseLevel; - if (_envelope <= 0.001) { - complete = true; - _envelope = 0.0; - if (_modeParam.value < 0.5 && (_loopParam.value <= 0.5 || _trigger.isHigh())) { - _stage = DELAY_STAGE; - _holdProgress = _stageProgress = 0.0; - } - else { - _stage = STOPPED_STAGE; - } - } - break; - } - } - - float env = _envelope * 10.0; - _envOutput.value = env; - _invOutput.value = 10.0 - env; - - if (complete) { - _triggerOuptutPulseGen.trigger(0.001); - } - _triggerOutput.value = _triggerOuptutPulseGen.process(engineGetSampleTime()) ? 5.0 : 0.0; - - if (_delayOutput) { - _delayOutput->value = _stage == DELAY_STAGE ? 5.0 : 0.0; - } - if (_attackOutput) { - _attackOutput->value = _stage == ATTACK_STAGE ? 5.0 : 0.0; - } - if (_decayOutput) { - _decayOutput->value = _stage == DECAY_STAGE ? 5.0 : 0.0; - } - if (_sustainOutput) { - _sustainOutput->value = _stage == SUSTAIN_STAGE ? 5.0 : 0.0; - } - if (_releaseOutput) { - _releaseOutput->value = _stage == RELEASE_STAGE ? 5.0 : 0.0; - } - - _delayLight.value = _stage == DELAY_STAGE; - _attackLight.value = _stage == ATTACK_STAGE; - _decayLight.value = _stage == DECAY_STAGE; - _sustainLight.value = _stage == SUSTAIN_STAGE; - _releaseLight.value = _stage == RELEASE_STAGE; - - _attackShape1Light.value = (int)_attackShapeParam.value == SHAPE1; - _attackShape2Light.value = (int)_attackShapeParam.value == SHAPE2; - _attackShape3Light.value = (int)_attackShapeParam.value == SHAPE3; - _decayShape1Light.value = (int)_decayShapeParam.value == SHAPE1; - _decayShape2Light.value = (int)_decayShapeParam.value == SHAPE2; - _decayShape3Light.value = (int)_decayShapeParam.value == SHAPE3; - _releaseShape1Light.value = (int)_releaseShapeParam.value == SHAPE1; - _releaseShape2Light.value = (int)_releaseShapeParam.value == SHAPE2; - _releaseShape3Light.value = (int)_releaseShapeParam.value == SHAPE3; - - _firstStep = false; -} - -float DADSRHCore::stepAmount(const Param& knob, const Input* cv, bool slow, bool allowZero) { - return engineGetSampleTime() / knobTime(knob, cv, slow, allowZero); -} - -float DADSRHCore::knobTime(const Param& knob, const Input* cv, bool slow, bool allowZero) { - float t = knobAmount(knob, cv); - t = pow(t, 2.0); - t = fmaxf(t, allowZero ? 0.0 : 0.001); - return t * (slow ? 100.0 : 10.0); -} - -float DADSRHCore::knobAmount(const Param& knob, const Input* cv) const { - float v = clampf(knob.value, 0.0, 1.0); - if (cv && cv->active) { - v *= clampf(cv->value / 10.0, 0.0, 1.0); - } - return v; -} diff --git a/src/DADSRHCore.hpp b/src/DADSRHCore.hpp @@ -1,182 +0,0 @@ - -#include "BogaudioModules.hpp" - -namespace bogaudio { - -struct DADSRHCore { - enum Stage { - STOPPED_STAGE, - DELAY_STAGE, - ATTACK_STAGE, - DECAY_STAGE, - SUSTAIN_STAGE, - RELEASE_STAGE - }; - - Param& _delayParam; - Param& _attackParam; - Param& _decayParam; - Param& _sustainParam; - Param& _releaseParam; - Param& _holdParam; - Param& _attackShapeParam; - Param& _decayShapeParam; - Param& _releaseShapeParam; - Param& _triggerParam; - Param& _modeParam; - Param& _loopParam; - Param& _speedParam; - Param& _retriggerParam; - - Input* _delayInput; - Input* _attackInput; - Input* _decayInput; - Input* _sustainInput; - Input* _releaseInput; - Input* _holdInput; - Input& _triggerInput; - - Output* _delayOutput; - Output* _attackOutput; - Output* _decayOutput; - Output* _sustainOutput; - Output* _releaseOutput; - Output& _envOutput; - Output& _invOutput; - Output& _triggerOutput; - - Light& _delayLight; - Light& _attackLight; - Light& _decayLight; - Light& _sustainLight; - Light& _releaseLight; - Light& _attackShape1Light; - Light& _attackShape2Light; - Light& _attackShape3Light; - Light& _decayShape1Light; - Light& _decayShape2Light; - Light& _decayShape3Light; - Light& _releaseShape1Light; - Light& _releaseShape2Light; - Light& _releaseShape3Light; - - bool _firstStep = true; - bool& _triggerOnLoad; - bool& _shouldTriggerOnLoad; - SchmittTrigger _trigger; - PulseGenerator _triggerOuptutPulseGen; - Stage _stage; - float _envelope, _stageProgress, _holdProgress, _releaseLevel; - - DADSRHCore( - Param& delayParam, - Param& attackParam, - Param& decayParam, - Param& sustainParam, - Param& releaseParam, - Param& holdParam, - Param& attackShapeParam, - Param& decayShapeParam, - Param& releaseShapeParam, - Param& triggerParam, - Param& modeParam, - Param& loopParam, - Param& speedParam, - Param& retriggerParam, - - Input* delayInput, - Input* attackInput, - Input* decayInput, - Input* sustainInput, - Input* releaseInput, - Input* holdInput, - Input& triggerInput, - - Output* delayOutput, - Output* attackOutput, - Output* decayOutput, - Output* sustainOutput, - Output* releaseOutput, - Output& envOutput, - Output& invOutput, - Output& triggerOutput, - - Light& delayLight, - Light& attackLight, - Light& decayLight, - Light& sustainLight, - Light& releaseLight, - Light& attackShape1Light, - Light& attackShape2Light, - Light& attackShape3Light, - Light& decayShape1Light, - Light& decayShape2Light, - Light& decayShape3Light, - Light& releaseShape1Light, - Light& releaseShape2Light, - Light& releaseShape3Light, - - bool& triggerOnLoad, - bool& shouldTriggerOnLoad - ) : _delayParam(delayParam) - , _attackParam(attackParam) - , _decayParam(decayParam) - , _sustainParam(sustainParam) - , _releaseParam(releaseParam) - , _holdParam(holdParam) - , _attackShapeParam(attackShapeParam) - , _decayShapeParam(decayShapeParam) - , _releaseShapeParam(releaseShapeParam) - , _triggerParam(triggerParam) - , _modeParam(modeParam) - , _loopParam(loopParam) - , _speedParam(speedParam) - , _retriggerParam(retriggerParam) - - , _delayInput(delayInput) - , _attackInput(attackInput) - , _decayInput(decayInput) - , _sustainInput(sustainInput) - , _releaseInput(releaseInput) - , _holdInput(holdInput) - , _triggerInput(triggerInput) - - , _delayOutput(delayOutput) - , _attackOutput(attackOutput) - , _decayOutput(decayOutput) - , _sustainOutput(sustainOutput) - , _releaseOutput(releaseOutput) - , _envOutput(envOutput) - , _invOutput(invOutput) - , _triggerOutput(triggerOutput) - - , _delayLight(delayLight) - , _attackLight(attackLight) - , _decayLight(decayLight) - , _sustainLight(sustainLight) - , _releaseLight(releaseLight) - , _attackShape1Light(attackShape1Light) - , _attackShape2Light(attackShape2Light) - , _attackShape3Light(attackShape3Light) - , _decayShape1Light(decayShape1Light) - , _decayShape2Light(decayShape2Light) - , _decayShape3Light(decayShape3Light) - , _releaseShape1Light(releaseShape1Light) - , _releaseShape2Light(releaseShape2Light) - , _releaseShape3Light(releaseShape3Light) - - , _triggerOnLoad(triggerOnLoad) - , _shouldTriggerOnLoad(shouldTriggerOnLoad) - { - reset(); - } - - void reset(); - void step(); - - float stepAmount(const Param& knob, const Input* cv, bool slow, bool allowZero = false); - float knobTime(const Param& knob, const Input* cv, bool slow, bool allowZero = false); - float knobAmount(const Param& knob, const Input* cv) const; -}; - -} // namespace bogaudio diff --git a/src/DADSRHPlus.cpp b/src/DADSRHPlus.cpp @@ -1,5 +1,5 @@ -#include "DADSRHCore.hpp" +#include "dadsrh_core.hpp" struct DADSRHPlus : TriggerOnLoadModule { enum ParamsIds { diff --git a/src/DGate.cpp b/src/DGate.cpp @@ -1,5 +1,5 @@ -#include "BogaudioModules.hpp" +#include "bogaudio.hpp" struct DGate : TriggerOnLoadModule { enum ParamsIds { diff --git a/src/Manual.cpp b/src/Manual.cpp @@ -1,5 +1,5 @@ -#include "BogaudioModules.hpp" +#include "bogaudio.hpp" struct Manual : Module { enum ParamsIds { diff --git a/src/Noise.cpp b/src/Noise.cpp @@ -1,5 +1,5 @@ -#include "BogaudioModules.hpp" +#include "bogaudio.hpp" #include "dsp/dsp.hpp" using namespace bogaudio::dsp; diff --git a/src/Offset.cpp b/src/Offset.cpp @@ -1,5 +1,5 @@ -#include "BogaudioModules.hpp" +#include "bogaudio.hpp" struct Offset : Module { enum ParamIds { diff --git a/src/Reftone.cpp b/src/Reftone.cpp @@ -1,5 +1,5 @@ -#include "BogaudioModules.hpp" +#include "bogaudio.hpp" #include "dsp/dsp.hpp" using namespace bogaudio::dsp; diff --git a/src/SampleHold.cpp b/src/SampleHold.cpp @@ -1,5 +1,5 @@ -#include "BogaudioModules.hpp" +#include "bogaudio.hpp" #include "dsp/dsp.hpp" using namespace bogaudio::dsp; diff --git a/src/Shaper.cpp b/src/Shaper.cpp @@ -1,5 +1,5 @@ -#include "ShaperCore.hpp" +#include "shaper_core.hpp" struct Shaper : TriggerOnLoadModule { enum ParamIds { diff --git a/src/ShaperCore.cpp b/src/ShaperCore.cpp @@ -1,134 +0,0 @@ - -#include "ShaperCore.hpp" - -void ShaperCore::reset() { - _trigger.reset(); - _triggerOuptutPulseGen.process(10.0); - _stage = STOPPED_STAGE; - _stageProgress = 0.0; -} - -void ShaperCore::step() { - bool complete = false; - bool slow = _speedParam.value <= 0.0; - if ( - _trigger.process(_triggerParam.value + _triggerInput.value) || - (_firstStep && _triggerOnLoad && _shouldTriggerOnLoad && _loopParam.value <= 0.0) - ) { - _stage = ATTACK_STAGE; - _stageProgress = 0.0; - } - else { - switch (_stage) { - case STOPPED_STAGE: { - break; - } - case ATTACK_STAGE: { - if (stepStage(_attackParam, _attackInput, slow)) { - _stage = ON_STAGE; - _stageProgress = 0.0; - } - break; - } - case ON_STAGE: { - if (stepStage(_onParam, _onInput, slow)) { - _stage = DECAY_STAGE; - _stageProgress = 0.0; - } - break; - } - case DECAY_STAGE: { - if (stepStage(_decayParam, _decayInput, slow)) { - _stage = OFF_STAGE; - _stageProgress = 0.0; - } - break; - } - case OFF_STAGE: { - if (stepStage(_offParam, _offInput, slow)) { - complete = true; - if (_loopParam.value <= 0.0 || _trigger.isHigh()) { - _stage = ATTACK_STAGE; - _stageProgress = 0.0; - } - else { - _stage = STOPPED_STAGE; - } - } - break; - } - } - } - - float envelope = 0.0; - switch (_stage) { - case STOPPED_STAGE: { - break; - } - case ATTACK_STAGE: { - envelope = _stageProgress * 10.0; - break; - } - case ON_STAGE: { - envelope = 10.0; - break; - } - case DECAY_STAGE: { - envelope = (1.0 - _stageProgress) * 10.0; - break; - } - case OFF_STAGE: { - break; - } - } - - float signalLevel = levelParam(_signalParam, _signalCVInput); - _signalOutput.value = signalLevel * envelope * _signalInput.normalize(0.0); - - float envLevel = levelParam(_envParam, _envInput); - float envOutput = clampf(envLevel * envelope, 0.0, 10.0); - _envOutput.value = envOutput; - _invOutput.value = 10.0 - envOutput; - - if (complete) { - _triggerOuptutPulseGen.trigger(0.001); - } - _triggerOutput.value = _triggerOuptutPulseGen.process(engineGetSampleTime()) ? 5.0 : 0.0; - - if (_attackOutput) { - _attackOutput->value = _stage == ATTACK_STAGE ? 5.0 : 0.0; - } - if (_onOutput) { - _onOutput->value = _stage == ON_STAGE ? 5.0 : 0.0; - } - if (_decayOutput) { - _decayOutput->value = _stage == DECAY_STAGE ? 5.0 : 0.0; - } - if (_offOutput) { - _offOutput->value = _stage == OFF_STAGE ? 5.0 : 0.0; - } - - _attackLight.value = _stage == ATTACK_STAGE; - _onLight.value = _stage == ON_STAGE; - _decayLight.value = _stage == DECAY_STAGE; - _offLight.value = _stage == OFF_STAGE; - - _firstStep = false; -} - -bool ShaperCore::stepStage(const Param& knob, const Input* cv, bool slow) { - float t = levelParam(knob, cv); - t = pow(t, 2); - t = fmaxf(t, 0.001); - t *= slow ? 100.0 : 10.0; - _stageProgress += engineGetSampleTime() / t; - return _stageProgress > 1.0; -} - -float ShaperCore::levelParam(const Param& knob, const Input* cv) const { - float v = clampf(knob.value, 0.0, 1.0); - if (cv && cv->active) { - v *= clampf(cv->value / 10.0, 0.0, 1.0); - } - return v; -} diff --git a/src/ShaperCore.hpp b/src/ShaperCore.hpp @@ -1,138 +0,0 @@ - -#include "BogaudioModules.hpp" - -namespace bogaudio { - -struct ShaperCore { - enum Stage { - STOPPED_STAGE, - ATTACK_STAGE, - ON_STAGE, - DECAY_STAGE, - OFF_STAGE - }; - - Param& _attackParam; - Param& _onParam; - Param& _decayParam; - Param& _offParam; - Param& _envParam; - Param& _signalParam; - Param& _triggerParam; - Param& _speedParam; - Param& _loopParam; - - Input& _signalInput; - Input& _triggerInput; - Input* _attackInput; - Input* _onInput; - Input* _decayInput; - Input* _offInput; - Input* _envInput; - Input* _signalCVInput; - - Output& _signalOutput; - Output& _envOutput; - Output& _invOutput; - Output& _triggerOutput; - Output* _attackOutput; - Output* _onOutput; - Output* _decayOutput; - Output* _offOutput; - - Light& _attackLight; - Light& _onLight; - Light& _decayLight; - Light& _offLight; - - bool _firstStep = true; - bool& _triggerOnLoad; - bool& _shouldTriggerOnLoad; - SchmittTrigger _trigger; - PulseGenerator _triggerOuptutPulseGen; - Stage _stage; - float _stageProgress; - - ShaperCore( - Param& attackParam, - Param& onParam, - Param& decayParam, - Param& offParam, - Param& envParam, - Param& signalParam, - Param& triggerParam, - Param& speedParam, - Param& loopParam, - - Input& signalInput, - Input& triggerInput, - Input* attackInput, - Input* onInput, - Input* decayInput, - Input* offInput, - Input* envInput, - Input* signalCVInput, - - Output& signalOutput, - Output& envOutput, - Output& invOutput, - Output& triggerOutput, - Output* attackOutput, - Output* onOutput, - Output* decayOutput, - Output* offOutput, - - Light& attackLight, - Light& onLight, - Light& decayLight, - Light& offLight, - - bool& triggerOnLoad, - bool& shouldTriggerOnLoad - ) : _attackParam(attackParam) - , _onParam(onParam) - , _decayParam(decayParam) - , _offParam(offParam) - , _envParam(envParam) - , _signalParam(signalParam) - , _triggerParam(triggerParam) - , _speedParam(speedParam) - , _loopParam(loopParam) - - , _signalInput(signalInput) - , _triggerInput(triggerInput) - , _attackInput(attackInput) - , _onInput(onInput) - , _decayInput(decayInput) - , _offInput(offInput) - , _envInput(envInput) - , _signalCVInput(signalCVInput) - - , _signalOutput(signalOutput) - , _envOutput(envOutput) - , _invOutput(invOutput) - , _triggerOutput(triggerOutput) - , _attackOutput(attackOutput) - , _onOutput(onOutput) - , _decayOutput(decayOutput) - , _offOutput(offOutput) - - , _attackLight(attackLight) - , _onLight(onLight) - , _decayLight(decayLight) - , _offLight(offLight) - - , _triggerOnLoad(triggerOnLoad) - , _shouldTriggerOnLoad(shouldTriggerOnLoad) - { - reset(); - } - - void reset(); - void step(); - - bool stepStage(const Param& knob, const Input* cv, bool slow); - float levelParam(const Param& knob, const Input* cv) const; -}; - -} // namespace bogaudio diff --git a/src/ShaperPlus.cpp b/src/ShaperPlus.cpp @@ -1,5 +1,5 @@ -#include "ShaperCore.hpp" +#include "shaper_core.hpp" struct ShaperPlus : TriggerOnLoadModule { enum ParamIds { diff --git a/src/Switch.cpp b/src/Switch.cpp @@ -1,5 +1,5 @@ -#include "BogaudioModules.hpp" +#include "bogaudio.hpp" namespace bogaudio { diff --git a/src/VCA.cpp b/src/VCA.cpp @@ -1,5 +1,5 @@ -#include "BogaudioModules.hpp" +#include "bogaudio.hpp" struct VCA : Module { enum ParamsIds { diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp @@ -0,0 +1,31 @@ +#include "bogaudio.hpp" + +Plugin *plugin; + +void init(rack::Plugin *p) { + plugin = p; + p->slug = "Bogaudio"; +#if defined(VERSION) + p->version = TOSTRING(VERSION); + p->website = "https://github.com/bogaudio/BogaudioModules"; + p->manual = "https://github.com/bogaudio/BogaudioModules/blob/master/README.md"; +#elif defined(REQUIRE_VERSION) +#error define VERSION=0.N.M to make dist +#endif + + p->addModel(createModel<ShaperWidget>("Bogaudio", "Bogaudio-Shaper", "Shaper", ENVELOPE_GENERATOR_TAG, AMPLIFIER_TAG)); + p->addModel(createModel<ShaperPlusWidget>("Bogaudio", "Bogaudio-ShaperPlus", "Shaper+", ENVELOPE_GENERATOR_TAG, AMPLIFIER_TAG)); + p->addModel(createModel<DADSRHWidget>("Bogaudio", "Bogaudio-DADSRH", "DADSR(H)", ENVELOPE_GENERATOR_TAG)); + p->addModel(createModel<DADSRHPlusWidget>("Bogaudio", "Bogaudio-DADSRHPlus", "DADSR(H)+", ENVELOPE_GENERATOR_TAG)); + + p->addModel(createModel<AnalyzerWidget>("Bogaudio", "Bogaudio-Analyzer", "Analyzer", VISUAL_TAG)); + + p->addModel(createModel<DGateWidget>("Bogaudio", "Bogaudio-DGate", "DGate", 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<OffsetWidget>("Bogaudio", "Bogaudio-Offset", "Offset", ATTENUATOR_TAG, UTILITY_TAG)); + p->addModel(createModel<ReftoneWidget>("Bogaudio", "Bogaudio-Reftone", "Reftone", TUNER_TAG, UTILITY_TAG)); + p->addModel(createModel<SampleHoldWidget>("Bogaudio", "Bogaudio-SampleHold", "S&H", SAMPLE_AND_HOLD_TAG, DUAL_TAG, UTILITY_TAG)); + p->addModel(createModel<SwitchWidget>("Bogaudio", "Bogaudio-Switch", "Switch", SWITCH_TAG, UTILITY_TAG)); + p->addModel(createModel<VCAWidget>("Bogaudio", "Bogaudio-VCA", "VCA", AMPLIFIER_TAG, DUAL_TAG, UTILITY_TAG)); +} diff --git a/src/BogaudioModules.hpp b/src/bogaudio.hpp diff --git a/src/dadsrh_core.cpp b/src/dadsrh_core.cpp @@ -0,0 +1,264 @@ + +#include "dadsrh_core.hpp" + +void DADSRHCore::reset() { + _trigger.reset(); + _triggerOuptutPulseGen.process(10.0); + _stage = STOPPED_STAGE; + _releaseLevel = _holdProgress = _stageProgress = _envelope = 0.0; +} + +void DADSRHCore::step() { + const int SHAPE1 = 1; + const int SHAPE2 = 2; + const int SHAPE3 = 3; + const float shapeExponent = 2.0; + const float shapeInverseExponent = 0.5; + + bool slow = _speedParam.value <= 0.5; + if ( + _trigger.process(_triggerParam.value + _triggerInput.value) || + (_firstStep && _triggerOnLoad && _shouldTriggerOnLoad && _loopParam.value < 0.5 && _modeParam.value < 0.5) + ) { + if (_stage == STOPPED_STAGE || _retriggerParam.value <= 0.5) { + _stage = DELAY_STAGE; + _holdProgress = _stageProgress = _envelope = 0.0; + } + else { + switch (_stage) { + case STOPPED_STAGE: + case ATTACK_STAGE: { + break; + } + + case DELAY_STAGE: { + _stage = ATTACK_STAGE; + _stageProgress = _envelope = 0.0; + + // we're skipping the delay; subtract the full delay time from hold time so that env has the same shape as if we'd waited out the delay. + float delayTime = knobTime(_delayParam, _delayInput, slow, true); + float holdTime = knobTime(_holdParam, _holdInput, slow); + _holdProgress = fminf(1.0, delayTime / holdTime); + break; + } + + case DECAY_STAGE: + case SUSTAIN_STAGE: + case RELEASE_STAGE: { + _stage = ATTACK_STAGE; + switch ((int)_attackShapeParam.value) { + case SHAPE2: { + _stageProgress = _envelope; + break; + } + case SHAPE3: { + _stageProgress = pow(_envelope, shapeInverseExponent); + break; + } + default: { + _stageProgress = pow(_envelope, shapeExponent); + break; + } + } + + // reset hold to what it would have been at this point in the attack the first time through. + float delayTime = knobTime(_delayParam, _delayInput, slow, true); + float attackTime = knobTime(_attackParam, _attackInput, slow); + float holdTime = knobTime(_holdParam, _holdInput, slow); + _holdProgress = fminf(1.0, (delayTime + _stageProgress * attackTime) / holdTime); + break; + } + } + } + } + else { + switch (_stage) { + case STOPPED_STAGE: + case RELEASE_STAGE: { + break; + } + + case DELAY_STAGE: + case ATTACK_STAGE: + case DECAY_STAGE: + case SUSTAIN_STAGE: { + bool gateMode = _modeParam.value > 0.5; + bool holdComplete = _holdProgress >= 1.0; + if (!holdComplete) { + // run the hold accumulation even if we're not in hold mode, in case we switch mid-cycle. + _holdProgress += stepAmount(_holdParam, _holdInput, slow); + holdComplete = _holdProgress >= 1.0; + } + + if (gateMode ? !_trigger.isHigh() : holdComplete) { + _stage = RELEASE_STAGE; + _stageProgress = 0.0; + _releaseLevel = _envelope; + } + break; + } + } + } + + bool complete = false; + switch (_stage) { + case STOPPED_STAGE: { + break; + } + + case DELAY_STAGE: { + _stageProgress += stepAmount(_delayParam, _delayInput, slow, true); + if (_stageProgress >= 1.0) { + _stage = ATTACK_STAGE; + _stageProgress = 0.0; + } + break; + } + + case ATTACK_STAGE: { + _stageProgress += stepAmount(_attackParam, _attackInput, slow); + switch ((int)_attackShapeParam.value) { + case SHAPE2: { + _envelope = _stageProgress; + break; + } + case SHAPE3: { + _envelope = pow(_stageProgress, shapeExponent); + break; + } + default: { + _envelope = pow(_stageProgress, shapeInverseExponent); + break; + } + } + if (_envelope >= 1.0) { + _stage = DECAY_STAGE; + _stageProgress = 0.0; + } + break; + } + + case DECAY_STAGE: { + float sustainLevel = knobAmount(_sustainParam, _sustainInput); + _stageProgress += stepAmount(_decayParam, _decayInput, slow); + switch ((int)_decayShapeParam.value) { + case SHAPE2: { + _envelope = 1.0 - _stageProgress; + break; + } + case SHAPE3: { + _envelope = _stageProgress >= 1.0 ? 0.0 : pow(1.0 - _stageProgress, shapeInverseExponent); + break; + } + default: { + _envelope = _stageProgress >= 1.0 ? 0.0 : pow(1.0 - _stageProgress, shapeExponent); + break; + } + } + _envelope *= 1.0 - sustainLevel; + _envelope += sustainLevel; + if (_envelope <= sustainLevel) { + _stage = SUSTAIN_STAGE; + } + break; + } + + case SUSTAIN_STAGE: { + _envelope = knobAmount(_sustainParam, _sustainInput); + break; + } + + case RELEASE_STAGE: { + _stageProgress += stepAmount(_releaseParam, _releaseInput, slow); + switch ((int)_releaseShapeParam.value) { + case SHAPE2: { + _envelope = 1.0 - _stageProgress; + break; + } + case SHAPE3: { + _envelope = _stageProgress >= 1.0 ? 0.0 : pow(1.0 - _stageProgress, shapeInverseExponent); + break; + } + default: { + _envelope = _stageProgress >= 1.0 ? 0.0 : pow(1.0 - _stageProgress, shapeExponent); + break; + } + } + _envelope *= _releaseLevel; + if (_envelope <= 0.001) { + complete = true; + _envelope = 0.0; + if (_modeParam.value < 0.5 && (_loopParam.value <= 0.5 || _trigger.isHigh())) { + _stage = DELAY_STAGE; + _holdProgress = _stageProgress = 0.0; + } + else { + _stage = STOPPED_STAGE; + } + } + break; + } + } + + float env = _envelope * 10.0; + _envOutput.value = env; + _invOutput.value = 10.0 - env; + + if (complete) { + _triggerOuptutPulseGen.trigger(0.001); + } + _triggerOutput.value = _triggerOuptutPulseGen.process(engineGetSampleTime()) ? 5.0 : 0.0; + + if (_delayOutput) { + _delayOutput->value = _stage == DELAY_STAGE ? 5.0 : 0.0; + } + if (_attackOutput) { + _attackOutput->value = _stage == ATTACK_STAGE ? 5.0 : 0.0; + } + if (_decayOutput) { + _decayOutput->value = _stage == DECAY_STAGE ? 5.0 : 0.0; + } + if (_sustainOutput) { + _sustainOutput->value = _stage == SUSTAIN_STAGE ? 5.0 : 0.0; + } + if (_releaseOutput) { + _releaseOutput->value = _stage == RELEASE_STAGE ? 5.0 : 0.0; + } + + _delayLight.value = _stage == DELAY_STAGE; + _attackLight.value = _stage == ATTACK_STAGE; + _decayLight.value = _stage == DECAY_STAGE; + _sustainLight.value = _stage == SUSTAIN_STAGE; + _releaseLight.value = _stage == RELEASE_STAGE; + + _attackShape1Light.value = (int)_attackShapeParam.value == SHAPE1; + _attackShape2Light.value = (int)_attackShapeParam.value == SHAPE2; + _attackShape3Light.value = (int)_attackShapeParam.value == SHAPE3; + _decayShape1Light.value = (int)_decayShapeParam.value == SHAPE1; + _decayShape2Light.value = (int)_decayShapeParam.value == SHAPE2; + _decayShape3Light.value = (int)_decayShapeParam.value == SHAPE3; + _releaseShape1Light.value = (int)_releaseShapeParam.value == SHAPE1; + _releaseShape2Light.value = (int)_releaseShapeParam.value == SHAPE2; + _releaseShape3Light.value = (int)_releaseShapeParam.value == SHAPE3; + + _firstStep = false; +} + +float DADSRHCore::stepAmount(const Param& knob, const Input* cv, bool slow, bool allowZero) { + return engineGetSampleTime() / knobTime(knob, cv, slow, allowZero); +} + +float DADSRHCore::knobTime(const Param& knob, const Input* cv, bool slow, bool allowZero) { + float t = knobAmount(knob, cv); + t = pow(t, 2.0); + t = fmaxf(t, allowZero ? 0.0 : 0.001); + return t * (slow ? 100.0 : 10.0); +} + +float DADSRHCore::knobAmount(const Param& knob, const Input* cv) const { + float v = clampf(knob.value, 0.0, 1.0); + if (cv && cv->active) { + v *= clampf(cv->value / 10.0, 0.0, 1.0); + } + return v; +} diff --git a/src/dadsrh_core.hpp b/src/dadsrh_core.hpp @@ -0,0 +1,182 @@ + +#include "bogaudio.hpp" + +namespace bogaudio { + +struct DADSRHCore { + enum Stage { + STOPPED_STAGE, + DELAY_STAGE, + ATTACK_STAGE, + DECAY_STAGE, + SUSTAIN_STAGE, + RELEASE_STAGE + }; + + Param& _delayParam; + Param& _attackParam; + Param& _decayParam; + Param& _sustainParam; + Param& _releaseParam; + Param& _holdParam; + Param& _attackShapeParam; + Param& _decayShapeParam; + Param& _releaseShapeParam; + Param& _triggerParam; + Param& _modeParam; + Param& _loopParam; + Param& _speedParam; + Param& _retriggerParam; + + Input* _delayInput; + Input* _attackInput; + Input* _decayInput; + Input* _sustainInput; + Input* _releaseInput; + Input* _holdInput; + Input& _triggerInput; + + Output* _delayOutput; + Output* _attackOutput; + Output* _decayOutput; + Output* _sustainOutput; + Output* _releaseOutput; + Output& _envOutput; + Output& _invOutput; + Output& _triggerOutput; + + Light& _delayLight; + Light& _attackLight; + Light& _decayLight; + Light& _sustainLight; + Light& _releaseLight; + Light& _attackShape1Light; + Light& _attackShape2Light; + Light& _attackShape3Light; + Light& _decayShape1Light; + Light& _decayShape2Light; + Light& _decayShape3Light; + Light& _releaseShape1Light; + Light& _releaseShape2Light; + Light& _releaseShape3Light; + + bool _firstStep = true; + bool& _triggerOnLoad; + bool& _shouldTriggerOnLoad; + SchmittTrigger _trigger; + PulseGenerator _triggerOuptutPulseGen; + Stage _stage; + float _envelope, _stageProgress, _holdProgress, _releaseLevel; + + DADSRHCore( + Param& delayParam, + Param& attackParam, + Param& decayParam, + Param& sustainParam, + Param& releaseParam, + Param& holdParam, + Param& attackShapeParam, + Param& decayShapeParam, + Param& releaseShapeParam, + Param& triggerParam, + Param& modeParam, + Param& loopParam, + Param& speedParam, + Param& retriggerParam, + + Input* delayInput, + Input* attackInput, + Input* decayInput, + Input* sustainInput, + Input* releaseInput, + Input* holdInput, + Input& triggerInput, + + Output* delayOutput, + Output* attackOutput, + Output* decayOutput, + Output* sustainOutput, + Output* releaseOutput, + Output& envOutput, + Output& invOutput, + Output& triggerOutput, + + Light& delayLight, + Light& attackLight, + Light& decayLight, + Light& sustainLight, + Light& releaseLight, + Light& attackShape1Light, + Light& attackShape2Light, + Light& attackShape3Light, + Light& decayShape1Light, + Light& decayShape2Light, + Light& decayShape3Light, + Light& releaseShape1Light, + Light& releaseShape2Light, + Light& releaseShape3Light, + + bool& triggerOnLoad, + bool& shouldTriggerOnLoad + ) : _delayParam(delayParam) + , _attackParam(attackParam) + , _decayParam(decayParam) + , _sustainParam(sustainParam) + , _releaseParam(releaseParam) + , _holdParam(holdParam) + , _attackShapeParam(attackShapeParam) + , _decayShapeParam(decayShapeParam) + , _releaseShapeParam(releaseShapeParam) + , _triggerParam(triggerParam) + , _modeParam(modeParam) + , _loopParam(loopParam) + , _speedParam(speedParam) + , _retriggerParam(retriggerParam) + + , _delayInput(delayInput) + , _attackInput(attackInput) + , _decayInput(decayInput) + , _sustainInput(sustainInput) + , _releaseInput(releaseInput) + , _holdInput(holdInput) + , _triggerInput(triggerInput) + + , _delayOutput(delayOutput) + , _attackOutput(attackOutput) + , _decayOutput(decayOutput) + , _sustainOutput(sustainOutput) + , _releaseOutput(releaseOutput) + , _envOutput(envOutput) + , _invOutput(invOutput) + , _triggerOutput(triggerOutput) + + , _delayLight(delayLight) + , _attackLight(attackLight) + , _decayLight(decayLight) + , _sustainLight(sustainLight) + , _releaseLight(releaseLight) + , _attackShape1Light(attackShape1Light) + , _attackShape2Light(attackShape2Light) + , _attackShape3Light(attackShape3Light) + , _decayShape1Light(decayShape1Light) + , _decayShape2Light(decayShape2Light) + , _decayShape3Light(decayShape3Light) + , _releaseShape1Light(releaseShape1Light) + , _releaseShape2Light(releaseShape2Light) + , _releaseShape3Light(releaseShape3Light) + + , _triggerOnLoad(triggerOnLoad) + , _shouldTriggerOnLoad(shouldTriggerOnLoad) + { + reset(); + } + + void reset(); + void step(); + + float stepAmount(const Param& knob, const Input* cv, bool slow, bool allowZero = false); + float knobTime(const Param& knob, const Input* cv, bool slow, bool allowZero = false); + float knobAmount(const Param& knob, const Input* cv) const; +}; + +} // namespace bogaudio diff --git a/src/shaper_core.cpp b/src/shaper_core.cpp @@ -0,0 +1,134 @@ + +#include "shaper_core.hpp" + +void ShaperCore::reset() { + _trigger.reset(); + _triggerOuptutPulseGen.process(10.0); + _stage = STOPPED_STAGE; + _stageProgress = 0.0; +} + +void ShaperCore::step() { + bool complete = false; + bool slow = _speedParam.value <= 0.0; + if ( + _trigger.process(_triggerParam.value + _triggerInput.value) || + (_firstStep && _triggerOnLoad && _shouldTriggerOnLoad && _loopParam.value <= 0.0) + ) { + _stage = ATTACK_STAGE; + _stageProgress = 0.0; + } + else { + switch (_stage) { + case STOPPED_STAGE: { + break; + } + case ATTACK_STAGE: { + if (stepStage(_attackParam, _attackInput, slow)) { + _stage = ON_STAGE; + _stageProgress = 0.0; + } + break; + } + case ON_STAGE: { + if (stepStage(_onParam, _onInput, slow)) { + _stage = DECAY_STAGE; + _stageProgress = 0.0; + } + break; + } + case DECAY_STAGE: { + if (stepStage(_decayParam, _decayInput, slow)) { + _stage = OFF_STAGE; + _stageProgress = 0.0; + } + break; + } + case OFF_STAGE: { + if (stepStage(_offParam, _offInput, slow)) { + complete = true; + if (_loopParam.value <= 0.0 || _trigger.isHigh()) { + _stage = ATTACK_STAGE; + _stageProgress = 0.0; + } + else { + _stage = STOPPED_STAGE; + } + } + break; + } + } + } + + float envelope = 0.0; + switch (_stage) { + case STOPPED_STAGE: { + break; + } + case ATTACK_STAGE: { + envelope = _stageProgress * 10.0; + break; + } + case ON_STAGE: { + envelope = 10.0; + break; + } + case DECAY_STAGE: { + envelope = (1.0 - _stageProgress) * 10.0; + break; + } + case OFF_STAGE: { + break; + } + } + + float signalLevel = levelParam(_signalParam, _signalCVInput); + _signalOutput.value = signalLevel * envelope * _signalInput.normalize(0.0); + + float envLevel = levelParam(_envParam, _envInput); + float envOutput = clampf(envLevel * envelope, 0.0, 10.0); + _envOutput.value = envOutput; + _invOutput.value = 10.0 - envOutput; + + if (complete) { + _triggerOuptutPulseGen.trigger(0.001); + } + _triggerOutput.value = _triggerOuptutPulseGen.process(engineGetSampleTime()) ? 5.0 : 0.0; + + if (_attackOutput) { + _attackOutput->value = _stage == ATTACK_STAGE ? 5.0 : 0.0; + } + if (_onOutput) { + _onOutput->value = _stage == ON_STAGE ? 5.0 : 0.0; + } + if (_decayOutput) { + _decayOutput->value = _stage == DECAY_STAGE ? 5.0 : 0.0; + } + if (_offOutput) { + _offOutput->value = _stage == OFF_STAGE ? 5.0 : 0.0; + } + + _attackLight.value = _stage == ATTACK_STAGE; + _onLight.value = _stage == ON_STAGE; + _decayLight.value = _stage == DECAY_STAGE; + _offLight.value = _stage == OFF_STAGE; + + _firstStep = false; +} + +bool ShaperCore::stepStage(const Param& knob, const Input* cv, bool slow) { + float t = levelParam(knob, cv); + t = pow(t, 2); + t = fmaxf(t, 0.001); + t *= slow ? 100.0 : 10.0; + _stageProgress += engineGetSampleTime() / t; + return _stageProgress > 1.0; +} + +float ShaperCore::levelParam(const Param& knob, const Input* cv) const { + float v = clampf(knob.value, 0.0, 1.0); + if (cv && cv->active) { + v *= clampf(cv->value / 10.0, 0.0, 1.0); + } + return v; +} diff --git a/src/shaper_core.hpp b/src/shaper_core.hpp @@ -0,0 +1,138 @@ + +#include "bogaudio.hpp" + +namespace bogaudio { + +struct ShaperCore { + enum Stage { + STOPPED_STAGE, + ATTACK_STAGE, + ON_STAGE, + DECAY_STAGE, + OFF_STAGE + }; + + Param& _attackParam; + Param& _onParam; + Param& _decayParam; + Param& _offParam; + Param& _envParam; + Param& _signalParam; + Param& _triggerParam; + Param& _speedParam; + Param& _loopParam; + + Input& _signalInput; + Input& _triggerInput; + Input* _attackInput; + Input* _onInput; + Input* _decayInput; + Input* _offInput; + Input* _envInput; + Input* _signalCVInput; + + Output& _signalOutput; + Output& _envOutput; + Output& _invOutput; + Output& _triggerOutput; + Output* _attackOutput; + Output* _onOutput; + Output* _decayOutput; + Output* _offOutput; + + Light& _attackLight; + Light& _onLight; + Light& _decayLight; + Light& _offLight; + + bool _firstStep = true; + bool& _triggerOnLoad; + bool& _shouldTriggerOnLoad; + SchmittTrigger _trigger; + PulseGenerator _triggerOuptutPulseGen; + Stage _stage; + float _stageProgress; + + ShaperCore( + Param& attackParam, + Param& onParam, + Param& decayParam, + Param& offParam, + Param& envParam, + Param& signalParam, + Param& triggerParam, + Param& speedParam, + Param& loopParam, + + Input& signalInput, + Input& triggerInput, + Input* attackInput, + Input* onInput, + Input* decayInput, + Input* offInput, + Input* envInput, + Input* signalCVInput, + + Output& signalOutput, + Output& envOutput, + Output& invOutput, + Output& triggerOutput, + Output* attackOutput, + Output* onOutput, + Output* decayOutput, + Output* offOutput, + + Light& attackLight, + Light& onLight, + Light& decayLight, + Light& offLight, + + bool& triggerOnLoad, + bool& shouldTriggerOnLoad + ) : _attackParam(attackParam) + , _onParam(onParam) + , _decayParam(decayParam) + , _offParam(offParam) + , _envParam(envParam) + , _signalParam(signalParam) + , _triggerParam(triggerParam) + , _speedParam(speedParam) + , _loopParam(loopParam) + + , _signalInput(signalInput) + , _triggerInput(triggerInput) + , _attackInput(attackInput) + , _onInput(onInput) + , _decayInput(decayInput) + , _offInput(offInput) + , _envInput(envInput) + , _signalCVInput(signalCVInput) + + , _signalOutput(signalOutput) + , _envOutput(envOutput) + , _invOutput(invOutput) + , _triggerOutput(triggerOutput) + , _attackOutput(attackOutput) + , _onOutput(onOutput) + , _decayOutput(decayOutput) + , _offOutput(offOutput) + + , _attackLight(attackLight) + , _onLight(onLight) + , _decayLight(decayLight) + , _offLight(offLight) + + , _triggerOnLoad(triggerOnLoad) + , _shouldTriggerOnLoad(shouldTriggerOnLoad) + { + reset(); + } + + void reset(); + void step(); + + bool stepStage(const Param& knob, const Input* cv, bool slow); + float levelParam(const Param& knob, const Input* cv) const; +}; + +} // namespace bogaudio