#include "Launchpad.h" #include "RtMidi.h" #include "MidiMessage.h" #include 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; } bool LaunchpadColor::operator!=(const LaunchpadColor& color) const { return !operator==(color); } Launchpad::Launchpad() : midiin(), midiout(), keyPressedCallback(0), keyReleasedCallback(0) { // define callback before opening port to keep the message queue empty. midiin.setCallback(midiMessageCallback, (void*) this); for(unsigned int i=0; i(&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::setColorAll(const LaunchpadColor& color) { for(unsigned char x = 0; x < width; x++) { for(unsigned char y = 0; y < height; y++) { if(x != 8 || y != 8) { setColor(x, y, color); } } } } void Launchpad::keyPressed(unsigned char x, unsigned char y) { if(keyPressedCallback) { keyPressedCallback(x, y, keyEventCallbackData); } } void Launchpad::keyReleased(unsigned char x, unsigned char y) { if(keyReleasedCallback) { keyReleasedCallback(x, y, keyEventCallbackData); } } void LaunchpadScreen::keyPressed(unsigned char x, unsigned char y) { } void LaunchpadScreen::keyReleased(unsigned char x, unsigned char y) { } const LaunchpadColor& LaunchpadScreen::getColor(unsigned char x, unsigned char y) const { return colors[x][y]; } void LaunchpadScreen::setColor(unsigned char x, unsigned char y, const LaunchpadColor& color) { if(active && (!launchpad->issetColor(x, y) || launchpad->getColor(x, y) != color)) { launchpad->setColor(x, y, color); } colors[x][y] = color; } void LaunchpadScreen::setColorAll(const LaunchpadColor& color) { for(unsigned char x = 0; x < Launchpad::width; x++) { for(unsigned char y = 0; y < Launchpad::height; y++) { if(x != 8 || y != 8) { setColor(x, y, color); } } } } void LaunchpadScreen::sync() { for(unsigned char x = 0; x < Launchpad::width; x++) { for(unsigned char y = 0; y < Launchpad::height; y++) { if((x != 8 || y != 8) && (!launchpad->issetColor(x, y) || launchpad->getColor(x, y) != colors[x][y])) { launchpad->setColor(x, y, colors[x][y]); } } } } LaunchpadScreen::LaunchpadScreen() : launchpad(0), active(false) { } void LaunchpadScreen::enable() { if(!launchpad) { throw RtMidiError( "no launchpad set", RtMidiError::INVALID_USE ); } launchpad->keyEventCallbackData = (void*)this; launchpad->keyPressedCallback = keyPressedCallback; launchpad->keyReleasedCallback = keyReleasedCallback; sync(); active = true; } void LaunchpadScreen::disable() { launchpad->keyPressedCallback = 0; launchpad->keyReleasedCallback = 0; launchpad->keyEventCallbackData = 0; active = false; } bool LaunchpadScreen::enabled() const { return active; } void LaunchpadScreen::setLaunchpad(Launchpad& l) { if(enabled()) { disable(); launchpad = &l; enable(); } else { launchpad = &l; } } void LaunchpadScreen::keyPressedCallback(unsigned char x, unsigned char y, void* screen) { ((LaunchpadScreen*)screen)->keyPressed(x, y); } void LaunchpadScreen::keyReleasedCallback(unsigned char x, unsigned char y, void* screen) { ((LaunchpadScreen*)screen)->keyReleased(x, y); }