1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
#define GRID_X 16
#define GRID_Y 8
#define LAUNCHPAD_GRID_X 8
#define LAUNCHPAD_GRID_Y 8
#define GRID_STATE(b,x,y) *(b + x + (y * GRID_X) )
#define LP_MIDI_NOTE_ON 0x90
#define LP_MIDI_NOTE_OFF 0x80
#define LP_MIDI_POLY_AT 0xA0
#define LP_MIDI_CC 0xB0
#define LP_MIDI_PGM 0xC0
#define LP_MIDI_CHAN_PR 0xD0
#define LP_MIDI_PB 0xE0
#define LP_MIDI_OTHER 0xF0
// midi note/cc numbers
#define LP_NOTE_PAD_START 00
#define LP_NOTE_PAD_END (LP_NOTE_PAD_START + 120)
//static uint8_t LP_NOTE_PAD[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
//16, 17, 18, 19, 20, 21, 22, 23,
//32, 33, 34, 35, 36, 37, 38, 39,
//48, 49, 50, 51, 52, 53, 54, 55,
//64, 65, 66, 67, 68, 69, 70, 71,
//80, 81, 82, 83, 84, 85, 86, 87,
//96, 97, 98, 99, 100,101,102,103,
//112,113,114,115,116,117,118,119
//};
#define LP_ENCODER_CC_TEMPO 14
#define LP_ENCODER_CC_SWING 15
void launchpad_handle_midi(void* self, union event_data* evin) {
struct dev_launchpad *launchpad = (struct dev_launchpad *) self;
uint8_t type = evin->midi_event.data[0] & 0xF0;
// uint8_t ch = ev->midi_event.data[0] & 0x0F;
// determine if midi message is going to be interpretted or just sent on
switch (type) {
case LP_MIDI_NOTE_ON:
case LP_MIDI_NOTE_OFF: {
int8_t note = evin->midi_event.data[1];
int8_t data = evin->midi_event.data[2];
if (note >= LP_NOTE_PAD_START && note <= LP_NOTE_PAD_END) {
if (launchpad->pad_mode_ == LPPM_GRID) {
// send grid key event
int x = ((note - LP_NOTE_PAD_START)% LAUNCHPAD_GRID_X ) + (launchpad->grid_page_ * LAUNCHPAD_GRID_X);
int y = LAUNCHPAD_GRID_Y - ((note - LP_NOTE_PAD_START) / LAUNCHPAD_GRID_X) - 1;
union event_data *ev = event_data_new(EVENT_GRID_KEY);
ev->grid_key.id = launchpad->dev_.id + LAUNCHPAD_DEV_OFFSET;
ev->grid_key.x = x;
ev->grid_key.y = y;
ev->grid_key.state = (type == LP_MIDI_NOTE_ON) && (data > 0);
// fprintf(stderr, "key %d\t%d\t%d\t%d\n", ev->grid_key.id, ev->grid_key.x, ev->grid_key.y , ev->grid_key.state);
event_post(ev);
} else { // LPPM_NOTE
const int tonic = 0;
const int rowOffset = 5;
int x = (note - LP_NOTE_PAD_START) % LAUNCHPAD_GRID_X;
int y = (note - LP_NOTE_PAD_START) / LAUNCHPAD_GRID_X;
int noteout = (launchpad->midi_octave_ * 12) + (y * rowOffset) + x + tonic;
evin->midi_event.data[1] = noteout;
// fprintf(stderr, "midi 0x%02x\t%d\t%d\n", evin->midi_event.data[0], evin->midi_event.data[1], evin->midi_event.data[2]);
event_post(evin);
uint8_t clr = PAD_NOTE_ON_CLR;
if (type == LP_MIDI_NOTE_OFF || data == 0) {
const int scale = 0b101011010101;
int note_s = (y * rowOffset) + x;
int i = note_s % 12;
int v = (scale & (1 << ( 11 - i)));
clr = (i == 0 ? PAD_NOTE_ROOT_CLR : (v > 0 ? PAD_NOTE_IN_KEY_CLR : PAD_NOTE_OFF_CLR));
}
dev_launchpad_midi_send_note(self, note, clr);
}
}
break;
|