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:
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