ADSRcrv2

ADSR module with exp/inverse exp controls for attack, decay and release stages. Also outputs stage number and a gate high when it changes from stage (eg selecting different waveforms for my wavetable oscillators for each stage. you could use the autoCurve (patt-folder) to morph between settings at the different stages of the envelope.) the exponential/inverse exponential sides of the A, D and R are swapped for D and R. This is done for a more intuitive control: -dial it left->signal is mostly low (exp for attack, inv-exp for decay and release) -dial it right->signal is mostly high (inv-exp for attack, exp for decay and release) this version has a single time control for the "attack" part, which sets the combined time for attack and decay. The slope control sets the "fastest" side: left for fast attack (and slow decay), right for fast decay (and slow attack). It also has an S-curve control, this dials in S-curves for all stages. Negative S-curve is inversed S-curve (force to mid-position)
Author: Remco van der Most
License: BSD
Github: sss/env/ADSRcrv2.axo

Inlets

bool32 gate

frac32.bipolar time

frac32.bipolar slope

frac32.bipolar S

frac32.bipolar R

frac32.bipolar crvA

frac32.bipolar crvD

frac32.bipolar crvR

frac32.bipolar Scrv

Outlets

frac32 out

frac32 attack

int32 stage

bool32 nxtStg

Parameters

frac32.u.map slope

frac32.u.map S

frac32.s.map.klineartime.exp time

frac32.s.map R

frac32.s.map crvA

frac32.s.map crvD

frac32.s.map crvR

frac32.s.map ScrvA

frac32.s.map ScrvD

frac32.s.map ScrvR

Declaration
int32_t env1;
int32_t env2;
int32_t env3;
int32_t Cenv1;
int32_t Cenv2;
int32_t Cenv3;
int32_t relLvl;
int trig;
int stage;
int trg;
int32_t curved;
int32_t ccomp;
int prev;
int32_t out;
int32_t enva1;
int32_t enva2;
int32_t remain;
int32_t Attack;
int32_t REM;
int32_t curving(int32_t in, int32_t Exp) {

  in = in >> 3;
  if (Exp < 0) {
    ccomp = (1 << 27) + Exp + ___SMMUL(-Exp << 3, in << 2);
    curved = ___SMMUL(in << 3, ccomp << 2);
    curved = ___SMMUL(curved << 3, ccomp << 2);
    curved = ___SMMUL(curved << 3, ccomp << 2);
    curved = ___SMMUL(curved << 3, ccomp << 2);
    curved = ___SMMUL(curved << 3, ccomp << 2);
  }
  if (Exp >= 0) {
    in = (1 << 27) - in;
    ccomp = (1 << 27) - Exp + ___SMMUL(Exp << 3, in << 2);
    curved = ___SMMUL(in << 3, ccomp << 2);
    curved = ___SMMUL(curved << 3, ccomp << 2);
    curved = ___SMMUL(curved << 3, ccomp << 2);
    curved = ___SMMUL(curved << 3, ccomp << 2);
    curved = ___SMMUL(curved << 3, ccomp << 2);
    curved = ((1 << 27) - curved);
  }
}
Control Rate
int32_t att;
int32_t sus;
int32_t CrvA =
    __SSAT(param_crvA + inlet_crvA +
               ___SMMUL(enva1 - (1 << 29), inlet_Scrv + param_ScrvA << 2),
           28);
int32_t CrvD =
    __SSAT(param_crvD + inlet_crvD -
               ___SMMUL(enva2 - (1 << 29), inlet_Scrv + param_ScrvD << 2),
           28);
int32_t CrvR =
    __SSAT((param_crvR << 1) + inlet_crvR -
               ___SMMUL(env3 - (1 << 29), inlet_Scrv + param_ScrvR << 2),
           28);
sus = __USAT((1 << 27) - param_S - inlet_S, 27);
int32_t slope;
int32_t rel;

slope = (___SMMUL(__USAT(param_slope + inlet_slope, 27) << 3, (1 << 29) - 64)
         << 3) +
        32;
float32_t ratio1 = ((float32_t)(1 << 30)) / (slope);
float32_t ratio2 = ((float32_t)(1 << 30)) / ((1 << 30) - slope);
MTOF(-param_time - inlet_time, att)
MTOF(-param_R - inlet_R, rel)
att = att >> 4;
rel = rel >> 3;

if ((inlet_gate > 0) && !trig) {
  stage = 1;
  trig = 1;
} else if ((!(inlet_gate > 0)) && trig) {
  trig = 0;
  stage = 0;
  remain = out;
  REM = Attack;
  enva1 = 0;
  enva2 = 0;
  env1 = 0;
  env3 = 0;
}

if (stage == 1) {
  env1 += att;
  env1 = __USAT(env1, 30);
  if (env1 >= ((1 << 30) - 1)) {
    stage = 2;
  }
}

if (stage > 0) {
  enva1 = env1 > slope ? slope : env1;
  enva2 = (env1 - enva1) * ratio2;
  enva1 = enva1 * ratio1;
}

curving(env3, -CrvR);
Cenv3 = curved;
Cenv3 = (1 << 27) - Cenv3,

    curving(enva1, CrvA);
Cenv1 = curved;
curving(enva2, -CrvD);
Attack = Cenv1 - curved;
outlet_attack = __USAT(Attack + ___SMMUL(Cenv3 << 3, REM << 2), 27);
Cenv2 = ___SMMUL(curved << 2, sus << 3);

out = __USAT(Cenv1 - Cenv2 + ___SMMUL(Cenv3 << 3, remain << 2), 27);
outlet_out = out;
outlet_nxtStg = prev == stage ? 0 : 1;
outlet_stage = stage;

prev = stage;

env3 += rel;
env3 = __USAT(env3, 30);

Privacy

© 2024 Zrna Research