Browse Source

ADSR new display and parameters WIP.

tags/v2.0.1
Andrew Belt 3 years ago
parent
commit
47f11f96e0
1 changed files with 94 additions and 33 deletions
  1. +94
    -33
      src/ADSR.cpp

+ 94
- 33
src/ADSR.cpp View File

@@ -1,12 +1,7 @@
#include "plugin.hpp"


using namespace simd;


const float MIN_TIME = 1e-3f;
const float MAX_TIME = 10.f;
const float LAMBDA_BASE = MAX_TIME / MIN_TIME;
using simd::float_4;


struct ADSR : Module {
@@ -15,6 +10,12 @@ struct ADSR : Module {
DECAY_PARAM,
SUSTAIN_PARAM,
RELEASE_PARAM,
// added in 2.0
ATTACK_CV_PARAM,
DECAY_CV_PARAM,
SUSTAIN_CV_PARAM,
RELEASE_CV_PARAM,
PUSH_PARAM,
NUM_PARAMS
};
enum InputIds {
@@ -23,7 +24,7 @@ struct ADSR : Module {
SUSTAIN_INPUT,
RELEASE_INPUT,
GATE_INPUT,
TRIG_INPUT,
RETRIG_INPUT,
NUM_INPUTS
};
enum OutputIds {
@@ -35,17 +36,22 @@ struct ADSR : Module {
DECAY_LIGHT,
SUSTAIN_LIGHT,
RELEASE_LIGHT,
PUSH_LIGHT,
NUM_LIGHTS
};

float_4 attacking[4] = {float_4::zero()};
float_4 env[4] = {0.f};
static constexpr float MIN_TIME = 1e-3f;
static constexpr float MAX_TIME = 10.f;
static constexpr float LAMBDA_BASE = MAX_TIME / MIN_TIME;

float_4 attacking[4] = {};
float_4 env[4] = {};
dsp::TSchmittTrigger<float_4> trigger[4];
dsp::ClockDivider cvDivider;
float_4 attackLambda[4] = {0.f};
float_4 decayLambda[4] = {0.f};
float_4 releaseLambda[4] = {0.f};
float_4 sustain[4] = {0.f};
float_4 attackLambda[4] = {};
float_4 decayLambda[4] = {};
float_4 releaseLambda[4] = {};
float_4 sustain[4] = {};
dsp::ClockDivider lightDivider;

ADSR() {
@@ -54,12 +60,21 @@ struct ADSR : Module {
configParam(DECAY_PARAM, 0.f, 1.f, 0.5f, "Decay", " ms", LAMBDA_BASE, MIN_TIME * 1000);
configParam(SUSTAIN_PARAM, 0.f, 1.f, 0.5f, "Sustain", "%", 0, 100);
configParam(RELEASE_PARAM, 0.f, 1.f, 0.5f, "Release", " ms", LAMBDA_BASE, MIN_TIME * 1000);

configParam(ATTACK_CV_PARAM, -1.f, 1.f, 0.f, "Attack CV", "%", 0, 100);
configParam(DECAY_CV_PARAM, -1.f, 1.f, 0.f, "Decay CV", "%", 0, 100);
configParam(SUSTAIN_CV_PARAM, -1.f, 1.f, 0.f, "Sustain CV", "%", 0, 100);
configParam(RELEASE_CV_PARAM, -1.f, 1.f, 0.f, "Release CV", "%", 0, 100);

configButton(PUSH_PARAM, "Push");

configInput(ATTACK_INPUT, "Attack");
configInput(DECAY_INPUT, "Decay");
configInput(SUSTAIN_INPUT, "Sustain");
configInput(RELEASE_INPUT, "Release");
configInput(GATE_INPUT, "Gate");
configInput(TRIG_INPUT, "Retrigger");
configInput(RETRIG_INPUT, "Retrigger");

configOutput(ENVELOPE_OUTPUT, "Envelope");

cvDivider.setDivision(16);
@@ -71,7 +86,7 @@ struct ADSR : Module {
// 0.23 us serial with all lambdas computed
// 0.15-0.18 us serial with all lambdas computed with SSE

int channels = inputs[GATE_INPUT].getChannels();
int channels = std::max(1, inputs[GATE_INPUT].getChannels());

// Compute lambdas
if (cvDivider.process()) {
@@ -80,12 +95,17 @@ struct ADSR : Module {
float sustainParam = params[SUSTAIN_PARAM].getValue();
float releaseParam = params[RELEASE_PARAM].getValue();

float attackCvParam = params[ATTACK_CV_PARAM].getValue();
float decayCvParam = params[DECAY_CV_PARAM].getValue();
float sustainCvParam = params[SUSTAIN_CV_PARAM].getValue();
float releaseCvParam = params[RELEASE_CV_PARAM].getValue();

for (int c = 0; c < channels; c += 4) {
// CV
float_4 attack = attackParam + inputs[ATTACK_INPUT].getPolyVoltageSimd<float_4>(c) / 10.f;
float_4 decay = decayParam + inputs[DECAY_INPUT].getPolyVoltageSimd<float_4>(c) / 10.f;
float_4 sustain = sustainParam + inputs[SUSTAIN_INPUT].getPolyVoltageSimd<float_4>(c) / 10.f;
float_4 release = releaseParam + inputs[RELEASE_INPUT].getPolyVoltageSimd<float_4>(c) / 10.f;
float_4 attack = attackParam + inputs[ATTACK_INPUT].getPolyVoltageSimd<float_4>(c) / 10.f * attackCvParam;
float_4 decay = decayParam + inputs[DECAY_INPUT].getPolyVoltageSimd<float_4>(c) / 10.f * decayCvParam;
float_4 sustain = sustainParam + inputs[SUSTAIN_INPUT].getPolyVoltageSimd<float_4>(c) / 10.f * sustainCvParam;
float_4 release = releaseParam + inputs[RELEASE_INPUT].getPolyVoltageSimd<float_4>(c) / 10.f * releaseCvParam;

attack = simd::clamp(attack, 0.f, 1.f);
decay = simd::clamp(decay, 0.f, 1.f);
@@ -99,14 +119,19 @@ struct ADSR : Module {
}
}

float_4 gate[4];
float_4 gate[4] = {};
bool push = params[PUSH_PARAM].getValue();

for (int c = 0; c < channels; c += 4) {
// Gate
gate[c / 4] = inputs[GATE_INPUT].getVoltageSimd<float_4>(c) >= 1.f;

if (push) {
gate[c / 4] = float_4::mask();
}

// Retrigger
float_4 triggered = trigger[c / 4].process(inputs[TRIG_INPUT].getPolyVoltageSimd<float_4>(c));
float_4 triggered = trigger[c / 4].process(inputs[RETRIG_INPUT].getPolyVoltageSimd<float_4>(c));
attacking[c / 4] = simd::ifelse(triggered, float_4::mask(), attacking[c / 4]);

// Get target and lambda for exponential decay
@@ -150,7 +175,41 @@ struct ADSR : Module {
if (simd::movemask(~gate[c / 4] & ~resting))
lights[RELEASE_LIGHT].setBrightness(1);
}

// Push button light
bool anyGate = false;
for (int c = 0; c < channels; c += 4)
anyGate = anyGate || simd::movemask(gate[c / 4]);
lights[PUSH_LIGHT].setBrightness(anyGate);
}
}
};


struct ADSRDisplay : LedDisplay {
ADSR* module;

void drawLayer(const DrawArgs& args, int layer) override {
if (layer == 1) {
Rect r = box.zeroPos().shrink(Vec(2, 4));
Vec s = r.getTopLeft();
Vec e = r.getBottomRight();
float decayX = 20.0;
float releaseX = 80.0;
float releaseY = 40.0;

nvgBeginPath(args.vg);
nvgMoveTo(args.vg, s.x, e.y);
nvgBezierTo(args.vg, s.x, s.y, decayX, s.y, decayX, s.y);
nvgBezierTo(args.vg, decayX, releaseY, releaseX, releaseY, releaseX, releaseY);
nvgBezierTo(args.vg, releaseX, e.y, e.x, e.y, e.x, e.y);
nvgLineCap(args.vg, NVG_ROUND);
nvgMiterLimit(args.vg, 2.f);
nvgStrokeWidth(args.vg, 1.5f);
nvgStrokeColor(args.vg, SCHEME_YELLOW);
nvgStroke(args.vg);
}
LedDisplay::drawLayer(args, layer);
}
};

@@ -165,27 +224,29 @@ struct ADSRWidget : ModuleWidget {
addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));

addParam(createParamCentered<LEDSlider>(mm2px(Vec(6.604, 55.454)), module, ADSR::ATTACK_PARAM));
addParam(createParamCentered<LEDSlider>(mm2px(Vec(17.441, 55.454)), module, ADSR::DECAY_PARAM));
addParam(createParamCentered<LEDSlider>(mm2px(Vec(28.279, 55.454)), module, ADSR::SUSTAIN_PARAM));
addParam(createParamCentered<LEDSlider>(mm2px(Vec(39.116, 55.454)), module, ADSR::RELEASE_PARAM));
// addParam(createParamCentered<Trimpot>(mm2px(Vec(6.604, 80.603)), module, ADSR::ATTCV_PARAM));
// addParam(createParamCentered<Trimpot>(mm2px(Vec(17.441, 80.63)), module, ADSR::DECCV_PARAM));
// addParam(createParamCentered<Trimpot>(mm2px(Vec(28.279, 80.603)), module, ADSR::SUSCV_PARAM));
// addParam(createParamCentered<Trimpot>(mm2px(Vec(39.119, 80.603)), module, ADSR::RELCV_PARAM));
// addParam(createParamCentered<LEDLightBezel>(mm2px(Vec(6.604, 113.115)), module, ADSR::PUSH_PARAM));
addParam(createLightParamCentered<LEDLightSlider<YellowLight>>(mm2px(Vec(6.604, 55.454)), module, ADSR::ATTACK_PARAM, ADSR::ATTACK_LIGHT));
addParam(createLightParamCentered<LEDLightSlider<YellowLight>>(mm2px(Vec(17.441, 55.454)), module, ADSR::DECAY_PARAM, ADSR::DECAY_LIGHT));
addParam(createLightParamCentered<LEDLightSlider<YellowLight>>(mm2px(Vec(28.279, 55.454)), module, ADSR::SUSTAIN_PARAM, ADSR::SUSTAIN_LIGHT));
addParam(createLightParamCentered<LEDLightSlider<YellowLight>>(mm2px(Vec(39.116, 55.454)), module, ADSR::RELEASE_PARAM, ADSR::RELEASE_LIGHT));
addParam(createParamCentered<Trimpot>(mm2px(Vec(6.604, 80.603)), module, ADSR::ATTACK_CV_PARAM));
addParam(createParamCentered<Trimpot>(mm2px(Vec(17.441, 80.63)), module, ADSR::DECAY_CV_PARAM));
addParam(createParamCentered<Trimpot>(mm2px(Vec(28.279, 80.603)), module, ADSR::SUSTAIN_CV_PARAM));
addParam(createParamCentered<Trimpot>(mm2px(Vec(39.119, 80.603)), module, ADSR::RELEASE_CV_PARAM));
addParam(createLightParamCentered<LEDLightBezel<>>(mm2px(Vec(6.604, 113.115)), module, ADSR::PUSH_PARAM, ADSR::PUSH_LIGHT));

addInput(createInputCentered<PJ301MPort>(mm2px(Vec(6.604, 96.882)), module, ADSR::ATTACK_INPUT));
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(17.441, 96.859)), module, ADSR::DECAY_INPUT));
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(28.279, 96.886)), module, ADSR::SUSTAIN_INPUT));
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(39.119, 96.89)), module, ADSR::RELEASE_INPUT));
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(17.441, 113.115)), module, ADSR::GATE_INPUT));
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(28.279, 113.115)), module, ADSR::TRIG_INPUT));
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(28.279, 113.115)), module, ADSR::RETRIG_INPUT));

addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(39.119, 113.115)), module, ADSR::ENVELOPE_OUTPUT));

// mm2px(Vec(45.72, 21.219))
// addChild(createWidget<Widget>(mm2px(Vec(0.0, 13.039))));
ADSRDisplay* display = createWidget<ADSRDisplay>(mm2px(Vec(0.0, 13.039)));
display->box.size = mm2px(Vec(45.72, 21.219));
display->module = module;
addChild(display);
}
};



Loading…
Cancel
Save