polyhandler III

an approach to midi polyphony.a 'map' of currently active notes is stored in a table with the same name as the object that can be referenced from 'outside'. currentNote,gate and velo correspond to the actual events,noteOn issues a pulse whenever a note-on occurs. notecount puts out the number of notes curently on hold,hold is 1 if any keys are on hold.
Author: Robert Schirmer
License: BSD
Github: rbrt/testing/polyhandler III.axo

Inlets

bool32 mute

int32 note

bool32.rising clear

bool32.rising trigger

Outlets

int32 note number of active key

int32 number of notes currently held down

int32 test

bool32 key pressed or released ?

bool32 any notes on hold?

frac32.positive velocity of active key

bool32.pulse pulse on note-on

bool32.pulse noteOff

Attributes

spinner startNote

spinner endNote

spinner noteshift

spinner maximum polyphony

spinner index of the latch-parameter in a block

spinner channel

objref is a note on?

objref is a note on OR on release,or latched?

objref ..where,in the parameter-table,to find if a note is set to latch

combo blocksize of that table

combo target device

Declaration
int8_t _note;
uint8_t _gate;
uint8_t _velo;
uint8_t _rvelo;
uint8_t _touch;
uint8_t count;
bool trig;
bool trigoff;
bool trigR;
bool trigoffR;
bool rtrig;
bool trigext;
bool maxpoly;

static const uint32_t LENGTHPOW = 7;
static const uint32_t LENGTH = 1 << 7;
static const uint32_t LENGTHMASK = (1 << 7) - 1;
static const uint32_t BITS = 8;
static const uint32_t GAIN = 20;
int8_t array[LENGTH];
uint8_t hold;
Init
_gate = 0;
_note = 0;
_touch = 0;
Control Rate
hold = 0;
int i;
for (i = 0; i < attr_active.LENGTH; i++) {
  if (attr_active.array[i])
    hold++;
}
maxpoly = (hold > (attr_maxpoly - 1)) ? 1 : 0;

outlet_currentNote = _note;
outlet_currentGate = _gate << 27;
outlet_currentVelo = _velo << 20;

outlet_noteOn = trig;
outlet_noteOff = trigoff;

outlet_notecount = count;
outlet_hold = bool(count);

if (inlet_clear && !rtrig) {
  {
    int i;
    for (i = 0; i < LENGTH; i++)
      array[i] = 0;
  }
  rtrig = 1;
  count = 0;
}
if (!inlet_clear)
  rtrig = 0;

if (!inlet_mute) {
  if (trig && (!maxpoly)) {
    if (!attr_latch.array[(_note << attr_blocksize) + attr_index])
      trigR = 1;
    if ((attr_latch.array[(_note << attr_blocksize) + attr_index]) &&
        (!attr_playing.array[_note]))
      trigR = 1;
  }
  if (trig && (attr_latch.array[(_note << attr_blocksize) + attr_index]) &&
      (attr_playing.array[_note]))
    trigoffR = 1;
}

if (trigoff && (!attr_latch.array[(_note << attr_blocksize) + attr_index]))
  trigoffR = 1;
if (trigR)
  MidiSend3((midi_device_t)attr_device, MIDI_NOTE_ON + (attr_channel - 1),
            _note, _velo);
if (trigoffR)
  MidiSend3((midi_device_t)attr_device, MIDI_NOTE_ON + (attr_channel - 1),
            _note, 0);

if ((inlet_trigger && !trigext) && (!maxpoly)) {
  trigext = 1;
  MidiSend3((midi_device_t)attr_device, MIDI_NOTE_ON + (attr_channel - 1),
            inlet_note, 127);
}
if (!inlet_trigger)
  trigext = 0;

trig = 0;
trigoff = 0;
trigR = 0;
trigoffR = 0;

outlet_test = hold;
Midi Handler
if ((status == MIDI_NOTE_ON + attr_midichannel) && (data2)) {
  if (((data1 >= attr_startNote) && (data1 <= attr_endNote)) &&
      ((data1 + attr_noteshift) > -1)) {
    _velo = data2;
    _note = (data1 + attr_noteshift);
    if (!array[data1 + attr_noteshift])
      trig = 1;
    array[data1 + attr_noteshift] = _velo;
    _gate = 1;
    count += 1;
  }
}
if (((status == MIDI_NOTE_ON + attr_midichannel) && (!data2)) ||
    (status == MIDI_NOTE_OFF + attr_midichannel)) {
  if ((data1 >= attr_startNote) && (data1 <= attr_endNote) &&
      ((data1 + attr_noteshift) > -1)) {
    if (array[data1 + attr_noteshift])
      trigoff = 1;
    array[data1 + attr_noteshift] = 0;
    if (count)
      count -= 1;
    _velo = data2;
    _note = (data1 + attr_noteshift);
    _gate = 0;
  }
}

else if ((status == attr_midichannel + MIDI_CONTROL_CHANGE) &&
         (data1 == MIDI_C_ALL_NOTES_OFF)) {
  _gate = 0;
}

Privacy

© 2024 Zrna Research