frac32 shape parameter
frac32 "rule" for m parameter in chained units
frac32 global feedback
frac32buffer input
frac32buffer out
frac32.u.map shape parameter
frac32.s.map "rule" for m parameter in chained units
frac32.s.map global feedback
spinner chain
// defining some data structures and functions for the object. Hackable.
typedef struct {
int32_t k0 = 0;
int32_t k1 = 0;
int32_t k2 = 0;
int32_t k0_2 = 0;
int32_t k1_4 = 0;
int32_t k2_6 = 0;
} sinefolder_coefs;
typedef struct {
int32_t x_old = 0;
int32_t Y_old = 0;
} sinefolder_state;
void sinefolder_setcoefs(sinefolder_state *state, sinefolder_coefs *coefs,
int32_t xp) {
int32_t xp1 = ___SMMLA(__USAT(xp, 27) << 3, 70317507 << 2, 43683676);
int32_t xp2 = ___SMMUL(xp1 << 2, xp1 << 3);
int32_t xp3 = ___SMMUL(xp2 << 2, xp1 << 3);
int32_t xp4 = ___SMMUL(xp3 << 2, xp1 << 3);
int32_t xp5 = ___SMMUL(xp4 << 2, xp1 << 3);
int32_t xp7 = ___SMMUL(xp5 << 2, xp2 << 3);
float D_rec = 1.0f / ((float)((xp7 << 1) - (xp5 << 2) + (xp3 << 1)));
float Nk1 = 5 * xp4 - (1 << 27);
float Nk2 = (1 << 27) - 3 * xp2;
// k in Q25 format. This way i can go up to k = 64 (massive wavefolding)
int32_t k1 = (1 << 25) * Nk1 * D_rec;
int32_t k2 = (1 << 25) * Nk2 * D_rec;
int32_t k0 = -k1 - k2;
int32_t k0_2 = k0 >> 1;
int32_t k1_4 = k1 >> 2;
int32_t k2_6 = k2 / 6;
(coefs->k0) = k0;
(coefs->k1) = k1;
(coefs->k2) = k2;
(coefs->k0_2) = k0_2;
(coefs->k1_4) = k1_4;
(coefs->k2_6) = k2_6;
int32_t x_old = (state->x_old);
int32_t x1 = x_old;
int32_t x2 = ___SMMUL(x1 << 2, x1 << 3);
int32_t x4 = ___SMMUL(x2 << 2, x2 << 3);
int32_t x6 = ___SMMUL(x2 << 2, x4 << 3);
// x_n are in Q27 format. k_m are in Q25 format. I want to come out in Q24
// format
int32_t Y =
___SMMUL(x2 << 3, k0_2) + ___SMMUL(x4 << 3, k1_4) +
___SMMUL(x6 << 3, k2_6); // 0.5*k0*x2 + 0.25*k1*x4 + 1.f/6.f*k2*x6;
(state->Y_old) = Y;
}
int32_t sinefolder_process(sinefolder_state *state, sinefolder_coefs *coefs,
int32_t input_Q27) {
int32_t x1 = __SSAT(input_Q27, 28);
int32_t x2 = ___SMMUL(x1 << 2, x1 << 3);
int32_t x3 = ___SMMUL(x1 << 2, x2 << 3);
int32_t x4 = ___SMMUL(x1 << 2, x3 << 3);
int32_t x5 = ___SMMUL(x1 << 2, x4 << 3);
int32_t x6 = ___SMMUL(x1 << 2, x5 << 3);
int32_t k0 = (coefs->k0);
int32_t k1 = (coefs->k1);
int32_t k2 = (coefs->k2);
int32_t k0_2 = (coefs->k0_2);
int32_t k1_4 = (coefs->k1_4);
int32_t k2_6 = (coefs->k2_6);
int32_t x_old = (state->x_old);
int32_t Y_old = (state->Y_old);
// x_n are in Q27 format. k_m are in Q25 format. I want to come out in Q24
// format
int32_t y = ___SMMUL(x1 << 3, k0) + ___SMMUL(x3 << 3, k1) +
___SMMUL(x5 << 3, k2); // x1*k0 + x3*k1 + x5*k2;
int32_t Y =
___SMMUL(x2 << 3, k0_2) + ___SMMUL(x4 << 3, k1_4) +
___SMMUL(x6 << 3, k2_6); // 0.5*k0*x2 + 0.25*k1*x4 + 1.f/6.f*k2*x6;
int32_t dx = x1 - x_old;
int32_t dY = Y - Y_old;
int32_t dx_abs = dx > 0 ? dx : -dx;
(state->Y_old) = Y;
(state->x_old) = x1;
int32_t dY_dx = dY * 134217728.0f / ((float)dx);
int32_t out;
if (dx_abs > 1 << 8)
out = dY_dx;
else
out = y;
return out << 4;
}
sinefolder_coefs wf_c[attr_chain];
sinefolder_state wf_s[attr_chain];
int32_t buffer[attr_chain + 1];
for (int i = 0; i < attr_chain; i++)
sinefolder_setcoefs(&wf_s[i], &wf_c[i],
param_m + inlet_m + (i * (param_chain / attr_chain)));
buffer[0] = inlet_in + ___SMMUL(param_feed << 2, buffer[attr_chain] << 3);
for (int i = 0; i < attr_chain; i++)
buffer[i + 1] = sinefolder_process(&wf_s[i], &wf_c[i], buffer[i]);
outlet_out = buffer[attr_chain];