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.

141 lines
3.1KB

  1. #include "global_pre.hpp"
  2. #include "keyboard.hpp"
  3. #include <GLFW/glfw3.h>
  4. #include "global.hpp"
  5. namespace rack {
  6. static const int KEYBOARD_DRIVER = -11;
  7. void KeyboardInputDevice::onKeyPress(int key) {
  8. int note = -1;
  9. switch (key) {
  10. case GLFW_KEY_Z: note = 0; break;
  11. case GLFW_KEY_S: note = 1; break;
  12. case GLFW_KEY_X: note = 2; break;
  13. case GLFW_KEY_D: note = 3; break;
  14. case GLFW_KEY_C: note = 4; break;
  15. case GLFW_KEY_V: note = 5; break;
  16. case GLFW_KEY_G: note = 6; break;
  17. case GLFW_KEY_B: note = 7; break;
  18. case GLFW_KEY_H: note = 8; break;
  19. case GLFW_KEY_N: note = 9; break;
  20. case GLFW_KEY_J: note = 10; break;
  21. case GLFW_KEY_M: note = 11; break;
  22. case GLFW_KEY_COMMA: note = 12; break;
  23. case GLFW_KEY_L: note = 13; break;
  24. case GLFW_KEY_PERIOD: note = 14; break;
  25. case GLFW_KEY_SEMICOLON: note = 15; break;
  26. case GLFW_KEY_SLASH: note = 16; break;
  27. case GLFW_KEY_Q: note = 12; break;
  28. case GLFW_KEY_2: note = 13; break;
  29. case GLFW_KEY_W: note = 14; break;
  30. case GLFW_KEY_3: note = 15; break;
  31. case GLFW_KEY_E: note = 16; break;
  32. case GLFW_KEY_R: note = 17; break;
  33. case GLFW_KEY_5: note = 18; break;
  34. case GLFW_KEY_T: note = 19; break;
  35. case GLFW_KEY_6: note = 20; break;
  36. case GLFW_KEY_Y: note = 21; break;
  37. case GLFW_KEY_7: note = 22; break;
  38. case GLFW_KEY_U: note = 23; break;
  39. case GLFW_KEY_I: note = 24; break;
  40. case GLFW_KEY_9: note = 25; break;
  41. case GLFW_KEY_O: note = 26; break;
  42. case GLFW_KEY_0: note = 27; break;
  43. case GLFW_KEY_P: note = 28; break;
  44. case GLFW_KEY_LEFT_BRACKET: note = 29; break;
  45. case GLFW_KEY_EQUAL: note = 30; break;
  46. case GLFW_KEY_RIGHT_BRACKET: note = 31; break;
  47. case GLFW_KEY_GRAVE_ACCENT: {
  48. octave--;
  49. } break;
  50. case GLFW_KEY_1: {
  51. octave++;
  52. } break;
  53. default: break;
  54. }
  55. octave = clamp(octave, 0, 9);
  56. if (note < 0)
  57. return;
  58. note += 12 * octave;
  59. if (note > 127)
  60. return;
  61. MidiMessage msg;
  62. msg.cmd = 0x9 << 4;
  63. msg.data1 = note;
  64. msg.data2 = 127;
  65. onMessage(msg);
  66. pressedNotes[key] = note;
  67. }
  68. void KeyboardInputDevice::onKeyRelease(int key) {
  69. auto it = pressedNotes.find(key);
  70. if (it != pressedNotes.end()) {
  71. int note = it->second;
  72. MidiMessage msg;
  73. msg.cmd = 0x8 << 4;
  74. msg.data1 = note;
  75. msg.data2 = 127;
  76. onMessage(msg);
  77. pressedNotes.erase(it);
  78. }
  79. }
  80. std::vector<int> KeyboardDriver::getInputDeviceIds() {
  81. return {0};
  82. }
  83. std::string KeyboardDriver::getInputDeviceName(int deviceId) {
  84. if (deviceId == 0)
  85. return "QWERTY keyboard (US)";
  86. return "";
  87. }
  88. MidiInputDevice *KeyboardDriver::subscribeInputDevice(int deviceId, MidiInput *midiInput) {
  89. if (deviceId != 0)
  90. return NULL;
  91. device.subscribe(midiInput);
  92. return &device;
  93. }
  94. void KeyboardDriver::unsubscribeInputDevice(int deviceId, MidiInput *midiInput) {
  95. if (deviceId != 0)
  96. return;
  97. device.unsubscribe(midiInput);
  98. }
  99. void keyboardInit() {
  100. global->keyboard.driver = new KeyboardDriver();
  101. midiDriverAdd(KEYBOARD_DRIVER, global->keyboard.driver);
  102. }
  103. void keyboardPress(int key) {
  104. if (!global->keyboard.driver)
  105. return;
  106. global->keyboard.driver->device.onKeyPress(key);
  107. }
  108. void keyboardRelease(int key) {
  109. if (!global->keyboard.driver)
  110. return;
  111. global->keyboard.driver->device.onKeyRelease(key);
  112. }
  113. } // namespace rack