reed

Reed
Author: Smashed Transistors
License: LGPL
Github: tiar/pata/reed.axo

Inlets

frac32buffer in

frac32 Fb gain

frac32 Fb HP

frac32 Fb LP

frac32 Fb delay

frac32 Fb phi

frac32 Out phi

Outlets

frac32buffer out

Declaration
static const uint32_t LENGTHPOW = 6;
static const uint32_t LENGTH = 1 << LENGTHPOW;
static const uint32_t LENGTHMASK = LENGTH - 1;

static const uint32_t INTERP_RIGHT_SHIFT = 27 - LENGTHPOW;
static const uint32_t INTERP_LEFT_SHIFT = 31 - INTERP_RIGHT_SHIFT;

int32_t d[LENGTH];
uint32_t ind;
int32_t lhpTheta;
int32_t lpTheta;
int32_t delay;
int32_t fbPhi, outPhi;
int32_t aIn;
int32_t fbGain;

int32_t interp(uint32_t ind, int32_t p) {
  // int32_t a = p&((1<<(27-LOG2))-1); //q27-LOG2
  // a <<= 31-(27-LOG2); //q31

  int32_t i = (ind + (p >> INTERP_RIGHT_SHIFT)) & LENGTHMASK;
  int32_t d0 = d[i];
  int32_t a = (p << INTERP_LEFT_SHIFT) & 0x7FFFFFFF; // q31
  return ___SMMLA(a, (d[(i + 1) & LENGTHMASK] - d0) << 1, d0);
}
int32_t calcCoef(int32_t pitch) { // q30
  uint32_t F;
  MTOFEXTENDED(pitch, F);

  int32_t a = (1 << 30) - (F >> 6);
  for (int i = 0; i < 6; i++) {
    a = ___SMMUL(a, a) << 2;
  }
  return (1 << 30) - a;
}
Init
for (int i = 0; i < LENGTH; i++)
  d[i] = 0;
lhpTheta = lpTheta = 0;
delay = 16 << 21;
fbPhi = outPhi = 0;
aIn = 0;
fbGain = 0;
Control Rate
// int32_t lpCoef;
// MTOF(inlet_Fb_space_LP, lpCoef);
int32_t lpCoef = calcCoef(inlet_Fb_space_LP);

int32_t hpCoef = calcCoef(inlet_Fb_space_HP);

// delay control is linearly interpolated
int32_t newDelay = inlet_Fb_space_delay;
if (newDelay < 0)
  newDelay = 0;
if (newDelay > (63 << 21))
  newDelay = 63 << 21;

for (int smp = 0; smp < BUFSIZE; smp++) {

  // parameters update on zero crossings
  if ((aIn < 0) != (inlet_in[smp] < 0)) {
    fbGain = inlet_Fb_space_gain;
    fbPhi = inlet_Fb_space_phi + (16 << 21);   //(16<<21) offset sine -> cosine
    outPhi = inlet_Out_space_phi + (16 << 21); //(16<<21) offset sine -> cosine
    delay = newDelay;
  }
  aIn = inlet_in[smp];

  // delayed Theta
  int32_t currentTheta = interp(ind, delay);
  ind--;
  ind &= LENGTHMASK;

  // output
  // sine2t -> 4096 entrie sine table, q31 fixed point format
  int32_t cosOut = sine2t[((currentTheta + outPhi) & 0x07FFFFFF) >> 15];
  outlet_out[smp] = ___SMMUL(cosOut, inlet_in[smp]) << 1;

  // feedback
  int32_t cosFb = sine2t[((currentTheta + fbPhi) & 0x07FFFFFF) >> 15];
  int32_t newTheta = ___SMMUL(cosFb, ___SMMUL(inlet_in[smp], fbGain) << 6);
  lpTheta = ___SMMLA((newTheta - lpTheta) << 2, lpCoef, lpTheta);
  lhpTheta = ___SMMLA((lpTheta - lhpTheta) << 2, hpCoef, lhpTheta);
  d[ind] = lpTheta - lhpTheta;
}

Privacy

© 2024 Zrna Research