History

Merge branch 'topic/midi20' into for-next

This is a (largish) patch set for adding the support of MIDI 2.0 functionality, mainly targeted for USB devices. MIDI 2.0 is a complete overhaul of the 40-years old MIDI 1.0. Unlike MIDI 1.0 byte stream, MIDI 2.0 uses packets in 32bit words for Universal MIDI Packet (UMP) protocol. It supports both MIDI 1.0 commands for compatibility and the extended MIDI 2.0 commands for higher resolutions and more functions. For supporting the UMP, the patch set extends the existing ALSA rawmidi and sequencer interfaces, and adds the USB MIDI 2.0 support to the standard USB-audio driver. The rawmidi for UMP has a different device name (/dev/snd/umpC*D*) and it reads/writes UMP packet data in 32bit CPU-native endianness. For the old MIDI 1.0 applications, the legacy rawmidi interface is provided, too. As default, USB-audio driver will take the alternate setting for MIDI 2.0 interface, and the compatibility with MIDI 1.0 is provided via the rawmidi common layer. However, user may let the driver falling back to the old MIDI 1.0 interface by a module option, too. A UMP-capable rawmidi device can create the corresponding ALSA sequencer client(s) to support the UMP Endpoint and UMP Group connections. As a nature of ALSA sequencer, arbitrary connections between clients/ports are allowed, and the ALSA sequencer core performs the automatic conversions for the connections between a new UMP sequencer client and a legacy MIDI 1.0 sequencer client. It allows the existing application to use MIDI 2.0 devices without changes. The MIDI-CI, which is another major extension in MIDI 2.0, isn't covered by this patch set. It would be implemented rather in user-space. Roughly speaking, the first half of this patch set is for extending the rawmidi and USB-audio, and the second half is for extending the ALSA sequencer interface. The patch set is based on 6.4-rc2 kernel, but all patches can be cleanly applicable on 6.2 and 6.3 kernels, too (while 6.1 and older kernels would need minor adjustment for uapi header changes). The updates for alsa-lib and alsa-utils will follow shortly later. The author thanks members of MIDI Association OS/API Working Group, especially Andrew Mee, for great helps for the initial design and debugging / testing the drivers.

Takashi Iwai committed 3 years ago

Commit 03a58512 parents 7195fb4 6b39e30234 files · +9190 −2343Browse files

Showing the changes to include/uapi (2 of 234 files). Show all

Unified · Split

2 files
  1. include/uapi/sound/asequencer.h +66 −17
  2. include/uapi/sound/asound.h +60 −2
