allpass int 3

3 modulatable 32bit schroeder allpass filters with different types of interpolation (for reverbs and diffusers)
Author: Jaffasplaffa (Original by Johannes Elliesen)
License: none yet
Github: jaffa/filt/allpass int 3.axo

Inlets

frac32buffer in

frac32buffer two

frac32buffer three

frac32.positive time

frac32.positive gain

frac32.positive time2

frac32.positive gain2

frac32.positive time3

frac32.positive gain3

frac32.bipolar timemod

frac32.bipolar timemod2

frac32.bipolar timemod3

Outlets

frac32buffer out

frac32buffer two

frac32buffer three

Attributes

combo buffsize

combo interpol

combo location

Declaration
// 1//
#if attr_location == 0
#define LOCATION
#else
#define LOCATION __attribute__((section(".sdram")))
#endif
static const uint32_t LENGTHPOW = (attr_buffsize);
static const uint32_t LENGTH = (1 << attr_buffsize);
static const uint32_t LENGTHMASK = ((1 << attr_buffsize) - 1);

int32_t *delayline;
int wptr;

// 2//
#if attr_location == 0
#define LOCATION2
#else
#define LOCATION2 __attribute__((section(".sdram")))
#endif
static const uint32_t LENGTHPOW2 = (attr_buffsize);
static const uint32_t LENGTH2 = (1 << attr_buffsize);
static const uint32_t LENGTHMASK2 = ((1 << attr_buffsize) - 1);

int32_t *delayline2;
int wptr2;

// 3//
#if attr_location == 0
#define LOCATION3
#else
#define LOCATION3 __attribute__((section(".sdram")))
#endif
static const uint32_t LENGTHPOW3 = (attr_buffsize);
static const uint32_t LENGTH3 = (1 << attr_buffsize);
static const uint32_t LENGTHMASK3 = ((1 << attr_buffsize) - 1);

int32_t *delayline3;
int wptr3;
Init
// Hvad med de der parent og poly index??? //

static int32_t array_[attr_poly][LENGTH] LOCATION;
delayline = &array_[parent->polyIndex][0];

for (int i = 0; i < LENGTH; i++)
  delayline[i] = 0;
wptr = 0;

static int32_t array2_[attr_poly][LENGTH2] LOCATION2;
delayline2 = &array2_[parent->polyIndex][0];

for (int i2 = 0; i2 < LENGTH2; i2++)
  delayline2[i2] = 0;
wptr2 = 0;

static int32_t array3_[attr_poly][LENGTH3] LOCATION3;
delayline3 = &array3_[parent->polyIndex][0];

for (int i3 = 0; i3 < LENGTH3; i3++)
  delayline3[i3] = 0;
wptr3 = 0;
Control Rate
// 1 //
int32_t g2 = inlet_gain << 3;

int32_t time = ___SMMUL(inlet_time, inlet_timemod) + inlet_time;
int32_t readOffset_ls8 = ___SMMUL(LENGTH << 10, time << 3);

if (readOffset_ls8 < (8 << 8))
  readOffset_ls8 = (8 << 8); // never less delay than 8 samples

#if attr_interpol > 0
int32_t rint = readOffset_ls8 >> 8; // integral part of delay time
int32_t rfrac =
    readOffset_ls8 & 0x000000FF; // fractional part of delay time in Q8 notation
#endif

// pre-calculate coefficients for 3pt interpolation
#if attr_interpol == 2

int32_t x2 = (rfrac * rfrac); // x^2 in Q16 notation
// in Q16 notation
int32_t c1 = (1 << 16) + (x2 >> 1) - (rfrac << 7) - (rfrac << 8);
int32_t c2 = -x2 + (rfrac << 9);
int32_t c3 = (x2 >> 1) - (rfrac << 7);
#endif

// 2 //
int32_t g22 = inlet_gain2 << 3;

int32_t time2 = ___SMMUL(inlet_time2, inlet_timemod2) + inlet_time2;
int32_t readOffset_ls82 = ___SMMUL(LENGTH2 << 10, time2 << 3);

if (readOffset_ls82 < (8 << 8))
  readOffset_ls82 = (8 << 8); // never less delay than 8 samples

#if attr_interpol > 0
int32_t rint2 = readOffset_ls82 >> 8; // integral part of delay time
int32_t rfrac2 = readOffset_ls82 &
                 0x000000FF; // fractional part of delay time in Q8 notation
#endif

// pre-calculate coefficients for 3pt interpolation
#if attr_interpol == 2

int32_t x22 = (rfrac2 * rfrac2); // x^2 in Q16 notation
// in Q16 notation
int32_t c12 = (1 << 16) + (x22 >> 1) - (rfrac2 << 7) - (rfrac2 << 8);
int32_t c22 = -x22 + (rfrac2 << 9);
int32_t c32 = (x22 >> 1) - (rfrac2 << 7);
#endif

// 3 //
int32_t g23 = inlet_gain3 << 3;

int32_t time3 = ___SMMUL(inlet_time3, inlet_timemod3) + inlet_time3;
int32_t readOffset_ls83 = ___SMMUL(LENGTH3 << 10, time3 << 3);

if (readOffset_ls83 < (8 << 8))
  readOffset_ls83 = (8 << 8); // never less delay than 8 samples

#if attr_interpol > 0
int32_t rint3 = readOffset_ls83 >> 8; // integral part of delay time
int32_t rfrac3 = readOffset_ls83 &
                 0x000000FF; // fractional part of delay time in Q8 notation
#endif

