1 /* SPDX-License-Identifier: LGPL-2.1+ */ 2 /** 3 * \file include/ump_msg.h 4 * \brief API library for ALSA rawmidi/UMP interface 5 * 6 * API library for ALSA rawmidi/UMP interface 7 */ 8 9 #ifndef __ALSA_UMP_MSG_H 10 #define __ALSA_UMP_MSG_H 11 12 #include <stdint.h> 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 /** general UMP packet header in 32bit word */ 19 typedef struct _snd_ump_msg_hdr { 20 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 21 uint8_t type:4; /**< UMP packet type */ 22 uint8_t group:4; /**< UMP Group */ 23 uint8_t status:4; /**< Status */ 24 uint8_t channel:4; /**< Channel */ 25 uint8_t byte1; /**< First data byte */ 26 uint8_t byte2; /**< Second data byte */ 27 #else 28 uint8_t byte2; /**< Second data byte */ 29 uint8_t byte1; /**< First data byte */ 30 uint8_t channel:4; /**< Channel */ 31 uint8_t status:4; /**< Status */ 32 uint8_t group:4; /**< UMP Group */ 33 uint8_t type:4; /**< UMP packet type */ 34 #endif 35 } __attribute((packed)) snd_ump_msg_hdr_t; 36 37 /** MIDI 1.0 Note Off / Note On (32bit) */ 38 typedef struct _snd_ump_msg_midi1_note { 39 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 40 uint8_t type:4; /**< UMP packet type */ 41 uint8_t group:4; /**< UMP Group */ 42 uint8_t status:4; /**< Status */ 43 uint8_t channel:4; /**< Channel */ 44 uint8_t note; /**< Note (7bit) */ 45 uint8_t velocity; /**< Velocity (7bit) */ 46 #else 47 uint8_t velocity; /**< Velocity (7bit) */ 48 uint8_t note; /**< Note (7bit) */ 49 uint8_t channel:4; /**< Channel */ 50 uint8_t status:4; /**< Status */ 51 uint8_t group:4; /**< UMP Group */ 52 uint8_t type:4; /**< UMP packet type */ 53 #endif 54 } __attribute((packed)) snd_ump_msg_midi1_note_t; 55 56 /** MIDI 1.0 Poly Pressure (32bit) */ 57 typedef struct _snd_ump_msg_midi1_paf { 58 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 59 uint8_t type:4; /**< UMP packet type */ 60 uint8_t group:4; /**< UMP Group */ 61 uint8_t status:4; /**< Status */ 62 uint8_t channel:4; /**< Channel */ 63 uint8_t note; /** Note (7bit) */ 64 uint8_t data; /** Pressure (7bit) */ 65 #else 66 uint8_t data; /** Pressure (7bit) */ 67 uint8_t note; /** Note (7bit) */ 68 uint8_t channel:4; /**< Channel */ 69 uint8_t status:4; /**< Status */ 70 uint8_t group:4; /**< UMP Group */ 71 uint8_t type:4; /**< UMP packet type */ 72 #endif 73 } __attribute((packed)) snd_ump_msg_midi1_paf_t; 74 75 /** MIDI 1.0 Control Change (32bit) */ 76 typedef struct _snd_ump_msg_midi1_cc { 77 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 78 uint8_t type:4; /**< UMP packet type */ 79 uint8_t group:4; /**< UMP Group */ 80 uint8_t status:4; /**< Status */ 81 uint8_t channel:4; /**< Channel */ 82 uint8_t index; /** Control index (7bit) */ 83 uint8_t data; /** Control data (7bit) */ 84 #else 85 uint8_t data; /** Control data (7bit) */ 86 uint8_t index; /** Control index (7bit) */ 87 uint8_t channel:4; /**< Channel */ 88 uint8_t status:4; /**< Status */ 89 uint8_t group:4; /**< UMP Group */ 90 uint8_t type:4; /**< UMP packet type */ 91 #endif 92 } __attribute((packed)) snd_ump_msg_midi1_cc_t; 93 94 /** MIDI 1.0 Program Change (32bit) */ 95 typedef struct _snd_ump_msg_midi1_program { 96 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 97 uint8_t type:4; /**< UMP packet type */ 98 uint8_t group:4; /**< UMP Group */ 99 uint8_t status:4; /**< Status */ 100 uint8_t channel:4; /**< Channel */ 101 uint8_t program; /**< Program number (7bit) */ 102 uint8_t reserved; /**< Unused */ 103 #else 104 uint8_t reserved; /**< Unused */ 105 uint8_t program; /**< Program number (7bit) */ 106 uint8_t channel:4; /**< Channel */ 107 uint8_t status:4; /**< Status */ 108 uint8_t group:4; /**< UMP Group */ 109 uint8_t type:4; /**< UMP packet type */ 110 #endif 111 } __attribute((packed)) snd_ump_msg_midi1_program_t; 112 113 /** MIDI 1.0 Channel Pressure (32bit) */ 114 typedef struct _snd_ump_msg_midi1_caf { 115 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 116 uint8_t type:4; /**< UMP packet type */ 117 uint8_t group:4; /**< UMP Group */ 118 uint8_t status:4; /**< Status */ 119 uint8_t channel:4; /**< Channel */ 120 uint8_t data; /**< Pressure (7bit) */ 121 uint8_t reserved; /**< Unused */ 122 #else 123 uint8_t reserved; /**< Unused */ 124 uint8_t data; /**< Pressure (7bit) */ 125 uint8_t channel:4; /**< Channel */ 126 uint8_t status:4; /**< Status */ 127 uint8_t group:4; /**< UMP Group */ 128 uint8_t type:4; /**< UMP packet type */ 129 #endif 130 } __attribute((packed)) snd_ump_msg_midi1_caf_t; 131 132 /** MIDI 1.0 Pitch Bend (32bit) */ 133 typedef struct _snd_ump_msg_midi1_pitchbend { 134 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 135 uint8_t type:4; /**< UMP packet type */ 136 uint8_t group:4; /**< UMP Group */ 137 uint8_t status:4; /**< Status */ 138 uint8_t channel:4; /**< Channel */ 139 uint8_t data_lsb; /**< LSB of pitchbend (7bit) */ 140 uint8_t data_msb; /**< MSB of pitchbend (7bit) */ 141 #else 142 uint8_t data_msb; /**< MSB of pitchbend (7bit) */ 143 uint8_t data_lsb; /**< LSB of pitchbend (7bit) */ 144 uint8_t channel:4; /**< Channel */ 145 uint8_t status:4; /**< Status */ 146 uint8_t group:4; /**< UMP Group */ 147 uint8_t type:4; /**< UMP packet type */ 148 #endif 149 } __attribute((packed)) snd_ump_msg_midi1_pitchbend_t; 150 151 /** System Common and Real Time messages (32bit); no channel field */ 152 typedef struct snd_ump_msg_system { 153 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 154 uint8_t type:4; /**< UMP packet type */ 155 uint8_t group:4; /**< UMP Group */ 156 uint8_t status; /**< Status */ 157 uint8_t parm1; /**< First parameter */ 158 uint8_t parm2; /**< Second parameter */ 159 #else 160 uint8_t parm1; /**< First parameter */ 161 uint8_t parm2; /**< Second parameter */ 162 uint8_t status; /**< Status */ 163 uint8_t group:4; /**< UMP Group */ 164 uint8_t type:4; /**< UMP packet type */ 165 #endif 166 } __attribute((packed)) snd_ump_msg_system_t; 167 168 /** MIDI 1.0 UMP CVM (32bit) */ 169 typedef union _snd_ump_msg_midi1 { 170 snd_ump_msg_midi1_note_t note_on; 171 snd_ump_msg_midi1_note_t note_off; 172 snd_ump_msg_midi1_paf_t poly_pressure; 173 snd_ump_msg_midi1_cc_t control_change; 174 snd_ump_msg_midi1_program_t program_change; 175 snd_ump_msg_midi1_caf_t channel_pressure; 176 snd_ump_msg_midi1_pitchbend_t pitchbend; 177 snd_ump_msg_system_t system; 178 snd_ump_msg_hdr_t hdr; 179 uint32_t raw; 180 } snd_ump_msg_midi1_t; 181 182 /** MIDI 2.0 Note-on/off attribute type */ 183 enum { 184 SND_UMP_MIDI2_NOTE_ATTR_NO_DATA = 0x00, /**< No attribute data */ 185 SND_UMP_MIDI2_NOTE_ATTR_MANUFACTURER = 0x01, /**< Manufacturer specific */ 186 SND_UMP_MIDI2_NOTE_ATTR_PROFILE = 0x02, /**< Profile specific */ 187 SND_UMP_MIDI2_NOTE_ATTR_PITCH79 = 0x03, /**< Pitch 7.9 */ 188 }; 189 190 /* MIDI 2.0 Note Off / Note On (64bit) */ 191 typedef struct _snd_ump_msg_midi2_note { 192 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 193 uint8_t type:4; /**< UMP packet type */ 194 uint8_t group:4; /**< UMP Group */ 195 uint8_t status:4; /**< Status */ 196 uint8_t channel:4; /**< Channel */ 197 uint8_t note; /**< Note (7bit) */ 198 uint8_t attr_type; /**< Attribute type */ 199 200 uint16_t velocity; /**< Velocity (16bit) */ 201 uint16_t attr_data; /**< Attribute data (16bit) */ 202 #else 203 uint8_t attr_type; /**< Attribute type */ 204 uint8_t note; /**< Note (7bit) */ 205 uint8_t channel:4; /**< Channel */ 206 uint8_t status:4; /**< Status */ 207 uint8_t group:4; /**< UMP Group */ 208 uint8_t type:4; /**< UMP packet type */ 209 210 uint16_t attr_data; /**< Attribute data (16bit) */ 211 uint16_t velocity; /**< Velocity (16bit) */ 212 #endif 213 } __attribute((packed)) snd_ump_msg_midi2_note_t; 214 215 /** MIDI 2.0 Poly Pressure (64bit) */ 216 typedef struct _snd_ump_msg_midi2_paf { 217 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 218 uint8_t type:4; /**< UMP packet type */ 219 uint8_t group:4; /**< UMP Group */ 220 uint8_t status:4; /**< Status */ 221 uint8_t channel:4; /**< Channel */ 222 uint8_t note; /**< Note (7bit) */ 223 uint8_t reserved; /**< Unused */ 224 225 uint32_t data; /**< Pressure (32bit) */ 226 #else 227 uint8_t reserved; /**< Unused */ 228 uint8_t note; /**< Note (7bit) */ 229 uint8_t channel:4; /**< Channel */ 230 uint8_t status:4; /**< Status */ 231 uint8_t group:4; /**< UMP Group */ 232 uint8_t type:4; /**< UMP packet type */ 233 234 uint32_t data; /**< Pressure (32bit) */ 235 #endif 236 } __attribute((packed)) snd_ump_msg_midi2_paf_t; 237 238 /** MIDI 2.0 Per-Note Controller (64bit) */ 239 typedef struct _snd_ump_msg_midi2_per_note_cc { 240 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 241 uint8_t type:4; /**< UMP packet type */ 242 uint8_t group:4; /**< UMP Group */ 243 uint8_t status:4; /**< Status */ 244 uint8_t channel:4; /**< Channel */ 245 uint8_t note; /**< Note (7bit) */ 246 uint8_t index; /**< Control index (8bit) */ 247 248 uint32_t data; /**< Data (32bit) */ 249 #else 250 uint8_t index; /**< Control index (8bit) */ 251 uint8_t note; /**< Note (7bit) */ 252 uint8_t channel:4; /**< Channel */ 253 uint8_t status:4; /**< Status */ 254 uint8_t group:4; /**< UMP Group */ 255 uint8_t type:4; /**< UMP packet type */ 256 257 uint32_t data; /**< Data (32bit) */ 258 #endif 259 } __attribute((packed)) snd_ump_msg_midi2_per_note_cc_t; 260 261 /** MIDI 2.0 per-note management flag bits */ 262 enum { 263 SND_UMP_MIDI2_PNMGMT_RESET_CONTROLLERS = 0x01, /**< Reset (set) per-note controllers */ 264 SND_UMP_MIDI2_PNMGMT_DETACH_CONTROLLERS = 0x02, /**< Detach per-note controllers */ 265 }; 266 267 /** MIDI 2.0 Per-Note Management (64bit) */ 268 typedef struct _snd_ump_msg_midi2_per_note_mgmt { 269 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 270 uint8_t type:4; /**< UMP packet type */ 271 uint8_t group:4; /**< UMP Group */ 272 uint8_t status:4; /**< Status */ 273 uint8_t channel:4; /**< Channel */ 274 uint8_t note; /**< Note (7bit) */ 275 uint8_t flags; /**< Option flags (8bit) */ 276 277 uint32_t reserved; /**< Unused */ 278 #else 279 uint8_t flags; /**< Option flags (8bit) */ 280 uint8_t note; /**< Note (7bit) */ 281 uint8_t channel:4; /**< Channel */ 282 uint8_t status:4; /**< Status */ 283 uint8_t group:4; /**< UMP Group */ 284 uint8_t type:4; /**< UMP packet type */ 285 286 uint32_t reserved; /**< Unused */ 287 #endif 288 } __attribute((packed)) snd_ump_msg_midi2_per_note_mgmt_t; 289 290 /** MIDI 2.0 Control Change (64bit) */ 291 typedef struct _snd_ump_msg_midi2_cc { 292 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 293 uint8_t type:4; /**< UMP packet type */ 294 uint8_t group:4; /**< UMP Group */ 295 uint8_t status:4; /**< Status */ 296 uint8_t channel:4; /**< Channel */ 297 uint8_t index; /**< Control index (7bit) */ 298 uint8_t reserved; /**< Unused */ 299 300 uint32_t data; /**< Control data (32bit) */ 301 #else 302 uint8_t reserved; /**< Unused */ 303 uint8_t index; /**< Control index (7bit) */ 304 uint8_t channel:4; /**< Channel */ 305 uint8_t status:4; /**< Status */ 306 uint8_t group:4; /**< UMP Group */ 307 uint8_t type:4; /**< UMP packet type */ 308 309 uint32_t data; /**< Control data (32bit) */ 310 #endif 311 } __attribute((packed)) snd_ump_msg_midi2_cc_t; 312 313 /** MIDI 2.0 Registered Controller (RPN) / Assignable Controller (NRPN) (64bit) */ 314 typedef struct _snd_ump_msg_midi2_rpn { 315 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 316 uint8_t type:4; /**< UMP packet type */ 317 uint8_t group:4; /**< UMP Group */ 318 uint8_t status:4; /**< Status */ 319 uint8_t channel:4; /**< Channel */ 320 uint8_t bank; /**< Bank number (7bit) */ 321 uint8_t index; /**< Control index (7bit) */ 322 323 uint32_t data; /**< Data (32bit) */ 324 #else 325 uint8_t index; /**< Control index (7bit) */ 326 uint8_t bank; /**< Bank number (7bit) */ 327 uint8_t channel:4; /**< Channel */ 328 uint8_t status:4; /**< Status */ 329 uint8_t group:4; /**< UMP Group */ 330 uint8_t type:4; /**< UMP packet type */ 331 332 uint32_t data; /**< Data (32bit) */ 333 #endif 334 } __attribute((packed)) snd_ump_msg_midi2_rpn_t; 335 336 /** MIDI 2.0 Program Change (64bit) */ 337 typedef struct _snd_ump_msg_midi2_program { 338 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 339 uint8_t type:4; /**< UMP packet type */ 340 uint8_t group:4; /**< UMP Group */ 341 uint8_t status:4; /**< Status */ 342 uint8_t channel:4; /**< Channel */ 343 uint16_t reserved:15; /**< Unused */ 344 uint16_t bank_valid:1; /**< Option flag: bank valid */ 345 346 uint8_t program; /**< Program number (7bit) */ 347 uint8_t reserved2; /**< Unused */ 348 uint8_t bank_msb; /**< MSB of bank (8bit) */ 349 uint8_t bank_lsb; /**< LSB of bank (7bit) */ 350 #else 351 uint16_t bank_valid:1; /**< Option flag: bank valid */ 352 uint16_t reserved:15; /**< Unused */ 353 uint8_t channel:4; /**< Channel */ 354 uint8_t status:4; /**< Status */ 355 uint8_t group:4; /**< UMP Group */ 356 uint8_t type:4; /**< UMP packet type */ 357 358 uint8_t bank_lsb; /**< LSB of bank (7bit) */ 359 uint8_t bank_msb; /**< MSB of bank (8bit) */ 360 uint8_t reserved2; /**< Unused */ 361 uint8_t program; /**< Program number (7bit) */ 362 #endif 363 } __attribute((packed)) snd_ump_msg_midi2_program_t; 364 365 /** MIDI 2.0 Channel Pressure (64bit) */ 366 typedef struct _snd_ump_msg_midi2_caf { 367 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 368 uint8_t type:4; /**< UMP packet type */ 369 uint8_t group:4; /**< UMP Group */ 370 uint8_t status:4; /**< Status */ 371 uint8_t channel:4; /**< Channel */ 372 uint16_t reserved; /**< Unused */ 373 374 uint32_t data; /** Data (32bit) */ 375 #else 376 uint16_t reserved; /**< Unused */ 377 uint8_t channel:4; /**< Channel */ 378 uint8_t status:4; /**< Status */ 379 uint8_t group:4; /**< UMP Group */ 380 uint8_t type:4; /**< UMP packet type */ 381 382 uint32_t data; /** Data (32bit) */ 383 #endif 384 } __attribute((packed)) snd_ump_msg_midi2_caf_t; 385 386 /* MIDI 2.0 Pitch Bend (64bit) */ 387 typedef struct _snd_ump_msg_midi2_pitchbend { 388 #ifdef SNDRV_BIG_ENDIAN_BITFIELD 389 uint8_t type:4; /**< UMP packet type */ 390 uint8_t group:4; /**< UMP Group */ 391 uint8_t status:4; /**< Status */ 392 uint8_t channel:4; /**< Channel */ 393 uint16_t reserved; /**< Unused */ 394 395 uint32_t data; /** Data (32bit) */ 396 #else 397 uint16_t reserved; /**< Unused */ 398 uint8_t channel:4; /**< Channel */ 399 uint8_t status:4; /**< Status */ 400 uint8_t group:4; /**< UMP Group */ 401 uint8_t type:4; /**< UMP packet type */ 402 403 uint32_t data; /** Data (32bit) */ 404 #endif 405 } __attribute((packed)) snd_ump_msg_midi2_pitchbend_t; 406 407 /* MIDI 2.0 Per-Note Pitch Bend (64bit) */ 408 typedef struct _snd_ump_msg_midi2_per_note_pitchbend { 409 #ifdef __BIG_ENDIAN_BITFIELD 410 uint8_t type:4; /**< UMP packet type */ 411 uint8_t group:4; /**< UMP Group */ 412 uint8_t status:4; /**< Status */ 413 uint8_t channel:4; /**< Channel */ 414 uint8_t note; /**< Note (7bit) */ 415 uint8_t reserved; /**< Unused */ 416 417 uint32_t data; /**< Data (32bit) */ 418 #else 419 /* 0 */ 420 uint8_t reserved; /**< Unused */ 421 uint8_t note; /**< Note (7bit) */ 422 uint8_t channel:4; /**< Channel */ 423 uint8_t status:4; /**< Status */ 424 uint8_t group:4; /**< UMP Group */ 425 uint8_t type:4; /**< UMP packet type */ 426 427 uint32_t data; /**< Data (32bit) */ 428 #endif 429 } __attribute((packed)) snd_ump_msg_midi2_per_note_pitchbend_t; 430 431 /** MIDI2 UMP packet (64bit little-endian) */ 432 typedef union _snd_ump_msg_midi2 { 433 snd_ump_msg_midi2_note_t note_on; 434 snd_ump_msg_midi2_note_t note_off; 435 snd_ump_msg_midi2_paf_t poly_pressure; 436 snd_ump_msg_midi2_per_note_cc_t per_note_acc; 437 snd_ump_msg_midi2_per_note_cc_t per_note_rcc; 438 snd_ump_msg_midi2_per_note_mgmt_t per_note_mgmt; 439 snd_ump_msg_midi2_cc_t control_change; 440 snd_ump_msg_midi2_rpn_t rpn; 441 snd_ump_msg_midi2_rpn_t nrpn; 442 snd_ump_msg_midi2_rpn_t relative_rpn; 443 snd_ump_msg_midi2_rpn_t relative_nrpn; 444 snd_ump_msg_midi2_program_t program_change; 445 snd_ump_msg_midi2_caf_t channel_pressure; 446 snd_ump_msg_midi2_pitchbend_t pitchbend; 447 snd_ump_msg_midi2_per_note_pitchbend_t per_note_pitchbend; 448 snd_ump_msg_hdr_t hdr; 449 uint32_t raw[2]; 450 } snd_ump_msg_midi2_t; 451 452 /** 453 * UMP message type 454 */ 455 enum { 456 SND_UMP_MSG_TYPE_UTILITY = 0x00, /* Utility messages */ 457 SND_UMP_MSG_TYPE_SYSTEM = 0x01, /* System messages */ 458 SND_UMP_MSG_TYPE_MIDI1_CHANNEL_VOICE = 0x02, /* MIDI 1.0 messages */ 459 SND_UMP_MSG_TYPE_DATA = 0x03, /* 7bit SysEx messages */ 460 SND_UMP_MSG_TYPE_MIDI2_CHANNEL_VOICE = 0x04, /* MIDI 2.0 messages */ 461 SND_UMP_MSG_TYPE_EXTENDED_DATA = 0x05, /* 8bit data message */ 462 SND_UMP_MSG_TYPE_FLEX_DATA = 0x0d, /* Flexible data messages */ 463 SND_UMP_MSG_TYPE_STREAM = 0x0f, /* Stream messages */ 464 }; 465 466 /** 467 * UMP MIDI 1.0 / 2.0 message status code (4bit) 468 */ 469 enum { 470 SND_UMP_MSG_PER_NOTE_RCC = 0x0, 471 SND_UMP_MSG_PER_NOTE_ACC = 0x1, 472 SND_UMP_MSG_RPN = 0x2, 473 SND_UMP_MSG_NRPN = 0x3, 474 SND_UMP_MSG_RELATIVE_RPN = 0x4, 475 SND_UMP_MSG_RELATIVE_NRPN = 0x5, 476 SND_UMP_MSG_PER_NOTE_PITCHBEND = 0x6, 477 SND_UMP_MSG_NOTE_OFF = 0x8, 478 SND_UMP_MSG_NOTE_ON = 0x9, 479 SND_UMP_MSG_POLY_PRESSURE = 0xa, 480 SND_UMP_MSG_CONTROL_CHANGE = 0xb, 481 SND_UMP_MSG_PROGRAM_CHANGE = 0xc, 482 SND_UMP_MSG_CHANNEL_PRESSURE = 0xd, 483 SND_UMP_MSG_PITCHBEND = 0xe, 484 SND_UMP_MSG_PER_NOTE_MGMT = 0xf, 485 }; 486 487 /** 488 * MIDI System / Realtime message status code (8bit) 489 */ 490 enum { 491 SND_UMP_MSG_REALTIME = 0xf0, /* mask */ 492 SND_UMP_MSG_SYSEX_START = 0xf0, 493 SND_UMP_MSG_MIDI_TIME_CODE = 0xf1, 494 SND_UMP_MSG_SONG_POSITION = 0xf2, 495 SND_UMP_MSG_SONG_SELECT = 0xf3, 496 SND_UMP_MSG_TUNE_REQUEST = 0xf6, 497 SND_UMP_MSG_SYSEX_END = 0xf7, 498 SND_UMP_MSG_TIMING_CLOCK = 0xf8, 499 SND_UMP_MSG_START = 0xfa, 500 SND_UMP_MSG_CONTINUE = 0xfb, 501 SND_UMP_MSG_STOP = 0xfc, 502 SND_UMP_MSG_ACTIVE_SENSING = 0xfe, 503 SND_UMP_MSG_RESET = 0xff, 504 }; 505 506 /** MIDI 2.0 SysEx / Data Status; same values for both 7-bit and 8-bit SysEx */ 507 enum { 508 SND_UMP_SYSEX_STATUS_SINGLE = 0, 509 SND_UMP_SYSEX_STATUS_START = 1, 510 SND_UMP_SYSEX_STATUS_CONTINUE = 2, 511 SND_UMP_SYSEX_STATUS_END = 3, 512 }; 513 514 /** UMP Utility Type Status (type 0x0) **/ 515 enum { 516 SND_UMP_UTILITY_MSG_STATUS_NOOP = 0x00, 517 SND_UMP_UTILITY_MSG_STATUS_JR_CLOCK = 0x01, 518 SND_UMP_UTILITY_MSG_STATUS_JR_TSTAMP = 0x02, 519 SND_UMP_UTILITY_MSG_STATUS_DCTPQ = 0x03, 520 SND_UMP_UTILITY_MSG_STATUS_DC = 0x04, 521 }; 522 523 /** UMP Stream Message Status (type 0xf) */ 524 enum { 525 SND_UMP_STREAM_MSG_STATUS_EP_DISCOVERY = 0x00, 526 SND_UMP_STREAM_MSG_STATUS_EP_INFO = 0x01, 527 SND_UMP_STREAM_MSG_STATUS_DEVICE_INFO = 0x02, 528 SND_UMP_STREAM_MSG_STATUS_EP_NAME = 0x03, 529 SND_UMP_STREAM_MSG_STATUS_PRODUCT_ID = 0x04, 530 SND_UMP_STREAM_MSG_STATUS_STREAM_CFG_REQUEST = 0x05, 531 SND_UMP_STREAM_MSG_STATUS_STREAM_CFG = 0x06, 532 SND_UMP_STREAM_MSG_STATUS_FB_DISCOVERY = 0x10, 533 SND_UMP_STREAM_MSG_STATUS_FB_INFO = 0x11, 534 SND_UMP_STREAM_MSG_STATUS_FB_NAME = 0x12, 535 SND_UMP_STREAM_MSG_STATUS_START_CLIP = 0x20, 536 SND_UMP_STREAM_MSG_STATUS_END_CLIP = 0x21, 537 }; 538 539 /** UMP Endpoint Discovery filter bitmap */ 540 enum { 541 SND_UMP_STREAM_MSG_REQUEST_EP_INFO = (1U << 0), 542 SND_UMP_STREAM_MSG_REQUEST_DEVICE_INFO = (1U << 1), 543 SND_UMP_STREAM_MSG_REQUEST_EP_NAME = (1U << 2), 544 SND_UMP_STREAM_MSG_REQUEST_PRODUCT_ID = (1U << 3), 545 SND_UMP_STREAM_MSG_REQUEST_STREAM_CFG = (1U << 4), 546 }; 547 548 /** UMP Function Block Discovery filter bitmap */ 549 enum { 550 SND_UMP_STREAM_MSG_REQUEST_FB_INFO = (1U << 0), 551 SND_UMP_STREAM_MSG_REQUEST_FB_NAME = (1U << 1), 552 }; 553 554 /** UMP Endpoint Info capability bits (used for protocol request/notify, too) */ 555 enum { 556 SND_UMP_STREAM_MSG_EP_INFO_CAP_TXJR = (1U << 0), /* Sending JRTS */ 557 SND_UMP_STREAM_MSG_EP_INFO_CAP_RXJR = (1U << 1), /* Receiving JRTS */ 558 SND_UMP_STREAM_MSG_EP_INFO_CAP_MIDI1 = (1U << 8), /* MIDI 1.0 */ 559 SND_UMP_STREAM_MSG_EP_INFO_CAP_MIDI2 = (1U << 9), /* MIDI 2.0 */ 560 }; 561 562 /** UMP Endpoint / Function Block name string format bits */ 563 enum { 564 SND_UMP_STREAM_MSG_FORMAT_SINGLE = 0, 565 SND_UMP_STREAM_MSG_FORMAT_START = 1, 566 SND_UMP_STREAM_MSG_FORMAT_CONTINUE = 2, 567 SND_UMP_STREAM_MSG_FORMAT_END = 3, 568 }; 569 570 /** 571 * \brief get UMP status (4bit) from 32bit UMP message header 572 */ 573 static inline uint8_t snd_ump_msg_hdr_status(uint32_t ump) 574 { 575 return (ump >> 20) & 0x0f; 576 } 577 578 /** 579 * \brief get UMP channel (4bit) from 32bit UMP message header 580 */ 581 static inline uint8_t snd_ump_msg_hdr_channel(uint32_t ump) 582 { 583 return (ump >> 16) & 0x0f; 584 } 585 586 /** 587 * \brief get UMP message type (4bit) from 32bit UMP message header 588 */ 589 static inline uint8_t snd_ump_msg_hdr_type(uint32_t ump) 590 { 591 return (ump >> 28); 592 } 593 594 /** 595 * \brief check if the given UMP type is a groupless message 596 */ 597 static inline int snd_ump_msg_type_is_groupless(uint8_t type) 598 { 599 return type == SND_UMP_MSG_TYPE_UTILITY || type == SND_UMP_MSG_TYPE_STREAM; 600 } 601 602 /** 603 * \brief get UMP group (4bit) from 32bit UMP message header 604 */ 605 static inline uint8_t snd_ump_msg_hdr_group(uint32_t ump) 606 { 607 return (ump >> 24) & 0x0f; 608 } 609 610 /** 611 * \brief get UMP status from UMP packet pointer 612 */ 613 static inline uint8_t snd_ump_msg_status(const uint32_t *ump) 614 { 615 return snd_ump_msg_hdr_status(*ump); 616 } 617 618 /** 619 * \brief get UMP channel from UMP packet pointer 620 */ 621 static inline uint8_t snd_ump_msg_channel(const uint32_t *ump) 622 { 623 return snd_ump_msg_hdr_channel(*ump); 624 } 625 626 /** 627 * \brief get UMP message type from UMP packet pointer 628 */ 629 static inline uint8_t snd_ump_msg_type(const uint32_t *ump) 630 { 631 return snd_ump_msg_hdr_type(*ump); 632 } 633 634 /** 635 * \brief get UMP group from UMP packet pointer 636 */ 637 static inline uint8_t snd_ump_msg_group(const uint32_t *ump) 638 { 639 return snd_ump_msg_hdr_group(*ump); 640 } 641 642 /** 643 * \brief get UMP sysex message status 644 */ 645 static inline uint8_t snd_ump_sysex_msg_status(const uint32_t *ump) 646 { 647 return (*ump >> 20) & 0xf; 648 } 649 650 /** 651 * \brief get UMP sysex message length 652 */ 653 static inline uint8_t snd_ump_sysex_msg_length(const uint32_t *ump) 654 { 655 return (*ump >> 16) & 0xf; 656 } 657 658 int snd_ump_msg_sysex_expand(const uint32_t *ump, uint8_t *buf, size_t maxlen, 659 size_t *filled); 660 661 #ifdef __cplusplus 662 } 663 #endif 664 665 #endif /* __ALSA_UMP_MSG_H */ 666