Browse Source

Implement ADSR display.

tags/v2.0.1
Andrew Belt 3 years ago
parent
commit
5d1922936c
1 changed files with 26 additions and 11 deletions
  1. +26
    -11
      src/ADSR.cpp

+ 26
- 11
src/ADSR.cpp View File

@@ -120,7 +120,7 @@ struct ADSR : Module {
} }


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


for (int c = 0; c < channels; c += 4) { for (int c = 0; c < channels; c += 4) {
// Gate // Gate
@@ -201,18 +201,33 @@ struct ADSRDisplay : LedDisplay {


void drawLayer(const DrawArgs& args, int layer) override { void drawLayer(const DrawArgs& args, int layer) override {
if (layer == 1) { 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;
// Module parameters
float attackLambda = module ? module->attackLambda[0][0] : 1.f;
float decayLambda = module ? module->decayLambda[0][0] : 1.f;
float releaseLambda = module ? module->releaseLambda[0][0] : 1.f;
float sustain = module ? module->sustain[0][0] : 0.5f;

// Scale lambdas
const float power = 0.5f;
float attack = std::pow(attackLambda, -power);
float decay = std::pow(decayLambda, -power);
float release = std::pow(releaseLambda, -power);
float totalLambda = attack + decay + release;

Rect r = box.zeroPos().shrink(Vec(4, 5));
Vec p0 = r.getBottomLeft();
Vec p1 = r.interpolate(Vec(attack / totalLambda, 0));
Vec p2 = r.interpolate(Vec((attack + decay) / totalLambda, 1 - sustain));
Vec p3 = r.getBottomRight();
Vec attackHandle = Vec(p0.x, crossfade(p0.y, p1.y, 0.8f));
Vec decayHandle = Vec(p1.x, crossfade(p1.y, p2.y, 0.8f));
Vec releaseHandle = Vec(p2.x, crossfade(p2.y, p3.y, 0.8f));


nvgBeginPath(args.vg); 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);
nvgMoveTo(args.vg, p0.x, p0.y);
nvgBezierTo(args.vg, p0.x, p0.y, attackHandle.x, attackHandle.y, p1.x, p1.y);
nvgBezierTo(args.vg, p1.x, p1.y, decayHandle.x, decayHandle.y, p2.x, p2.y);
nvgBezierTo(args.vg, p2.x, p2.y, releaseHandle.x, releaseHandle.y, p3.x, p3.y);
nvgLineCap(args.vg, NVG_ROUND); nvgLineCap(args.vg, NVG_ROUND);
nvgMiterLimit(args.vg, 2.f); nvgMiterLimit(args.vg, 2.f);
nvgStrokeWidth(args.vg, 1.5f); nvgStrokeWidth(args.vg, 1.5f);


Loading…
Cancel
Save