// pre-calculate coefficients for 3pt interpolation
#if attr_interpol == 2

int32_t x3 = (rfrac3 * rfrac3); // x^2 in Q16 notation
// in Q16 notation
int32_t c13 = (1 << 16) + (x3 >> 1) - (rfrac3 << 7) - (rfrac3 << 8);
int32_t c23 = -x3 + (rfrac3 << 9);
int32_t c33 = (x3 >> 1) - (rfrac3 << 7);
#endif
Audio Rate
// no interpolation
#if attr_interpol == 0
int32_t rptr = wptr - (readOffset_ls8 >> 8);
int32_t dout = delayline[rptr & LENGTHMASK];
// linear (2pt) interpolation
#elif attr_interpol == 1
int32_t rptr1 = wptr - rint;
int32_t rptr2 = rptr1 + 1;
int32_t dout1 = delayline[rptr2 & LENGTHMASK] >> 1;
int32_t dout2 = delayline[rptr1 & LENGTHMASK] >> 1;
int32_t dout = ___SMMLA(rfrac << 23, (dout2 - dout1) << 1, dout1) << 1;
// qubic (3pt) interpolation
#elif attr_interpol == 2
int32_t rptr1 = wptr - rint;
int32_t rptr2 = rptr1 + 1;
int32_t rptr3 = rptr1 + 2;

int32_t dout1 = delayline[rptr3 & LENGTHMASK];
int32_t dout2 = delayline[rptr2 & LENGTHMASK];
int32_t dout3 = delayline[rptr1 & LENGTHMASK];
int32_t douttmp1 = ___SMMUL(dout1, c1 << 14);
int32_t douttmp2 = ___SMMLA(dout2, c2 << 14, douttmp1);
int32_t dout = ___SMMLA(dout3, c3 << 14, douttmp2) << 2;
#endif

int32_t din = ___SMMLA(g2, dout, inlet_in >> 2) << 1;
delayline[wptr] = din;
outlet_out = ___SMMLS(g2, din, dout >> 1) << 2;
wptr = (wptr + 1) & LENGTHMASK;

// no interpolation
#if attr_interpol == 0
int32_t rptr2 = wptr2 - (readOffset_ls82 >> 8);
int32_t dout222 = delayline2[rptr2 & LENGTHMASK2];
// linear (2pt) interpolation
#elif attr_interpol == 1
int32_t rptr12 = wptr2 - rint2;
int32_t rptr22 = rptr12 + 1;
int32_t dout12 = delayline2[rptr22 & LENGTHMASK2] >> 1;
int32_t dout22 = delayline2[rptr12 & LENGTHMASK2] >> 1;
int32_t dout222 = ___SMMLA(rfrac2 << 23, (dout22 - dout12) << 1, dout12) << 1;
// qubic (3pt) interpolation
#elif attr_interpol == 2
int32_t rptr12 = wptr2 - rint2;
int32_t rptr22 = rptr12 + 1;
int32_t rptr32 = rptr12 + 2;

int32_t dout12 = delayline2[rptr32 & LENGTHMASK2];
int32_t dout22 = delayline2[rptr22 & LENGTHMASK2];
int32_t dout32 = delayline2[rptr12 & LENGTHMASK2];
int32_t douttmp12 = ___SMMUL(dout12, c12 << 14);
int32_t douttmp22 = ___SMMLA(dout22, c22 << 14, douttmp12);
int32_t dout222 = ___SMMLA(dout32, c32 << 14, douttmp22) << 2;
#endif

int32_t din2 = ___SMMLA(g22, dout222, inlet_two >> 2) << 1;
delayline2[wptr2] = din2;
outlet_two = ___SMMLS(g22, din2, dout222 >> 1) << 2;
wptr2 = (wptr2 + 1) & LENGTHMASK2;

// no interpolation
#if attr_interpol == 0
int32_t rptr3 = wptr3 - (readOffset_ls83 >> 8);
int32_t dout333 = delayline3[rptr3 & LENGTHMASK3];
// linear (2pt) interpolation
#elif attr_interpol == 1
int32_t rptr13 = wptr3 - rint3;
int32_t rptr23 = rptr13 + 1;
int32_t dout13 = delayline3[rptr23 & LENGTHMASK3] >> 1;
int32_t dout23 = delayline3[rptr13 & LENGTHMASK3] >> 1;
int32_t dout333 = ___SMMLA(rfrac3 << 23, (dout23 - dout13) << 1, dout13) << 1;
// qubic (3pt) interpolation
#elif attr_interpol == 2
int32_t rptr13 = wptr3 - rint3;
int32_t rptr23 = rptr13 + 1;
int32_t rptr33 = rptr13 + 2;

int32_t dout13 = delayline3[rptr33 & LENGTHMASK3];
int32_t dout23 = delayline3[rptr23 & LENGTHMASK3];
int32_t dout33 = delayline3[rptr13 & LENGTHMASK3];
int32_t douttmp13 = ___SMMUL(dout13, c13 << 14);
int32_t douttmp23 = ___SMMLA(dout23, c23 << 14, douttmp13);
int32_t dout333 = ___SMMLA(dout33, c33 << 14, douttmp23) << 2;
#endif

int32_t din3 = ___SMMLA(g23, dout333, inlet_three >> 2) << 1;
delayline3[wptr3] = din3;
outlet_three = ___SMMLS(g23, din3, dout333 >> 1) << 2;
wptr3 = (wptr3 + 1) & LENGTHMASK3;

Privacy

© 2024 Zrna Research