int32.positive note
int32.positive velo
int32.positive note number to stop
int32.positive startnote
bool32.rising stop it!
bool32.rising start
int32.positive note
int32.positive velo
int32.positive target
int32 test
bool32.tgl kill notes on release
combo polyphony
int8_t _note;
uint8_t _velo;
uint8_t pren;
uint8_t prev;
bool trig;
bool trigoff;
bool stop;
bool start;
uint8_t i;
uint8_t ii;
bool doit;
uint8_t target;
static const uint8_t LENGTHPOW = 5;
static const uint8_t POLY = attr_polyphony;
static const uint8_t BITS = 8;
static const uint8_t GAIN = 20;
uint8_t Rhold[POLY];
uint8_t Rrelease[POLY];
uint8_t Snote[POLY];
uint8_t Svelo[POLY];
uint8_t old_voice[POLY];
uint8_t old_voice_length;
pren = 0;
prev = 0;
_note = 0;
_velo = 0;
stop = 0;
start = 0;
trig = 0;
trigoff = 0;
// 'thin' the old voice list if voices are done with release or got stolen
for (i = 0; i < old_voice_length; i++)
if (!Rrelease[old_voice[i] - 1] || !old_voice[i]) {
old_voice_length--;
for (ii = i; ii < old_voice_length; ii++)
old_voice[ii] = old_voice[ii + 1];
break;
}
if ((inlet_note != pren) || (inlet_velo != prev)) {
pren = inlet_note;
prev = inlet_velo;
_velo = inlet_velo;
_note = inlet_note;
if (_velo)
trig = 1;
else
trigoff = 1;
}
TRIGGER : if (trig) {
// retrig
for (i = 0; i < POLY; i++) {
if (Rrelease[i] == (_note + 1)) {
target = i;
// remove this voice from the old voices list
for (ii = 0; ii < old_voice_length; ii++)
if (old_voice[ii] == (target + 1))
old_voice[ii] = 0;
doit = 1;
}
}
// if it's NOT a retrigger or a toggle-event,try to start a 'normal' voice..
if (!doit) {
for (i = 0; i < POLY; i++)
if ((!Rhold[i]) && (!Rrelease[i])) {
target = i;
doit = 1;
}
}
// if there are no empty voices available,try to STEAL a voice that's on
// release
if ((!doit && param_steal) && old_voice_length) {
// set the target to the oldest voice
target = old_voice[0] - 1;
// remove that voice from the old voices list
old_voice[0] = 0;
doit = 1;
}
}
// trigger off
if (trigoff) {
for (i = 0; i < POLY; i++)
if (Rhold[i] == (_note + 1)) {
target = i;
doit = 1;
// add the voice to the old voices list
old_voice[old_voice_length] = target + 1;
old_voice_length++;
}
}
// stop
if (inlet_stop && (!stop)) {
_note = inlet_stopnote;
_velo = 0;
pren = _note;
prev = _velo;
stop = 1;
trigoff = 1;
goto TRIGGER;
}
if (!inlet_stop)
stop = 0;
// start
if (inlet_start && (!start)) {
_note = inlet_startnote;
_velo = 127;
pren = _note;
prev = _velo;
start = 1;
trig = 1;
goto TRIGGER;
}
if (!inlet_start)
start = 0;
if (doit) {
doit = 0;
Snote[target] = _note + 1;
Svelo[target] = _velo;
if (_velo)
Rhold[target] = _note + 1;
else
Rhold[target] = 0;
}
outlet_note = _note;
outlet_velo = _velo;
outlet_target = target;
outlet_test = old_voice_length;