usb_midi.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * Copyright (c) 2022, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #ifndef USB_MIDI_H
  7. #define USB_MIDI_H
  8. #include "usb_audio.h"
  9. /* bDescriptorSubType */
  10. #define MIDI_VC_HEADER_DESCRIPTOR_SUBTYPE 0x01U
  11. #define MIDI_MS_HEADER_DESCRIPTOR_SUBTYPE 0x01U
  12. #define MIDI_MS_GENERAL_DESCRIPTOR_SUBTYPE 0x01U
  13. #define MIDI_MIDI_IN_JACK_DESCRIPTOR_SUBTYPE 0x02U
  14. #define MIDI_MIDI_OUT_JACK_DESCRIPTOR_SUBTYPE 0x03U
  15. /* bJackType */
  16. #define MIDI_JACK_TYPE_EMBEDDED 0x01
  17. #define MIDI_JACK_TYPE_EXTERNAL 0x02
  18. #define MIDI_CHANNEL_OMNI 0
  19. #define MIDI_CHANNEL_OFF 17
  20. #define MIDI_PITCHBEND_MIN -8192
  21. #define MIDI_PITCHBEND_MAX 8191
  22. /*! Enumeration of MIDI code index number */
  23. enum MidiCodeIndexNumber {
  24. MIDI_CIN_MISC = 0,
  25. MIDI_CIN_CABLE_EVENT = 1,
  26. MIDI_CIN_SYSCOM_2BYTE = 2, ///< 2 byte system common message e.g MTC, SongSelect
  27. MIDI_CIN_SYSCOM_3BYTE = 3, ///< 3 byte system common message e.g SPP
  28. MIDI_CIN_SYSEX_START = 4, ///< SysEx starts or continue
  29. MIDI_CIN_SYSEX_END_1BYTE = 5, ///< SysEx ends with 1 data, or 1 byte system common message
  30. MIDI_CIN_SYSEX_END_2BYTE = 6, ///< SysEx ends with 2 data
  31. MIDI_CIN_SYSEX_END_3BYTE = 7, ///< SysEx ends with 3 data
  32. MIDI_CIN_NOTE_OFF = 8,
  33. MIDI_CIN_NOTE_ON = 9,
  34. MIDI_CIN_POLY_KEYPRESS = 10,
  35. MIDI_CIN_CONTROL_CHANGE = 11,
  36. MIDI_CIN_PROGRAM_CHANGE = 12,
  37. MIDI_CIN_CHANNEL_PRESSURE = 13,
  38. MIDI_CIN_PITCH_BEND_CHANGE = 14,
  39. MIDI_CIN_1BYTE_DATA = 15
  40. };
  41. /*! Enumeration of MIDI types */
  42. enum MidiType {
  43. InvalidType = 0x00, ///< For notifying errors
  44. NoteOff = 0x80, ///< Note Off
  45. NoteOn = 0x90, ///< Note On
  46. AfterTouchPoly = 0xA0, ///< Polyphonic AfterTouch
  47. ControlChange = 0xB0, ///< Control Change / Channel Mode
  48. ProgramChange = 0xC0, ///< Program Change
  49. AfterTouchChannel = 0xD0, ///< Channel (monophonic) AfterTouch
  50. PitchBend = 0xE0, ///< Pitch Bend
  51. SystemExclusive = 0xF0, ///< System Exclusive
  52. TimeCodeQuarterFrame = 0xF1, ///< System Common - MIDI Time Code Quarter Frame
  53. SongPosition = 0xF2, ///< System Common - Song Position Pointer
  54. SongSelect = 0xF3, ///< System Common - Song Select
  55. TuneRequest = 0xF6, ///< System Common - Tune Request
  56. Clock = 0xF8, ///< System Real Time - Timing Clock
  57. Start = 0xFA, ///< System Real Time - Start
  58. Continue = 0xFB, ///< System Real Time - Continue
  59. Stop = 0xFC, ///< System Real Time - Stop
  60. ActiveSensing = 0xFE, ///< System Real Time - Active Sensing
  61. SystemReset = 0xFF, ///< System Real Time - System Reset
  62. };
  63. /*! Enumeration of Thru filter modes */
  64. enum MidiFilterMode {
  65. Off = 0, ///< Thru disabled (nothing passes through).
  66. Full = 1, ///< Fully enabled Thru (every incoming message is sent back).
  67. SameChannel = 2, ///< Only the messages on the Input Channel will be sent back.
  68. DifferentChannel = 3, ///< All the messages but the ones on the Input Channel will be sent back.
  69. };
  70. /*! \brief Enumeration of Control Change command numbers.
  71. See the detailed controllers numbers & description here:
  72. http://www.somascape.org/midi/tech/spec.html#ctrlnums
  73. */
  74. enum MidiControlChangeNumber {
  75. // High resolution Continuous Controllers MSB (+32 for LSB) ----------------
  76. BankSelect = 0,
  77. ModulationWheel = 1,
  78. BreathController = 2,
  79. // CC3 undefined
  80. FootController = 4,
  81. PortamentoTime = 5,
  82. DataEntry = 6,
  83. ChannelVolume = 7,
  84. Balance = 8,
  85. // CC9 undefined
  86. Pan = 10,
  87. ExpressionController = 11,
  88. EffectControl1 = 12,
  89. EffectControl2 = 13,
  90. // CC14 undefined
  91. // CC15 undefined
  92. GeneralPurposeController1 = 16,
  93. GeneralPurposeController2 = 17,
  94. GeneralPurposeController3 = 18,
  95. GeneralPurposeController4 = 19,
  96. // Switches ----------------------------------------------------------------
  97. Sustain = 64,
  98. Portamento = 65,
  99. Sostenuto = 66,
  100. SoftPedal = 67,
  101. Legato = 68,
  102. Hold = 69,
  103. // Low resolution continuous controllers -----------------------------------
  104. SoundController1 = 70, ///< Synth: Sound Variation FX: Exciter On/Off
  105. SoundController2 = 71, ///< Synth: Harmonic Content FX: Compressor On/Off
  106. SoundController3 = 72, ///< Synth: Release Time FX: Distortion On/Off
  107. SoundController4 = 73, ///< Synth: Attack Time FX: EQ On/Off
  108. SoundController5 = 74, ///< Synth: Brightness FX: Expander On/Off
  109. SoundController6 = 75, ///< Synth: Decay Time FX: Reverb On/Off
  110. SoundController7 = 76, ///< Synth: Vibrato Rate FX: Delay On/Off
  111. SoundController8 = 77, ///< Synth: Vibrato Depth FX: Pitch Transpose On/Off
  112. SoundController9 = 78, ///< Synth: Vibrato Delay FX: Flange/Chorus On/Off
  113. SoundController10 = 79, ///< Synth: Undefined FX: Special Effects On/Off
  114. GeneralPurposeController5 = 80,
  115. GeneralPurposeController6 = 81,
  116. GeneralPurposeController7 = 82,
  117. GeneralPurposeController8 = 83,
  118. PortamentoControl = 84,
  119. // CC85 to CC90 undefined
  120. Effects1 = 91, ///< Reverb send level
  121. Effects2 = 92, ///< Tremolo depth
  122. Effects3 = 93, ///< Chorus send level
  123. Effects4 = 94, ///< Celeste depth
  124. Effects5 = 95, ///< Phaser depth
  125. // Channel Mode messages ---------------------------------------------------
  126. AllSoundOff = 120,
  127. ResetAllControllers = 121,
  128. LocalControl = 122,
  129. AllNotesOff = 123,
  130. OmniModeOff = 124,
  131. OmniModeOn = 125,
  132. MonoModeOn = 126,
  133. PolyModeOn = 127
  134. };
  135. struct midi_cs_if_ac_header_descriptor {
  136. uint8_t bLength;
  137. uint8_t bDescriptorType;
  138. uint8_t bDescriptorSubType;
  139. uint16_t bcdADC;
  140. uint16_t wTotalLength;
  141. uint8_t bInCollection;
  142. uint8_t baInterfaceNr[];
  143. } __PACKED;
  144. #define MIDI_SIZEOF_AC_HEADER_DESC(n) (8 + n)
  145. struct midi_cs_if_ms_header_descriptor {
  146. uint8_t bLength;
  147. uint8_t bDescriptorType;
  148. uint8_t bDescriptorSubType;
  149. uint16_t bcdMSC;
  150. uint16_t wTotalLength;
  151. } __PACKED;
  152. #define MIDI_SIZEOF_MS_HEADER_DESC (7)
  153. struct midi_cs_if_in_jack_descriptor {
  154. uint8_t bLength;
  155. uint8_t bDescriptorType;
  156. uint8_t bDescriptorSubType;
  157. uint8_t bJackType;
  158. uint8_t bJackId;
  159. uint8_t iJack;
  160. } __PACKED;
  161. #define MIDI_SIZEOF_IN_JACK_DESC (6)
  162. struct midi_cs_if_out_jack_descriptor {
  163. uint8_t bLength;
  164. uint8_t bDescriptorType;
  165. uint8_t bDescriptorSubType;
  166. uint8_t bJackType;
  167. uint8_t bJackId;
  168. uint8_t bNrInputPins;
  169. uint8_t baSourceId;
  170. uint8_t baSourcePin;
  171. uint8_t iJack;
  172. } __PACKED;
  173. #define MIDI_SIZEOF_OUT_JACK_DESC (9)
  174. struct midi_cs_ep_ms_general_descriptor {
  175. uint8_t bLength;
  176. uint8_t bDescriptorType;
  177. uint8_t bDescriptorSubType;
  178. uint8_t bNumEmbMIDIJack;
  179. uint8_t baAssocJackID[];
  180. } __PACKED;
  181. #define MIDI_SIZEOF_MS_GENERAL_DESC(n) (4 + n)
  182. // clang-format off
  183. #define MIDI_STANDARD_DESCRIPTOR_INIT(bInterfaceNumber, bNumEndpoints) \
  184. 0x09, /* bLength */ \
  185. USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
  186. bInterfaceNumber, /* bInterfaceNumber */ \
  187. 0x00, /* bAlternateSetting */ \
  188. bNumEndpoints, /* bNumEndpoints */ \
  189. USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
  190. AUDIO_SUBCLASS_MIDISTREAMING, /* bInterfaceSubClass */ \
  191. AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
  192. 0x00 /* iInterface */
  193. #define MIDI_STANDARD_DESCRIPTOR_LEN 0x09
  194. #define MIDI_CS_HEADER_DESCRIPTOR_INIT(wTotalLength) \
  195. 0x07, /* bLength */ \
  196. USB_CS_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
  197. MIDI_MS_HEADER_DESCRIPTOR_SUBTYPE, /* bDescriptorSubtype */ \
  198. WBVAL(0x0100), /* bcdMSC */ \
  199. WBVAL(wTotalLength) /* wTotalLength */
  200. #define MIDI_IN_JACK_DESCRIPTOR_INIT(bJackType, bJackID) \
  201. 0x06, \
  202. 0x24, \
  203. MIDI_MIDI_IN_JACK_DESCRIPTOR_SUBTYPE, \
  204. bJackType, \
  205. bJackID, \
  206. 0x00
  207. #define MIDI_OUT_JACK_DESCRIPTOR_INIT(bJackType, bJackID, baSourceID) \
  208. 0x09, \
  209. 0x24, \
  210. MIDI_MIDI_OUT_JACK_DESCRIPTOR_SUBTYPE, \
  211. bJackType, \
  212. bJackID, \
  213. 0x01, \
  214. baSourceID, \
  215. 0x01, \
  216. 0x00
  217. #define MIDI_JACK_DESCRIPTOR_INIT(bJackFirstID) \
  218. MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, bJackFirstID), \
  219. MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, (bJackFirstID + 1)), \
  220. MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, (bJackFirstID + 2), (bJackFirstID + 1)), \
  221. MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, (bJackFirstID + 3), (bJackFirstID))
  222. #define MIDI_SIZEOF_JACK_DESC (6 + 6 + 9 + 9)
  223. // clang-format on
  224. #endif /* USB_MIDI_H */