crossmorph

Time Crossmophing delay Connect "base" to the basedelay output of the BPMext module. Mix crossfades through the timings. -"quant" sets the amount of timings for the mix input/parameter, which goes from 0-64 and then rewraps back to 0. -"step" multiplies the the timing-step (multiplying the base-delay time) -"over" adds an offset to the timing-step when it went over maximum time (still host-tempo synced), this will create some more variation in the crossmorph. -basedelay time could be divided/multiplied before this module to enable polyrithmic delays (eg triplets)
Author: Remco van der Most
License: BSD
Github: sss/delay/crossmorph.axo

Inlets

frac32buffer wave input

frac32 connects to a positive 0-64 modulation

frac32 connects to "basedelay" output on BPMext module

Outlets

int32 connects to a LFO that's connected to the waveinput. (check my LFO's) This can divide the LFO's rate, so it stays the same rate no matter how many steps the quantizer is set to.

frac32buffer out

Parameters

frac32.s.map feedback amount

frac32.u.map.gain wet amount

frac32.u.map.gain dry amount

frac32.u.map mix

int32 sets the amount of timing-steps in the 0-64 range of the "mix"

int32 multiplies the steps so the morph selects different timings each next timing

int32 when the steps pass the maximum delaytime, it wraps and adds an offset to prevent playing the same row of timings

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;
int32_t out;
int32_t feed;
int32_t vi27 = ((1 << 27) - 1);
int32_t READ(int32_t T) {
  uint32_t tmp_d = __USAT(T, 27);
  uint32_t tmp_di = writepos - (tmp_d >> (27 - LENGTHPOW)) - 1;
  uint32_t tmp_w1 = (tmp_d << (LENGTHPOW + 3)) & 0x3FFFFFFF;
  uint32_t tmp_w2 = (1 << 30) - tmp_w1;
  int32_t tmp_a1 = array[tmp_di & LENGTHMASK] << 16;
  int32_t tmp_a2 = array[(tmp_di + 1) & LENGTHMASK] << 16;
  int32_t tmp_r = ___SMMUL(tmp_a1, tmp_w1);
  tmp_r = ___SMMLA(tmp_a2, tmp_w2, tmp_r);
  return out = tmp_r;
}
int32_t hp;
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 rt = (1 << 27) / inlet_base;

int32_t qnt = param_quant;
int32_t step = param_step;

int32_t mix = (param_mix + inlet_mix) & vi27;
int32_t sel1;
int32_t sel2;
sel1 = (int64_t)mix * qnt >> 27;

sel2 = sel1 + 1;
sel2 = sel2 - sel2 / qnt * qnt;
mix = (mix - ((int64_t)((int64_t)sel1 << 27) / qnt)) * qnt;
sel1 = sel1 * step;
sel2 = sel2 * step;
sel1 += sel1 / rt * param_over;
sel2 += sel2 / rt * param_over;
sel1 = (sel1 * inlet_base);
sel2 = (sel2 * inlet_base);
rt = (rt - 1) * inlet_base;
sel1 = sel1 - sel1 / rt * rt + inlet_base;
sel2 = sel2 - sel2 / rt * rt + inlet_base;
outlet_div = qnt;
Audio Rate
writepos = (writepos + 1) & LENGTHMASK;
array[writepos] = __SSAT(inlet_in + feed >> 14, 16);
int32_t tmp = READ(sel1);
feed =
    ___SMMUL(param_feed << 4, tmp + ___SMMUL(READ(sel2) - tmp << 2, mix << 3))
    << 1;
hp += feed - hp >> 9;
feed -= hp;
outlet_out =
    ___SMMUL(inlet_in << 1, param_dry) + ___SMMUL(feed << 2, param_wet);

Privacy

© 2024 Zrna Research