MSPPdelay

mono to stereo pingpong delay with modulatable predelay and feedback time -predelay sets the time the first delayed signal is fed to the output. -feedtime sets the time for feedback after the predelay -both can be modulated externally->use conv/interp module to convert control-rate signals to audio-rate for smooth low frequency modulation. -modulation width can be attenuated with the AttMod selector (higher values will give smaller modulation ranges) with their respective controls, both predelay and feedback time can be made different between left and right delay channel, but summed time of left and right will stay the same. the predelay can be added to the feedback signal to provide an extra "hit" into the decaying delay.
Author: Remco van der Most
License: BSD
Github: sss/delay/MSPPdelay.axo

Inlets

frac32buffer in

frac32buffer predelay

frac32buffer feedtime

frac32 pan

frac32 Pre

frac32 Feed

Outlets

frac32buffer outL

frac32buffer outR

int32 PowOut

Parameters

frac32.u.map predelay

frac32.u.map feedtime

frac32.s.map diffPre

frac32.s.map diffFeed

frac32.s.map feed

int32 AttMod

bool32.tgl addPre

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);
int32_t *array1;
int32_t *array2;
uint32_t writepos;
int32_t memL;
int32_t memR;
Init
static int32_t _array1[attr_poly][1 << attr_size]
    __attribute__((section(".sdram")));
array1 = &_array1[parent->polyIndex][0];
static int32_t _array2[attr_poly][1 << attr_size]
    __attribute__((section(".sdram")));
array2 = &_array2[parent->polyIndex][0];
int i;
writepos = 0;
for (i = 0; i < LENGTH; i++) {
  array1[i] = 0;
  array2[i] = 0;
}
Control Rate
outlet_PowOut = attr_size;
int32_t diff1 = ___SMMUL(param_diffPre << 3, (param_predelay + inlet_Pre) << 2);
int32_t diff2 =
    ___SMMUL(param_diffFeed << 3, (param_feedtime + inlet_Feed) << 2);
Audio Rate
writepos = (writepos + 1) & LENGTHMASK;
int32_t temp1 =
    __SSAT(___SMMUL(inlet_in << 3, (inlet_pan + (1 << 27)) << 1), 29);
int32_t temp2 =
    __SSAT(___SMMUL(inlet_in << 3, (-inlet_pan + (1 << 27)) << 1), 29);

array1[writepos] += temp1;
array2[writepos] += temp2;
int32_t predelay1 = __USAT(
    param_predelay + diff1 - (inlet_predelay >> param_AttMod) + inlet_Pre, 27);
uint32_t tmp_dwrite =
    predelay1 - (__USAT(-(inlet_feedtime >> param_AttMod) + diff2 +
                            param_feedtime + inlet_Feed,
                        27));
uint32_t tmp_diwrite = writepos - (tmp_dwrite >> (27 - LENGTHPOW));
uint32_t tmp_w1write = (tmp_dwrite << (LENGTHPOW + 3)) & 0x3FFFFFFF;
uint32_t tmp_w2write = (1 << 30) - tmp_w1write;
memL = ___SMMUL(memR + inlet_in * (param_addPre) << 3, param_feed << 2);
array1[tmp_diwrite & LENGTHMASK] += ___SMMUL(memL << 4, tmp_w1write);
array1[(tmp_diwrite + 1) & LENGTHMASK] += ___SMMUL(memL << 4, tmp_w2write);

int32_t predelay2 = __USAT(
    param_predelay - diff1 + (inlet_predelay >> param_AttMod) + inlet_Pre, 27);
tmp_dwrite = predelay2 - (__USAT((inlet_feedtime >> param_AttMod) - diff2 +
                                     param_feedtime + inlet_Feed,
                                 27));
tmp_diwrite = writepos - (tmp_dwrite >> (27 - LENGTHPOW));
tmp_w1write = (tmp_dwrite << (LENGTHPOW + 3)) & 0x3FFFFFFF;
tmp_w2write = (1 << 30) - tmp_w1write;
memR = ___SMMUL(memL + inlet_in * (param_addPre) << 3, param_feed << 2);
array2[tmp_diwrite & LENGTHMASK] += ___SMMUL(memR << 4, tmp_w1write);
array2[(tmp_diwrite + 1) & LENGTHMASK] += ___SMMUL(memR << 4, tmp_w2write);

uint32_t tmp_dread = predelay1;
uint32_t tmp_diread = writepos - (tmp_dread >> (27 - LENGTHPOW));
uint32_t tmp_w1read = (tmp_dread << (LENGTHPOW + 3)) & 0x3FFFFFFF;
uint32_t tmp_w2read = (1 << 30) - tmp_w1read;
int32_t tmp_a1read = array1[tmp_diread & LENGTHMASK];
int32_t tmp_a2read = array1[(tmp_diread + 1) & LENGTHMASK];
int32_t tmp_rread = ___SMMUL(tmp_a1read, tmp_w1read);
tmp_rread = ___SMMLA(tmp_a2read, tmp_w2read, tmp_rread);
memL = tmp_rread;

tmp_dread = predelay2;
tmp_diread = writepos - (tmp_dread >> (27 - LENGTHPOW));
tmp_w1read = (tmp_dread << (LENGTHPOW + 3)) & 0x3FFFFFFF;
tmp_w2read = (1 << 30) - tmp_w1read;
tmp_a1read = array2[tmp_diread & LENGTHMASK];
tmp_a2read = array2[(tmp_diread + 1) & LENGTHMASK];
tmp_rread = ___SMMUL(tmp_a1read, tmp_w1read);
tmp_rread = ___SMMLA(tmp_a2read, tmp_w2read, tmp_rread);
memR = tmp_rread;

array1[(writepos + LENGTHMASK / 4) & LENGTHMASK] = 0;
array2[(writepos + LENGTHMASK / 4) & LENGTHMASK] = 0;

outlet_outL = ___SMMUL(memR << 3, param_feed << 3) + temp1;
outlet_outR = ___SMMUL(memL << 3, param_feed << 3) + temp2;
//      outlet_out= mem;

Privacy

© 2024 Zrna Research