Skip to content

Commit 4639762

Browse files
committed
ALSA: seq: Add UMP support
Starting from this commit, we add the basic support of UMP (Universal MIDI Packet) events on ALSA sequencer infrastructure. The biggest change here is that, for transferring UMP packets that are up to 128 bits, we extend the data payload of ALSA sequencer event record when the client is declared to support for the new UMP events. A new event flag bit, SNDRV_SEQ_EVENT_UMP, is defined and it shall be set for the UMP packet events that have the larger payload of 128 bits, defined as struct snd_seq_ump_event. For controlling the UMP feature enablement in kernel, a new Kconfig, CONFIG_SND_SEQ_UMP is introduced. The extended event for UMP is available only when this Kconfig item is set. Similarly, the size of the internal snd_seq_event_cell also increases (in 4 bytes) when the Kconfig item is set. (But the size increase is effective only for 32bit architectures; 64bit archs already have padding there.) Overall, when CONFIG_SND_SEQ_UMP isn't set, there is no change in the event and cell, keeping the old sizes. For applications that want to access the UMP packets, first of all, a sequencer client has to declare the user-protocol to match with the latest one via the new SNDRV_SEQ_IOCTL_USER_PVERSION; otherwise it's treated as if a legacy client without UMP support. Then the client can switch to the new UMP mode (MIDI 1.0 or MIDI 2.0) with a new field, midi_version, in snd_seq_client_info. When switched to UMP mode (midi_version = 1 or 2), the client can write the UMP events with SNDRV_SEQ_EVENT_UMP flag. For reads, the alignment size is changed from snd_seq_event (28 bytes) to snd_seq_ump_event (32 bytes). When a UMP sequencer event is delivered to a legacy sequencer client, it's ignored or handled as an error. Conceptually, ALSA sequencer client and port correspond to the UMP Endpoint and Group, respectively; each client may have multiple ports and each port has the fixed number (16) of channels, total up to 256 channels. As of this commit, ALSA sequencer core just sends and receives the UMP events as-is from/to clients. The automatic conversions between the legacy events and the new UMP events will be implemented in a later patch. Along with this commit, bump the sequencer protocol version to 1.0.3. Reviewed-by: Jaroslav Kysela <perex@perex.cz> Link: https://lore.kernel.org/r/20230523075358.9672-26-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent afb7250 commit 4639762

File tree

8 files changed

+193
-63
lines changed

8 files changed

+193
-63
lines changed

include/sound/asequencer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@
6565
#define snd_seq_ev_is_abstime(ev) (snd_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_ABS)
6666
#define snd_seq_ev_is_reltime(ev) (snd_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_REL)
6767

68+
/* check whether the given event is a UMP event */
69+
#define snd_seq_ev_is_ump(ev) \
70+
(IS_ENABLED(CONFIG_SND_SEQ_UMP) && ((ev)->flags & SNDRV_SEQ_EVENT_UMP))
71+
6872
/* queue sync port */
6973
#define snd_seq_queue_sync_port(q) ((q) + 16)
7074

include/sound/seq_kernel.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ int snd_seq_expand_var_event_at(const struct snd_seq_event *event, int count,
7575
int snd_seq_dump_var_event(const struct snd_seq_event *event,
7676
snd_seq_dump_func_t func, void *private_data);
7777

78+
/* size of the event packet; it can be greater than snd_seq_event size */
79+
static inline size_t snd_seq_event_packet_size(struct snd_seq_event *ev)
80+
{
81+
if (snd_seq_ev_is_ump(ev))
82+
return sizeof(struct snd_seq_ump_event);
83+
return sizeof(struct snd_seq_event);
84+
}
85+
7886
/* interface for OSS emulation */
7987
int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo);
8088

include/uapi/sound/asequencer.h

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
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 {
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 {
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 {
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
@@ -344,9 +360,14 @@ struct snd_seq_client_info {
344360
int event_lost; /* number of lost events */
345361
int card; /* RO: card number[kernel] */
346362
int pid; /* RO: pid[user] */
347-
char reserved[56]; /* for future use */
363+
unsigned int midi_version; /* MIDI version */
364+
char reserved[52]; /* for future use */
348365
};
349366

367+
/* MIDI version numbers in client info */
368+
#define SNDRV_SEQ_CLIENT_LEGACY_MIDI 0 /* Legacy client */
369+
#define SNDRV_SEQ_CLIENT_UMP_MIDI_1_0 1 /* UMP MIDI 1.0 */
370+
#define SNDRV_SEQ_CLIENT_UMP_MIDI_2_0 2 /* UMP MIDI 2.0 */
350371

351372
/* client pool size */
352373
struct snd_seq_client_pool {

sound/core/seq/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,11 @@ config SND_SEQ_MIDI_EMUL
6060
config SND_SEQ_VIRMIDI
6161
tristate
6262

63+
config SND_SEQ_UMP
64+
bool "Support for UMP events"
65+
help
66+
Say Y here to enable the support for handling UMP (Universal MIDI
67+
Packet) events via ALSA sequencer infrastructure, which is an
68+
essential feature for enabling MIDI 2.0 support.
69+
6370
endif # SND_SEQUENCER

0 commit comments

Comments
 (0)