frac32buffer in
frac32 Fb gain
frac32 Fb HP
frac32 Fb LP
frac32 Fb delay
frac32 Fb phi
frac32 Out phi
frac32buffer out
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;
}
for (int i = 0; i < LENGTH; i++)
d[i] = 0;
lhpTheta = lpTheta = 0;
delay = 16 << 21;
fbPhi = outPhi = 0;
aIn = 0;
fbGain = 0;
// 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;
}