You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

315 lines
6.0KB

  1. #include <map>
  2. #include <keyboard.hpp>
  3. #include <midi.hpp>
  4. #include <window/Window.hpp>
  5. namespace rack {
  6. namespace keyboard {
  7. struct Driver;
  8. static const int DRIVER = -11;
  9. static Driver* driver = NULL;
  10. static const int MOUSE_DEVICE_ID = 1000;
  11. enum {
  12. CMD_OCTAVE_DOWN = -1,
  13. CMD_OCTAVE_UP = -2,
  14. };
  15. struct DeviceInfo {
  16. std::string name;
  17. std::map<int, int> keyMap;
  18. };
  19. static const int deviceCount = 2;
  20. static const std::vector<DeviceInfo> deviceInfos = {
  21. {
  22. "QWERTY keyboard (US)",
  23. {
  24. {GLFW_KEY_GRAVE_ACCENT, CMD_OCTAVE_DOWN},
  25. {GLFW_KEY_1, CMD_OCTAVE_UP},
  26. {GLFW_KEY_Z, 0},
  27. {GLFW_KEY_S, 1},
  28. {GLFW_KEY_X, 2},
  29. {GLFW_KEY_D, 3},
  30. {GLFW_KEY_C, 4},
  31. {GLFW_KEY_V, 5},
  32. {GLFW_KEY_G, 6},
  33. {GLFW_KEY_B, 7},
  34. {GLFW_KEY_H, 8},
  35. {GLFW_KEY_N, 9},
  36. {GLFW_KEY_J, 10},
  37. {GLFW_KEY_M, 11},
  38. {GLFW_KEY_COMMA, 12},
  39. {GLFW_KEY_L, 13},
  40. {GLFW_KEY_PERIOD, 14},
  41. {GLFW_KEY_SEMICOLON, 15},
  42. {GLFW_KEY_SLASH, 16},
  43. {GLFW_KEY_Q, 12},
  44. {GLFW_KEY_2, 13},
  45. {GLFW_KEY_W, 14},
  46. {GLFW_KEY_3, 15},
  47. {GLFW_KEY_E, 16},
  48. {GLFW_KEY_R, 17},
  49. {GLFW_KEY_5, 18},
  50. {GLFW_KEY_T, 19},
  51. {GLFW_KEY_6, 20},
  52. {GLFW_KEY_Y, 21},
  53. {GLFW_KEY_7, 22},
  54. {GLFW_KEY_U, 23},
  55. {GLFW_KEY_I, 24},
  56. {GLFW_KEY_9, 25},
  57. {GLFW_KEY_O, 26},
  58. {GLFW_KEY_0, 27},
  59. {GLFW_KEY_P, 28},
  60. {GLFW_KEY_LEFT_BRACKET, 29},
  61. {GLFW_KEY_EQUAL, 30},
  62. {GLFW_KEY_RIGHT_BRACKET, 31},
  63. },
  64. },
  65. {
  66. "Numpad keyboard (US)",
  67. {
  68. {GLFW_KEY_KP_DIVIDE, CMD_OCTAVE_DOWN},
  69. {GLFW_KEY_KP_MULTIPLY, CMD_OCTAVE_UP},
  70. {GLFW_KEY_KP_0, 0},
  71. {GLFW_KEY_KP_DECIMAL, 2},
  72. {GLFW_KEY_KP_ENTER, 3},
  73. {GLFW_KEY_KP_1, 4},
  74. {GLFW_KEY_KP_2, 5},
  75. {GLFW_KEY_KP_3, 6},
  76. {GLFW_KEY_KP_4, 8},
  77. {GLFW_KEY_KP_5, 9},
  78. {GLFW_KEY_KP_6, 10},
  79. {GLFW_KEY_KP_ADD, 11},
  80. {GLFW_KEY_KP_7, 12},
  81. {GLFW_KEY_KP_8, 13},
  82. {GLFW_KEY_KP_9, 14},
  83. },
  84. }
  85. };
  86. struct InputDevice : midi::InputDevice {
  87. int deviceId;
  88. int octave = 5;
  89. std::map<int, int> pressedNotes;
  90. void setDeviceId(int deviceId) {
  91. this->deviceId = deviceId;
  92. // Default lowest key of numpad is C1.
  93. if (deviceId == 1) {
  94. octave = 3;
  95. }
  96. }
  97. std::string getName() override {
  98. return deviceInfos[deviceId].name;
  99. }
  100. void onKeyPress(int key) {
  101. // Do nothing if no ports are subscribed
  102. if (subscribed.empty())
  103. return;
  104. const auto& keyMap = deviceInfos[deviceId].keyMap;
  105. auto it = keyMap.find(key);
  106. if (it == keyMap.end())
  107. return;
  108. int note = it->second;
  109. if (note < 0) {
  110. if (note == CMD_OCTAVE_DOWN)
  111. octave--;
  112. else if (note == CMD_OCTAVE_UP)
  113. octave++;
  114. octave = math::clamp(octave, 0, 9);
  115. return;
  116. }
  117. note += 12 * octave;
  118. if (note > 127)
  119. return;
  120. // MIDI note on
  121. midi::Message msg;
  122. msg.setStatus(0x9);
  123. msg.setNote(note);
  124. msg.setValue(127);
  125. onMessage(msg);
  126. pressedNotes[key] = note;
  127. }
  128. void onKeyRelease(int key) {
  129. // Do nothing if no ports are subscribed
  130. if (subscribed.empty())
  131. return;
  132. auto it = pressedNotes.find(key);
  133. if (it == pressedNotes.end())
  134. return;
  135. int note = it->second;
  136. // MIDI note off
  137. midi::Message msg;
  138. msg.setStatus(0x8);
  139. msg.setNote(note);
  140. msg.setValue(127);
  141. onMessage(msg);
  142. pressedNotes.erase(it);
  143. }
  144. };
  145. struct MouseInputDevice : midi::InputDevice {
  146. int16_t lastValues[2] = {};
  147. std::string getName() override {
  148. return "Mouse";
  149. }
  150. void onMouseMove(math::Vec pos) {
  151. int16_t values[2];
  152. values[0] = math::clamp((int) std::round(pos.x * 0x3f80), 0, 0x3f80);
  153. // Flip Y values
  154. values[1] = math::clamp((int) std::round((1.f - pos.y) * 0x3f80), 0, 0x3f80);
  155. for (int id = 0; id < 2; id++) {
  156. if (values[id] != lastValues[id]) {
  157. // Continuous controller MSB
  158. midi::Message m;
  159. m.setStatus(0xb);
  160. m.setNote(id);
  161. m.setValue(values[id] >> 7);
  162. onMessage(m);
  163. // Continuous controller LSB
  164. midi::Message m2;
  165. m2.setStatus(0xb);
  166. m2.setNote(id + 32);
  167. m2.setValue(values[id] & 0x7f);
  168. onMessage(m2);
  169. lastValues[id] = values[id];
  170. }
  171. }
  172. }
  173. };
  174. struct Driver : midi::Driver {
  175. InputDevice devices[deviceCount];
  176. MouseInputDevice mouseDevice;
  177. Driver() {
  178. for (int deviceId = 0; deviceId < deviceCount; deviceId++) {
  179. devices[deviceId].setDeviceId(deviceId);
  180. }
  181. }
  182. std::string getName() override {
  183. return "Computer keyboard/mouse";
  184. }
  185. std::vector<int> getInputDeviceIds() override {
  186. std::vector<int> deviceIds;
  187. for (int deviceId = 0; deviceId < deviceCount; deviceId++) {
  188. deviceIds.push_back(deviceId);
  189. }
  190. deviceIds.push_back(MOUSE_DEVICE_ID);
  191. return deviceIds;
  192. }
  193. int getDefaultInputDeviceId() override {
  194. // QWERTY keyboard device
  195. return 0;
  196. }
  197. midi::InputDevice* getInputDevice(int deviceId) {
  198. if (deviceId == MOUSE_DEVICE_ID)
  199. return &mouseDevice;
  200. if (0 <= deviceId && deviceId < deviceCount)
  201. return &devices[deviceId];
  202. return NULL;
  203. }
  204. std::string getInputDeviceName(int deviceId) override {
  205. midi::InputDevice* inputDevice = getInputDevice(deviceId);
  206. if (!inputDevice)
  207. return "";
  208. return inputDevice->getName();
  209. }
  210. midi::InputDevice* subscribeInput(int deviceId, midi::Input* input) override {
  211. midi::InputDevice* inputDevice = getInputDevice(deviceId);
  212. if (!inputDevice)
  213. return NULL;
  214. inputDevice->subscribe(input);
  215. return inputDevice;
  216. }
  217. void unsubscribeInput(int deviceId, midi::Input* input) override {
  218. midi::InputDevice* inputDevice = getInputDevice(deviceId);
  219. if (!inputDevice)
  220. return;
  221. inputDevice->unsubscribe(input);
  222. }
  223. // Events that forward to InputDevices
  224. void onKeyPress(int key) {
  225. for (int deviceId = 0; deviceId < deviceCount; deviceId++) {
  226. devices[deviceId].onKeyPress(key);
  227. }
  228. }
  229. void onKeyRelease(int key) {
  230. for (int deviceId = 0; deviceId < deviceCount; deviceId++) {
  231. devices[deviceId].onKeyRelease(key);
  232. }
  233. }
  234. void onMouseMove(math::Vec pos) {
  235. mouseDevice.onMouseMove(pos);
  236. }
  237. };
  238. void init() {
  239. driver = new Driver;
  240. midi::addDriver(DRIVER, driver);
  241. }
  242. void press(int key) {
  243. if (!driver)
  244. return;
  245. driver->onKeyPress(key);
  246. }
  247. void release(int key) {
  248. if (!driver)
  249. return;
  250. driver->onKeyRelease(key);
  251. }
  252. void mouseMove(math::Vec pos) {
  253. if (!driver)
  254. return;
  255. driver->onMouseMove(pos);
  256. }
  257. } // namespace keyboard
  258. } // namespace rack