quadEnv

Quad Attack/decay envelope, linear attack, exponential decay. "Amin", "Amax", "Dmin" and "Dmax" define the range of the attack and decay values for all 4 envelope generators. Values are spreaded following a sine-curve of 45 degrees offset for each envelope. "Amorph" and "Dmorph" set the position within the sine-curve, allowing to morph all attack and decay values simultanuously between minimum and maximum range.
Author: Remco van der Most
License: BSD
Github: sss/env/quadEnv.axo

Inlets

bool32.rising trigger

bool32.rising trig2

bool32.rising trig3

bool32.rising trig4

frac32 Amorph

frac32 Dmorph

Outlets

frac32.positive envelope output

frac32.positive env2

frac32.positive env3

frac32.positive env4

frac32.positive max

Parameters

frac32.s.map.kdecaytime.exp Amax

frac32.u.map Amorph

frac32.u.map Dmin

frac32.u.map Dmax

frac32.u.map Dmorph

frac32.s.map.klineartime.exp Amin

Declaration
int8_t stage[4];
int ntrig[4];
int32_t val[4];
int trig[4];
int32_t a[4];
int32_t d[4];
int32_t sine[8];
int i;
int32_t max1;
int32_t max2;
Init
for (i = 0; i < 4; i++) {
  ntrig[i] = 0;
  val[i] = 0;
}
Control Rate
trig[0] = inlet_trig1;
trig[1] = inlet_trig2;
trig[2] = inlet_trig3;
trig[3] = inlet_trig4;

SINE2TINTERP((inlet_Amorph + param_Amorph) << 5, sine[0])
SINE2TINTERP((inlet_Amorph + param_Amorph + (1 << 26)) << 5, sine[1])
sine[0] = (sine[0] >> 5) + (1 << 26);
sine[1] = (sine[1] >> 5) + (1 << 26);
sine[2] = (1 << 27) - sine[0];
sine[3] = (1 << 27) - sine[1];

SINE2TINTERP((inlet_Dmorph + param_Dmorph) << 5, sine[4])
SINE2TINTERP((inlet_Dmorph + param_Dmorph + (1 << 26)) << 5, sine[5])
sine[4] = (sine[4] >> 5) + (1 << 26);
sine[5] = (sine[5] >> 5) + (1 << 26);
sine[6] = (1 << 27) - sine[4];
sine[7] = (1 << 27) - sine[5];

for (i = 0; i < 4; i++) {
  a[i] = (1 << 27) - param_Amin -
         ___SMMUL((param_Amax - param_Amin) << 3, sine[i] << 2);
  d[i] = (((1 << 27) - param_Dmin) -
          ___SMMUL((param_Dmax - param_Dmin) << 3, sine[i + 4] << 2));
  d[i] = ___SMMUL(d[i] << 3, d[i] << 2);

  if ((trig[i] > 0) && !ntrig[i]) {
    ntrig[i] = 1;
    stage[i] = 1;
  } else if (!(trig[i] > 0)) {
    ntrig[i] = 0;
  }
  if (stage[i] == 0) {
    val[i] = val[i] - (___SMMUL(val[i], d[i]) << 1);
  } else {
    int32_t t;
    MTOF(a[i], t);
    val[i] = val[i] + (t >> 3);
    if (val[i] < 0) {
      val[i] = 0x7FFFFFFF;
      stage[i] = 0;
    }
  }
}
outlet_env1 = val[0] >> 4;
outlet_env2 = val[1] >> 4;
outlet_env3 = val[2] >> 4;
outlet_env4 = val[3] >> 4;
max1 = outlet_env1 > outlet_env2 ? outlet_env1 : outlet_env2;
max2 = max1 > outlet_env3 ? max1 : outlet_env3;
outlet_max = max2 > outlet_env4 ? max2 : outlet_env4;

Privacy

© 2024 Zrna Research