frac32.bipolar pitch
frac32buffer.bipolar wf16
bool32 update
frac32buffer.bipolar out
frac32.s.map.pitch pitch
static const int LEN = 16;
bool _update = false;
float x[16], dx[16], Ix[16], IIx[16], x1_2[16], dx1_6[16];
float _dp2, y0, y1, y2;
uint32_t p, dp;
float I2(uint32_t p) {
uint8_t i = (p >> (32 - 4)) & (15);
float a = (p & ((1 << (32 - 4)) - 1)) * (1.0f / (1 << (32 - 4)));
// p q27
/* uint8_t i = (p >> (27-4))&(4-1);
float a = (p & ((1<<(27-4))-1)) * (1.0f/(1<<(27-4)));
*/
return IIx[i] + a * (Ix[i] + a * (x1_2[i] + a * dx1_6[i]));
}
y0 = y1 = y2 = 0;
p = 0;
if (inlet_update && !_update) {
const int16_t *xStartEnd = (const int16_t *)inlet_wf16;
// q15 to q27 float
float coef = (float)(1 << (27 - 15));
for (int i = 0; i < 16; i++) {
x[i] = coef * xStartEnd[i * 2];
dx[i] = coef * (xStartEnd[i * 2 + 1] - xStartEnd[i * 2]);
}
// Table update
float dc = x[0] + 0.5f * dx[0];
for (int i = 1; i < LEN; i++)
dc += x[i] + 0.5f * dx[i];
dc *= 1.0f / LEN;
for (int i = 0; i < LEN; i++)
x[i] -= dc;
Ix[0] = 0;
for (int i = 0; i < LEN - 1; i++)
Ix[i + 1] = Ix[i] + x[i] + 0.5f * dx[i];
for (int i = 0; i < LEN; i++) {
x1_2[i] = 0.5f * x[i];
dx1_6[i] = (1.0f / 6) * dx[i];
}
dc = Ix[0] + x1_2[0] + dx1_6[0];
for (int i = 1; i < LEN; i++)
dc += Ix[i] + x1_2[i] + dx1_6[i];
dc *= 1.0f / LEN;
for (int i = 0; i < LEN; i++)
Ix[i] -= dc;
IIx[0] = 0;
for (int i = 0; i < LEN - 1; i++)
IIx[i + 1] = IIx[i] + Ix[i] + x1_2[i] + dx1_6[i];
}
_update = inlet_update;
// state variables update
MTOFEXTENDED(param_pitch + inlet_pitch, dp);
_dp2 = (1 << 28) / (float)(dp);
_dp2 *= _dp2;
// change of dp => update state variables y1 y2
p -= dp;
y2 = I2(p);
p += dp;
y1 = I2(p);
p += dp;
y0 = I2(p);
outlet_out = (int32_t)((y0 + y2 - 2 * y1) * _dp2);
y2 = y1;
y1 = y0;