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.

140 lines
3.0KB

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