GUITAR

4/8 stage FDN reverb network has overall decay and size parameters for quick adjusting the reverb times can be modulated by internal LFOs which are evenly phase-spreaded sines.
Author: Remco van der Most
License: BSD
Github: sss/synth/GUITAR.axo

Inlets

frac32buffer wave input

frac32buffer inR

Outlets

frac32buffer outL

frac32buffer outR

Parameters

frac32.s.map.lfopitch rate

frac32.s.map depth

frac32.s.map spread

bool32.tgl sine

bool32.tgl rnd

bool32.tgl stages

frac32.u.map.kdecaytime decay

frac32.u.map size

frac32.u.map t1

frac32.u.map t2

frac32.u.map t3

frac32.u.map t4

frac32.u.map t5

frac32.u.map t6

frac32.u.map t7

frac32.u.map t8

frac32.u.map dry

frac32.u.map wet

Attributes

combo size

Declaration
static const uint32_t LENGTHPOW = (attr_size);
static const uint32_t LENGTH = (1 << attr_size);
static const uint32_t LENGTHMASK = ((1 << attr_size) - 1);
int16_t *array;
uint32_t writepos;
int i;
int32_t t[8];
int32_t J[8];
int32_t phase;
bool rtrg;
Init
static int16_t _array[1 << attr_size + 3] __attribute__((section(".sdram")));
array = &_array[0];

writepos = 0;
for (i = 0; i < LENGTH << 2; i++)
  array[i] = 0;
Control Rate
int32_t decay = param_decay << 1;
int32_t rate;
int32_t stages = param_stages > 0 ? 8 : 4;
int sm = stages - 1;
int32_t ON = param_stages > 0 ? 1 : 0;
MTOFEXTENDED(param_rate, rate)
phase += rate >> 4;
int32_t sine[8];
for (i = 0; i < stages; i++) {
  if (param_sine > 0) {
    SINE2TINTERP(phase + i * (1 << 30 - ON), sine[i])
  } else {
    sine[i] = phase + (i * (param_spread << 3) << 3 - ON);
    sine[i] = sine[i] > 0 ? sine[i] : -sine[i];
  }
  sine[i] = ___SMMUL(param_depth, sine[i]) >> 31 - LENGTHPOW;
}

t[0] = param_t1 >> 27 - LENGTHPOW;
t[1] = param_t2 >> 27 - LENGTHPOW;
t[2] = param_t3 >> 27 - LENGTHPOW;
t[3] = param_t4 >> 27 - LENGTHPOW;
t[4] = param_t5 >> 27 - LENGTHPOW;
t[5] = param_t6 >> 27 - LENGTHPOW;
t[6] = param_t7 >> 27 - LENGTHPOW;
t[7] = param_t8 >> 27 - LENGTHPOW;

for (i = 0; i < stages; i++) {
  t[i] = sine[i] + ___SMMUL(t[i] << 3, param_size << 4);
}

if ((param_rnd > 0) && !rtrg) {
  rtrg = 1;
  for (i = 0; i < stages; i++) {
    PExParameterChange(&parent->PExch[PARAM_INDEX_attr_legal_name_t1 + i],
                       (int32_t)GenerateRandomNumber() & ((1 << 27) - 1),
                       0xFFFD);
  }
} else if (param_rnd == 0) {
  rtrg = 0;
}
Audio Rate
writepos = (writepos + 1) & LENGTHMASK;

int32_t O[8];
int32_t I[8];
for (i = 0; i < stages; i++) {
  O[i] = array[(writepos - t[i]) & LENGTHMASK];
}

for (i = 0; i < stages; i++) {
  I[i] = ___SMMUL(
      decay,
      -(__SSAT(((i & 1) > 0 ? inlet_inL : inlet_inR) >> 14, 16) - O[i] +
        O[(i + 1) & sm] + O[(i + 2) & sm] + O[(i + 3) & sm] +
        (O[(i + 4) & 7] + O[(i + 5) & 7] + O[(i + 6) & 7] + O[(i + 7) & 7]) *
            ON)
          << 3 - ON);
  J[i] += (I[i] - J[i]) - ((I[i] - J[i]) >> 3);
  array[writepos + i * LENGTH] = J[i];
}

outlet_outL =
    ___SMMUL(((J[0] + J[2] + (J[4] + J[6]) * ON) << 15) << 2, -param_wet << 3) +
    ___SMMUL(inlet_inL << 2, param_dry << 3);
outlet_outR =
    ___SMMUL(((J[1] + J[3] + (J[5] + J[7]) * ON) << 15) << 2, -param_wet << 3) +
    ___SMMUL(inlet_inR << 2, param_dry << 3);

Privacy

© 2024 Zrna Research