nestAS3

modulatable nested scatter/allpass function for delaylines. Can be used with the factory delayline module to add diffusion to a delay
Author: Remco van der Most
License: BSD
Github: sss/delay/nestAS3.axo

Inlets

frac32buffer size

Outlets

None

Parameters

frac32.u.map scatter

frac32.u.map size

int32.hradio off,scatter,allpass

int32.hradio select

Attributes

combo size

objref del1

objref del2

objref del3

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;
Init
static int16_t _array[attr_poly][1 << attr_size]
    __attribute__((section(".sdram")));
array = &_array[parent->polyIndex][0];
int i;
writepos = 0;
for (i = 0; i < LENGTH; i++)
  array[i] = 0;
Control Rate
int32_t scatter = __USAT(param_scatter, 27) << 4;
int32_t wp = 0;

int32_t POS;

switch (param_select) {
case 0:
  POS = attr_del1.writepos - BUFSIZE - 1 - 1;
  break;
case 1:
  POS = attr_del2.writepos - BUFSIZE - 1 - 1;
  break;
case 2:
  POS = attr_del3.writepos - BUFSIZE - 1 - 1;
  break;
}
Audio Rate
if (param_mode > 0) {
  int32_t sz = __USAT(param_size + inlet_size, 27);
  int32_t size = sz >> 27 - LENGTHPOW;
  int32_t mix = ((uint32_t)sz << 5 + LENGTHPOW) >> 1;

  int32_t in;
  switch (param_select) {
  case 0:
    in = attr_del1.array[POS] << 14;
    break;
  case 1:
    in = attr_del2.array[POS] << 14;
    break;
  case 2:
    in = attr_del3.array[POS] << 14;
    break;
  }
  int32_t t1, t2, t3;
  t2 = ___SMMUL(in, scatter) << 1;
  t3 = array[(writepos - size) & LENGTHMASK] << 14;
  t3 += ___SMMUL((array[(writepos - size) & LENGTHMASK] << 14) - t3, mix) << 1;
  t1 = ___SMMUL(t3, scatter) << 1;

  array[writepos] = __SSAT(in + (param_mode > 1 ? 0 : t2) - t1 >> 14, 16);
  int32_t out;
  if (param_mode == 1) {
    out = __SSAT(t2 + t3 - t1 >> 14, 16);
  } else {
    out = __SSAT(___SMMUL(in - t1 << 1, scatter) + t3 >> 14, 16);
  }

  switch (param_select) {
  case 0:
    attr_del1.array[POS] = out;
    break;
  case 1:
    attr_del2.array[POS] = out;
    break;
  case 2:
    attr_del3.array[POS] = out;
    break;
  }

  writepos = (writepos + 1) & LENGTHMASK;
  switch (param_select) {
  case 0:
    POS = (POS + 1) & attr_del1.LENGTHMASK;
    break;
  case 1:
    POS = (POS + 1) & attr_del2.LENGTHMASK;
    break;
  case 2:
    POS = (POS + 1) & attr_del3.LENGTHMASK;
    break;
  }
}

Privacy

© 2024 Zrna Research