include/uapi/sound/asequencer.h+66−17
@@ -10,7 +10,7 @@ · 9 unmodified lines
1010 #include <sound/asound.h>
1111
1212 /** version of the sequencer */
13−#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 2)
13+#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 3)
1414
1515 /**
1616 * definition of sequencer event types
@@ -174,6 +174,7 @@ struct snd_seq_connect { · 157 unmodified lines
174174 #define SNDRV_SEQ_PRIORITY_HIGH (1<<4) /* event should be processed before others */
175175 #define SNDRV_SEQ_PRIORITY_MASK (1<<4)
176176
177+#define SNDRV_SEQ_EVENT_UMP (1<<5) /* event holds a UMP packet */
177178
178179 /* note event */
179180 struct snd_seq_ev_note {
@@ -252,6 +253,19 @@ struct snd_seq_ev_quote { · 72 unmodified lines
252253 struct snd_seq_event *event; /* quoted event */
253254 } __attribute__((packed));
254255
256+union snd_seq_event_data { /* event data... */
257+ struct snd_seq_ev_note note;
258+ struct snd_seq_ev_ctrl control;
259+ struct snd_seq_ev_raw8 raw8;
260+ struct snd_seq_ev_raw32 raw32;
261+ struct snd_seq_ev_ext ext;
262+ struct snd_seq_ev_queue_control queue;
263+ union snd_seq_timestamp time;
264+ struct snd_seq_addr addr;
265+ struct snd_seq_connect connect;
266+ struct snd_seq_result result;
267+ struct snd_seq_ev_quote quote;
268+};
255269
256270 /* sequencer event */
257271 struct snd_seq_event {
@@ -262,25 +276,27 @@ struct snd_seq_event { · 4 unmodified lines
262276 unsigned char queue; /* schedule queue */
263277 union snd_seq_timestamp time; /* schedule time */
264278
265−
266279 struct snd_seq_addr source; /* source address */
267280 struct snd_seq_addr dest; /* destination address */
268281
269− union { /* event data... */
270− struct snd_seq_ev_note note;
271− struct snd_seq_ev_ctrl control;
272− struct snd_seq_ev_raw8 raw8;
273− struct snd_seq_ev_raw32 raw32;
274− struct snd_seq_ev_ext ext;
275− struct snd_seq_ev_queue_control queue;
276− union snd_seq_timestamp time;
277− struct snd_seq_addr addr;
278− struct snd_seq_connect connect;
279− struct snd_seq_result result;
280− struct snd_seq_ev_quote quote;
281− } data;
282+ union snd_seq_event_data data;
282283 };
283284
285+ /* (compatible) event for UMP-capable clients */
286+struct snd_seq_ump_event {
287+ snd_seq_event_type_t type; /* event type */
288+ unsigned char flags; /* event flags */
289+ char tag;
290+ unsigned char queue; /* schedule queue */
291+ union snd_seq_timestamp time; /* schedule time */
292+ struct snd_seq_addr source; /* source address */
293+ struct snd_seq_addr dest; /* destination address */
294+
295+ union {
296+ union snd_seq_event_data data;
297+ unsigned int ump[4];
298+ };
299+};
284300
285301 /*
286302 * bounce event - stored as variable size data
@@ -331,6 +347,7 @@ typedef int __bitwise snd_seq_client_type_t; · 44 unmodified lines
331347 #define SNDRV_SEQ_FILTER_BROADCAST (1U<<0) /* accept broadcast messages */
332348 #define SNDRV_SEQ_FILTER_MULTICAST (1U<<1) /* accept multicast messages */
333349 #define SNDRV_SEQ_FILTER_BOUNCE (1U<<2) /* accept bounce event in error */
350+#define SNDRV_SEQ_FILTER_NO_CONVERT (1U<<30) /* don't convert UMP events */
334351 #define SNDRV_SEQ_FILTER_USE_EVENT (1U<<31) /* use event filter */
335352
336353 struct snd_seq_client_info {
@@ -344,9 +361,15 @@ struct snd_seq_client_info { · 7 unmodified lines
344361 int event_lost; /* number of lost events */
345362 int card; /* RO: card number[kernel] */
346363 int pid; /* RO: pid[user] */
347− char reserved[56]; /* for future use */
364+ unsigned int midi_version; /* MIDI version */
365+ unsigned int group_filter; /* UMP group filter bitmap (for 1-based Group indices) */
366+ char reserved[48]; /* for future use */
348367 };
349368
369+/* MIDI version numbers in client info */
370+#define SNDRV_SEQ_CLIENT_LEGACY_MIDI 0 /* Legacy client */
371+#define SNDRV_SEQ_CLIENT_UMP_MIDI_1_0 1 /* UMP MIDI 1.0 */
372+#define SNDRV_SEQ_CLIENT_UMP_MIDI_2_0 2 /* UMP MIDI 2.0 */
350373
351374 /* client pool size */
352375 struct snd_seq_client_pool {
@@ -406,6 +429,8 @@ struct snd_seq_remove_events { · 53 unmodified lines
406429 #define SNDRV_SEQ_PORT_CAP_SUBS_READ (1<<5) /* allow read subscription */
407430 #define SNDRV_SEQ_PORT_CAP_SUBS_WRITE (1<<6) /* allow write subscription */
408431 #define SNDRV_SEQ_PORT_CAP_NO_EXPORT (1<<7) /* routing not allowed */
432+#define SNDRV_SEQ_PORT_CAP_INACTIVE (1<<8) /* inactive port */
433+#define SNDRV_SEQ_PORT_CAP_UMP_ENDPOINT (1<<9) /* MIDI 2.0 UMP Endpoint port */
409434
410435 /* port type */
411436 #define SNDRV_SEQ_PORT_TYPE_SPECIFIC (1<<0) /* hardware specific */
@@ -415,6 +440,7 @@ struct snd_seq_remove_events { · 3 unmodified lines
415440 #define SNDRV_SEQ_PORT_TYPE_MIDI_XG (1<<4) /* XG compatible device */
416441 #define SNDRV_SEQ_PORT_TYPE_MIDI_MT32 (1<<5) /* MT-32 compatible device */
417442 #define SNDRV_SEQ_PORT_TYPE_MIDI_GM2 (1<<6) /* General MIDI 2 compatible device */
443+#define SNDRV_SEQ_PORT_TYPE_MIDI_UMP (1<<7) /* UMP */
418444
419445 /* other standards...*/
420446 #define SNDRV_SEQ_PORT_TYPE_SYNTH (1<<10) /* Synth device (no MIDI compatible - direct wavetable) */
@@ -432,6 +458,12 @@ struct snd_seq_remove_events { · 11 unmodified lines
432458 #define SNDRV_SEQ_PORT_FLG_TIMESTAMP (1<<1)
433459 #define SNDRV_SEQ_PORT_FLG_TIME_REAL (1<<2)
434460
461+/* port direction */
462+#define SNDRV_SEQ_PORT_DIR_UNKNOWN 0
463+#define SNDRV_SEQ_PORT_DIR_INPUT 1
464+#define SNDRV_SEQ_PORT_DIR_OUTPUT 2
465+#define SNDRV_SEQ_PORT_DIR_BIDIRECTION 3
466+
435467 struct snd_seq_port_info {
436468 struct snd_seq_addr addr; /* client/port numbers */
437469 char name[64]; /* port name */
@@ -448,7 +480,9 @@ struct snd_seq_port_info { · 10 unmodified lines
448480 void *kernel; /* reserved for kernel use (must be NULL) */
449481 unsigned int flags; /* misc. conditioning */
450482 unsigned char time_queue; /* queue # for timestamping */
451− char reserved[59]; /* for future use */
483+ unsigned char direction; /* port usage direction (r/w/bidir) */
484+ unsigned char ump_group; /* 0 = UMP EP (no conversion), 1-16 = UMP group number */
485+ char reserved[57]; /* for future use */
452486 };
453487
454488
@@ -552,6 +586,18 @@ struct snd_seq_query_subs { · 97 unmodified lines
552586 char reserved[64]; /* for future use */
553587 };
554588
589+/*
590+ * UMP-specific information
591+ */
592+/* type of UMP info query */
593+#define SNDRV_SEQ_CLIENT_UMP_INFO_ENDPOINT 0
594+#define SNDRV_SEQ_CLIENT_UMP_INFO_BLOCK 1
595+
596+struct snd_seq_client_ump_info {
597+ int client; /* client number to inquire/set */
598+ int type; /* type to inquire/set */
599+ unsigned char info[512]; /* info (either UMP ep or block info) */
600+} __packed;
555601
556602 /*
557603 * IOCTL commands
@@ -561,9 +607,12 @@ struct snd_seq_query_subs { · 3 unmodified lines
561607 #define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR ('S', 0x01, int)
562608 #define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct snd_seq_system_info)
563609 #define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct snd_seq_running_info)
610+#define SNDRV_SEQ_IOCTL_USER_PVERSION _IOW('S', 0x04, int)
564611
565612 #define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct snd_seq_client_info)
566613 #define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW ('S', 0x11, struct snd_seq_client_info)
614+#define SNDRV_SEQ_IOCTL_GET_CLIENT_UMP_INFO _IOWR('S', 0x12, struct snd_seq_client_ump_info)
615+#define SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO _IOWR('S', 0x13, struct snd_seq_client_ump_info)
567616
568617 #define SNDRV_SEQ_IOCTL_CREATE_PORT _IOWR('S', 0x20, struct snd_seq_port_info)
569618 #define SNDRV_SEQ_IOCTL_DELETE_PORT _IOW ('S', 0x21, struct snd_seq_port_info)
include/uapi/sound/asound.h+60−2
@@ -712,7 +712,7 @@ enum { · 711 unmodified lines
712712 * Raw MIDI section - /dev/snd/midi??
713713 */
714714
715−#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 2)
715+#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 3)
716716
717717 enum {
718718 SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
@@ -723,6 +723,7 @@ enum { · 4 unmodified lines
723723 #define SNDRV_RAWMIDI_INFO_OUTPUT 0x00000001
724724 #define SNDRV_RAWMIDI_INFO_INPUT 0x00000002
725725 #define SNDRV_RAWMIDI_INFO_DUPLEX 0x00000004
726+#define SNDRV_RAWMIDI_INFO_UMP 0x00000008
726727
727728 struct snd_rawmidi_info {
728729 unsigned int device; /* RO/WR (control): device number */
@@ -783,6 +784,57 @@ struct snd_rawmidi_status { · 54 unmodified lines
783784 };
784785 #endif
785786
787+/* UMP EP Protocol / JRTS capability bits */
788+#define SNDRV_UMP_EP_INFO_PROTO_MIDI_MASK 0x0300
789+#define SNDRV_UMP_EP_INFO_PROTO_MIDI1 0x0100 /* MIDI 1.0 */
790+#define SNDRV_UMP_EP_INFO_PROTO_MIDI2 0x0200 /* MIDI 2.0 */
791+#define SNDRV_UMP_EP_INFO_PROTO_JRTS_MASK 0x0003
792+#define SNDRV_UMP_EP_INFO_PROTO_JRTS_TX 0x0001 /* JRTS Transmit */
793+#define SNDRV_UMP_EP_INFO_PROTO_JRTS_RX 0x0002 /* JRTS Receive */
794+
795+/* UMP Endpoint information */
796+struct snd_ump_endpoint_info {
797+ int card; /* card number */
798+ int device; /* device number */
799+ unsigned int flags; /* additional info */
800+ unsigned int protocol_caps; /* protocol capabilities */
801+ unsigned int protocol; /* current protocol */
802+ unsigned int num_blocks; /* # of function blocks */
803+ unsigned short version; /* UMP major/minor version */
804+ unsigned short padding[7];
805+ unsigned char name[128]; /* endpoint name string */
806+ unsigned char product_id[128]; /* unique product id string */
807+ unsigned char reserved[32];
808+} __packed;
809+
810+/* UMP direction */
811+#define SNDRV_UMP_DIR_INPUT 0x01
812+#define SNDRV_UMP_DIR_OUTPUT 0x02
813+#define SNDRV_UMP_DIR_BIDIRECTION 0x03
814+
815+/* UMP block info flags */
816+#define SNDRV_UMP_BLOCK_IS_MIDI1 (1U << 0) /* MIDI 1.0 port w/o restrict */
817+#define SNDRV_UMP_BLOCK_IS_LOWSPEED (1U << 1) /* 31.25Kbps B/W MIDI1 port */
818+
819+/* UMP groups and blocks */
820+#define SNDRV_UMP_MAX_GROUPS 16
821+#define SNDRV_UMP_MAX_BLOCKS 32
822+
823+/* UMP Block information */
824+struct snd_ump_block_info {
825+ int card; /* card number */
826+ int device; /* device number */
827+ unsigned char block_id; /* block ID (R/W) */
828+ unsigned char direction; /* UMP direction */
829+ unsigned char active; /* Activeness */
830+ unsigned char first_group; /* first group ID */
831+ unsigned char num_groups; /* number of groups */
832+ unsigned char padding[3];
833+ unsigned int flags; /* various info flags */
834+ unsigned char name[128]; /* block name string */
835+ unsigned char reserved[32];
836+} __packed;
837+
786838 #define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int)
787839 #define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info)
788840 #define SNDRV_RAWMIDI_IOCTL_USER_PVERSION _IOW('W', 0x02, int)
@@ -790,6 +842,9 @@ struct snd_rawmidi_status { · 1 unmodified line
790842 #define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status)
791843 #define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int)
792844 #define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int)
845+/* Additional ioctls for UMP rawmidi devices */
846+#define SNDRV_UMP_IOCTL_ENDPOINT_INFO _IOR('W', 0x40, struct snd_ump_endpoint_info)
847+#define SNDRV_UMP_IOCTL_BLOCK_INFO _IOR('W', 0x41, struct snd_ump_block_info)
793848
794849 /*
795850 * Timer section - /dev/snd/timer
@@ -965,7 +1020,7 @@ struct snd_timer_tread { · 169 unmodified lines
9651020 * *
9661021 ****************************************************************************/
9671022
968−#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8)
1023+#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 9)
9691024
9701025 struct snd_ctl_card_info {
9711026 int card; /* card number */
@@ -1126,6 +1181,9 @@ struct snd_ctl_tlv { · 154 unmodified lines
11261181 #define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int)
11271182 #define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct snd_rawmidi_info)
11281183 #define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
1184+#define SNDRV_CTL_IOCTL_UMP_NEXT_DEVICE _IOWR('U', 0x43, int)
1185+#define SNDRV_CTL_IOCTL_UMP_ENDPOINT_INFO _IOWR('U', 0x44, struct snd_ump_endpoint_info)
1186+#define SNDRV_CTL_IOCTL_UMP_BLOCK_INFO _IOWR('U', 0x45, struct snd_ump_block_info)
11291187 #define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int)
11301188 #define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int)
11311189

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t