frac32.bipolar vib0
frac32.bipolar vib1
frac32.bipolar vib2
frac32.positive waveform
frac32buffer.bipolar out
frac32.u.map L
frac32.s.map.kdecaytime.exp A
frac32.s.map.kdecaytime.exp R1
frac32.s.map.kdecaytime.exp R2
int32_t y[8], v, integ;
uint8_t i;
int8_t gates[128];
int32_t envs[8 * 12];
int32_t envc[8 * 12];
uint16_t spl;
int8_t dyad[256] = {
7, 6, 7, 5, 7, 6, 7, 4, 7, 6, 7, 5, 7, 6, 7, 3, 7, 6, 7, 5, 7, 6, 7, 4,
7, 6, 7, 5, 7, 6, 7, 2, 7, 6, 7, 5, 7, 6, 7, 4, 7, 6, 7, 5, 7, 6, 7, 3,
7, 6, 7, 5, 7, 6, 7, 4, 7, 6, 7, 5, 7, 6, 7, 1, 7, 6, 7, 5, 7, 6, 7, 4,
7, 6, 7, 5, 7, 6, 7, 3, 7, 6, 7, 5, 7, 6, 7, 4, 7, 6, 7, 5, 7, 6, 7, 2,
7, 6, 7, 5, 7, 6, 7, 4, 7, 6, 7, 5, 7, 6, 7, 3, 7, 6, 7, 5, 7, 6, 7, 4,
7, 6, 7, 5, 7, 6, 7, 0, 7, 6, 7, 5, 7, 6, 7, 4, 7, 6, 7, 5, 7, 6, 7, 3,
7, 6, 7, 5, 7, 6, 7, 4, 7, 6, 7, 5, 7, 6, 7, 2, 7, 6, 7, 5, 7, 6, 7, 4,
7, 6, 7, 5, 7, 6, 7, 3, 7, 6, 7, 5, 7, 6, 7, 4, 7, 6, 7, 5, 7, 6, 7, 1,
7, 6, 7, 5, 7, 6, 7, 4, 7, 6, 7, 5, 7, 6, 7, 3, 7, 6, 7, 5, 7, 6, 7, 4,
7, 6, 7, 5, 7, 6, 7, 2, 7, 6, 7, 5, 7, 6, 7, 4, 7, 6, 7, 5, 7, 6, 7, 3,
7, 6, 7, 5, 7, 6, 7, 4, 7, 6, 7, 5, 7, 6, 7, -1};
class BLIT {
public:
int32_t sgn[8];
int32_t env[8];
int32_t val[8];
uint32_t per = 5 << 10;
uint16_t nextSpl = 0;
uint32_t next = 0;
uint8_t cpt = 0;
void setF(float f) { per = (uint32_t)(48000.0f * (1 << (6 + 10)) / f); }
void init(float f) {
setF(f);
for (int i = 0; i < 8; i++) {
env[i] = 0;
val[i] = 0;
sgn[i] = 1;
}
}
void proc(uint16_t spl, int8_t *dyad, int32_t *y, int i) {
if (spl == nextSpl) {
int8_t oct = dyad[cpt];
sgn[oct] *= -1;
int32_t ampli = sgn[oct] * env[oct] - val[oct];
val[oct] += ampli;
// select the band limited pulse according to subsample time since the
// transition
const int16_t *t = tiar_bli_8_64 + 8 * (((next >> 10) & 63));
// add the selected band limited pulse to the output 8 taps
for (int j = 0; j <= 7; j++) {
y[(i - j) & 7] += ampli * t[j];
}
next += per;
cpt++;
if (cpt == 255) { // skip the last one
cpt = 0;
next += per;
}
nextSpl = (next >> (6 + 10)) & 65535;
}
}
};
BLIT blit[12];
y[0] = y[1] = y[2] = y[3] = y[4] = y[5] = y[6] = y[7] = v = integ = 0;
i = 0;
spl = 0;
float f = 4186.009f * 4;
for (int i = 0; i < 12; i++) {
blit[i].init(f);
f *= 1.059463094f;
}
for (int i = 0; i < 128; i++) {
gates[i] = 0;
}
for (int i = 0; i < 8 * 12; i++) {
envs[i] = 0;
}
float vib0 = inlet_vib0 * 1e-10f;
float vib1 = inlet_vib1 * 1e-10f;
float vib2 = inlet_vib2 * 1e-10f;
float f = 4186.009f * 4;
for (int i = 0; i < 12; i += 3) {
blit[i].setF(f * vib0 + f);
f *= 1.059463094f;
blit[i + 1].setF(f * vib1 + f);
f *= 1.059463094f;
blit[i + 2].setF(f * vib2 + f);
f *= 1.059463094f;
}
float envTot = 0;
for (int i = 0; i < 8 * 12; i++) {
int32_t b = envs[i];
if (gates[24 + i] > 10)
envs[i] = ___SMMLA(0x7FFFFFFF - param_A, (100 << 20) - b, b >> 1)
<< 1; // ascending
else if (b > param_L)
envs[i] = ___SMMUL(b, param_R1) << 1;
else
envs[i] = ___SMMUL(b, param_R2) << 1;
envTot += envs[i];
}
int32_t comp = arm::float_to_q(10000000 / sqrtf(envTot + (1 << 27)), 27);
for (int i = 0; i < 8 * 12; i++) {
envc[i] = ___SMMUL(envs[i], comp);
}
for (int i = 0; i < 12; i++) {
for (int oct = 0; oct < 8; oct++) {
blit[i].env[oct] = (envc[i + 12 * oct] >> 12);
}
int32_t coef = __USAT(inlet_waveform, 27) >> (11 - 3);
for (int j = 1; j < 8; j++) {
for (int oct = j; oct < 8; oct++) {
blit[i].env[oct] =
___SMMLA(coef, envc[i + 12 * oct - j * 12], blit[i].env[oct]);
}
coef >>= 1;
}
}
for (int note = 0; note < 12; note++) {
blit[note].proc(spl, dyad, y, i);
}
spl++;
outlet_out = integ += y[i]; // output integrator
y[i] = 0;
i = (i + 1) & 7;
if (status == MIDI_NOTE_ON + attr_midichannel) {
gates[data1 & 0x7F] = data2 ? 100 : 0;
} else if (status == MIDI_NOTE_OFF + attr_midichannel) {
gates[data1 & 0x7F] = 0;
} else if ((status == attr_midichannel + MIDI_CONTROL_CHANGE) &&
(data1 == MIDI_C_ALL_NOTES_OFF)) {
for (int i = 0; i < 128; i++)
gates[data1 & 0x7F] = 0;
}