123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- #include "Launchpad.h"
- #include "RtMidi.h"
- #include "MidiMessage.h"
- #include <string>
- 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<midiout.getPortCount(); i++)
- {
- if(midiout.getPortName(i).find("Launchpad") != std::string::npos)
- {
- midiout.openPort(i);
- break;
- }
- }
- if(!midiout.isPortOpen())
- {
- throw RtMidiError(
- "no launchpad for midi output found",
- RtMidiError::NO_DEVICES_FOUND
- );
- }
- for(unsigned int i=0; i<midiin.getPortCount(); i++)
- {
- if(midiin.getPortName(i).find("Launchpad") != std::string::npos)
- {
- midiin.openPort(i);
- break;
- }
- }
- if(!midiin.isPortOpen())
- {
- throw RtMidiError(
- "no launchpad for midi input found",
- RtMidiError::NO_DEVICES_FOUND
- );
- }
- }
- 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<NoteMessage*>(&message);
- if(noteMessage)
- {
- unsigned char x = noteMessage->pitch % 16;
- unsigned char y = 7 - noteMessage->pitch / 16;
- if(dynamic_cast<NoteOnMessage*>(noteMessage))
- {
- launchpad->keyPressed(x, y);
- }
- else
- {
- launchpad->keyReleased(x, y);
- }
- }
- else
- {
- ControlChangeMessage *controlChangeMessage = dynamic_cast<ControlChangeMessage*>(&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)
- {
- }
- 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);
- }
|