Launchpad.cpp 3.6 KB

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