None
int32 notecount
frac32.bipolar note1
frac32.bipolar note2
frac32.bipolar note3
frac32.bipolar note4
frac32.positive velocity
bool32 gate
bool32.tgl retrigger
spinner MIDIchannel
#define MAX_VOX 4
int8_t pressed_note[MAX_VOX];
int32_t pitches[MAX_VOX];
int notecount = 0;
int32_t velocity = 0;
int retrigger = 0;
int doretrigger = 0;
for (int i = 0; i < MAX_VOX; i++) {
pressed_note[i] = 0;
pitches[i] = 0;
}
if (doretrigger) {
doretrigger = 0;
outlet_gate = 0;
} else {
outlet_gate = notecount > 0 ? 1 : 0;
}
outlet_note1 = pitches[0];
outlet_note2 = pitches[1];
outlet_note3 = pitches[2];
outlet_note4 = pitches[3];
outlet_velocity = velocity;
outlet_notecount = notecount;
retrigger = param_retrigger;
int channel = (status & 0xf) + 1;
int cmd = (status & 0x70) >> 4;
if ((channel != attr_MIDIchannel && attr_MIDIchannel > 0)) {
return;
}
// some midi devices send note on with velocity 0 instead of note off
if (cmd == 1 && data2 == 0) {
cmd = 0;
}
if (cmd == 1) {
// note on
if (notecount < MAX_VOX) {
if (notecount == 0) {
velocity = data2 << 20;
}
for (int i = 0; i < MAX_VOX; i++) {
if (pressed_note[i] == 0) {
pressed_note[i] = data1;
notecount++;
break;
}
}
} else {
pressed_note[MAX_VOX - 1] = data1;
}
if (retrigger) {
doretrigger = 1;
}
} else if (cmd == 0) {
// note off
for (int i = 0; i < MAX_VOX; i++) {
if (pressed_note[i] == data1) {
pressed_note[i] = 0;
notecount--;
break;
}
}
}
if ((cmd == 1 || cmd == 0) && notecount > 0) {
// distribute pitches
int notei = 0;
for (int i = 0; i < MAX_VOX; i++) {
while (pressed_note[notei] == 0) {
notei = (notei + 1) % MAX_VOX;
}
pitches[i] = (pressed_note[notei] - 64) << 21;
notei++;
}
}
if ((cmd == 3) && (data1 == 123)) { // all notes off message
for (int i = 0; i < MAX_VOX; i++) {
pressed_note[i] = 0;
}
notecount = 0;
}