qmk_midi.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include <LUFA/Drivers/USB/USB.h>
  2. #include "qmk_midi.h"
  3. #include "sysex_tools.h"
  4. #include "midi.h"
  5. #include "usb_descriptor.h"
  6. #include "process_midi.h"
  7. /*******************************************************************************
  8. * MIDI
  9. ******************************************************************************/
  10. MidiDevice midi_device;
  11. #define SYSEX_START_OR_CONT 0x40
  12. #define SYSEX_ENDS_IN_1 0x50
  13. #define SYSEX_ENDS_IN_2 0x60
  14. #define SYSEX_ENDS_IN_3 0x70
  15. #define SYS_COMMON_1 0x50
  16. #define SYS_COMMON_2 0x20
  17. #define SYS_COMMON_3 0x30
  18. static void usb_send_func(MidiDevice* device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
  19. MIDI_EventPacket_t event;
  20. event.Data1 = byte0;
  21. event.Data2 = byte1;
  22. event.Data3 = byte2;
  23. uint8_t cable = 0;
  24. // if the length is undefined we assume it is a SYSEX message
  25. if (midi_packet_length(byte0) == UNDEFINED) {
  26. switch (cnt) {
  27. case 3:
  28. if (byte2 == SYSEX_END)
  29. event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
  30. else
  31. event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
  32. break;
  33. case 2:
  34. if (byte1 == SYSEX_END)
  35. event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
  36. else
  37. event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
  38. break;
  39. case 1:
  40. if (byte0 == SYSEX_END)
  41. event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
  42. else
  43. event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
  44. break;
  45. default:
  46. return; // invalid cnt
  47. }
  48. } else {
  49. // deal with 'system common' messages
  50. // TODO are there any more?
  51. switch (byte0 & 0xF0) {
  52. case MIDI_SONGPOSITION:
  53. event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
  54. break;
  55. case MIDI_SONGSELECT:
  56. case MIDI_TC_QUARTERFRAME:
  57. event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
  58. break;
  59. default:
  60. event.Event = MIDI_EVENT(cable, byte0);
  61. break;
  62. }
  63. }
  64. send_midi_packet(&event);
  65. }
  66. static void usb_get_midi(MidiDevice* device) {
  67. MIDI_EventPacket_t event;
  68. while (recv_midi_packet(&event)) {
  69. midi_packet_length_t length = midi_packet_length(event.Data1);
  70. uint8_t input[3];
  71. input[0] = event.Data1;
  72. input[1] = event.Data2;
  73. input[2] = event.Data3;
  74. if (length == UNDEFINED) {
  75. // sysex
  76. if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
  77. length = 3;
  78. } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
  79. length = 2;
  80. } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
  81. length = 1;
  82. } else {
  83. // XXX what to do?
  84. }
  85. }
  86. // pass the data to the device input function
  87. if (length != UNDEFINED) midi_device_input(device, length, input);
  88. }
  89. }
  90. static void fallthrough_callback(MidiDevice* device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
  91. #ifdef AUDIO_ENABLE
  92. if (cnt == 3) {
  93. switch (byte0 & 0xF0) {
  94. case MIDI_NOTEON:
  95. play_note(((double)261.6) * pow(2.0, -4.0) * pow(2.0, (byte1 & 0x7F) / 12.0), (byte2 & 0x7F) / 8);
  96. break;
  97. case MIDI_NOTEOFF:
  98. stop_note(((double)261.6) * pow(2.0, -4.0) * pow(2.0, (byte1 & 0x7F) / 12.0));
  99. break;
  100. }
  101. }
  102. if (byte0 == MIDI_STOP) {
  103. stop_all_notes();
  104. }
  105. #endif
  106. }
  107. static void cc_callback(MidiDevice* device, uint8_t chan, uint8_t num, uint8_t val) {
  108. // sending it back on the next channel
  109. // midi_send_cc(device, (chan + 1) % 16, num, val);
  110. }
  111. void midi_init(void);
  112. void setup_midi(void) {
  113. #ifdef MIDI_ADVANCED
  114. midi_init();
  115. #endif
  116. midi_device_init(&midi_device);
  117. midi_device_set_send_func(&midi_device, usb_send_func);
  118. midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
  119. midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
  120. midi_register_cc_callback(&midi_device, cc_callback);
  121. }