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.

usb_midi.h 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2013 PJRC.COM, LLC.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * 1. The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * 2. If the Software is incorporated into a build system that allows
  17. * selection among a list of target devices, then similar target
  18. * devices manufactured by PJRC.COM must be included in the list of
  19. * target devices and selectable in the same manner.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  25. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  26. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  27. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. * SOFTWARE.
  29. */
  30. #ifndef USBmidi_h_
  31. #define USBmidi_h_
  32. #include "usb_desc.h"
  33. #if defined(MIDI_INTERFACE)
  34. #include <inttypes.h>
  35. /*
  36. These were originally meant to allow programs written for
  37. Francois Best's MIDI library to be easily used with
  38. Teensy's usbMIDI which implements the same API. However,
  39. the MIDI library definitions have changed, so these names
  40. now conflict. They've never been documented (the PJRC web
  41. page documents usbMIDI.getType() in numbers) so they are
  42. now commented out so usbMIDI and the MIDI library can be
  43. used together without conflict.
  44. #define NoteOff 0
  45. #define NoteOn 1
  46. #define AfterTouchPoly 2
  47. #define ControlChange 3
  48. #define ProgramChange 4
  49. #define AfterTouchChannel 5
  50. #define PitchBend 6
  51. #define SystemExclusive 7
  52. */
  53. #define USB_MIDI_SYSEX_MAX 60 // maximum sysex length we can receive
  54. // C language implementation
  55. #ifdef __cplusplus
  56. extern "C" {
  57. #endif
  58. void usb_midi_write_packed(uint32_t n);
  59. void usb_midi_send_sysex(const uint8_t *data, uint32_t length);
  60. void usb_midi_flush_output(void);
  61. int usb_midi_read(uint32_t channel);
  62. extern uint8_t usb_midi_msg_channel;
  63. extern uint8_t usb_midi_msg_type;
  64. extern uint8_t usb_midi_msg_data1;
  65. extern uint8_t usb_midi_msg_data2;
  66. extern uint8_t usb_midi_msg_sysex[USB_MIDI_SYSEX_MAX];
  67. extern uint8_t usb_midi_msg_sysex_len;
  68. extern void (*usb_midi_handleNoteOff)(uint8_t ch, uint8_t note, uint8_t vel);
  69. extern void (*usb_midi_handleNoteOn)(uint8_t ch, uint8_t note, uint8_t vel);
  70. extern void (*usb_midi_handleVelocityChange)(uint8_t ch, uint8_t note, uint8_t vel);
  71. extern void (*usb_midi_handleControlChange)(uint8_t ch, uint8_t control, uint8_t value);
  72. extern void (*usb_midi_handleProgramChange)(uint8_t ch, uint8_t program);
  73. extern void (*usb_midi_handleAfterTouch)(uint8_t ch, uint8_t pressure);
  74. extern void (*usb_midi_handlePitchChange)(uint8_t ch, int pitch);
  75. extern void (*usb_midi_handleSysEx)(const uint8_t *data, uint16_t length, uint8_t complete);
  76. extern void (*usb_midi_handleRealTimeSystem)(uint8_t rtb);
  77. extern void (*usb_midi_handleTimeCodeQuarterFrame)(uint16_t data);
  78. #ifdef __cplusplus
  79. }
  80. #endif
  81. // C++ interface
  82. #ifdef __cplusplus
  83. class usb_midi_class
  84. {
  85. public:
  86. void begin(void) { }
  87. void end(void) { }
  88. void sendNoteOff(uint32_t note, uint32_t velocity, uint32_t channel) __attribute__((always_inline)) {
  89. usb_midi_write_packed(0x8008 | (((channel - 1) & 0x0F) << 8)
  90. | ((note & 0x7F) << 16) | ((velocity & 0x7F) << 24));
  91. }
  92. void sendNoteOn(uint32_t note, uint32_t velocity, uint32_t channel) __attribute__((always_inline)) {
  93. usb_midi_write_packed(0x9009 | (((channel - 1) & 0x0F) << 8)
  94. | ((note & 0x7F) << 16) | ((velocity & 0x7F) << 24));
  95. }
  96. void sendPolyPressure(uint32_t note, uint32_t pressure, uint32_t channel) __attribute__((always_inline)) {
  97. usb_midi_write_packed(0xA00A | (((channel - 1) & 0x0F) << 8)
  98. | ((note & 0x7F) << 16) | ((pressure & 0x7F) << 24));
  99. }
  100. void sendControlChange(uint32_t control, uint32_t value, uint32_t channel) __attribute__((always_inline)) {
  101. usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8)
  102. | ((control & 0x7F) << 16) | ((value & 0x7F) << 24));
  103. }
  104. void sendProgramChange(uint32_t program, uint32_t channel) __attribute__((always_inline)) {
  105. usb_midi_write_packed(0xC00C | (((channel - 1) & 0x0F) << 8)
  106. | ((program & 0x7F) << 16));
  107. }
  108. void sendAfterTouch(uint32_t pressure, uint32_t channel) __attribute__((always_inline)) {
  109. usb_midi_write_packed(0xD00D | (((channel - 1) & 0x0F) << 8)
  110. | ((pressure & 0x7F) << 16));
  111. }
  112. void sendPitchBend(uint32_t value, uint32_t channel) __attribute__((always_inline)) {
  113. usb_midi_write_packed(0xE00E | (((channel - 1) & 0x0F) << 8)
  114. | ((value & 0x7F) << 16) | ((value & 0x3F80) << 17));
  115. }
  116. void sendSysEx(uint32_t length, const uint8_t *data) {
  117. usb_midi_send_sysex(data, length);
  118. }
  119. void sendRealTime(uint32_t type) __attribute__((always_inline)) {
  120. uint32_t data = ( (type & 0xFF) | ((type << 8) & 0xFF00) );
  121. switch (type) {
  122. case 0xF8: // Clock
  123. case 0xFA: // Start
  124. case 0xFC: // Stop
  125. case 0xFB: // Continue
  126. case 0xFE: // ActiveSensing
  127. case 0xFF: // SystemReset
  128. usb_midi_write_packed(data);
  129. break;
  130. default: // Invalid Real Time marker
  131. break;
  132. }
  133. }
  134. void sendTimeCodeQuarterFrame(uint32_t type, uint32_t value) __attribute__((always_inline)) {
  135. uint32_t data = ( ((type & 0x07) << 4) | (value & 0x0F) );
  136. sendTimeCodeQuarterFrame(data);
  137. }
  138. void sendTimeCodeQuarterFrame(uint32_t data) __attribute__((always_inline)) {
  139. usb_midi_write_packed(0xF108 | ((data & 0x7F) << 16));
  140. }
  141. void send_now(void) {
  142. usb_midi_flush_output();
  143. }
  144. uint8_t analog2velocity(uint16_t val, uint8_t range);
  145. bool read(uint8_t channel=0) {
  146. return usb_midi_read(channel);
  147. }
  148. inline uint8_t getType(void) {
  149. return usb_midi_msg_type;
  150. };
  151. inline uint8_t getChannel(void) {
  152. return usb_midi_msg_channel;
  153. };
  154. inline uint8_t getData1(void) {
  155. return usb_midi_msg_data1;
  156. };
  157. inline uint8_t getData2(void) {
  158. return usb_midi_msg_data2;
  159. };
  160. inline uint8_t * getSysExArray(void) {
  161. return usb_midi_msg_sysex;
  162. };
  163. inline void setHandleNoteOff(void (*fptr)(uint8_t channel, uint8_t note, uint8_t velocity)) {
  164. usb_midi_handleNoteOff = fptr;
  165. };
  166. inline void setHandleNoteOn(void (*fptr)(uint8_t channel, uint8_t note, uint8_t velocity)) {
  167. usb_midi_handleNoteOn = fptr;
  168. };
  169. inline void setHandleVelocityChange(void (*fptr)(uint8_t channel, uint8_t note, uint8_t velocity)) {
  170. usb_midi_handleVelocityChange = fptr;
  171. };
  172. inline void setHandleControlChange(void (*fptr)(uint8_t channel, uint8_t control, uint8_t value)) {
  173. usb_midi_handleControlChange = fptr;
  174. };
  175. inline void setHandleProgramChange(void (*fptr)(uint8_t channel, uint8_t program)) {
  176. usb_midi_handleProgramChange = fptr;
  177. };
  178. inline void setHandleAfterTouch(void (*fptr)(uint8_t channel, uint8_t pressure)) {
  179. usb_midi_handleAfterTouch = fptr;
  180. };
  181. inline void setHandlePitchChange(void (*fptr)(uint8_t channel, int pitch)) {
  182. usb_midi_handlePitchChange = fptr;
  183. };
  184. inline void setHandleSysEx(void (*fptr)(const uint8_t *data, uint16_t length, bool complete)) {
  185. usb_midi_handleSysEx = (void (*)(const uint8_t *, uint16_t, uint8_t))fptr;
  186. }
  187. inline void setHandleRealTimeSystem(void (*fptr)(uint8_t realtimebyte)) {
  188. usb_midi_handleRealTimeSystem = fptr;
  189. };
  190. inline void setHandleTimeCodeQuarterFrame(void (*fptr)(uint16_t data)) {
  191. usb_midi_handleTimeCodeQuarterFrame = fptr;
  192. };
  193. private:
  194. };
  195. extern usb_midi_class usbMIDI;
  196. #endif // __cplusplus
  197. #endif // MIDI_INTERFACE
  198. #endif // USBmidi_h_