frac32 4Feet
frac32 8Feet
frac32 16Feet
frac32 A1
frac32 D1
frac32 S1
frac32 R1
frac32 A2
frac32 D2
frac32 S2
frac32 R2
frac32 Vibrato
frac32.bipolar lfo
frac32buffer.bipolar out
frac32.positive keys
#define NB_OCT 6
int32_t outLP;
int32_t phi[12];
int32_t dPhi[12];
// 6 octaves + one note (C to C)
int32_t envMix[12 * NB_OCT + 1];
int32_t env1[12 * NB_OCT + 1];
int32_t env2[12 * NB_OCT + 1];
int32_t coefEnv[12 * NB_OCT + 1];
bool att1[12 * NB_OCT + 1];
bool att2[12 * NB_OCT + 1];
bool gate[12 * NB_OCT + 1];
int32_t mixmax(int32_t v1, int32_t v2) {
return v1 > v2 ? ___SMMUL(1431655765, 2 * v1 + v2)
: ___SMMUL(1431655765, 2 * v2 + v1);
}
for (int n12 = 0; n12 < 12; n12++) {
int32_t dp;
MTOFEXTENDED((-40 << 21) + (n12 << 21), dp)
dPhi[n12] = -dp;
for (int oct = 0; oct < NB_OCT + (n12 == 0); oct++) {
int32_t note = 12 * oct + n12;
int32_t coef;
MTOFEXTENDED(-note << 21, coef)
coefEnv[note] = coef;
env1[note] = env2[note] = 0;
att1[note] = att2[note] = gate[note] = false;
}
}
outLP = 0;
{
int32_t cA1;
MTOFEXTENDED(-2 * inlet_A1 + (1 << 27), cA1);
int32_t cD1;
MTOFEXTENDED((___SMMLA(-3 << 27, inlet_D1, +1 << 22) << 4), cD1);
int32_t cR1;
MTOFEXTENDED((___SMMLA(-3 << 27, inlet_R1, +1 << 22) << 4), cR1);
for (int i = 0; i < 12 * NB_OCT + 1; i++) {
if (att1[i]) {
env1[i] = ___SMMLA(cA1, (3 << 26) - env1[i], env1[i]);
if (env1[i] >= (1 << 27)) {
att1[i] = false;
env1[i] = (1 << 27) - 1;
}
} else {
if (gate[i]) {
env1[i] = ___SMMLA(cD1, inlet_S1 - env1[i], env1[i]);
} else {
env1[i] = ___SMMLS(cR1, env1[i], env1[i]);
}
}
}
}
{
int32_t cA2;
MTOFEXTENDED(-2 * inlet_A2 + (1 << 27), cA2);
int32_t cD2;
MTOFEXTENDED((___SMMLA(-3 << 27, inlet_D2, +1 << 22) << 4), cD2);
int32_t cR2;
MTOFEXTENDED((___SMMLA(-3 << 27, inlet_R2, +1 << 22) << 4), cR2);
for (int i = 0; i < 12 * NB_OCT + 1; i++) {
if (att2[i]) {
env2[i] = ___SMMLA(cA2, (3 << 26) - env2[i], env2[i]);
if (env2[i] >= (1 << 27)) {
att2[i] = false;
env2[i] = (1 << 27) - 1;
}
} else {
if (gate[i]) {
env2[i] = ___SMMLA(cD2, inlet_S2 - env2[i], env2[i]);
} else {
env2[i] = ___SMMLS(cR2, env2[i], env2[i]);
}
}
}
}
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
int32_t coef8Feet = __SSAT(inlet_8Feet, 28) << 3; // q31
for (int i = 0; i < 12 * NB_OCT + 1; i++) {
envMix[i] = ___SMMUL(mixmax(env1[i], env2[i]), coef8Feet) << 1;
}
// we add coef4Feet*env to the mix env above
int32_t coef4Feet = __SSAT(inlet_4Feet, 28) << 3; // q31
for (int i = 0; i < 12 * NB_OCT + 1 - 12; i++) {
envMix[i + 12] = ___SMMLA(env1[i], coef4Feet, envMix[i + 12] >> 1) << 1;
}
// we add coef16Feet*env to the mix env below
int32_t coef16Feet = __SSAT(inlet_16Feet, 28) << 3; // q31
for (int i = 12; i < 12 * NB_OCT + 1; i++) {
envMix[i - 12] = ___SMMLA((env2[i]), coef16Feet, envMix[i - 12] >> 1) << 1;
}
int32_t keys = 0;
for (int i = 0; i < 12 * NB_OCT + 1; i++) {
keys += envMix[i] >> 5;
envMix[i] = ___SMMUL(envMix[i], coefEnv[i]) << 7;
}
outlet_keys = keys;
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// pre loop to avoid differentiation glitches on parameter modulation
int32_t y1;
int32_t y0 = 0;
for (int n12 = 0; n12 < 12; n12++) {
int32_t *e = envMix + n12;
int32_t p = phi[n12];
for (int oct = 0; oct < NB_OCT + (n12 == 0); oct++) {
int32_t x = __USAT(p, 31);
x = ___SMMUL(x, x); // q30
x = ___SMMLS(x, x, x >> 2); // q28
y0 = ___SMMLA(x, *e, y0);
e += 12;
p -= 1 << 30;
p <<= 1;
}
}
int32_t dPhiM[12];
int32_t lfo = ___SMMUL(inlet_lfo, inlet_Vibrato) << 5;
for (int n12 = 0; n12 < 12; n12++) {
dPhiM[n12] = ___SMMLA(lfo, dPhi[n12], dPhi[n12]);
}
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// "srate"
for (int i = 0; i < BUFSIZE; i++) {
for (int n12 = 0; n12 < 12; n12++) {
phi[n12] += dPhiM[n12];
}
y1 = y0;
y0 = 0;
for (int n12 = 0; n12 < 12; n12++) {
int32_t *e = envMix + n12;
int32_t p = phi[n12];
for (int oct = 0; oct < NB_OCT + (n12 == 0); oct++) {
int32_t x = __USAT(p, 31);
x = ___SMMUL(x, x); // q30
x = ___SMMLS(x, x, x >> 2); // q28
y0 = ___SMMLA(x, *e, y0);
e += 12;
p -= 1 << 30;
p <<= 1;
}
}
outlet_out[i] = (y0 - y1) << 12;
}
if (status == MIDI_NOTE_ON + attr_midichannel) {
int n = ((data1 & 0x7F) - 24);
if (n >= 0 && n < 12 * NB_OCT + 1) {
if (data2 != 0) {
gate[n] = true;
att1[n] = true;
att2[n] = true;
} else {
gate[n] = false;
att1[n] = false;
att2[n] = false;
}
}
// gates[data1 & 0x7F] = data2 * coef1[data1];
} else if (status == MIDI_NOTE_OFF + attr_midichannel) {
int n = ((data1 & 0x7F) - 24);
if (n >= 0 && n < 12 * NB_OCT + 1) {
gate[n] = false;
att1[n] = false;
att2[n] = false;
}
// gates[data1 & 0x7F] = 0;
} else if ((status == attr_midichannel + MIDI_CONTROL_CHANGE) &&
(data1 == MIDI_C_ALL_NOTES_OFF)) {
for (int i = 0; i < 12 * NB_OCT + 1; i++) {
gate[i] = false;
att1[i] = false;
att2[i] = false;
}
}