void LaunchpadController::deviceMessage(LaunchpadDevice *device, const MidiMessage &msg) { DBG("Launchpad %d received %s", device->index(), msg); int deviceIndex = device->index(); int event = msg.event(); int channel = msg.channel(); const auto &data = msg.data(); int data1 = data[1]; int data2 = data[2]; if (event == 0x09 && channel == 0) { if ((data1 & 0x0f) == 8) { // Button A..H int b = data1 >> 4; switch (device->rotation()) { case LaunchpadDevice::Rotation0: { int mappedX = 0x40 + 0x10*(deviceIndex % 2); int mappedY = b + 8*(deviceIndex / 2); _blm->sendNoteEvent(mappedY, mappedX, data2); } break; case LaunchpadDevice::Rotation90: { int mappedX = 0x60 + 8*(deviceIndex % 2) + (7-b) + 8*(deviceIndex / 2); int mappedY = 0; _blm->sendNoteEvent(mappedY, mappedX, data2); } break; case LaunchpadDevice::Rotation180: { int mappedX = 0x40 + 0x10*(deviceIndex % 2); int mappedY = (7-b) + 8*(deviceIndex / 2); _blm->sendNoteEvent(mappedY, mappedX, data2); } break; case LaunchpadDevice::Rotation270: { int mappedX = 0x60 + 8*(deviceIndex % 2) + b + 8*(deviceIndex / 2); int mappedY = 0; _blm->sendNoteEvent(mappedY, mappedX, data2); } break; } } else if ((data1 & 0x0f) <= 7) {