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  */
snd_ump_msg_hdr_status(uint32_t ump)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  */
snd_ump_msg_hdr_channel(uint32_t ump)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  */
snd_ump_msg_hdr_type(uint32_t ump)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  */
snd_ump_msg_type_is_groupless(uint8_t type)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  */
snd_ump_msg_hdr_group(uint32_t ump)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  */
snd_ump_msg_status(const uint32_t *ump)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  */
snd_ump_msg_channel(const uint32_t *ump)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  */
snd_ump_msg_type(const uint32_t *ump)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  */
snd_ump_msg_group(const uint32_t *ump)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  */
snd_ump_sysex_msg_status(const uint32_t *ump)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  */
snd_ump_sysex_msg_length(const uint32_t *ump)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