1 /* 2 Copyright 2012-2016 David Robillard <http://drobilla.net> 3 Copyright 2018 Ethan Reker <http://cutthroughrecordings.com> 4 5 Permission to use, copy, modify, and/or distribute this software for any 6 purpose with or without fee is hereby granted, provided that the above 7 copyright notice and this permission notice appear in all copies. 8 9 THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 module dplug.lv2.midi; 18 19 version(LV2): 20 21 /** 22 @defgroup midi MIDI 23 24 Definitions of standard MIDI messages, see <http://lv2plug.in/ns/ext/midi> 25 for details. 26 27 @{ 28 */ 29 30 import core.stdc.stdint; 31 32 extern(C) { 33 34 enum LV2_MIDI_URI = "http://lv2plug.in/ns/ext/midi"; ///< http://lv2plug.in/ns/ext/midi 35 enum LV2_MIDI_PREFIX = LV2_MIDI_URI ~ "#"; ///< http://lv2plug.in/ns/ext/midi# 36 37 enum LV2_MIDI__ActiveSense = LV2_MIDI_PREFIX ~ "ActiveSense"; ///< http://lv2plug.in/ns/ext/midi#ActiveSense 38 enum LV2_MIDI__Aftertouch = LV2_MIDI_PREFIX ~ "Aftertouch"; ///< http://lv2plug.in/ns/ext/midi#Aftertouch 39 enum LV2_MIDI__Bender = LV2_MIDI_PREFIX ~ "Bender"; ///< http://lv2plug.in/ns/ext/midi#Bender 40 enum LV2_MIDI__ChannelPressure = LV2_MIDI_PREFIX ~ "ChannelPressure"; ///< http://lv2plug.in/ns/ext/midi#ChannelPressure 41 enum LV2_MIDI__Chunk = LV2_MIDI_PREFIX ~ "Chunk"; ///< http://lv2plug.in/ns/ext/midi#Chunk 42 enum LV2_MIDI__Clock = LV2_MIDI_PREFIX ~ "Clock"; ///< http://lv2plug.in/ns/ext/midi#Clock 43 enum LV2_MIDI__Continue = LV2_MIDI_PREFIX ~ "Continue"; ///< http://lv2plug.in/ns/ext/midi#Continue 44 enum LV2_MIDI__Controller = LV2_MIDI_PREFIX ~ "Controller"; ///< http://lv2plug.in/ns/ext/midi#Controller 45 enum LV2_MIDI__MidiEvent = LV2_MIDI_PREFIX ~ "MidiEvent"; ///< http://lv2plug.in/ns/ext/midi#MidiEvent 46 enum LV2_MIDI__NoteOff = LV2_MIDI_PREFIX ~ "NoteOff"; ///< http://lv2plug.in/ns/ext/midi#NoteOff 47 enum LV2_MIDI__NoteOn = LV2_MIDI_PREFIX ~ "NoteOn"; ///< http://lv2plug.in/ns/ext/midi#NoteOn 48 enum LV2_MIDI__ProgramChange = LV2_MIDI_PREFIX ~ "ProgramChange"; ///< http://lv2plug.in/ns/ext/midi#ProgramChange 49 enum LV2_MIDI__QuarterFrame = LV2_MIDI_PREFIX ~ "QuarterFrame"; ///< http://lv2plug.in/ns/ext/midi#QuarterFrame 50 enum LV2_MIDI__Reset = LV2_MIDI_PREFIX ~ "Reset"; ///< http://lv2plug.in/ns/ext/midi#Reset 51 enum LV2_MIDI__SongPosition = LV2_MIDI_PREFIX ~ "SongPosition"; ///< http://lv2plug.in/ns/ext/midi#SongPosition 52 enum LV2_MIDI__SongSelect = LV2_MIDI_PREFIX ~ "SongSelect"; ///< http://lv2plug.in/ns/ext/midi#SongSelect 53 enum LV2_MIDI__Start = LV2_MIDI_PREFIX ~ "Start"; ///< http://lv2plug.in/ns/ext/midi#Start 54 enum LV2_MIDI__Stop = LV2_MIDI_PREFIX ~ "Stop"; ///< http://lv2plug.in/ns/ext/midi#Stop 55 enum LV2_MIDI__SystemCommon = LV2_MIDI_PREFIX ~ "SystemCommon"; ///< http://lv2plug.in/ns/ext/midi#SystemCommon 56 enum LV2_MIDI__SystemExclusive = LV2_MIDI_PREFIX ~ "SystemExclusive"; ///< http://lv2plug.in/ns/ext/midi#SystemExclusive 57 enum LV2_MIDI__SystemMessage = LV2_MIDI_PREFIX ~ "SystemMessage"; ///< http://lv2plug.in/ns/ext/midi#SystemMessage 58 enum LV2_MIDI__SystemRealtime = LV2_MIDI_PREFIX ~ "SystemRealtime"; ///< http://lv2plug.in/ns/ext/midi#SystemRealtime 59 enum LV2_MIDI__Tick = LV2_MIDI_PREFIX ~ "Tick"; ///< http://lv2plug.in/ns/ext/midi#Tick 60 enum LV2_MIDI__TuneRequest = LV2_MIDI_PREFIX ~ "TuneRequest"; ///< http://lv2plug.in/ns/ext/midi#TuneRequest 61 enum LV2_MIDI__VoiceMessage = LV2_MIDI_PREFIX ~ "VoiceMessage"; ///< http://lv2plug.in/ns/ext/midi#VoiceMessage 62 enum LV2_MIDI__benderValue = LV2_MIDI_PREFIX ~ "benderValue"; ///< http://lv2plug.in/ns/ext/midi#benderValue 63 enum LV2_MIDI__binding = LV2_MIDI_PREFIX ~ "binding"; ///< http://lv2plug.in/ns/ext/midi#binding 64 enum LV2_MIDI__byteNumber = LV2_MIDI_PREFIX ~ "byteNumber"; ///< http://lv2plug.in/ns/ext/midi#byteNumber 65 enum LV2_MIDI__channel = LV2_MIDI_PREFIX ~ "channel"; ///< http://lv2plug.in/ns/ext/midi#channel 66 enum LV2_MIDI__chunk = LV2_MIDI_PREFIX ~ "chunk"; ///< http://lv2plug.in/ns/ext/midi#chunk 67 enum LV2_MIDI__controllerNumber = LV2_MIDI_PREFIX ~ "controllerNumber"; ///< http://lv2plug.in/ns/ext/midi#controllerNumber 68 enum LV2_MIDI__controllerValue = LV2_MIDI_PREFIX ~ "controllerValue"; ///< http://lv2plug.in/ns/ext/midi#controllerValue 69 enum LV2_MIDI__noteNumber = LV2_MIDI_PREFIX ~ "noteNumber"; ///< http://lv2plug.in/ns/ext/midi#noteNumber 70 enum LV2_MIDI__pressure = LV2_MIDI_PREFIX ~ "pressure"; ///< http://lv2plug.in/ns/ext/midi#pressure 71 enum LV2_MIDI__programNumber = LV2_MIDI_PREFIX ~ "programNumber"; ///< http://lv2plug.in/ns/ext/midi#programNumber 72 enum LV2_MIDI__property = LV2_MIDI_PREFIX ~ "property"; ///< http://lv2plug.in/ns/ext/midi#property 73 enum LV2_MIDI__songNumber = LV2_MIDI_PREFIX ~ "songNumber"; ///< http://lv2plug.in/ns/ext/midi#songNumber 74 enum LV2_MIDI__songPosition = LV2_MIDI_PREFIX ~ "songPosition"; ///< http://lv2plug.in/ns/ext/midi#songPosition 75 enum LV2_MIDI__status = LV2_MIDI_PREFIX ~ "status"; ///< http://lv2plug.in/ns/ext/midi#status 76 enum LV2_MIDI__statusMask = LV2_MIDI_PREFIX ~ "statusMask"; ///< http://lv2plug.in/ns/ext/midi#statusMask 77 enum LV2_MIDI__velocity = LV2_MIDI_PREFIX ~ "velocity"; ///< http://lv2plug.in/ns/ext/midi#velocity 78 79 /** 80 MIDI Message Type. 81 82 This includes both voice messages (which have a channel) and system messages 83 (which do not), as well as a sentinel value for invalid messages. To get 84 the type of a message suitable for use in a switch statement, use 85 lv2_midi_get_type() on the status byte. 86 */ 87 alias LV2_Midi_Message_Type = byte; 88 enum { 89 LV2_MIDI_MSG_INVALID = 0, /**< Invalid Message */ 90 LV2_MIDI_MSG_NOTE_OFF = 0x80, /**< Note Off */ 91 LV2_MIDI_MSG_NOTE_ON = 0x90, /**< Note On */ 92 LV2_MIDI_MSG_NOTE_PRESSURE = 0xA0, /**< Note Pressure */ 93 LV2_MIDI_MSG_CONTROLLER = 0xB0, /**< Controller */ 94 LV2_MIDI_MSG_PGM_CHANGE = 0xC0, /**< Program Change */ 95 LV2_MIDI_MSG_CHANNEL_PRESSURE = 0xD0, /**< Channel Pressure */ 96 LV2_MIDI_MSG_BENDER = 0xE0, /**< Pitch Bender */ 97 LV2_MIDI_MSG_SYSTEM_EXCLUSIVE = 0xF0, /**< System Exclusive Begin */ 98 LV2_MIDI_MSG_MTC_QUARTER = 0xF1, /**< MTC Quarter Frame */ 99 LV2_MIDI_MSG_SONG_POS = 0xF2, /**< Song Position */ 100 LV2_MIDI_MSG_SONG_SELECT = 0xF3, /**< Song Select */ 101 LV2_MIDI_MSG_TUNE_REQUEST = 0xF6, /**< Tune Request */ 102 LV2_MIDI_MSG_CLOCK = 0xF8, /**< Clock */ 103 LV2_MIDI_MSG_START = 0xFA, /**< Start */ 104 LV2_MIDI_MSG_CONTINUE = 0xFB, /**< Continue */ 105 LV2_MIDI_MSG_STOP = 0xFC, /**< Stop */ 106 LV2_MIDI_MSG_ACTIVE_SENSE = 0xFE, /**< Active Sensing */ 107 LV2_MIDI_MSG_RESET = 0xFF /**< Reset */ 108 } 109 110 /** 111 Standard MIDI Controller Numbers. 112 */ 113 alias LV2_Midi_Controller = byte; 114 enum { 115 LV2_MIDI_CTL_MSB_BANK = 0x00, /**< Bank Selection */ 116 LV2_MIDI_CTL_MSB_MODWHEEL = 0x01, /**< Modulation */ 117 LV2_MIDI_CTL_MSB_BREATH = 0x02, /**< Breath */ 118 LV2_MIDI_CTL_MSB_FOOT = 0x04, /**< Foot */ 119 LV2_MIDI_CTL_MSB_PORTAMENTO_TIME = 0x05, /**< Portamento Time */ 120 LV2_MIDI_CTL_MSB_DATA_ENTRY = 0x06, /**< Data Entry */ 121 LV2_MIDI_CTL_MSB_MAIN_VOLUME = 0x07, /**< Main Volume */ 122 LV2_MIDI_CTL_MSB_BALANCE = 0x08, /**< Balance */ 123 LV2_MIDI_CTL_MSB_PAN = 0x0A, /**< Panpot */ 124 LV2_MIDI_CTL_MSB_EXPRESSION = 0x0B, /**< Expression */ 125 LV2_MIDI_CTL_MSB_EFFECT1 = 0x0C, /**< Effect1 */ 126 LV2_MIDI_CTL_MSB_EFFECT2 = 0x0D, /**< Effect2 */ 127 LV2_MIDI_CTL_MSB_GENERAL_PURPOSE1 = 0x10, /**< General Purpose 1 */ 128 LV2_MIDI_CTL_MSB_GENERAL_PURPOSE2 = 0x11, /**< General Purpose 2 */ 129 LV2_MIDI_CTL_MSB_GENERAL_PURPOSE3 = 0x12, /**< General Purpose 3 */ 130 LV2_MIDI_CTL_MSB_GENERAL_PURPOSE4 = 0x13, /**< General Purpose 4 */ 131 LV2_MIDI_CTL_LSB_BANK = 0x20, /**< Bank Selection */ 132 LV2_MIDI_CTL_LSB_MODWHEEL = 0x21, /**< Modulation */ 133 LV2_MIDI_CTL_LSB_BREATH = 0x22, /**< Breath */ 134 LV2_MIDI_CTL_LSB_FOOT = 0x24, /**< Foot */ 135 LV2_MIDI_CTL_LSB_PORTAMENTO_TIME = 0x25, /**< Portamento Time */ 136 LV2_MIDI_CTL_LSB_DATA_ENTRY = 0x26, /**< Data Entry */ 137 LV2_MIDI_CTL_LSB_MAIN_VOLUME = 0x27, /**< Main Volume */ 138 LV2_MIDI_CTL_LSB_BALANCE = 0x28, /**< Balance */ 139 LV2_MIDI_CTL_LSB_PAN = 0x2A, /**< Panpot */ 140 LV2_MIDI_CTL_LSB_EXPRESSION = 0x2B, /**< Expression */ 141 LV2_MIDI_CTL_LSB_EFFECT1 = 0x2C, /**< Effect1 */ 142 LV2_MIDI_CTL_LSB_EFFECT2 = 0x2D, /**< Effect2 */ 143 LV2_MIDI_CTL_LSB_GENERAL_PURPOSE1 = 0x30, /**< General Purpose 1 */ 144 LV2_MIDI_CTL_LSB_GENERAL_PURPOSE2 = 0x31, /**< General Purpose 2 */ 145 LV2_MIDI_CTL_LSB_GENERAL_PURPOSE3 = 0x32, /**< General Purpose 3 */ 146 LV2_MIDI_CTL_LSB_GENERAL_PURPOSE4 = 0x33, /**< General Purpose 4 */ 147 LV2_MIDI_CTL_SUSTAIN = 0x40, /**< Sustain Pedal */ 148 LV2_MIDI_CTL_PORTAMENTO = 0x41, /**< Portamento */ 149 LV2_MIDI_CTL_SOSTENUTO = 0x42, /**< Sostenuto */ 150 LV2_MIDI_CTL_SOFT_PEDAL = 0x43, /**< Soft Pedal */ 151 LV2_MIDI_CTL_LEGATO_FOOTSWITCH = 0x44, /**< Legato Foot Switch */ 152 LV2_MIDI_CTL_HOLD2 = 0x45, /**< Hold2 */ 153 LV2_MIDI_CTL_SC1_SOUND_VARIATION = 0x46, /**< SC1 Sound Variation */ 154 LV2_MIDI_CTL_SC2_TIMBRE = 0x47, /**< SC2 Timbre */ 155 LV2_MIDI_CTL_SC3_RELEASE_TIME = 0x48, /**< SC3 Release Time */ 156 LV2_MIDI_CTL_SC4_ATTACK_TIME = 0x49, /**< SC4 Attack Time */ 157 LV2_MIDI_CTL_SC5_BRIGHTNESS = 0x4A, /**< SC5 Brightness */ 158 LV2_MIDI_CTL_SC6 = 0x4B, /**< SC6 */ 159 LV2_MIDI_CTL_SC7 = 0x4C, /**< SC7 */ 160 LV2_MIDI_CTL_SC8 = 0x4D, /**< SC8 */ 161 LV2_MIDI_CTL_SC9 = 0x4E, /**< SC9 */ 162 LV2_MIDI_CTL_SC10 = 0x4F, /**< SC10 */ 163 LV2_MIDI_CTL_GENERAL_PURPOSE5 = 0x50, /**< General Purpose 5 */ 164 LV2_MIDI_CTL_GENERAL_PURPOSE6 = 0x51, /**< General Purpose 6 */ 165 LV2_MIDI_CTL_GENERAL_PURPOSE7 = 0x52, /**< General Purpose 7 */ 166 LV2_MIDI_CTL_GENERAL_PURPOSE8 = 0x53, /**< General Purpose 8 */ 167 LV2_MIDI_CTL_PORTAMENTO_CONTROL = 0x54, /**< Portamento Control */ 168 LV2_MIDI_CTL_E1_REVERB_DEPTH = 0x5B, /**< E1 Reverb Depth */ 169 LV2_MIDI_CTL_E2_TREMOLO_DEPTH = 0x5C, /**< E2 Tremolo Depth */ 170 LV2_MIDI_CTL_E3_CHORUS_DEPTH = 0x5D, /**< E3 Chorus Depth */ 171 LV2_MIDI_CTL_E4_DETUNE_DEPTH = 0x5E, /**< E4 Detune Depth */ 172 LV2_MIDI_CTL_E5_PHASER_DEPTH = 0x5F, /**< E5 Phaser Depth */ 173 LV2_MIDI_CTL_DATA_INCREMENT = 0x60, /**< Data Increment */ 174 LV2_MIDI_CTL_DATA_DECREMENT = 0x61, /**< Data Decrement */ 175 LV2_MIDI_CTL_NRPN_LSB = 0x62, /**< Non-registered Parameter Number */ 176 LV2_MIDI_CTL_NRPN_MSB = 0x63, /**< Non-registered Parameter Number */ 177 LV2_MIDI_CTL_RPN_LSB = 0x64, /**< Registered Parameter Number */ 178 LV2_MIDI_CTL_RPN_MSB = 0x65, /**< Registered Parameter Number */ 179 LV2_MIDI_CTL_ALL_SOUNDS_OFF = 0x78, /**< All Sounds Off */ 180 LV2_MIDI_CTL_RESET_CONTROLLERS = 0x79, /**< Reset Controllers */ 181 LV2_MIDI_CTL_LOCAL_CONTROL_SWITCH = 0x7A, /**< Local Control Switch */ 182 LV2_MIDI_CTL_ALL_NOTES_OFF = 0x7B, /**< All Notes Off */ 183 LV2_MIDI_CTL_OMNI_OFF = 0x7C, /**< Omni Off */ 184 LV2_MIDI_CTL_OMNI_ON = 0x7D, /**< Omni On */ 185 LV2_MIDI_CTL_MONO1 = 0x7E, /**< Mono1 */ 186 LV2_MIDI_CTL_MONO2 = 0x7F /**< Mono2 */ 187 } 188 189 /** 190 Return true iff `msg` is a MIDI voice message (which has a channel). 191 */ 192 static bool 193 lv2_midi_is_voice_message(const uint8_t* msg) { 194 return msg[0] >= 0x80 && msg[0] < 0xF0; 195 } 196 197 /** 198 Return true iff `msg` is a MIDI system message (which has no channel). 199 */ 200 static bool 201 lv2_midi_is_system_message(const uint8_t* msg) { 202 switch (msg[0]) { 203 case 0xF4: case 0xF5: case 0xF7: case 0xF9: case 0xFD: 204 return false; 205 default: 206 return (msg[0] & 0xF0) == 0xF0; 207 } 208 } 209 210 /** 211 Return the type of a MIDI message. 212 @param msg Pointer to the start (status byte) of a MIDI message. 213 */ 214 static LV2_Midi_Message_Type 215 lv2_midi_message_type(const uint8_t* msg) { 216 if (lv2_midi_is_voice_message(msg)) { 217 return cast(LV2_Midi_Message_Type)(msg[0] & 0xF0); 218 } else if (lv2_midi_is_system_message(msg)) { 219 return cast(LV2_Midi_Message_Type)msg[0]; 220 } else { 221 return LV2_MIDI_MSG_INVALID; 222 } 223 } 224 225 }