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