Launchpad.cpp 3.8 KB

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