mpe

Controller input for MIDI Polyphonic Expression
Author: Mark Harris
License: BSD
Github: midi/ctrl/mpe.axo

Inlets

None

Outlets

frac32.bipolar midi note number (-64..63)

bool32 key pressed, no retrigger legato

bool32 key pressed, retrigger on legato

frac32.positive note-on velocity

frac32.positive note-off velocity

frac32.positive continuous pressure

frac32 continuous pitchbend (-64..63)

frac32 continuous timbre (-64..63)

frac32 pitch including pitchbend

Declaration
int8_t _note;
int32_t _gate;
int32_t _gate2;
uint32_t _velo;
uint32_t _rvelo;
uint32_t _pressure;
int32_t _bend;
int32_t _timbre;
uint8_t _lastRPN_LSB;
uint8_t _lastRPN_MSB;
uint8_t _bendRange;
int32_t _pitch;
int32_t _xl, _yl, _zl;
static const uint8_t xccl = 85;
static const uint8_t yccl = 87;
static const uint8_t zccl = 86;
Init
_gate = 0;
_note = 0;
_pressure = 0;
_bend = 0;
_timbre = 0;
_bendRange = 48;
_xl = _yl = _zl = 0;
Control Rate
outlet_note = _note << 21;
outlet_gate = _gate;
outlet_gate2 = _gate2;
_gate2 = _gate;
outlet_velocity = _velo;
outlet_releaseVelocity = _rvelo;
outlet_pressure = _pressure;
outlet_bend = _bend;
outlet_timbre = _timbre;
outlet_pitch = _pitch;
Midi Handler
if ((status == MIDI_NOTE_ON + attr_midichannel) && (data2)) {
  _velo = data2 << 20;
  _note = data1 - 64;
  _gate = 1 << 27;
  _gate2 = 0;
  _pitch = (_note << 21) + ((_bend >> 6) * _bendRange);
} else if (((status == MIDI_NOTE_ON + attr_midichannel) && (!data2)) ||
           (status == MIDI_NOTE_OFF + attr_midichannel)) {
  if (_note == data1 - 64) {
    _rvelo = data2 << 20;
    _gate = 0;
    _pressure = 0;
  }
} else if (status == attr_midichannel + MIDI_CHANNEL_PRESSURE) {
  _pressure = (data1 << 20) + _zl;
} else if (status == attr_midichannel + MIDI_PITCH_BEND) {
  _bend = (((int)((data2 << 7) + data1) - 0x2000) << 14) + _xl;
  _pitch = (_note << 21) + ((_bend >> 6) * _bendRange);
} else if (status == attr_midichannel + MIDI_CONTROL_CHANGE) {
  if (data1 == MIDI_C_TIMBRE) {
    _timbre = (((int)(data2 << 7) - 0x2000) << 14) + _yl;
  } else if (data1 == zccl) {
    _zl = data2 << 13;
  } else if (data1 == xccl) {
    _xl = data2 << 7;
  } else if (data1 == yccl) {
    _yl = data2 << 14;
  } else if (data1 == MIDI_C_ALL_NOTES_OFF) {
    _gate = 0;
  } else if (data1 == MIDI_C_RPN_MSB || data1 == MIDI_C_RPN_LSB ||
             data1 == MIDI_C_DATA_ENTRY) {
    switch (data1) {
    case MIDI_C_RPN_LSB:
      _lastRPN_LSB = data2;
      break;
    case MIDI_C_RPN_MSB:
      _lastRPN_MSB = data2;
      break;
    case MIDI_C_DATA_ENTRY: {
      if (_lastRPN_LSB == 0 && _lastRPN_MSB == 0) {
        _bendRange = data2;
      }
    } break;
    default:
      break;
    }
  }
}

Privacy

© 2024 Zrna Research