#include "Launchpad.h" #include "RtMidi.h" #include "MidiMessage.h" LaunchpadColor::LaunchpadColor() : red(0), green(0) { } LaunchpadColor::LaunchpadColor(unsigned char r, unsigned char g) : red(r), green(g) { } bool LaunchpadColor::operator==(const LaunchpadColor& color) const { return red == color.red && green == color.green; } Launchpad::Launchpad() : midiin(), midiout(), keyPressedCallback(0), keyReleasedCallback(0) { midiin.setCallback(midiMessageCallback, (void*) this); midiout.openPort(1); midiin.openPort(0); } void Launchpad::midiMessageCallback(double timeStamp, MidiMessage &message, void *userData) { Launchpad *launchpad = (Launchpad*) userData; // use runtime type information to check for the message type. // this requires the specified class to have a virtual member. NoteMessage *noteMessage = dynamic_cast(&message); if(noteMessage) { unsigned char x = noteMessage->pitch % 16; unsigned char y = 7 - noteMessage->pitch / 16; if(dynamic_cast(noteMessage)) { launchpad->keyPressed(x, y); } else { launchpad->keyReleased(x, y); } } else { ControlChangeMessage *controlChangeMessage = dynamic_cast(&message); if(controlChangeMessage) { unsigned char x = controlChangeMessage->control - 104; unsigned char y = 8; if(controlChangeMessage->value == 127) { launchpad->keyPressed(x, y); } else { launchpad->keyReleased(x, y); } } } } bool Launchpad::issetColor(unsigned char x, unsigned char y) const { return colorSet[x][y]; } const LaunchpadColor& Launchpad::getColor(unsigned char x, unsigned char y) const { return colors[x][y]; } void Launchpad::setColor(unsigned char x, unsigned char y, const LaunchpadColor& color) { if(x >= width || y >= height || (x == 8 && y == 8)) { throw RtMidiError( "specified launchpad position is out of range", RtMidiError::INVALID_PARAMETER ); } if(color.red > 3 || color.green > 3) { throw RtMidiError( "specified launchpad color is out of range", RtMidiError::INVALID_PARAMETER ); } unsigned char velocity = (color.green << 4) + color.red; if(y == 8) { midiout.sendMessage(ControlChangeMessage( 0, 104 + x, velocity )); } else { midiout.sendMessage(NoteOnMessage( 0, ((7 - y) << 4) + x, velocity )); } colors[x][y] = color; colorSet[x][y] = true; } void Launchpad::keyPressed(unsigned char x, unsigned char y) { if(keyPressedCallback) { keyPressedCallback(x, y); } } void Launchpad::keyReleased(unsigned char x, unsigned char y) { if(keyReleasedCallback) { keyReleasedCallback(x, y); } }