Launchpad.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include "Launchpad.h"
  2. #include <string>
  3. namespace midi {
  4. Launchpad::Launchpad()
  5. : midiin(), midiout(), keyPressedCallback(0), keyReleasedCallback(0)
  6. {
  7. // define callback before opening port to keep the message queue empty.
  8. midiin.setCallback(midiMessageCallback, (void*) this);
  9. for(unsigned int i=0; i<midiout.getPortCount(); i++)
  10. {
  11. if(midiout.getPortName(i).find("Launchpad") != std::string::npos)
  12. {
  13. midiout.openPort(i);
  14. break;
  15. }
  16. }
  17. if(!midiout.isPortOpen())
  18. {
  19. throw "no launchpad for midi output found";
  20. }
  21. for(unsigned int i=0; i<midiin.getPortCount(); i++)
  22. {
  23. if(midiin.getPortName(i).find("Launchpad") != std::string::npos)
  24. {
  25. midiin.openPort(i);
  26. break;
  27. }
  28. }
  29. if(!midiin.isPortOpen())
  30. {
  31. throw "no launchpad for midi input found";
  32. }
  33. for(KeyCoordinate x = 0; x < width; x++) {
  34. for(KeyCoordinate y = 0; y < height; y++) {
  35. if(x != 8 || y != 8) {
  36. setKeyPressed(x, y, false);
  37. }
  38. }
  39. }
  40. }
  41. void Launchpad::midiMessageCallback(double timeStamp, Message &message, void *userData)
  42. {
  43. Launchpad *launchpad = (Launchpad*) userData;
  44. // use runtime type information to check for the message type.
  45. // this requires the specified class to have a virtual member.
  46. NoteMessage *noteMessage = dynamic_cast<NoteMessage*>(&message);
  47. if(noteMessage)
  48. {
  49. unsigned char x = noteMessage->pitch % 16;
  50. unsigned char y = 7 - noteMessage->pitch / 16;
  51. if(dynamic_cast<NoteOnMessage*>(noteMessage))
  52. {
  53. launchpad->keyPressed(x, y);
  54. }
  55. else
  56. {
  57. launchpad->keyReleased(x, y);
  58. }
  59. }
  60. else
  61. {
  62. ControlChangeMessage *controlChangeMessage = dynamic_cast<ControlChangeMessage*>(&message);
  63. if(controlChangeMessage)
  64. {
  65. unsigned char x = controlChangeMessage->control - 104;
  66. unsigned char y = 8;
  67. if(controlChangeMessage->value == 127)
  68. {
  69. launchpad->keyPressed(x, y);
  70. }
  71. else
  72. {
  73. launchpad->keyReleased(x, y);
  74. }
  75. }
  76. }
  77. }
  78. bool Launchpad::issetColor(unsigned char x, unsigned char y) const
  79. {
  80. return colorSet[x][y];
  81. }
  82. const LaunchpadColor& Launchpad::getColor(unsigned char x, unsigned char y) const
  83. {
  84. return colors[x][y];
  85. }
  86. void Launchpad::setColor(unsigned char x, unsigned char y, const LaunchpadColor& color)
  87. {
  88. if(x >= width || y >= height || (x == 8 && y == 8))
  89. {
  90. throw "specified launchpad position is out of range";
  91. }
  92. if(color.red > 3 || color.green > 3)
  93. {
  94. throw "specified launchpad color is out of range";
  95. }
  96. unsigned char velocity = (color.green << 4) + color.red;
  97. if(y == 8)
  98. {
  99. midiout.sendMessage(ControlChangeMessage(
  100. 0,
  101. 104 + x,
  102. velocity
  103. ));
  104. }
  105. else
  106. {
  107. midiout.sendMessage(NoteOnMessage(
  108. 0,
  109. ((7 - y) << 4) + x,
  110. velocity
  111. ));
  112. }
  113. colors[x][y] = color;
  114. colorSet[x][y] = true;
  115. }
  116. void Launchpad::setColorAll(const LaunchpadColor& color)
  117. {
  118. for(unsigned char x = 0; x < width; x++)
  119. {
  120. for(unsigned char y = 0; y < height; y++)
  121. {
  122. if(x != 8 || y != 8)
  123. {
  124. setColor(x, y, color);
  125. }
  126. }
  127. }
  128. }
  129. bool Launchpad::getKeyPressed(KeyCoordinate x, KeyCoordinate y)
  130. {
  131. return keyBeingPressed[x][y];
  132. }
  133. void Launchpad::keyPressed(unsigned char x, unsigned char y)
  134. {
  135. setKeyPressed(x, y, true);
  136. if(keyPressedCallback)
  137. {
  138. keyPressedCallback(x, y, keyEventCallbackData);
  139. }
  140. }
  141. void Launchpad::keyReleased(unsigned char x, unsigned char y)
  142. {
  143. setKeyPressed(x, y, false);
  144. if(keyReleasedCallback)
  145. {
  146. keyReleasedCallback(x, y, keyEventCallbackData);
  147. }
  148. }
  149. void Launchpad::setKeyPressed(KeyCoordinate x, KeyCoordinate y, bool pressed)
  150. {
  151. keyBeingPressed[x][y] = pressed;
  152. }
  153. } // namespace