frac32.bipolar vib0
frac32.bipolar vib1
frac32.bipolar vib2
frac32buffer.bipolar out
frac32.s.map.kdecaytime.exp A
frac32.s.map.kdecaytime.exp R1
frac32.s.map.kdecaytime.exp R2
frac32.u.map L
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;
int32_t d[256];
uint8_t w = 0;
class BLIT {
public:
int32_t env[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;
}
}
void proc(uint16_t spl, int32_t *y, int i) {
if (spl == nextSpl) {
int32_t ampli = env[7]; // all cycles
if ((cpt & 1))
ampli += env[6];
if ((cpt & 3) == 1)
ampli += env[5];
if ((cpt & 7) == 1)
ampli += env[4];
if ((cpt & 15) == 1)
ampli += env[3];
if ((cpt & 31) == 1)
ampli += env[2];
if ((cpt & 63) == 1)
ampli += env[1];
if ((cpt & 127) == 1)
ampli += env[0];
// 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++;
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;
}
for (int i = 0; i < 256; i++) {
d[i] = 0;
}
float vib0 = inlet_vib0 * 1e-10f;
float vib1 = inlet_vib1 * 1e-10f;
float vib2 = inlet_vib2 * 1e-10f;
float f = 4186.009f;
blit[0].setF(f *vib0 + f);
f *= 1.059463094f;
blit[1].setF(f *vib0 + f);
f *= 1.059463094f;
blit[2].setF(f *vib1 + f);
f *= 1.059463094f;
blit[3].setF(f *vib1 + f);
f *= 1.059463094f;
blit[4].setF(f *vib2 + f);
f *= 1.059463094f;
blit[5].setF(f *vib2 + f);
f *= 1.059463094f;
blit[6].setF(-f *vib0 + f);
f *= 1.059463094f;
blit[7].setF(-f *vib0 + f);
f *= 1.059463094f;
blit[8].setF(-f *vib1 + f);
f *= 1.059463094f;
blit[9].setF(-f *vib1 + f);
f *= 1.059463094f;
blit[10].setF(-f *vib2 + f);
f *= 1.059463094f;
blit[11].setF(-f *vib2 + f);
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);
}
}
for (int note = 0; note < 12; note++) {
blit[note].proc(spl, y, i);
}
spl++;
w--;
d[w] = y[i];
integ = ___SMMUL(integ, 0x7F000000) << 1;
int32_t filter =
d[w] - d[(uint8_t)(w + (uint8_t)7)] - d[(uint8_t)(w + (uint8_t)26)] -
d[(uint8_t)(w + (uint8_t)80)] - d[(uint8_t)(w + (uint8_t)88)] +
d[(uint8_t)(w + (uint8_t)113)] + d[(uint8_t)(w + (uint8_t)126)] +
d[(uint8_t)(w + (uint8_t)138)] + d[(uint8_t)(w + (uint8_t)148)] +
d[(uint8_t)(w + (uint8_t)154)] + d[(uint8_t)(w + (uint8_t)190)] -
d[(uint8_t)(w + (uint8_t)217)] - d[(uint8_t)(w + (uint8_t)220)] -
d[(uint8_t)(w + (uint8_t)233)] - d[(uint8_t)(w + (uint8_t)253)] +
d[(uint8_t)(w + (uint8_t)255)]
;
integ += filter;
outlet_out = integ;
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;
}